@Override
  public void handle(
      final String target,
      final Request baseRequest,
      final HttpServletRequest request,
      final HttpServletResponse response)
      throws IOException, ServletException {
    if (!isStarted()) {
      return;
    }

    final ContextModel matched = serverModel.matchPathToContext(target);
    if (matched != null) {
      // check for nulls and start complaining
      NullArgumentException.validateNotNull(
          matched.getHttpContext(), "The http Context of " + matched.getContextName() + " is null");
      NullArgumentException.validateNotNull(getServer(), "The server is null!");

      final ContextHandler context =
          ((JettyServerWrapper) getServer()).getContext(matched.getHttpContext());

      try {
        NullArgumentException.validateNotNull(context, "Found context is Null");
        context.handle(target, baseRequest, request, response);

        // CHECKSTYLE:OFF
      } catch (EofException e) {
        throw e;
      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new ServletException(e);
      }
      // CHECKSTYLE:ON

    }
    // now handle all other handlers
    for (Handler handler : getHandlers()) {
      if (matched != null && matchedContextEqualsHandler(matched, handler)) {
        continue;
      }
      handler.handle(target, baseRequest, request, response);
    }
  }
  /*
   * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
   */
  protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch)
      throws ServletException, IOException {
    Request baseRequest =
        (request instanceof Request)
            ? ((Request) request)
            : HttpChannel.getCurrentHttpChannel().getRequest();
    Response base_response = baseRequest.getResponse();
    base_response.resetForForward();

    if (!(request instanceof HttpServletRequest)) request = new ServletRequestHttpWrapper(request);
    if (!(response instanceof HttpServletResponse))
      response = new ServletResponseHttpWrapper(response);

    final boolean old_handled = baseRequest.isHandled();
    final String old_uri = baseRequest.getRequestURI();
    final String old_context_path = baseRequest.getContextPath();
    final String old_servlet_path = baseRequest.getServletPath();
    final String old_path_info = baseRequest.getPathInfo();
    final String old_query = baseRequest.getQueryString();
    final Attributes old_attr = baseRequest.getAttributes();
    final DispatcherType old_type = baseRequest.getDispatcherType();
    MultiMap<String> old_params = baseRequest.getParameters();

    try {
      baseRequest.setHandled(false);
      baseRequest.setDispatcherType(dispatch);

      if (_named != null)
        _contextHandler.handle(
            _named, baseRequest, (HttpServletRequest) request, (HttpServletResponse) response);
      else {

        // process any query string from the dispatch URL
        String query = _dQuery;
        if (query != null) {
          // force parameter extraction
          if (old_params == null) {
            baseRequest.extractParameters();
            old_params = baseRequest.getParameters();
          }

          baseRequest.mergeQueryString(query);
        }

        ForwardAttributes attr = new ForwardAttributes(old_attr);

        // If we have already been forwarded previously, then keep using the established
        // original value. Otherwise, this is the first forward and we need to establish the values.
        // Note: the established value on the original request for pathInfo and
        // for queryString is allowed to be null, but cannot be null for the other values.
        if (old_attr.getAttribute(FORWARD_REQUEST_URI) != null) {
          attr._pathInfo = (String) old_attr.getAttribute(FORWARD_PATH_INFO);
          attr._query = (String) old_attr.getAttribute(FORWARD_QUERY_STRING);
          attr._requestURI = (String) old_attr.getAttribute(FORWARD_REQUEST_URI);
          attr._contextPath = (String) old_attr.getAttribute(FORWARD_CONTEXT_PATH);
          attr._servletPath = (String) old_attr.getAttribute(FORWARD_SERVLET_PATH);
        } else {
          attr._pathInfo = old_path_info;
          attr._query = old_query;
          attr._requestURI = old_uri;
          attr._contextPath = old_context_path;
          attr._servletPath = old_servlet_path;
        }

        baseRequest.setRequestURI(_uri);
        baseRequest.setContextPath(_contextHandler.getContextPath());
        baseRequest.setServletPath(null);
        baseRequest.setPathInfo(_uri);
        baseRequest.setAttributes(attr);

        _contextHandler.handle(
            _path, baseRequest, (HttpServletRequest) request, (HttpServletResponse) response);

        if (!baseRequest.getHttpChannelState().isAsync()) commitResponse(response, baseRequest);
      }
    } finally {
      baseRequest.setHandled(old_handled);
      baseRequest.setRequestURI(old_uri);
      baseRequest.setContextPath(old_context_path);
      baseRequest.setServletPath(old_servlet_path);
      baseRequest.setPathInfo(old_path_info);
      baseRequest.setAttributes(old_attr);
      baseRequest.setParameters(old_params);
      baseRequest.setQueryString(old_query);
      baseRequest.setDispatcherType(old_type);
    }
  }
  /*
   * @see javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
   */
  @Override
  public void include(ServletRequest request, ServletResponse response)
      throws ServletException, IOException {
    Request baseRequest =
        (request instanceof Request)
            ? ((Request) request)
            : HttpChannel.getCurrentHttpChannel().getRequest();

    if (!(request instanceof HttpServletRequest)) request = new ServletRequestHttpWrapper(request);
    if (!(response instanceof HttpServletResponse))
      response = new ServletResponseHttpWrapper(response);

    final DispatcherType old_type = baseRequest.getDispatcherType();
    final Attributes old_attr = baseRequest.getAttributes();
    MultiMap<String> old_params = baseRequest.getParameters();
    try {
      baseRequest.setDispatcherType(DispatcherType.INCLUDE);
      baseRequest.getResponse().include();
      if (_named != null)
        _contextHandler.handle(
            _named, baseRequest, (HttpServletRequest) request, (HttpServletResponse) response);
      else {
        String query = _dQuery;

        if (query != null) {
          // force parameter extraction
          if (old_params == null) {
            baseRequest.extractParameters();
            old_params = baseRequest.getParameters();
          }

          MultiMap<String> parameters = new MultiMap<>();
          UrlEncoded.decodeTo(query, parameters, baseRequest.getCharacterEncoding(), -1);

          if (old_params != null) {
            // Merge parameters.
            parameters.addAllValues(old_params);
          }
          baseRequest.setParameters(parameters);
        }

        IncludeAttributes attr = new IncludeAttributes(old_attr);

        attr._requestURI = _uri;
        attr._contextPath = _contextHandler.getContextPath();
        attr._servletPath = null; // set by ServletHandler
        attr._pathInfo = _path;
        attr._query = query;

        baseRequest.setAttributes(attr);

        _contextHandler.handle(
            _path, baseRequest, (HttpServletRequest) request, (HttpServletResponse) response);
      }
    } finally {
      baseRequest.setAttributes(old_attr);
      baseRequest.getResponse().included();
      baseRequest.setParameters(old_params);
      baseRequest.setDispatcherType(old_type);
    }
  }
 void runInContext(AsyncContextEvent event, Runnable runnable) {
   ContextHandler contextHandler = getContextHandler(event);
   if (contextHandler == null) runnable.run();
   else contextHandler.handle(_channel.getRequest(), runnable);
 }