// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// WARNING: NoteDbUpdateManager cares about the package name RestApiServlet lives in.
package com.google.gerrit.httpd.restapi;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.flogger.LazyArgs.lazy;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_MAX_AGE;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS;
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD;
import static com.google.common.net.HttpHeaders.AUTHORIZATION;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.HttpHeaders.ORIGIN;
import static com.google.common.net.HttpHeaders.VARY;
import static com.google.gerrit.server.experiments.ExperimentFeaturesConstants.GERRIT_BACKEND_REQUEST_FEATURE_REMOVE_REVISION_ETAG;
import static java.math.RoundingMode.CEILING;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NOT_IMPLEMENTED;
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
import static javax.servlet.http.HttpServletResponse.SC_REQUEST_TIMEOUT;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.BaseEncoding;
import com.google.common.io.CountingOutputStream;
import com.google.common.math.IntMath;
import com.google.common.net.HttpHeaders;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.RawInputUtil;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.CacheControl;
import com.google.gerrit.extensions.restapi.DefaultInput;
import com.google.gerrit.extensions.restapi.ETagView;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.NeedsParams;
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.PreconditionFailedException;
import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestCollection;
import com.google.gerrit.extensions.restapi.RestCollectionCreateView;
import com.google.gerrit.extensions.restapi.RestCollectionDeleteMissingView;
import com.google.gerrit.extensions.restapi.RestCollectionModifyView;
import com.google.gerrit.extensions.restapi.RestCollectionView;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.httpd.restapi.ParameterParser.QueryParams;
import com.google.gerrit.json.OutputFormat;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CancellationMetrics;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.DeadlineChecker;
import com.google.gerrit.server.DynamicOptions;
import com.google.gerrit.server.ExceptionHook;
import com.google.gerrit.server.InvalidDeadlineException;
import com.google.gerrit.server.OptionUtil;
import com.google.gerrit.server.RequestInfo;
import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.audit.ExtendedHttpAuditEvent;
import com.google.gerrit.server.cache.PerThreadCache;
import com.google.gerrit.server.cancellation.RequestCancelledException;
import com.google.gerrit.server.cancellation.RequestStateContext;
import com.google.gerrit.server.cancellation.RequestStateProvider;
import com.google.gerrit.server.change.ChangeFinder;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.experiments.ExperimentFeatures;
import com.google.gerrit.server.group.GroupAuditService;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.PerformanceLogContext;
import com.google.gerrit.server.logging.PerformanceLogger;
import com.google.gerrit.server.logging.RequestId;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.plugincontext.PluginSetContext;
import com.google.gerrit.server.quota.QuotaException;
import com.google.gerrit.server.restapi.change.ChangesCollection;
import com.google.gerrit.server.restapi.project.ProjectsCollection;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryableAction;
import com.google.gerrit.server.update.RetryableAction.Action;
import com.google.gerrit.server.update.RetryableAction.ActionType;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.util.http.CacheHeaders;
import com.google.gerrit.util.http.RequestUtil;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Providers;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.eclipse.jgit.util.TemporaryBuffer.Heap;

