public void service(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String method = req.getMethod();
    String path = req.getPathInfo();
    String query = req.getQueryString();

    ClassificationResult classification = processor.classifyRequest(method, path, query);

    if (supportCors != Cors.NONE) {
      addCorsHeaders(req, resp);
    }
    switch (classification.getStatus()) {
      case INVALID_PATH:
        sendError(resp, HttpServletResponse.SC_NOT_FOUND, "Invalid path " + path);
        break;
      case INVALID_METHOD:
        resp.setHeader("Allow", makeAllowHeader(classification));
        sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method not allowed: " + method);
        break;
      case REQUIRED_QPS_MISSING:
        sendError(
            resp,
            HttpServletResponse.SC_BAD_REQUEST,
            "Required query parameters missing: " + classification.getMissingQueryParams());
        break;
      case INVALID_QP_VALUE:
        sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Bad query parameter value");
        break;
      case EXTRA_QPS:
        processRequest(classification, req, resp);
        break;
      case SUCCESSFUL:
        if (req.getMethod().equalsIgnoreCase("OPTIONS")) {
          resp.setHeader("Allow", makeAllowHeader(classification));
          if (supportCors != Cors.NONE) {
            addOptionsCorsHeaders(req, resp, classification);
          }
        } else {
          processRequest(classification, req, resp);
        }
        break;
      default:
        throw new AssertionError();
    }
  }
  private void buildAPIProcessor(String model, String mapping, ServletConfig cfg)
      throws IOException, ServletException, APIModelException {
    InputStream modelIn = getClass().getResourceAsStream(model);
    if (modelIn == null) {
      throw new ServletException("API model \"" + model + "\" not found");
    }

    List<API> apis;
    try {
      if (model.endsWith(".xml") || model.endsWith(".wadl")) {
        apis = WADLReader.get().readModel("API", modelIn);
      } else if (model.endsWith(".txt") || model.endsWith(".md")) {
        apis = APITextReader.get().readModel("API", modelIn);
      } else {
        throw new ServletException("API model extension not supported for \"" + model + '\"');
      }
    } finally {
      modelIn.close();
    }

    log("Successfully read the API model from " + model);

    InputStream mappingIn = getClass().getResourceAsStream(mapping);
    if (mappingIn == null) {
      throw new ServletException("API mapping file \"" + mapping + "\" not found");
    }
    Properties mappingProps = new Properties();
    try {
      mappingProps.load(mappingIn);
    } finally {
      mappingIn.close();
    }

    log("Successfully loaded the object mapping from " + mapping);

    processor = APIProcessorFactory.get().createProcessor(apis);
    for (String resName : mappingProps.stringPropertyNames()) {
      String className = mappingProps.getProperty(resName);
      Class<?> contextClass;
      try {
        contextClass = getClass().getClassLoader().loadClass(className);
      } catch (ClassNotFoundException cnfe) {
        throw new APIModelException("Cannot load class \"" + className + '\"', cnfe);
      }

      Object newHandler;
      try {
        newHandler = contextClass.newInstance();
      } catch (InstantiationException ie) {
        throw new APIModelException("Can't create instance of \"" + className + '\"', ie);
      } catch (IllegalAccessException iae) {
        throw new APIModelException("Can't create instance of \"" + className + '\"', iae);
      }

      Object realHandler;
      if (newHandler instanceof HttpServlet) {
        HttpServlet handlerServlet = (HttpServlet) newHandler;
        handlerServlet.init(cfg);
        realHandler = handlerServlet;
      } else if (newHandler instanceof APIResourceHandler) {
        APIResourceHandler resHandler = (APIResourceHandler) newHandler;
        realHandler = new MasterResourceHandler(resHandler);
      } else {
        throw new ServletException(
            "Content class \""
                + className
                + "\" is not of the right type. "
                + "It must extend HttpServlet or APIResourceHandler");
      }

      processor.attachContext(resName, realHandler);
    }

    log("API processor initialized and ready to go");
  }