Return tuple (pos args, kwargs) to call given callable

    Let's define a callable that will printout

    >>> arguments = {'alphonse': 1, 'bertrand': 2, 'charlie': 3}

    >>> match_prototype(lambda arguments: None, arguments)
    ([{'bertrand': 2, 'charlie': 3, 'alphonse': 1}], {})
    >>> match_prototype(lambda args: None, arguments)
    ([{'bertrand': 2, 'charlie': 3, 'alphonse': 1}], {})


    >>> match_prototype(lambda bertrand, arguments: None, arguments)
    ([2, {'charlie': 3, 'alphonse': 1}], {})

    >>> match_prototype(lambda bertrand, arguments, foo=None: None, arguments)
    ([2, {'charlie': 3, 'alphonse': 1}], {})

    >>> match_prototype(lambda bertrand, arguments, charlie=None: None,
    ...                 arguments)
    ([2, {'alphonse': 1}], {'charlie': 3})

def match_prototype(acallable, arguments):
    """Return tuple (pos args, kwargs) to call given callable

    Let's define a callable that will printout

    >>> arguments = {'alphonse': 1, 'bertrand': 2, 'charlie': 3}

    >>> match_prototype(lambda arguments: None, arguments)
    ([{'bertrand': 2, 'charlie': 3, 'alphonse': 1}], {})
    >>> match_prototype(lambda args: None, arguments)
    ([{'bertrand': 2, 'charlie': 3, 'alphonse': 1}], {})


    >>> match_prototype(lambda bertrand, arguments: None, arguments)
    ([2, {'charlie': 3, 'alphonse': 1}], {})

    >>> match_prototype(lambda bertrand, arguments, foo=None: None, arguments)
    ([2, {'charlie': 3, 'alphonse': 1}], {})

    >>> match_prototype(lambda bertrand, arguments, charlie=None: None,
    ...                 arguments)
    ([2, {'alphonse': 1}], {'charlie': 3})

    """

    args, defaults = get_calling_prototype(acallable)
    arguments = arguments.copy()
    defaults = [] if defaults is None else defaults
    p = []
    kw = {}

    pos_args = len(args) - len(defaults)
    has_args = any(k in ('args', 'arguments')
                   for k in args)
    args_label_pos = None
    for i, arg in enumerate(args):
        is_pos = i < pos_args
        val = None
        if not args_label_pos and arg in ('arguments', 'args'):
            val = arguments  ## copy by reference here is important
        else:
            k = None
            for k in arguments:
                norm = k
                if norm.startswith("--"):
                    if is_pos:
                        continue
                    norm = norm[2:]
                elif k.startswith("-"):
                    if is_pos:
                        continue
                    norm = norm[1:]
                norm = norm.lower()
                norm = norm.replace('-', '_')
                if norm == arg:
                    break
            else:
                if not has_args:
                    raise SyntaxError(
                        "Can't match your function argument %r with "
                        "command line keys (%s)."
                        % (arg, ", ".join(arguments.keys())))
                else:
                    k = None
            if k is not None:
                ## inplace removal is important here
                val = arguments.pop(k)
        if is_pos:
            p.append(val)
        else:
            if val is not None:
                ## we should only have strings if it was set.
                kw[arg] = val
    return p, kw