public class RestApiServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  /** MIME type used for a JSON response body. */
  private static final String JSON_TYPE = "application/json";

  private static final String FORM_TYPE = "application/x-www-form-urlencoded";

  @VisibleForTesting public static final String X_GERRIT_DEADLINE = "X-Gerrit-Deadline";
  @VisibleForTesting public static final String X_GERRIT_TRACE = "X-Gerrit-Trace";
  @VisibleForTesting public static final String X_GERRIT_UPDATED_REF = "X-Gerrit-UpdatedRef";

  @VisibleForTesting
  public static final String X_GERRIT_UPDATED_REF_ENABLED = "X-Gerrit-UpdatedRef-Enabled";

  private static final String X_REQUESTED_WITH = "X-Requested-With";
  private static final String X_GERRIT_AUTH = "X-Gerrit-Auth";
  static final ImmutableSet<String> ALLOWED_CORS_METHODS =
      ImmutableSet.of("GET", "HEAD", "POST", "PUT", "DELETE");
  private static final ImmutableSet<String> ALLOWED_CORS_REQUEST_HEADERS =
      Stream.of(AUTHORIZATION, CONTENT_TYPE, X_GERRIT_AUTH, X_REQUESTED_WITH)
          .map(s -> s.toLowerCase(Locale.US))
          .collect(ImmutableSet.toImmutableSet());

  public static final String XD_AUTHORIZATION = "access_token";
  public static final String XD_CONTENT_TYPE = "$ct";
  public static final String XD_METHOD = "$m";
  public static final int SC_UNPROCESSABLE_ENTITY = 422;
  public static final int SC_TOO_MANY_REQUESTS = 429;
  public static final int SC_CLIENT_CLOSED_REQUEST = 499;

  private static final int HEAP_EST_SIZE = 10 * 8 * 1024; // Presize 10 blocks.
  private static final String PLAIN_TEXT = "text/plain";
  private static final Pattern TYPE_SPLIT_PATTERN = Pattern.compile("[ ,;][ ,;]*");

  /**
   * Garbage prefix inserted before JSON output to prevent XSSI.
   *
   * <p>This prefix is ")]}'\n" and is designed to prevent a web browser from executing the response
   * body if the resource URI were to be referenced using a &lt;script src="...&gt; HTML tag from
   * another web site. Clients using the HTTP interface will need to always strip the first line of
   * response data to remove this magic header.
   */
  public static final byte[] JSON_MAGIC;

  static {
    JSON_MAGIC = ")]}'\n".getBytes(UTF_8);
  }

  public static class Globals {
    final Provider<CurrentUser> currentUser;
    final DynamicItem<WebSession> webSession;
    final Provider<ParameterParser> paramParser;
    final PluginSetContext<RequestListener> requestListeners;
    final PermissionBackend permissionBackend;
    final GroupAuditService auditService;
    final RestApiMetrics metrics;
    final Pattern allowOrigin;
    final RestApiQuotaEnforcer quotaChecker;
    final Config config;
    final DynamicSet<PerformanceLogger> performanceLoggers;
    final ChangeFinder changeFinder;
    final RetryHelper retryHelper;
    final PluginSetContext<ExceptionHook> exceptionHooks;
    final Injector injector;
    final DynamicMap<DynamicOptions.DynamicBean> dynamicBeans;
    final ExperimentFeatures experimentFeatures;
    final DeadlineChecker.Factory deadlineCheckerFactory;
    final CancellationMetrics cancellationMetrics;

    @Inject
    Globals(
        Provider<CurrentUser> currentUser,
        DynamicItem<WebSession> webSession,
        Provider<ParameterParser> paramParser,
        PluginSetContext<RequestListener> requestListeners,
        PermissionBackend permissionBackend,
        GroupAuditService auditService,
        RestApiMetrics metrics,
        RestApiQuotaEnforcer quotaChecker,
        @GerritServerConfig Config config,
        DynamicSet<PerformanceLogger> performanceLoggers,
        ChangeFinder changeFinder,
        RetryHelper retryHelper,
        PluginSetContext<ExceptionHook> exceptionHooks,
        Injector injector,
        DynamicMap<DynamicOptions.DynamicBean> dynamicBeans,
        ExperimentFeatures experimentFeatures,
        DeadlineChecker.Factory deadlineCheckerFactory,
        CancellationMetrics cancellationMetrics) {
      this.currentUser = currentUser;
      this.webSession = webSession;
      this.paramParser = paramParser;
      this.requestListeners = requestListeners;
      this.permissionBackend = permissionBackend;
      this.auditService = auditService;
      this.metrics = metrics;
      this.quotaChecker = quotaChecker;
      this.config = config;
      this.performanceLoggers = performanceLoggers;
      this.changeFinder = changeFinder;
      this.retryHelper = retryHelper;
      this.exceptionHooks = exceptionHooks;
      allowOrigin = makeAllowOrigin(config);
      this.injector = injector;
      this.dynamicBeans = dynamicBeans;
      this.experimentFeatures = experimentFeatures;
      this.deadlineCheckerFactory = deadlineCheckerFactory;
      this.cancellationMetrics = cancellationMetrics;
    }

    private static Pattern makeAllowOrigin(Config cfg) {
      String[] allow = cfg.getStringList("site", null, "allowOriginRegex");
      if (allow.length > 0) {
        return Pattern.compile(Joiner.on('|').join(allow));
      }
      return null;
    }
  }

  private final Globals globals;
  private final Provider<RestCollection<RestResource, RestResource>> members;

  public RestApiServlet(
      Globals globals, RestCollection<? extends RestResource, ? extends RestResource> members) {
    this(globals, Providers.of(members));
  }

  public RestApiServlet(
      Globals globals,
      Provider<? extends RestCollection<? extends RestResource, ? extends RestResource>> members) {
    @SuppressWarnings("unchecked")
    Provider<RestCollection<RestResource, RestResource>> n =
        (Provider<RestCollection<RestResource, RestResource>>) requireNonNull((Object) members);
    this.globals = globals;
    this.members = n;
  }

  @Override
  protected final void service(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    final long startNanos = System.nanoTime();
    long auditStartTs = TimeUtil.nowMs();
    res.setHeader("Content-Disposition", "attachment");
    res.setHeader("X-Content-Type-Options", "nosniff");
    int statusCode = SC_OK;
    long responseBytes = -1;
    Optional<Exception> cause = Optional.empty();
    Response<?> response = null;
    QueryParams qp = null;
    Object inputRequestBody = null;
    RestResource rsrc = TopLevelResource.INSTANCE;
    ViewData viewData = null;

    try (TraceContext traceContext = enableTracing(req, res)) {
      String requestUri = requestUri(req);

      try (PerThreadCache ignored = PerThreadCache.create()) {
        List<IdString> path = splitPath(req);
        RequestInfo requestInfo = createRequestInfo(traceContext, requestUri, path);
        globals.requestListeners.runEach(l -> l.onRequest(requestInfo));

        // It's important that the PerformanceLogContext is closed before the response is sent to
        // the client. Only this way it is ensured that the invocation of the PerformanceLogger
        // plugins happens before the client sees the response. This is needed for being able to
        // test performance logging from an acceptance test (see
        // TraceIT#performanceLoggingForRestCall()).
        try (RequestStateContext requestStateContext =
                RequestStateContext.open()
                    .addRequestStateProvider(
                        globals.deadlineCheckerFactory.create(
                            requestInfo, req.getHeader(X_GERRIT_DEADLINE)));
            PerformanceLogContext performanceLogContext =
                new PerformanceLogContext(globals.config, globals.performanceLoggers)) {
          traceRequestData(req);

          if (isCorsPreflight(req)) {
            doCorsPreflight(req, res);
            return;
          }

          qp = ParameterParser.getQueryParams(req);
          checkCors(req, res, qp.hasXdOverride());
          if (qp.hasXdOverride()) {
            req = applyXdOverrides(req, qp);
          }
          checkUserSession(req);

          RestCollection<RestResource, RestResource> rc = members.get();
          globals
              .permissionBackend
              .currentUser()
              .checkAny(GlobalPermission.fromAnnotation(rc.getClass()));

          viewData = new ViewData(null, null);

          if (path.isEmpty()) {
            globals.quotaChecker.enforce(req);
            if (rc instanceof NeedsParams) {
              ((NeedsParams) rc).setParams(qp.params());
            }

            if (isRead(req)) {
              viewData = new ViewData(null, rc.list());
            } else if (isPost(req)) {
              RestView<RestResource> restCollectionView =
                  rc.views().get(PluginName.GERRIT, "POST_ON_COLLECTION./");
              if (restCollectionView != null) {
                viewData = new ViewData(null, restCollectionView);
              } else {
                throw methodNotAllowed(req);
              }
            } else {
              // DELETE on root collections is not supported
              throw methodNotAllowed(req);
            }
          } else {
            IdString id = path.remove(0);
            try {
              rsrc = parseResourceWithRetry(req, traceContext, viewData.pluginName, rc, rsrc, id);
              globals.quotaChecker.enforce(rsrc, req);
              if (path.isEmpty()) {
                checkPreconditions(req);
              }
            } catch (ResourceNotFoundException e) {
              if (!path.isEmpty()) {
                throw e;
              }
              globals.quotaChecker.enforce(req);

              if (isPost(req) || isPut(req)) {
                RestView<RestResource> createView = rc.views().get(PluginName.GERRIT, "CREATE./");
                if (createView != null) {
                  viewData = new ViewData(null, createView);
                  path.add(id);
                } else {
                  throw e;
                }
              } else if (isDelete(req)) {
                RestView<RestResource> deleteView =
                    rc.views().get(PluginName.GERRIT, "DELETE_MISSING./");
                if (deleteView != null) {
                  viewData = new ViewData(null, deleteView);
                  path.add(id);
                } else {
                  throw e;
                }
              } else {
                throw e;
              }
            }
            if (viewData.view == null) {
              viewData = view(rc, req.getMethod(), path);
            }
          }
          checkRequiresCapability(viewData);

          while (viewData.view instanceof RestCollection<?, ?>) {
            @SuppressWarnings("unchecked")
            RestCollection<RestResource, RestResource> c =
                (RestCollection<RestResource, RestResource>) viewData.view;

            if (path.isEmpty()) {
              if (isRead(req)) {
                viewData = new ViewData(null, c.list());
              } else if (isPost(req)) {
                // TODO: Here and on other collection methods: There is a bug that binds child views
                // with pluginName="gerrit" instead of the real plugin name. This has never worked
                // correctly and should be fixed where the binding gets created (DynamicMapProvider)
                // and here.
                RestView<RestResource> restCollectionView =
                    c.views().get(PluginName.GERRIT, "POST_ON_COLLECTION./");
                if (restCollectionView != null) {
                  viewData = new ViewData(null, restCollectionView);
                } else {
                  throw methodNotAllowed(req);
                }
              } else if (isDelete(req)) {
                RestView<RestResource> restCollectionView =
                    c.views().get(PluginName.GERRIT, "DELETE_ON_COLLECTION./");
                if (restCollectionView != null) {
                  viewData = new ViewData(null, restCollectionView);
                } else {
                  throw methodNotAllowed(req);
                }
              } else {
                throw methodNotAllowed(req);
              }
              break;
            }
            IdString id = path.remove(0);
            try {
              rsrc = parseResourceWithRetry(req, traceContext, viewData.pluginName, c, rsrc, id);
              checkPreconditions(req);
              viewData = new ViewData(null, null);
            } catch (ResourceNotFoundException e) {
              if (!path.isEmpty()) {
                throw e;
              }

              if (isPost(req) || isPut(req)) {
                RestView<RestResource> createView = c.views().get(PluginName.GERRIT, "CREATE./");
                if (createView != null) {
                  viewData = new ViewData(viewData.pluginName, createView);
                  path.add(id);
                } else {
                  throw e;
                }
              } else if (isDelete(req)) {
                RestView<RestResource> deleteView =
                    c.views().get(PluginName.GERRIT, "DELETE_MISSING./");
                if (deleteView != null) {
                  viewData = new ViewData(viewData.pluginName, deleteView);
                  path.add(id);
                } else {
                  throw e;
                }
              } else {
                throw e;
              }
            }
            if (viewData.view == null) {
              viewData = view(c, req.getMethod(), path);
            }
            checkRequiresCapability(viewData);
          }

          if (notModified(req, traceContext, viewData, rsrc)) {
            logger.atFinest().log("REST call succeeded: %d", SC_NOT_MODIFIED);
            res.sendError(SC_NOT_MODIFIED);
            return;
          }

          try (DynamicOptions pluginOptions =
              new DynamicOptions(globals.injector, globals.dynamicBeans)) {
            if (!globals
                .paramParser
                .get()
                .parse(viewData.view, pluginOptions, qp.params(), req, res)) {
              return;
            }

            if (viewData.view instanceof RestReadView<?> && isRead(req)) {
              response =
                  invokeRestReadViewWithRetry(
                      req,
                      traceContext,
                      viewData,
                      (RestReadView<RestResource>) viewData.view,
                      rsrc);
            } else if (viewData.view instanceof RestModifyView<?, ?>) {
              @SuppressWarnings("unchecked")
              RestModifyView<RestResource, Object> m =
                  (RestModifyView<RestResource, Object>) viewData.view;

              Type type = inputType(m);
              inputRequestBody = parseRequest(req, type);
              response =
                  invokeRestModifyViewWithRetry(
                      req, traceContext, viewData, m, rsrc, inputRequestBody);

              if (inputRequestBody instanceof RawInput) {
                try (InputStream is = req.getInputStream()) {
                  ServletUtils.consumeRequestBody(is);
                }
              }
            } else if (viewData.view instanceof RestCollectionCreateView<?, ?, ?>) {
              @SuppressWarnings("unchecked")
              RestCollectionCreateView<RestResource, RestResource, Object> m =
                  (RestCollectionCreateView<RestResource, RestResource, Object>) viewData.view;

              Type type = inputType(m);
              inputRequestBody = parseRequest(req, type);
              response =
                  invokeRestCollectionCreateViewWithRetry(
                      req, traceContext, viewData, m, rsrc, path.get(0), inputRequestBody);
              if (inputRequestBody instanceof RawInput) {
                try (InputStream is = req.getInputStream()) {
                  ServletUtils.consumeRequestBody(is);
                }
              }
            } else if (viewData.view instanceof RestCollectionDeleteMissingView<?, ?, ?>) {
              @SuppressWarnings("unchecked")
              RestCollectionDeleteMissingView<RestResource, RestResource, Object> m =
                  (RestCollectionDeleteMissingView<RestResource, RestResource, Object>)
                      viewData.view;

              Type type = inputType(m);
              inputRequestBody = parseRequest(req, type);
              response =
                  invokeRestCollectionDeleteMissingViewWithRetry(
                      req, traceContext, viewData, m, rsrc, path.get(0), inputRequestBody);
              if (inputRequestBody instanceof RawInput) {
                try (InputStream is = req.getInputStream()) {
                  ServletUtils.consumeRequestBody(is);
                }
              }
            } else if (viewData.view instanceof RestCollectionModifyView<?, ?, ?>) {
              @SuppressWarnings("unchecked")
              RestCollectionModifyView<RestResource, RestResource, Object> m =
                  (RestCollectionModifyView<RestResource, RestResource, Object>) viewData.view;

              Type type = inputType(m);
              inputRequestBody = parseRequest(req, type);
              response =
                  invokeRestCollectionModifyViewWithRetry(
                      req, traceContext, viewData, m, rsrc, inputRequestBody);
              if (inputRequestBody instanceof RawInput) {
                try (InputStream is = req.getInputStream()) {
                  ServletUtils.consumeRequestBody(is);
                }
              }
            } else {
              throw new ResourceNotFoundException();
            }
            String isUpdatedRefEnabled = req.getHeader(X_GERRIT_UPDATED_REF_ENABLED);
            if (!Strings.isNullOrEmpty(isUpdatedRefEnabled)
                && Boolean.valueOf(isUpdatedRefEnabled)) {
              setXGerritUpdatedRefResponseHeaders(req, res);
            }

            if (response instanceof Response.Redirect) {
              CacheHeaders.setNotCacheable(res);
              String location = ((Response.Redirect) response).location();
              res.sendRedirect(location);
              logger.atFinest().log("REST call redirected to: %s", location);
              return;
            } else if (response instanceof Response.Accepted) {
              CacheHeaders.setNotCacheable(res);
              res.setStatus(response.statusCode());
              res.setHeader(HttpHeaders.LOCATION, ((Response.Accepted) response).location());
              logger.atFinest().log("REST call succeeded: %d", response.statusCode());
              return;
            }

            statusCode = response.statusCode();
            configureCaching(req, res, traceContext, rsrc, viewData, response.caching());
            res.setStatus(statusCode);
            logger.atFinest().log("REST call succeeded: %d", statusCode);
          }

          if (response != Response.none()) {
            Object value = Response.unwrap(response);
            if (value instanceof BinaryResult) {
              responseBytes = replyBinaryResult(req, res, (BinaryResult) value);
            } else {
              responseBytes = replyJson(req, res, false, qp.config(), value);
            }
          }
        }
      } catch (MalformedJsonException | JsonParseException e) {
        cause = Optional.of(e);
        logger.atFine().withCause(e).log("REST call failed on JSON parsing");
        responseBytes =
            replyError(
                req, res, statusCode = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request", e);
      } catch (BadRequestException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req, res, statusCode = SC_BAD_REQUEST, messageOr(e, "Bad Request"), e.caching(), e);
      } catch (AuthException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req, res, statusCode = SC_FORBIDDEN, messageOr(e, "Forbidden"), e.caching(), e);
      } catch (AmbiguousViewException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(req, res, statusCode = SC_NOT_FOUND, messageOr(e, "Ambiguous"), e);
      } catch (ResourceNotFoundException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req, res, statusCode = SC_NOT_FOUND, messageOr(e, "Not Found"), e.caching(), e);
      } catch (MethodNotAllowedException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req,
                res,
                statusCode = SC_METHOD_NOT_ALLOWED,
                messageOr(e, "Method Not Allowed"),
                e.caching(),
                e);
      } catch (ResourceConflictException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req, res, statusCode = SC_CONFLICT, messageOr(e, "Conflict"), e.caching(), e);
      } catch (PreconditionFailedException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req,
                res,
                statusCode = SC_PRECONDITION_FAILED,
                messageOr(e, "Precondition Failed"),
                e.caching(),
                e);
      } catch (UnprocessableEntityException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req,
                res,
                statusCode = SC_UNPROCESSABLE_ENTITY,
                messageOr(e, "Unprocessable Entity"),
                e.caching(),
                e);
      } catch (NotImplementedException e) {
        cause = Optional.of(e);
        logger.atSevere().withCause(e).log("Error in %s %s", req.getMethod(), uriForLogging(req));
        responseBytes =
            replyError(
                req, res, statusCode = SC_NOT_IMPLEMENTED, messageOr(e, "Not Implemented"), e);
      } catch (QuotaException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(
                req,
                res,
                statusCode = SC_TOO_MANY_REQUESTS,
                messageOr(e, "Quota limit reached"),
                e.caching(),
                e);
      } catch (InvalidDeadlineException e) {
        cause = Optional.of(e);
        responseBytes =
            replyError(req, res, statusCode = SC_BAD_REQUEST, messageOr(e, "Bad Request"), e);
      } catch (Exception e) {
        cause = Optional.of(e);

        Optional<RequestCancelledException> requestCancelledException =
            RequestCancelledException.getFromCausalChain(e);
        if (requestCancelledException.isPresent()) {
          RequestStateProvider.Reason cancellationReason =
              requestCancelledException.get().getCancellationReason();
          globals.cancellationMetrics.countCancelledRequest(
              RequestInfo.RequestType.REST, requestUri, cancellationReason);
          statusCode = getCancellationStatusCode(cancellationReason);
          responseBytes =
              replyError(
                  req, res, statusCode, getCancellationMessage(requestCancelledException.get()), e);
        } else {
          statusCode = SC_INTERNAL_SERVER_ERROR;

          Optional<ExceptionHook.Status> status = getStatus(e);
          statusCode =
              status.map(ExceptionHook.Status::statusCode).orElse(SC_INTERNAL_SERVER_ERROR);

          if (res.isCommitted()) {
            responseBytes = 0;
            if (statusCode == SC_INTERNAL_SERVER_ERROR) {
              logger.atSevere().withCause(e).log(
                  "Error in %s %s, response already committed",
                  req.getMethod(), uriForLogging(req));
            } else {
              logger.atWarning().log(
                  "Response for %s %s already committed, wanted to set status %d",
                  req.getMethod(), uriForLogging(req), statusCode);
            }
          } else {
            res.reset();
            TraceContext.getTraceId().ifPresent(traceId -> res.addHeader(X_GERRIT_TRACE, traceId));

            if (status.isPresent()) {
              responseBytes = reply(req, res, e, status.get(), getUserMessages(e));
            } else {
              responseBytes = replyInternalServerError(req, res, e, getUserMessages(e));
            }
          }
        }
      } finally {
        String metric = getViewName(viewData);
        String formattedCause = cause.map(globals.retryHelper::formatCause).orElse("_none");
        globals.metrics.count.increment(metric);
        if (statusCode >= SC_BAD_REQUEST) {
          globals.metrics.errorCount.increment(metric, statusCode, formattedCause);
        }
        if (responseBytes != -1) {
          globals.metrics.responseBytes.record(metric, responseBytes);
        }
        globals.metrics.serverLatency.record(
            metric, System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
        globals.auditService.dispatch(
            new ExtendedHttpAuditEvent(
                globals.webSession.get().getSessionId(),
                globals.currentUser.get(),
                req,
                auditStartTs,
                qp != null ? qp.params() : ImmutableListMultimap.of(),
                inputRequestBody,
                statusCode,
                response,
                rsrc,
                viewData == null ? null : viewData.view));
      }
    }
  }

  /**
   * Fill in the refs that were updated during this request in the response header. The updated refs
   * will be in the form of "project~ref~updated_SHA-1".
   */
  private void setXGerritUpdatedRefResponseHeaders(
      HttpServletRequest request, HttpServletResponse response) {
    for (GitReferenceUpdatedListener.Event refUpdate :
        globals.webSession.get().getRefUpdatedEvents()) {
      String refUpdateFormat =
          String.format(
              "%s~%s~%s~%s",
              // encode the project and ref names since they may contain `~`
              Url.encode(refUpdate.getProjectName()),
              Url.encode(refUpdate.getRefName()),
              refUpdate.getOldObjectId(),
              refUpdate.getNewObjectId());

      if (isRead(request)) {
        logger.atWarning().log(
            "request %s performed a ref update %s although the request is a READ request",
            request.getRequestURL().toString(), refUpdateFormat);
      }
      response.addHeader(X_GERRIT_UPDATED_REF, refUpdateFormat);
    }
    globals.webSession.get().resetRefUpdatedEvents();
  }

  private String getEtagWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      ETagView<RestResource> view,
      RestResource rsrc) {
    try (TraceTimer ignored =
        TraceContext.newTimer(
            "RestApiServlet#getEtagWithRetry:view",
            Metadata.builder().restViewName(getViewName(viewData)).build())) {
      return invokeRestEndpointWithRetry(
          req,
          traceContext,
          getViewName(viewData) + "#etag",
          ActionType.REST_READ_REQUEST,
          () -> view.getETag(rsrc));
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      throw new IllegalStateException("Failed to get ETag for view", e);
    }
  }

  private String getEtagWithRetry(
      HttpServletRequest req, TraceContext traceContext, RestResource.HasETag rsrc) {
    try (TraceTimer ignored =
        TraceContext.newTimer(
            "RestApiServlet#getEtagWithRetry:resource",
            Metadata.builder().restViewName(rsrc.getClass().getSimpleName()).build())) {
      if (rsrc instanceof RevisionResource
          && globals.experimentFeatures.isFeatureEnabled(
              GERRIT_BACKEND_REQUEST_FEATURE_REMOVE_REVISION_ETAG)) {
        return null;
      }
      return invokeRestEndpointWithRetry(
          req,
          traceContext,
          rsrc.getClass().getSimpleName() + "#etag",
          ActionType.REST_READ_REQUEST,
          () -> rsrc.getETag());
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      throw new IllegalStateException("Failed to get ETag for resource", e);
    }
  }

  private RestResource parseResourceWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      @Nullable String pluginName,
      RestCollection<RestResource, RestResource> restCollection,
      RestResource parentResource,
      IdString id)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        globals.metrics.view(restCollection.getClass(), pluginName) + "#parse",
        ActionType.REST_READ_REQUEST,
        () -> restCollection.parse(parentResource, id));
  }

  private Response<?> invokeRestReadViewWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      RestReadView<RestResource> view,
      RestResource rsrc)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        getViewName(viewData),
        ActionType.REST_READ_REQUEST,
        () -> view.apply(rsrc));
  }

  private Response<?> invokeRestModifyViewWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      RestModifyView<RestResource, Object> view,
      RestResource rsrc,
      Object inputRequestBody)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        getViewName(viewData),
        ActionType.REST_WRITE_REQUEST,
        () -> view.apply(rsrc, inputRequestBody));
  }

  private Response<?> invokeRestCollectionCreateViewWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      RestCollectionCreateView<RestResource, RestResource, Object> view,
      RestResource rsrc,
      IdString path,
      Object inputRequestBody)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        getViewName(viewData),
        ActionType.REST_WRITE_REQUEST,
        () -> view.apply(rsrc, path, inputRequestBody));
  }

  private Response<?> invokeRestCollectionDeleteMissingViewWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      RestCollectionDeleteMissingView<RestResource, RestResource, Object> view,
      RestResource rsrc,
      IdString path,
      Object inputRequestBody)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        getViewName(viewData),
        ActionType.REST_WRITE_REQUEST,
        () -> view.apply(rsrc, path, inputRequestBody));
  }

  private Response<?> invokeRestCollectionModifyViewWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      ViewData viewData,
      RestCollectionModifyView<RestResource, RestResource, Object> view,
      RestResource rsrc,
      Object inputRequestBody)
      throws Exception {
    return invokeRestEndpointWithRetry(
        req,
        traceContext,
        getViewName(viewData),
        ActionType.REST_WRITE_REQUEST,
        () -> view.apply(rsrc, inputRequestBody));
  }

  private <T> T invokeRestEndpointWithRetry(
      HttpServletRequest req,
      TraceContext traceContext,
      String caller,
      ActionType actionType,
      Action<T> action)
      throws Exception {
    RetryableAction<T> retryableAction = globals.retryHelper.action(actionType, caller, action);
    AtomicReference<Optional<String>> traceId = new AtomicReference<>(Optional.empty());
    if (!TraceContext.isTracing()) {
      // enable automatic retry with tracing in case of non-recoverable failure
      retryableAction
          .retryWithTrace(t -> !(t instanceof RestApiException))
          .onAutoTrace(
              autoTraceId -> {
                traceId.set(Optional.of(autoTraceId));

                // Include details of the request into the trace.
                traceRequestData(req);
              });
    }
    try {
      return retryableAction.call();
    } finally {
      // If auto-tracing got triggered due to a non-recoverable failure, also trace the rest of
      // this request. This means logging is forced for all further log statements and the logs are
      // associated with the same trace ID.
      traceId
          .get()
          .ifPresent(tid -> traceContext.addTag(RequestId.Type.TRACE_ID, tid).forceLogging());
    }
  }

  private String getViewName(ViewData viewData) {
    return viewData != null && viewData.view != null ? globals.metrics.view(viewData) : "_unknown";
  }

  private static HttpServletRequest applyXdOverrides(HttpServletRequest req, QueryParams qp)
      throws BadRequestException {
    if (!isPost(req)) {
      throw new BadRequestException("POST required");
    }

    String method = qp.xdMethod();
    String contentType = qp.xdContentType();
    if (method.equals("POST") || method.equals("PUT")) {
      if (!isType(PLAIN_TEXT, req.getContentType())) {
        throw new BadRequestException("invalid " + CONTENT_TYPE);
      }
      if (Strings.isNullOrEmpty(contentType)) {
        throw new BadRequestException(XD_CONTENT_TYPE + " required");
      }
    }

    return new HttpServletRequestWrapper(req) {
      @Override
      public String getMethod() {
        return method;
      }

      @Override
      public String getContentType() {
        return contentType;
      }
    };
  }

  private void checkCors(HttpServletRequest req, HttpServletResponse res, boolean isXd)
      throws BadRequestException {
    String origin = req.getHeader(ORIGIN);
    if (isXd) {
      // Cross-domain, non-preflighted requests must come from an approved origin.
      if (Strings.isNullOrEmpty(origin) || !isOriginAllowed(origin)) {
        throw new BadRequestException("origin not allowed");
      }
      res.addHeader(VARY, ORIGIN);
      res.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
      res.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    } else if (!Strings.isNullOrEmpty(origin)) {
      // All other requests must be processed, but conditionally set CORS headers.
      if (globals.allowOrigin != null) {
        res.addHeader(VARY, ORIGIN);
      }
      if (isOriginAllowed(origin)) {
        setCorsHeaders(res, origin);
      }
    }
  }

  private static boolean isCorsPreflight(HttpServletRequest req) {
    return "OPTIONS".equals(req.getMethod())
        && !Strings.isNullOrEmpty(req.getHeader(ORIGIN))
        && !Strings.isNullOrEmpty(req.getHeader(ACCESS_CONTROL_REQUEST_METHOD));
  }

  private void doCorsPreflight(HttpServletRequest req, HttpServletResponse res)
      throws BadRequestException {
    CacheHeaders.setNotCacheable(res);
    setHeaderList(
        res,
        VARY,
        ImmutableList.of(ORIGIN, ACCESS_CONTROL_REQUEST_METHOD, ACCESS_CONTROL_REQUEST_HEADERS));

    String origin = req.getHeader(ORIGIN);
    if (Strings.isNullOrEmpty(origin) || !isOriginAllowed(origin)) {
      throw new BadRequestException("CORS not allowed");
    }

    String method = req.getHeader(ACCESS_CONTROL_REQUEST_METHOD);
    if (!ALLOWED_CORS_METHODS.contains(method)) {
      throw new BadRequestException(method + " not allowed in CORS");
    }

    String headers = req.getHeader(ACCESS_CONTROL_REQUEST_HEADERS);
    if (headers != null) {
      for (String reqHdr : Splitter.on(',').trimResults().split(headers)) {
        if (!ALLOWED_CORS_REQUEST_HEADERS.contains(reqHdr.toLowerCase(Locale.US))) {
          throw new BadRequestException(reqHdr + " not allowed in CORS");
        }
      }
    }

    res.setStatus(SC_OK);
    setCorsHeaders(res, origin);
    res.setContentType(PLAIN_TEXT);
    res.setContentLength(0);
  }

  private static void setCorsHeaders(HttpServletResponse res, String origin) {
    res.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
    res.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    res.setHeader(ACCESS_CONTROL_MAX_AGE, "600");
    setHeaderList(
        res,
        ACCESS_CONTROL_ALLOW_METHODS,
        Iterables.concat(ALLOWED_CORS_METHODS, ImmutableList.of("OPTIONS")));
    setHeaderList(res, ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_CORS_REQUEST_HEADERS);
  }

  private static void setHeaderList(HttpServletResponse res, String name, Iterable<String> values) {
    res.setHeader(name, Joiner.on(", ").join(values));
  }

  private boolean isOriginAllowed(String origin) {
    return globals.allowOrigin != null && globals.allowOrigin.matcher(origin).matches();
  }

  private static String messageOr(Throwable t, String defaultMessage) {
    if (!Strings.isNullOrEmpty(t.getMessage())) {
      return t.getMessage();
    }
    return defaultMessage;
  }

  private boolean notModified(
      HttpServletRequest req, TraceContext traceContext, ViewData viewData, RestResource rsrc) {
    if (!isRead(req)) {
      return false;
    }

    RestView<RestResource> view = viewData.view;
    if (view instanceof ETagView) {
      String have = req.getHeader(HttpHeaders.IF_NONE_MATCH);
      if (have != null) {
        String eTag =
            getEtagWithRetry(req, traceContext, viewData, (ETagView<RestResource>) view, rsrc);
        return have.equals(eTag);
      }
    }

    if (rsrc instanceof RestResource.HasETag) {
      String have = req.getHeader(HttpHeaders.IF_NONE_MATCH);
      if (!Strings.isNullOrEmpty(have)) {
        String eTag = getEtagWithRetry(req, traceContext, (RestResource.HasETag) rsrc);
        return have.equals(eTag);
      }
    }

    if (rsrc instanceof RestResource.HasLastModified) {
      Timestamp m = ((RestResource.HasLastModified) rsrc).getLastModified();
      long d = req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);

      // HTTP times are in seconds, database may have millisecond precision.
      return d / 1000L == m.getTime() / 1000L;
    }
    return false;
  }

  private <R extends RestResource> void configureCaching(
      HttpServletRequest req,
      HttpServletResponse res,
      TraceContext traceContext,
      R rsrc,
      ViewData viewData,
      CacheControl cacheControl) {
    setCacheHeaders(req, res, cacheControl);
    if (isRead(req)) {
      switch (cacheControl.getType()) {
        case NONE:
        default:
          break;
        case PRIVATE:
          addResourceStateHeaders(req, res, traceContext, viewData, rsrc);
          break;
        case PUBLIC:
          addResourceStateHeaders(req, res, traceContext, viewData, rsrc);
          break;
      }
    }
  }

  private static <R extends RestResource> void setCacheHeaders(
      HttpServletRequest req, HttpServletResponse res, CacheControl cacheControl) {
    if (isRead(req)) {
      switch (cacheControl.getType()) {
        case NONE:
        default:
          CacheHeaders.setNotCacheable(res);
          break;
        case PRIVATE:
          CacheHeaders.setCacheablePrivate(
              res, cacheControl.getAge(), cacheControl.getUnit(), cacheControl.isMustRevalidate());
          break;
        case PUBLIC:
          CacheHeaders.setCacheable(
              req,
              res,
              cacheControl.getAge(),
              cacheControl.getUnit(),
              cacheControl.isMustRevalidate());
          break;
      }
    } else {
      CacheHeaders.setNotCacheable(res);
    }
  }

  private void addResourceStateHeaders(
      HttpServletRequest req,
      HttpServletResponse res,
      TraceContext traceContext,
      ViewData viewData,
      RestResource rsrc) {
    RestView<RestResource> view = viewData.view;
    if (view instanceof ETagView) {
      String eTag =
          getEtagWithRetry(req, traceContext, viewData, (ETagView<RestResource>) view, rsrc);
      res.setHeader(HttpHeaders.ETAG, eTag);
    } else if (rsrc instanceof RestResource.HasETag) {
      String eTag = getEtagWithRetry(req, traceContext, (RestResource.HasETag) rsrc);
      if (!Strings.isNullOrEmpty(eTag)) {
        res.setHeader(HttpHeaders.ETAG, eTag);
      }
    }
    if (rsrc instanceof RestResource.HasLastModified) {
      res.setDateHeader(
          HttpHeaders.LAST_MODIFIED,
          ((RestResource.HasLastModified) rsrc).getLastModified().getTime());
    }
  }

  private void checkPreconditions(HttpServletRequest req) throws PreconditionFailedException {
    if ("*".equals(req.getHeader(HttpHeaders.IF_NONE_MATCH))) {
      throw new PreconditionFailedException("Resource already exists");
    }
  }

  private static Type inputType(RestModifyView<RestResource, Object> m) {
    // MyModifyView implements RestModifyView<SomeResource, MyInput>
    TypeLiteral<?> typeLiteral = TypeLiteral.get(m.getClass());

    // RestModifyView<SomeResource, MyInput>
    // This is smart enough to resolve even when there are intervening subclasses, even if they have
    // reordered type arguments.
    TypeLiteral<?> supertypeLiteral = typeLiteral.getSupertype(RestModifyView.class);

    Type supertype = supertypeLiteral.getType();
    checkState(
        supertype instanceof ParameterizedType,
        "supertype of %s is not parameterized: %s",
        typeLiteral,
        supertypeLiteral);
    return ((ParameterizedType) supertype).getActualTypeArguments()[1];
  }

  private static Type inputType(RestCollectionView<RestResource, RestResource, Object> m) {
    // MyCollectionView implements RestCollectionView<SomeResource, SomeResource, MyInput>
    TypeLiteral<?> typeLiteral = TypeLiteral.get(m.getClass());

    // RestCollectionView<SomeResource, SomeResource, MyInput>
    // This is smart enough to resolve even when there are intervening subclasses, even if they have
    // reordered type arguments.
    TypeLiteral<?> supertypeLiteral = typeLiteral.getSupertype(RestCollectionView.class);

    Type supertype = supertypeLiteral.getType();
    checkState(
        supertype instanceof ParameterizedType,
        "supertype of %s is not parameterized: %s",
        typeLiteral,
        supertypeLiteral);
    return ((ParameterizedType) supertype).getActualTypeArguments()[2];
  }

  private Object parseRequest(HttpServletRequest req, Type type)
      throws IOException, BadRequestException, SecurityException, IllegalArgumentException,
          NoSuchMethodException, IllegalAccessException, InstantiationException,
          InvocationTargetException, MethodNotAllowedException {
    // HTTP/1.1 requires consuming the request body before writing non-error response (less than
    // 400). Consume the request body for all but raw input request types here.
    if (isType(JSON_TYPE, req.getContentType())) {
      try (BufferedReader br = req.getReader();
          JsonReader json = new JsonReader(br)) {
        try {
          json.setLenient(true);

          JsonToken first;
          try {
            first = json.peek();
          } catch (EOFException e) {
            throw new BadRequestException("Expected JSON object", e);
          }
          if (first == JsonToken.STRING) {
            return parseString(json.nextString(), type);
          }
          return OutputFormat.JSON.newGson().fromJson(json, type);
        } finally {
          try {
            // Reader.close won't consume the rest of the input. Explicitly consume the request
            // body.
            br.skip(Long.MAX_VALUE);
          } catch (Exception e) {
            // ignore, e.g. trying to consume the rest of the input may fail if the request was
            // cancelled
          }
        }
      }
    }
    String method = req.getMethod();
    if (("PUT".equals(method) || "POST".equals(method)) && acceptsRawInput(type)) {
      return parseRawInput(req, type);
    }
    if (isDelete(req) && hasNoBody(req)) {
      return null;
    }
    if (hasNoBody(req)) {
      return createInstance(type);
    }
    if (isType(PLAIN_TEXT, req.getContentType())) {
      try (BufferedReader br = req.getReader()) {
        char[] tmp = new char[256];
        StringBuilder sb = new StringBuilder();
        int n;
        while (0 < (n = br.read(tmp))) {
          sb.append(tmp, 0, n);
        }
        return parseString(sb.toString(), type);
      }
    }
    if (isPost(req) && isType(FORM_TYPE, req.getContentType())) {
      return OutputFormat.JSON.newGson().fromJson(ParameterParser.formToJson(req), type);
    }
    throw new BadRequestException("Expected Content-Type: " + JSON_TYPE);
  }

  private static boolean hasNoBody(HttpServletRequest req) {
    int len = req.getContentLength();
    String type = req.getContentType();
    return (len <= 0 && type == null) || (len == 0 && isType(FORM_TYPE, type));
  }

  @SuppressWarnings("rawtypes")
  private static boolean acceptsRawInput(Type type) {
    if (type instanceof Class) {
      for (Field f : ((Class) type).getDeclaredFields()) {
        if (f.getType() == RawInput.class) {
          return true;
        }
      }
    }
    return false;
  }

  private Object parseRawInput(HttpServletRequest req, Type type)
      throws SecurityException, NoSuchMethodException, IllegalArgumentException,
          InstantiationException, IllegalAccessException, InvocationTargetException,
          MethodNotAllowedException {
    Object obj = createInstance(type);
    for (Field f : obj.getClass().getDeclaredFields()) {
      if (f.getType() == RawInput.class) {
        f.setAccessible(true);
        f.set(obj, RawInputUtil.create(req));
        return obj;
      }
    }
    throw new MethodNotAllowedException("raw input not supported");
  }

  private Object parseString(String value, Type type)
      throws BadRequestException, SecurityException, NoSuchMethodException,
          IllegalArgumentException, IllegalAccessException, InstantiationException,
          InvocationTargetException {
    if (type == String.class) {
      return value;
    }

    Object obj = createInstance(type);
    if (Strings.isNullOrEmpty(value)) {
      return obj;
    }
    Field[] fields = obj.getClass().getDeclaredFields();
    for (Field f : fields) {
      if (f.getAnnotation(DefaultInput.class) != null && f.getType() == String.class) {
        f.setAccessible(true);
        f.set(obj, value);
        return obj;
      }
    }
    throw new BadRequestException("Expected JSON object");
  }

  @SuppressWarnings("unchecked")
  private static Object createInstance(Type type)
      throws NoSuchMethodException, InstantiationException, IllegalAccessException,
          InvocationTargetException {
    if (type instanceof Class) {
      Class<Object> clazz = (Class<Object>) type;
      Constructor<Object> c = clazz.getDeclaredConstructor();
      c.setAccessible(true);
      return c.newInstance();
    }
    if (type instanceof ParameterizedType) {
      Type rawType = ((ParameterizedType) type).getRawType();
      if (rawType instanceof Class && List.class.isAssignableFrom((Class<Object>) rawType)) {
        return new ArrayList<>();
      }
      if (rawType instanceof Class && Map.class.isAssignableFrom((Class<Object>) rawType)) {
        return new HashMap<>();
      }
    }
    throw new InstantiationException("Cannot make " + type);
  }

  /**
   * Sets a JSON reply on the given HTTP servlet response.
   *
   * @param req the HTTP servlet request
   * @param res the HTTP servlet response on which the reply should be set
   * @param allowTracing whether it is allowed to log the reply if tracing is enabled, must not be
   *     set to {@code true} if the reply may contain sensitive data
   * @param config config parameters for the JSON formatting
   * @param result the object that should be formatted as JSON
   * @return the length of the response
   */
  public static long replyJson(
      @Nullable HttpServletRequest req,
      HttpServletResponse res,
      boolean allowTracing,
      ListMultimap<String, String> config,
      Object result)
      throws IOException {
    TemporaryBuffer.Heap buf = heap(HEAP_EST_SIZE, Integer.MAX_VALUE);
    buf.write(JSON_MAGIC);
    Writer w = new BufferedWriter(new OutputStreamWriter(buf, UTF_8));
    Gson gson = newGson(config);
    if (result instanceof JsonElement) {
      gson.toJson((JsonElement) result, w);
    } else {
      gson.toJson(result, w);
    }
    w.write('\n');
    w.flush();

    if (allowTracing) {
      logger.atFinest().log(
          "JSON response body:\n%s",
          lazy(
              () -> {
                try {
                  ByteArrayOutputStream debugOut = new ByteArrayOutputStream();
                  buf.writeTo(debugOut, null);
                  return debugOut.toString(UTF_8.name());
                } catch (IOException e) {
                  return "<JSON formatting failed>";
                }
              }));
    }
    return replyBinaryResult(
        req, res, asBinaryResult(buf).setContentType(JSON_TYPE).setCharacterEncoding(UTF_8));
  }

  private static Gson newGson(ListMultimap<String, String> config) {
    GsonBuilder gb = OutputFormat.JSON_COMPACT.newGsonBuilder();

    enablePrettyPrint(gb, config);
    enablePartialGetFields(gb, config);

    return gb.create();
  }

  private static void enablePrettyPrint(GsonBuilder gb, ListMultimap<String, String> config) {
    String pp =
        Iterables.getFirst(config.get("pp"), Iterables.getFirst(config.get("prettyPrint"), "0"));
    if ("1".equals(pp) || "true".equals(pp)) {
      gb.setPrettyPrinting();
    }
  }

  private static void enablePartialGetFields(GsonBuilder gb, ListMultimap<String, String> config) {
    final Set<String> want = new HashSet<>();
    for (String p : config.get("fields")) {
      Iterables.addAll(want, OptionUtil.splitOptionValue(p));
    }
    if (!want.isEmpty()) {
      gb.addSerializationExclusionStrategy(
          new ExclusionStrategy() {
            private final Map<String, String> names = new HashMap<>();

            @Override
            public boolean shouldSkipField(FieldAttributes field) {
              String name = names.get(field.getName());
              if (name == null) {
                // Names are supplied by Gson in terms of Java source.
                // Translate and cache the JSON lower_case_style used.
                try {
                  name =
                      FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES.translateName( //
                          field.getDeclaringClass().getDeclaredField(field.getName()));
                  names.put(field.getName(), name);
                } catch (SecurityException | NoSuchFieldException e) {
                  return true;
                }
              }
              return !want.contains(name);
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
              return false;
            }
          });
    }
  }

  @SuppressWarnings("resource")
  static long replyBinaryResult(
      @Nullable HttpServletRequest req, HttpServletResponse res, BinaryResult bin)
      throws IOException {
    final BinaryResult appResult = bin;
    try {
      if (bin.getAttachmentName() != null) {
        res.setHeader(
            "Content-Disposition", "attachment; filename=\"" + bin.getAttachmentName() + "\"");
      }
      if (bin.isBase64()) {
        if (req != null && JSON_TYPE.equals(req.getHeader(HttpHeaders.ACCEPT))) {
          bin = stackJsonString(res, bin);
        } else {
          bin = stackBase64(res, bin);
        }
      }
      if (bin.canGzip() && acceptsGzip(req)) {
        bin = stackGzip(res, bin);
      }

      res.setContentType(bin.getContentType());
      long len = bin.getContentLength();
      if (0 <= len && len < Integer.MAX_VALUE) {
        res.setContentLength((int) len);
      } else if (0 <= len) {
        res.setHeader("Content-Length", Long.toString(len));
      }

      if (req == null || !"HEAD".equals(req.getMethod())) {
        try (CountingOutputStream dst = new CountingOutputStream(res.getOutputStream())) {
          bin.writeTo(dst);
          return dst.getCount();
        }
      }
      return 0;
    } finally {
      appResult.close();
    }
  }

  private static BinaryResult stackJsonString(HttpServletResponse res, BinaryResult src)
      throws IOException {
    TemporaryBuffer.Heap buf = heap(HEAP_EST_SIZE, Integer.MAX_VALUE);
    buf.write(JSON_MAGIC);
    try (Writer w = new BufferedWriter(new OutputStreamWriter(buf, UTF_8));
        JsonWriter json = new JsonWriter(w)) {
      json.setLenient(true);
      json.setHtmlSafe(true);
      json.value(src.asString());
      w.write('\n');
    }
    res.setHeader("X-FYI-Content-Encoding", "json");
    res.setHeader("X-FYI-Content-Type", src.getContentType());
    return asBinaryResult(buf).setContentType(JSON_TYPE).setCharacterEncoding(UTF_8);
  }

  private static BinaryResult stackBase64(HttpServletResponse res, BinaryResult src)
      throws IOException {
    BinaryResult b64;
    long len = src.getContentLength();
    if (0 <= len && len <= (7 << 20)) {
      b64 = base64(src);
    } else {
      b64 =
          new BinaryResult() {
            @Override
            public void writeTo(OutputStream out) throws IOException {
              try (OutputStreamWriter w =
                      new OutputStreamWriter(
                          new FilterOutputStream(out) {
                            @Override
                            public void close() {
                              // Do not close out, but only w and e.
                            }
                          },
                          ISO_8859_1);
                  OutputStream e = BaseEncoding.base64().encodingStream(w)) {
                src.writeTo(e);
              }
            }
          };
    }
    res.setHeader("X-FYI-Content-Encoding", "base64");
    res.setHeader("X-FYI-Content-Type", src.getContentType());
    return b64.setContentType(PLAIN_TEXT).setCharacterEncoding(ISO_8859_1);
  }

  private static BinaryResult stackGzip(HttpServletResponse res, BinaryResult src)
      throws IOException {
    BinaryResult gz;
    long len = src.getContentLength();
    if (len < 256) {
      return src; // Do not compress very small payloads.
    }
    if (len <= (10 << 20)) {
      gz = compress(src);
      if (len <= gz.getContentLength()) {
        return src;
      }
    } else {
      gz =
          new BinaryResult() {
            @Override
            public void writeTo(OutputStream out) throws IOException {
              GZIPOutputStream gz = new GZIPOutputStream(out);
              src.writeTo(gz);
              gz.finish();
              gz.flush();
            }
          };
    }
    res.setHeader("Content-Encoding", "gzip");
    return gz.setContentType(src.getContentType());
  }

  private ViewData view(
      RestCollection<RestResource, RestResource> rc, String method, List<IdString> path)
      throws AmbiguousViewException, RestApiException {
    DynamicMap<RestView<RestResource>> views = rc.views();
    final IdString projection = path.isEmpty() ? IdString.fromUrl("/") : path.remove(0);
    if (!path.isEmpty()) {
      // If there are path components still remaining after this projection
      // is chosen, look for the projection based upon GET as the method as
      // the client thinks it is a nested collection.
      method = "GET";
    } else if ("HEAD".equals(method)) {
      method = "GET";
    }

    List<String> p = splitProjection(projection);
    if (p.size() == 2) {
      String viewname = p.get(1);
      if (Strings.isNullOrEmpty(viewname)) {
        viewname = "/";
      }
      RestView<RestResource> view = views.get(p.get(0), method + "." + viewname);
      if (view != null) {
        return new ViewData(p.get(0), view);
      }
      view = views.get(p.get(0), "GET." + viewname);
      if (view != null) {
        return new ViewData(p.get(0), view);
      }
      throw new ResourceNotFoundException(projection);
    }

    String name = method + "." + p.get(0);
    RestView<RestResource> core = views.get(PluginName.GERRIT, name);
    if (core != null) {
      return new ViewData(PluginName.GERRIT, core);
    }

    // Check if we want to delegate to a child collection. Child collections are bound with
    // GET.name so we have to check for this since we haven't found any other views.
    if (method.equals("GET")) {
      core = views.get(PluginName.GERRIT, "GET." + p.get(0));
      if (core != null) {
        return new ViewData(PluginName.GERRIT, core);
      }
    }

    Map<String, RestView<RestResource>> r = new TreeMap<>();
    for (String plugin : views.plugins()) {
      RestView<RestResource> action = views.get(plugin, name);
      if (action != null) {
        r.put(plugin, action);
      }
    }

    if (r.isEmpty()) {
      // Check if we want to delegate to a child collection. Child collections are bound with
      // GET.name so we have to check for this since we haven't found any other views.
      for (String plugin : views.plugins()) {
        RestView<RestResource> action = views.get(plugin, "GET." + p.get(0));
        if (action != null) {
          r.put(plugin, action);
        }
      }
    }

    if (r.size() == 1) {
      Map.Entry<String, RestView<RestResource>> entry = Iterables.getOnlyElement(r.entrySet());
      return new ViewData(entry.getKey(), entry.getValue());
    }
    if (r.isEmpty()) {
      throw new ResourceNotFoundException(projection);
    }
    throw new AmbiguousViewException(
        String.format(
            "Projection %s is ambiguous: %s",
            name, r.keySet().stream().map(in -> in + "~" + projection).collect(joining(", "))));
  }

  private static List<IdString> splitPath(HttpServletRequest req) {
    String path = RequestUtil.getEncodedPathInfo(req);
    if (Strings.isNullOrEmpty(path)) {
      return Collections.emptyList();
    }
    List<IdString> out = new ArrayList<>();
    for (String p : Splitter.on('/').split(path)) {
      out.add(IdString.fromUrl(p));
    }
    if (!out.isEmpty() && out.get(out.size() - 1).isEmpty()) {
      out.remove(out.size() - 1);
    }
    return out;
  }

  private static List<String> splitProjection(IdString projection) {
    List<String> p = Lists.newArrayListWithCapacity(2);
    Iterables.addAll(p, Splitter.on('~').limit(2).split(projection.get()));
    return p;
  }

  private void checkUserSession(HttpServletRequest req) throws AuthException {
    CurrentUser user = globals.currentUser.get();
    if (isRead(req)) {
      user.setAccessPath(AccessPath.REST_API);
    } else if (user instanceof AnonymousUser) {
      throw new AuthException("Authentication required");
    } else if (!globals.webSession.get().isAccessPathOk(AccessPath.REST_API)) {
      throw new AuthException(
          "Invalid authentication method. In order to authenticate, "
              + "prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/).");
    }
  }

  private List<String> getParameterNames(HttpServletRequest req) {
    List<String> parameterNames = new ArrayList<>(req.getParameterMap().keySet());
    Collections.sort(parameterNames);
    return parameterNames;
  }

  private TraceContext enableTracing(HttpServletRequest req, HttpServletResponse res) {
    // There are 2 ways to enable tracing for REST calls:
    // 1. by using the 'trace' or 'trace=<trace-id>' request parameter
    // 2. by setting the 'X-Gerrit-Trace:' or 'X-Gerrit-Trace:<trace-id>' header
    String traceValueFromHeader = req.getHeader(X_GERRIT_TRACE);
    String traceValueFromRequestParam = req.getParameter(ParameterParser.TRACE_PARAMETER);
    boolean doTrace = traceValueFromHeader != null || traceValueFromRequestParam != null;

    // Check whether no trace ID, one trace ID or 2 different trace IDs have been specified.
    String traceId1;
    String traceId2;
    if (!Strings.isNullOrEmpty(traceValueFromHeader)) {
      traceId1 = traceValueFromHeader;
      if (!Strings.isNullOrEmpty(traceValueFromRequestParam)
          && !traceValueFromHeader.equals(traceValueFromRequestParam)) {
        traceId2 = traceValueFromRequestParam;
      } else {
        traceId2 = null;
      }
    } else {
      traceId1 = Strings.emptyToNull(traceValueFromRequestParam);
      traceId2 = null;
    }

    // Use the first trace ID to start tracing. If this trace ID is null, a trace ID will be
    // generated.
    TraceContext traceContext =
        TraceContext.newTrace(
            doTrace, traceId1, (tagName, traceId) -> res.setHeader(X_GERRIT_TRACE, traceId));
    // If a second trace ID was specified, add a tag for it as well.
    if (traceId2 != null) {
      traceContext.addTag(RequestId.Type.TRACE_ID, traceId2);
      res.addHeader(X_GERRIT_TRACE, traceId2);
    }
    return traceContext;
  }

  private RequestInfo createRequestInfo(
      TraceContext traceContext, String requestUri, List<IdString> path) {
    RequestInfo.Builder requestInfo =
        RequestInfo.builder(RequestInfo.RequestType.REST, globals.currentUser.get(), traceContext)
            .requestUri(requestUri);

    if (path.size() < 1) {
      return requestInfo.build();
    }

    RestCollection<?, ?> rootCollection = members.get();
    String resourceId = path.get(0).get();
    if (rootCollection instanceof ProjectsCollection) {
      requestInfo.project(Project.nameKey(resourceId));
    } else if (rootCollection instanceof ChangesCollection) {
      Optional<ChangeNotes> changeNotes = globals.changeFinder.findOne(resourceId);
      if (changeNotes.isPresent()) {
        requestInfo.project(changeNotes.get().getProjectName());
      }
    }
    return requestInfo.build();
  }

  private void traceRequestData(HttpServletRequest req) {
    logger.atFinest().log(
        "Received REST request: %s %s (parameters: %s)",
        req.getMethod(), req.getRequestURI(), getParameterNames(req));
    Optional.ofNullable(req.getHeader(X_GERRIT_DEADLINE))
        .ifPresent(
            clientProvidedDeadline ->
                logger.atFine().log("%s = %s", X_GERRIT_DEADLINE, clientProvidedDeadline));
    logger.atFinest().log("Calling user: %s", globals.currentUser.get().getLoggableName());
    logger.atFinest().log(
        "Groups: %s", lazy(() -> globals.currentUser.get().getEffectiveGroups().getKnownGroups()));
  }

  private boolean isDelete(HttpServletRequest req) {
    return "DELETE".equals(req.getMethod());
  }

  private static boolean isPost(HttpServletRequest req) {
    return "POST".equals(req.getMethod());
  }

  private boolean isPut(HttpServletRequest req) {
    return "PUT".equals(req.getMethod());
  }

  private static boolean isRead(HttpServletRequest req) {
    return "GET".equals(req.getMethod()) || "HEAD".equals(req.getMethod());
  }

  private static MethodNotAllowedException methodNotAllowed(HttpServletRequest req) {
    return new MethodNotAllowedException(
        String.format("Not implemented: %s %s", req.getMethod(), requestUri(req)));
  }

  private static String requestUri(HttpServletRequest req) {
    String uri = req.getRequestURI();
    if (uri.startsWith("/a/")) {
      return uri.substring(2);
    }
    return uri;
  }

  private void checkRequiresCapability(ViewData d)
      throws AuthException, PermissionBackendException {
    try {
      globals.permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
    } catch (AuthException e) {
      // Skiping
      globals
          .permissionBackend
          .currentUser()
          .checkAny(GlobalPermission.fromAnnotation(d.pluginName, d.view.getClass()));
    }
  }

  private Optional<ExceptionHook.Status> getStatus(Throwable err) {
    return globals.exceptionHooks.stream()
        .map(h -> h.getStatus(err))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .findFirst();
  }

  private ImmutableList<String> getUserMessages(Throwable err) {
    return globals.exceptionHooks.stream()
        .flatMap(h -> h.getUserMessages(err, TraceContext.getTraceId().orElse(null)).stream())
        .collect(toImmutableList());
  }

  private static long reply(
      HttpServletRequest req,
      HttpServletResponse res,
      Throwable err,
      ExceptionHook.Status status,
      ImmutableList<String> userMessages)
      throws IOException {
    res.setStatus(status.statusCode());

    StringBuilder msg = new StringBuilder(status.statusMessage());
    if (!userMessages.isEmpty()) {
      msg.append("\n");
      userMessages.forEach(m -> msg.append("\n* ").append(m));
    }

    if (status.statusCode() < SC_BAD_REQUEST) {
      logger.atFinest().withCause(err).log("REST call finished: %d", status.statusCode());
      return replyText(req, res, true, msg.toString());
    }
    if (status.statusCode() >= SC_INTERNAL_SERVER_ERROR) {
      logger.atSevere().withCause(err).log("Error in %s %s", req.getMethod(), uriForLogging(req));
    }
    return replyError(req, res, status.statusCode(), msg.toString(), err);
  }

  private long replyInternalServerError(
      HttpServletRequest req,
      HttpServletResponse res,
      Throwable err,
      ImmutableList<String> userMessages)
      throws IOException {
    logger.atSevere().withCause(err).log(
        "Error in %s %s: %s",
        req.getMethod(), uriForLogging(req), globals.retryHelper.formatCause(err));

    StringBuilder msg = new StringBuilder("Internal server error");
    if (!userMessages.isEmpty()) {
      msg.append("\n");
      userMessages.forEach(m -> msg.append("\n* ").append(m));
    }

    return replyError(req, res, SC_INTERNAL_SERVER_ERROR, msg.toString(), err);
  }

  private static String uriForLogging(HttpServletRequest req) {
    String uri = req.getRequestURI();
    if (!Strings.isNullOrEmpty(req.getQueryString())) {
      uri += "?" + LogRedactUtil.redactQueryString(req.getQueryString());
    }
    return uri;
  }

  public static long replyError(
      HttpServletRequest req,
      HttpServletResponse res,
      int statusCode,
      String msg,
      @Nullable Throwable err)
      throws IOException {
    return replyError(req, res, statusCode, msg, CacheControl.NONE, err);
  }

  public static long replyError(
      HttpServletRequest req,
      HttpServletResponse res,
      int statusCode,
      String msg,
      CacheControl cacheControl,
      @Nullable Throwable err)
      throws IOException {
    if (err != null) {
      RequestUtil.setErrorTraceAttribute(req, err);
    }
    setCacheHeaders(req, res, cacheControl);
    checkArgument(statusCode >= 400, "non-error status: %s", statusCode);
    res.setStatus(statusCode);
    logger.atFinest().withCause(err).log("REST call failed: %d", statusCode);
    return replyText(req, res, true, msg);
  }

  /**
   * Sets a text reply on the given HTTP servlet response.
   *
   * @param req the HTTP servlet request
   * @param res the HTTP servlet response on which the reply should be set
   * @param allowTracing whether it is allowed to log the reply if tracing is enabled, must not be
   *     set to {@code true} if the reply may contain sensitive data
   * @param text the text reply
   * @return the length of the response
   */
  static long replyText(
      @Nullable HttpServletRequest req, HttpServletResponse res, boolean allowTracing, String text)
      throws IOException {
    if (!text.endsWith("\n")) {
      text += "\n";
    }
    if (allowTracing) {
      logger.atFinest().log("Text response body:\n%s", text);
    }
    return replyBinaryResult(req, res, BinaryResult.create(text).setContentType(PLAIN_TEXT));
  }

  private static int getCancellationStatusCode(RequestStateProvider.Reason cancellationReason) {
    switch (cancellationReason) {
      case CLIENT_CLOSED_REQUEST:
        return SC_CLIENT_CLOSED_REQUEST;
      case CLIENT_PROVIDED_DEADLINE_EXCEEDED:
      case SERVER_DEADLINE_EXCEEDED:
        return SC_REQUEST_TIMEOUT;
    }
    logger.atSevere().log("Unexpected cancellation reason: %s", cancellationReason);
    return SC_INTERNAL_SERVER_ERROR;
  }

  private static String getCancellationMessage(
      RequestCancelledException requestCancelledException) {
    StringBuilder msg = new StringBuilder(requestCancelledException.formatCancellationReason());
    if (requestCancelledException.getCancellationMessage().isPresent()) {
      msg.append("\n\n");
      msg.append(requestCancelledException.getCancellationMessage().get());
    }
    return msg.toString();
  }

  private static boolean acceptsGzip(HttpServletRequest req) {
    if (req != null) {
      String accepts = req.getHeader(HttpHeaders.ACCEPT_ENCODING);
      return accepts != null && accepts.contains("gzip");
    }
    return false;
  }

  private static boolean isType(String expect, String given) {
    if (given == null) {
      return false;
    }
    if (expect.equals(given)) {
      return true;
    }
    if (given.startsWith(expect + ",")) {
      return true;
    }
    for (String p : Splitter.on(TYPE_SPLIT_PATTERN).split(given)) {
      if (expect.equals(p)) {
        return true;
      }
    }
    return false;
  }

  private static int base64MaxSize(long n) {
    return 4 * IntMath.divide((int) n, 3, CEILING);
  }

  private static BinaryResult base64(BinaryResult bin) throws IOException {
    int maxSize = base64MaxSize(bin.getContentLength());
    int estSize = Math.min(base64MaxSize(HEAP_EST_SIZE), maxSize);
    TemporaryBuffer.Heap buf = heap(estSize, maxSize);
    try (OutputStream encoded =
        BaseEncoding.base64().encodingStream(new OutputStreamWriter(buf, ISO_8859_1))) {
      bin.writeTo(encoded);
    }
    return asBinaryResult(buf);
  }

  private static BinaryResult compress(BinaryResult bin) throws IOException {
    TemporaryBuffer.Heap buf = heap(HEAP_EST_SIZE, 20 << 20);
    try (GZIPOutputStream gz = new GZIPOutputStream(buf)) {
      bin.writeTo(gz);
    }
    return asBinaryResult(buf).setContentType(bin.getContentType());
  }

  @SuppressWarnings("resource")
  private static BinaryResult asBinaryResult(TemporaryBuffer.Heap buf) {
    return new BinaryResult() {
      @Override
      public void writeTo(OutputStream os) throws IOException {
        buf.writeTo(os, null);
      }
    }.setContentLength(buf.length());
  }

  private static Heap heap(int est, int max) {
    return new TemporaryBuffer.Heap(est, max);
  }

  private static class AmbiguousViewException extends Exception {
    private static final long serialVersionUID = 1L;

    AmbiguousViewException(String message) {
      super(message);
    }
  }

  static class ViewData {
    String pluginName;
    RestView<RestResource> view;

    ViewData(String pluginName, RestView<RestResource> view) {
      this.pluginName = pluginName;
      this.view = view;
    }
  }
}
