docs: def resolve_handler(request, view_handlers):
      """Select a suitable handler to handle the request.
  
      Returns a (handler, vary) tuple, where handler is a handler_metadata tuple
      and vary is a set containing header names that were used during content
      negotiation and that should be included in the 'Vary' header of the
      outgoing response.
  
      When no suitable handler exists, raises NotFound, MethodNotAllowed,
      UnsupportedMediaType or NotAcceptable.
      """
      view = None
      if request._context:  # Allow context to be missing for easier testing
          route_name = request._context[-1].route.name
          if route_name and VIEW_SEPARATOR in route_name:
              view = route_name.split(VIEW_SEPARATOR, 1)[1] or None
  
      if view not in view_handlers:
          raise NotFound
  
      method_handlers = view_handlers[view]
  
      verb = request.method
      if verb not in method_handlers:
          if verb == 'HEAD' and 'GET' in method_handlers:
              verb = 'GET'
          else:
              allowed_methods = set(method_handlers.keys())
              if 'HEAD' not in allowed_methods and 'GET' in allowed_methods:
                  allowed_methods.add('HEAD')
              allow = ', '.join(sorted(allowed_methods))
              raise MethodNotAllowed(allow=allow)
  
      handlers = method_handlers[verb]
      vary = set()
      if len(set(h.provides for h in handlers if h.provides is not None)) > 1:
          vary.add('Accept')
      if len(set(h.accepts for h in handlers)) > 1:
          vary.add('Content-Type')
  
      content_type = request.content_type
      if content_type:
          handlers = negotiate_content_type(content_type, handlers)
          if not handlers:
              raise UnsupportedMediaType
  
      accept = request.headers.get('Accept')
      if accept:
          handlers = negotiate_accept(accept, handlers)
          if not handlers:
              raise NotAcceptable
  
      return handlers[0], vary