docs: def match(self, path_info=None, method=None, return_rule=False,
                query_args=None):
          """The usage is simple: you just pass the match method the current
          path info as well as the method (which defaults to `GET`).  The
          following things can then happen:
  
          - you receive a `NotFound` exception that indicates that no URL is
            matching.  A `NotFound` exception is also a WSGI application you
            can call to get a default page not found page (happens to be the
            same object as `werkzeug.exceptions.NotFound`)
  
          - you receive a `MethodNotAllowed` exception that indicates that there
            is a match for this URL but not for the current request method.
            This is useful for RESTful applications.
  
          - you receive a `RequestRedirect` exception with a `new_url`
            attribute.  This exception is used to notify you about a request
            Werkzeug requests from your WSGI application.  This is for example the
            case if you request ``/foo`` although the correct URL is ``/foo/``
            You can use the `RequestRedirect` instance as response-like object
            similar to all other subclasses of `HTTPException`.
  
          - you get a tuple in the form ``(endpoint, arguments)`` if there is
            a match (unless `return_rule` is True, in which case you get a tuple
            in the form ``(rule, arguments)``)
  
          If the path info is not passed to the match method the default path
          info of the map is used (defaults to the root URL if not defined
          explicitly).
  
          All of the exceptions raised are subclasses of `HTTPException` so they
          can be used as WSGI responses.  The will all render generic error or
          redirect pages.
  
          Here is a small example for matching:
  
          >>> m = Map([
          ...     Rule('/', endpoint='index'),
          ...     Rule('/downloads/', endpoint='downloads/index'),
          ...     Rule('/downloads/<int:id>', endpoint='downloads/show')
          ... ])
          >>> urls = m.bind("example.com", "/")
          >>> urls.match("/", "GET")
          ('index', {})
          >>> urls.match("/downloads/42")
          ('downloads/show', {'id': 42})
  
          And here is what happens on redirect and missing URLs:
  
          >>> urls.match("/downloads")
          Traceback (most recent call last):
            ...
          RequestRedirect: http://example.com/downloads/
          >>> urls.match("/missing")
          Traceback (most recent call last):
            ...
          NotFound: 404 Not Found
  
          :param path_info: the path info to use for matching.  Overrides the
                            path info specified on binding.
          :param method: the HTTP method used for matching.  Overrides the
                         method specified on binding.
          :param return_rule: return the rule that matched instead of just the
                              endpoint (defaults to `False`).
          :param query_args: optional query arguments that are used for
                             automatic redirects as string or dictionary.  It's
                             currently not possible to use the query arguments
                             for URL matching.
  
          .. versionadded:: 0.6
             `return_rule` was added.
  
          .. versionadded:: 0.7
             `query_args` was added.
  
          .. versionchanged:: 0.8
             `query_args` can now also be a string.
          """
          self.map.update()
          if path_info is None:
              path_info = self.path_info
          else:
              path_info = to_unicode(path_info, self.map.charset)
          if query_args is None:
              query_args = self.query_args
          method = (method or self.default_method).upper()
  
          path = u'%s|/%s' % (self.map.host_matching and self.server_name or
                              self.subdomain, path_info.lstrip('/'))
  
          have_match_for = set()
          for rule in self.map._rules:
              try:
                  rv = rule.match(path)
              except RequestSlash:
                  raise RequestRedirect(self.make_redirect_url(
                      path_info + '/', query_args))
              except RequestAliasRedirect as e:
                  raise RequestRedirect(self.make_alias_redirect_url(
                      path, rule.endpoint, e.matched_values, method, query_args))
              if rv is None:
                  continue
              if rule.methods is not None and method not in rule.methods:
                  have_match_for.update(rule.methods)
                  continue
  
              if self.map.redirect_defaults:
                  redirect_url = self.get_default_redirect(rule, method, rv,
                                                           query_args)
                  if redirect_url is not None:
                      raise RequestRedirect(redirect_url)
  
              if rule.redirect_to is not None:
                  if isinstance(rule.redirect_to, string_types):
                      def _handle_match(match):
                          value = rv[match.group(1)]
                          return rule._converters[match.group(1)].to_url(value)
                      redirect_url = _simple_rule_re.sub(_handle_match,
                                                         rule.redirect_to)
                  else:
                      redirect_url = rule.redirect_to(self, **rv)
                  raise RequestRedirect(str(urljoin('%s://%s%s%s' % (
                      self.url_scheme,
                      self.subdomain and self.subdomain + '.' or '',
                      self.server_name,
                      self.script_name
                  ), redirect_url)))
  
              if return_rule:
                  return rule, rv
              else:
                  return rule.endpoint, rv
  
          if have_match_for:
              raise MethodNotAllowed(valid_methods=list(have_match_for))
          raise NotFound()