'Return a string that matches a named route. Use keyword arguments
to fill out named wildcards. Remaining arguments are appended as a
query string. Raises RouteBuildError or KeyError.'

def build(self, _name, *anon, **args):

    if (_name not in self.named):
        raise RouteBuildError('No    route    with    that    name.', _name)
    (rule, pairs) = self.named[_name]
    if (not pairs):
        token = self.syntax.split(rule)
        parts = [p.replace('\\:', ':') for p in token[::3]]
        names = token[1::3]
        if (len(parts) > len(names)):
            names.append(None)
        pairs = zip(parts, names)
        self.named[_name] = (rule, pairs)
    try:
        anon = list(anon)
        url = [(s if (k is None) else ((s + str(args.pop(k))) if k else (s + str(anon.pop())))) for (s, k) in pairs]
    except IndexError:
        msg = 'Not    enough    arguments    to    fill    out    anonymous    wildcards.'
        raise RouteBuildError(msg)
    except KeyError as e:
        raise RouteBuildError(*e.args)
    if args:
        url += ['?', urlencode(args)]
    return ''.join(url)
