void doPatch(final HttpServletRequest req, final HttpServletResponse resp) {
    try {
      // Parse out the required API versions.
      final AcceptAPIVersion acceptVersion = parseAcceptAPIVersion(req);

      // Prepare response.
      prepareResponse(req, resp);

      // Validate request.
      preprocessRequest(req);
      if (req.getHeader(HEADER_IF_NONE_MATCH) != null) {
        // FIXME: i18n
        throw new PreconditionFailedException(
            "Use of If-None-Match not supported for PATCH requests");
      }

      final Map<String, String[]> parameters = req.getParameterMap();
      final PatchRequest request =
          Requests.newPatchRequest(getResourceName(req)).setRevision(getIfMatch(req));
      request.getPatchOperations().addAll(getJsonPatchContent(req));
      for (final Map.Entry<String, String[]> p : parameters.entrySet()) {
        final String name = p.getKey();
        final String[] values = p.getValue();
        if (HttpUtils.isMultiPartRequest(req.getContentType())) {
          // Ignore - multipart content adds form parts to the parameter set
        } else if (parseCommonParameter(name, values, request)) {
          continue;
        } else {
          request.setAdditionalParameter(name, asSingleValue(name, values));
        }
      }
      doRequest(req, resp, acceptVersion, request);
    } catch (final Exception e) {
      fail(req, resp, e);
    }
  }