Creates an argparse.ArgumentParser from the function's signature.

        Arguments with no default are compulsary positional arguments,
        Arguments with defaults are optional --flags.

        If the default is True or False, the action of the flag will
        toggle the argument and the flag takes no parameters.

        If the default is None or a unicode string, the flag takes a
        string argument that passed to the function as a unicode string
        decoded using entrypoint.ENCODING

        If the default is a string, then the argument is passed as a binary
        string (be careful!), an int and a float cause parsing of those too.

        If you want the arguments to be a file, consider using the
        @withfile decorator.

        Documentation can be read out of the function's docstring, which should
        be of the basic form:
        '''
            A short introduction to your program.

                arg: Help for positional parameter.
                frm/from: Help for a positional parameter
                          with a reserved public name
                          (i.e. this displays to the user as "from"
                          but sets the "frm" variable)
                --opt: Help for optional parameter.
                -f --flag: An optional parameter that has a short version.
                --mode=MODE: An optional parameter that takes a MODE
                -t --type: A combination of both of the above, and one
                                which requires continuing of the documentation
                                on an indented line

            An epilog explaining anything you feel needs further clarity.

            ----

            Any documentation for the function itself that isn't covered by the
            public documentation above the line.
        '''

        All sections, and indeed the presence of a docstring, are not required.

        NOTE: for this to work, the function's signature must be in-tact
              some decorators (like @acceptargv for example) destroy, or
              mutilate the signature.

def signature_parser(func):
    """
        Creates an argparse.ArgumentParser from the function's signature.

        Arguments with no default are compulsary positional arguments,
        Arguments with defaults are optional --flags.

        If the default is True or False, the action of the flag will
        toggle the argument and the flag takes no parameters.

        If the default is None or a unicode string, the flag takes a
        string argument that passed to the function as a unicode string
        decoded using entrypoint.ENCODING

        If the default is a string, then the argument is passed as a binary
        string (be careful!), an int and a float cause parsing of those too.

        If you want the arguments to be a file, consider using the
        @withfile decorator.

        Documentation can be read out of the function's docstring, which should
        be of the basic form:
        '''
            A short introduction to your program.

                arg: Help for positional parameter.
                frm/from: Help for a positional parameter
                          with a reserved public name
                          (i.e. this displays to the user as "from"
                          but sets the "frm" variable)
                --opt: Help for optional parameter.
                -f --flag: An optional parameter that has a short version.
                --mode=MODE: An optional parameter that takes a MODE
                -t --type: A combination of both of the above, and one
                                which requires continuing of the documentation
                                on an indented line

            An epilog explaining anything you feel needs further clarity.

            ----

            Any documentation for the function itself that isn't covered by the
            public documentation above the line.
        '''

        All sections, and indeed the presence of a docstring, are not required.

        NOTE: for this to work, the function's signature must be in-tact
              some decorators (like @acceptargv for example) destroy, or
              mutilate the signature.
    """

    args, trail, kwargs, defaults = inspect.getargspec(func)

    if not args:
        args = []

    if not defaults:
        defaults = []

    if kwargs:
        raise Exception("Can't wrap a function with **kwargs")

    # Compulsary positional options
    needed = args[0:len(args) - len(defaults)]

    # Optional flag options
    params = args[len(needed):]

    shorts, metavars, helps, description, epilog = _parse_doc(func.__doc__)

    parser = argparse.ArgumentParser(
        description=description,
        epilog=epilog,
        formatter_class=ParagraphPreservingArgParseFormatter)

    # special flags
    special_flags = []

    special_flags += ['debug']
    defaults += (False,)
    helps['debug'] = 'set logging level to DEBUG'
    if module_version(func):
        special_flags += ['version']
        defaults += (False,)
        helps['version'] = "show program's version number and exit"
    params += special_flags

    # Optional flag options
    used_shorts = set()
    for param, default in zip(params, defaults):
        args = ["--%s" % param.replace("_", "-")]
        short = None
        if param in shorts:
            short = shorts[param]
        else:
            if param not in special_flags and len(param) > 1:
                first_char = param[0]
                if first_char not in used_shorts:
                    used_shorts.add(first_char)
                    short = '-' + first_char
        # -h conflicts with 'help'
        if short and short != '-h':
            args = [short] + args

        kwargs = {'default': default, 'dest': param.replace("-", "_")}

        if param == 'version':
            kwargs['action'] = 'version'
            kwargs['version'] = module_version(func)
        elif default is True:
            kwargs['action'] = 'store_false'
        elif default is False:
            kwargs['action'] = 'store_true'
        elif isinstance(default, list):
            kwargs['action'] = 'append'
#  default is not working
#            if len(default):
#                first = default[0]
#                if type(first) in [type(None), unicode]:
#                    kwargs['type'] = unidecode
#                else:
#                    kwargs['type'] = type(first)
#                kwargs['default'] = []
#            else:
            kwargs['type'] = unidecode
        else:
            kwargs['action'] = 'store'
            if type(default) in [type(None), unicode]:
                kwargs['type'] = unidecode
            else:
                kwargs['type'] = type(default)

        if param in helps:
            kwargs['help'] = helps[param]

        if param in metavars:
            kwargs['metavar'] = metavars[param]

        parser.add_argument(*args, **kwargs)

    # Compulsary positional options
    for need in needed:

        kwargs = {'action': 'store', 'type': unidecode}

        if need in helps:
            kwargs['help'] = helps[need]

        if need in shorts:
            args = [shorts[need]]
        else:
            args = [need]

        parser.add_argument(*args, **kwargs)

    # The trailing arguments
    if trail:
        kwargs = {'action': 'store', 'type': unidecode, 'nargs': "*"}

        if trail in helps:
            kwargs['help'] = helps[trail]

        if trail in shorts:
            kwargs['metavar'] = shorts[trail]
        else:
            kwargs['metavar'] = trail

        parser.add_argument('__args', **kwargs)

    return parser