Merge "Fix build, return value must be used."
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 09ce63b..fae2a87 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,5 @@
 eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.annotationPath.allLocations=disabled
 org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
 org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
 org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
@@ -102,7 +103,7 @@
 org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
 org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
 org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
 org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
 org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
 org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=warning
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 4c666b9..3cc5a5a 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1791,7 +1791,7 @@
 ----
 [commentlink "changeid"]
   match = (I[0-9a-f]{8,40})
-  link = "#/q/$1"
+  link = "/q/$1"
 
 [commentlink "bugzilla"]
   match = "(^|\\s)(bug\\s+#?)(\\d+)($|\\s)"
@@ -5545,18 +5545,6 @@
 +
 By default, false.
 
-[[tracing.exportPerformanceMetrics]]tracing.exportPerformanceMetrics::
-+
-Whether to export performance metrics.
-+
-Performace logged when link:#tracing.performanceLogging[`performanceLogging`] is
-enabled, can be exported as metrics.
-+
-NOTE: Since the payload returned could be of tens of thousands metrics,
-assess the latency of the metrics endpoint before enabling this option.
-+
-By default, false.
-
 [[tracing.traceid]]
 ==== Subsection tracing.<trace-id>
 
diff --git a/Documentation/metrics.txt b/Documentation/metrics.txt
index 6c9dfef..2f43538 100644
--- a/Documentation/metrics.txt
+++ b/Documentation/metrics.txt
@@ -73,30 +73,6 @@
 ** `cancellation_type`:
    The cancellation type (graceful or forceful).
 
-[[performance]]
-=== Performance
-
-* `performance/operations`: Latency of performing operations
-** `operation_name`:
-   The operation that was performed.
-** `request`:
-   The request for which the operation was performed (format = '<request-type>
-   <redacted-request-uri>').
-** `plugin`:
-   The name of the plugin that performed the operation.
-* `performance/operations_count`: Number of performed operations
-** `operation_name`:
-   The operation that was performed.
-** `request`:
-   The request for which the operation was performed (format = '<request-type>
-   <redacted-request-uri>').
-** `plugin`:
-   The name of the plugin that performed the operation.
-
-Performance metrics can be enabled via the
-link:config.gerrit.html#tracing.exportPerformanceMetrics[`tracing.exportPerformanceMetrics`]
-setting.
-
 === Pushes
 
 * `receivecommits/changes`: histogram of number of changes processed in a single
diff --git a/java/com/google/gerrit/gpg/PublicKeyChecker.java b/java/com/google/gerrit/gpg/PublicKeyChecker.java
index 5347398..946fee3 100644
--- a/java/com/google/gerrit/gpg/PublicKeyChecker.java
+++ b/java/com/google/gerrit/gpg/PublicKeyChecker.java
@@ -237,7 +237,6 @@
       List<PGPSignature> revocations,
       Map<Long, RevocationKey> revokers)
       throws PGPException {
-    @SuppressWarnings("unchecked")
     Iterator<PGPSignature> allSigs = key.getSignatures();
     while (allSigs.hasNext()) {
       PGPSignature sig = allSigs.next();
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index 9056732..4e11346 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -519,7 +519,6 @@
                       (RestReadView<RestResource>) viewData.view,
                       rsrc);
             } else if (viewData.view instanceof RestModifyView<?, ?>) {
-              @SuppressWarnings("unchecked")
               RestModifyView<RestResource, Object> m =
                   (RestModifyView<RestResource, Object>) viewData.view;
 
@@ -535,7 +534,6 @@
                 }
               }
             } else if (viewData.view instanceof RestCollectionCreateView<?, ?, ?>) {
-              @SuppressWarnings("unchecked")
               RestCollectionCreateView<RestResource, RestResource, Object> m =
                   (RestCollectionCreateView<RestResource, RestResource, Object>) viewData.view;
 
@@ -550,7 +548,6 @@
                 }
               }
             } else if (viewData.view instanceof RestCollectionDeleteMissingView<?, ?, ?>) {
-              @SuppressWarnings("unchecked")
               RestCollectionDeleteMissingView<RestResource, RestResource, Object> m =
                   (RestCollectionDeleteMissingView<RestResource, RestResource, Object>)
                       viewData.view;
@@ -566,7 +563,6 @@
                 }
               }
             } else if (viewData.view instanceof RestCollectionModifyView<?, ?, ?>) {
-              @SuppressWarnings("unchecked")
               RestCollectionModifyView<RestResource, RestResource, Object> m =
                   (RestCollectionModifyView<RestResource, RestResource, Object>) viewData.view;
 
@@ -1869,8 +1865,9 @@
       case CLIENT_CLOSED_REQUEST:
         return SC_CLIENT_CLOSED_REQUEST;
       case CLIENT_PROVIDED_DEADLINE_EXCEEDED:
-      case SERVER_DEADLINE_EXCEEDED:
         return SC_REQUEST_TIMEOUT;
+      case SERVER_DEADLINE_EXCEEDED:
+        return SC_INTERNAL_SERVER_ERROR;
     }
     logger.atSevere().log("Unexpected cancellation reason: %s", cancellationReason);
     return SC_INTERNAL_SERVER_ERROR;
diff --git a/java/com/google/gerrit/server/PerformanceMetrics.java b/java/com/google/gerrit/server/PerformanceMetrics.java
deleted file mode 100644
index 845ed80..0000000
--- a/java/com/google/gerrit/server/PerformanceMetrics.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (C) 2021 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.
-
-package com.google.gerrit.server;
-
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.metrics.Counter3;
-import com.google.gerrit.metrics.Description;
-import com.google.gerrit.metrics.Field;
-import com.google.gerrit.metrics.MetricMaker;
-import com.google.gerrit.metrics.Timer3;
-import com.google.gerrit.server.logging.Metadata;
-import com.google.gerrit.server.logging.PerformanceLogger;
-import com.google.gerrit.server.logging.TraceContext;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.concurrent.TimeUnit;
-
-/** Performance logger that records the execution times as a metric. */
-@Singleton
-public class PerformanceMetrics implements PerformanceLogger {
-  private static final String OPERATION_LATENCY_METRIC_NAME = "performance/operations";
-  private static final String OPERATION_COUNT_METRIC_NAME = "performance/operations_count";
-
-  public final Timer3<String, String, String> operationsLatency;
-  public final Counter3<String, String, String> operationsCounter;
-
-  @Inject
-  PerformanceMetrics(MetricMaker metricMaker) {
-    Field<String> operationNameField =
-        Field.ofString(
-                "operation_name",
-                (metadataBuilder, fieldValue) -> metadataBuilder.operationName(fieldValue))
-            .description("The operation that was performed.")
-            .build();
-    Field<String> requestField =
-        Field.ofString("request", (metadataBuilder, fieldValue) -> {})
-            .description(
-                "The request for which the operation was performed"
-                    + " (format = '<request-type> <redacted-request-uri>').")
-            .build();
-    Field<String> pluginField =
-        Field.ofString(
-                "plugin", (metadataBuilder, fieldValue) -> metadataBuilder.pluginName(fieldValue))
-            .description("The name of the plugin that performed the operation.")
-            .build();
-
-    this.operationsLatency =
-        metricMaker
-            .newTimer(
-                OPERATION_LATENCY_METRIC_NAME,
-                new Description("Latency of performing operations")
-                    .setCumulative()
-                    .setUnit(Description.Units.MILLISECONDS),
-                operationNameField,
-                requestField,
-                pluginField)
-            .suppressLogging();
-    this.operationsCounter =
-        metricMaker.newCounter(
-            OPERATION_COUNT_METRIC_NAME,
-            new Description("Number of performed operations").setRate(),
-            operationNameField,
-            requestField,
-            pluginField);
-  }
-
-  @Override
-  public void log(String operation, long durationMs) {
-    log(operation, durationMs, /* metadata= */ null);
-  }
-
-  @Override
-  public void log(String operation, long durationMs, @Nullable Metadata metadata) {
-    String requestTag = TraceContext.getTag(TraceRequestListener.TAG_REQUEST).orElse("");
-    String pluginTag = TraceContext.getPluginTag().orElse("");
-    operationsLatency.record(operation, requestTag, pluginTag, durationMs, TimeUnit.MILLISECONDS);
-    operationsCounter.increment(operation, requestTag, pluginTag);
-  }
-}
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 3373860..e9912f5 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -89,7 +89,6 @@
 import com.google.gerrit.server.ExceptionHookImpl;
 import com.google.gerrit.server.ExternalUser;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.PerformanceMetrics;
 import com.google.gerrit.server.RequestListener;
 import com.google.gerrit.server.TraceRequestListener;
 import com.google.gerrit.server.account.AccountCacheImpl;
@@ -446,9 +445,6 @@
     DynamicSet.setOf(binder(), SubmitRequirement.class);
     DynamicSet.setOf(binder(), QuotaEnforcer.class);
     DynamicSet.setOf(binder(), PerformanceLogger.class);
-    if (cfg.getBoolean("tracing", "exportPerformanceMetrics", false)) {
-      DynamicSet.bind(binder(), PerformanceLogger.class).to(PerformanceMetrics.class);
-    }
     DynamicSet.setOf(binder(), RequestListener.class);
     DynamicSet.bind(binder(), RequestListener.class).to(TraceRequestListener.class);
     DynamicSet.setOf(binder(), ChangeETagComputation.class);
diff --git a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
index 93521f3..6f2bfdd 100644
--- a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
+++ b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
@@ -248,7 +248,6 @@
           .build();
 
   /** Upgrade Lucene to 8.x requires reindexing. */
-  @SuppressWarnings("deprecation")
   static final Schema<ChangeData> V83 = schema(V82);
 
   /**
diff --git a/java/com/google/gerrit/server/mail/EmailModule.java b/java/com/google/gerrit/server/mail/EmailModule.java
index 340a103..92777e4 100644
--- a/java/com/google/gerrit/server/mail/EmailModule.java
+++ b/java/com/google/gerrit/server/mail/EmailModule.java
@@ -114,9 +114,8 @@
         AttentionSetChange attentionSetChange, ChangeEmail changeEmail) {
       if (attentionSetChange.equals(AttentionSetChange.USER_ADDED)) {
         return outgoingEmailFactory.create("addToAttentionSet", changeEmail);
-      } else {
-        return outgoingEmailFactory.create("removeFromAttentionSet", changeEmail);
       }
+      return outgoingEmailFactory.create("removeFromAttentionSet", changeEmail);
     }
   }
 
diff --git a/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
index 0b909cd..00c73a0 100644
--- a/java/com/google/gerrit/server/mail/send/ChangeEmail.java
+++ b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
@@ -107,7 +107,7 @@
     void populateEmailContent() throws EmailException;
 
     /** If returns false email is not sent to any recipients. */
-    default boolean shouldSendMessage() throws EmailException {
+    default boolean shouldSendMessage() {
       return true;
     }
   }
@@ -195,7 +195,7 @@
   }
 
   @Override
-  public boolean shouldSendMessage() throws EmailException {
+  public boolean shouldSendMessage() {
     return changeEmailDecorator.shouldSendMessage();
   }
 
diff --git a/java/com/google/gerrit/server/mail/send/OutgoingEmail.java b/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
index a1db847..afdcbad 100644
--- a/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
+++ b/java/com/google/gerrit/server/mail/send/OutgoingEmail.java
@@ -88,16 +88,28 @@
     void populateEmailContent() throws EmailException;
 
     /** If returns false email is not sent to any recipients. */
-    default boolean shouldSendMessage() throws EmailException {
+    default boolean shouldSendMessage() {
       return true;
     }
 
-    /** Evaluates whether account can be added to the list of recipients. */
+    /**
+     * Evaluates whether account can be added to the list of recipients.
+     *
+     * @param rcpt the recipient for which it should be checker whether it can be added to the list
+     *     of recipients
+     * @throws PermissionBackendException thrown if checking permissions fails
+     */
     default boolean isRecipientAllowed(Account.Id rcpt) throws PermissionBackendException {
       return true;
     }
 
-    /** Evaluates whether email can be added to the list of recipients. */
+    /**
+     * Evaluates whether email can be added to the list of recipients.
+     *
+     * @param rcpt the recipient for which it should be checker whether it can be added to the list
+     *     of recipients
+     * @throws PermissionBackendException thrown if checking permissions fails
+     */
     default boolean isRecipientAllowed(Address rcpt) throws PermissionBackendException {
       return true;
     }
@@ -108,7 +120,7 @@
 
   private String messageClass;
   private final Set<Account.Id> rcptTo = new HashSet<>();
-  private final Map<String, EmailHeader> headers = new LinkedHashMap<>();;
+  private final Map<String, EmailHeader> headers = new LinkedHashMap<>();
   private final Set<Address> smtpRcptTo = new HashSet<>();
   private final Set<Address> smtpBccRcptTo = new HashSet<>();
   private Address smtpFromAddress;
@@ -564,7 +576,7 @@
     return accountState.get().userName().orElse(null);
   }
 
-  private boolean shouldSendMessage() throws EmailException {
+  private boolean shouldSendMessage() {
     if (textBody.length() == 0) {
       // If we have no message body, don't send.
       logger.atFine().log("Not sending '%s': No message body", messageClass);
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
index 95e528b..5c84589 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
@@ -730,7 +730,7 @@
     }
   }
 
-  private void parseCustomKeyedValues(ChangeNotesCommit commit) throws ConfigInvalidException {
+  private void parseCustomKeyedValues(ChangeNotesCommit commit) {
     for (String customKeyedValueLine : commit.getFooterLineValues(FOOTER_CUSTOM_KEYED_VALUE)) {
       String[] parts = customKeyedValueLine.split("=", 2);
       String key = parts[0];
diff --git a/javatests/com/google/gerrit/acceptance/rest/CancellationIT.java b/javatests/com/google/gerrit/acceptance/rest/CancellationIT.java
index c868d0b..2cc4857 100644
--- a/javatests/com/google/gerrit/acceptance/rest/CancellationIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/CancellationIT.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.httpd.restapi.RestApiServlet.SC_CLIENT_CLOSED_REQUEST;
+import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
 import static org.apache.http.HttpStatus.SC_REQUEST_TIMEOUT;
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -100,7 +101,7 @@
     try (Registration registration =
         extensionRegistry.newRegistration().add(projectCreationListener)) {
       RestResponse response = adminRestSession.put("/projects/" + name("new"));
-      assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+      assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
       assertThat(response.getEntityContent()).isEqualTo("Server Deadline Exceeded");
     }
   }
@@ -119,7 +120,7 @@
     try (Registration registration =
         extensionRegistry.newRegistration().add(projectCreationListener)) {
       RestResponse response = adminRestSession.put("/projects/" + name("new"));
-      assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+      assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
       assertThat(response.getEntityContent())
           .isEqualTo("Server Deadline Exceeded\n\ndeadline = 10m");
     }
@@ -140,7 +141,7 @@
     try (Registration registration =
         extensionRegistry.newRegistration().add(projectCreationListener)) {
       RestResponse response = adminRestSession.put("/projects/" + name("new"));
-      assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+      assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
       assertThat(response.getEntityContent())
           .isEqualTo("Server Deadline Exceeded\n\ndeadline = 10m");
     }
@@ -197,7 +198,7 @@
   public void abortIfServerDeadlineExceeded() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent()).isEqualTo("Server Deadline Exceeded\n\ntimeout=1ms");
   }
 
@@ -207,7 +208,7 @@
   public void stricterDeadlineTakesPrecedence() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\nfoo.timeout=1ms");
   }
@@ -218,7 +219,7 @@
   public void abortIfServerDeadlineExceeded_requestType() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -229,7 +230,7 @@
   public void abortIfServerDeadlineExceeded_requestUriPattern() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -242,7 +243,7 @@
   public void abortIfServerDeadlineExceeded_excludedRequestUriPattern() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -257,7 +258,7 @@
       throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -268,7 +269,7 @@
   public void abortIfServerDeadlineExceeded_projectPattern() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -279,7 +280,7 @@
   public void abortIfServerDeadlineExceeded_account() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(2));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=1ms");
   }
@@ -356,7 +357,7 @@
   public void nonAdvisoryDeadlineIsAppliedIfStricterAdvisoryDeadlineExists() throws Exception {
     testTicker.useFakeTicker().setAutoIncrementStep(Duration.ofMillis(4));
     RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-    assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+    assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
     assertThat(response.getEntityContent())
         .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=2ms");
   }
@@ -462,7 +463,7 @@
     try (Registration registration =
         extensionRegistry.newRegistration().add(projectCreationValidationListener)) {
       RestResponse response = adminRestSession.putWithHeaders("/projects/" + name("new"));
-      assertThat(response.getStatusCode()).isEqualTo(SC_REQUEST_TIMEOUT);
+      assertThat(response.getStatusCode()).isEqualTo(SC_INTERNAL_SERVER_ERROR);
       assertThat(response.getEntityContent())
           .isEqualTo("Server Deadline Exceeded\n\ndefault.timeout=500ms");
     }
diff --git a/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java b/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
index 8bafafe..c360b2f 100644
--- a/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
+++ b/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
@@ -279,7 +279,6 @@
 
   private PGPPublicKeyRing removeRevokers(PGPPublicKeyRing kr) {
     PGPPublicKey k = kr.getPublicKey();
-    @SuppressWarnings("unchecked")
     Iterator<PGPSignature> sigs = k.getSignaturesOfType(DIRECT_KEY);
     while (sigs.hasNext()) {
       PGPSignature sig = sigs.next();
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
index d04964b..04ff4fc 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
@@ -340,8 +340,7 @@
         newBuilder()
             .customKeyedValues(
                 ImmutableList.of(
-                    new SimpleEntry<String, String>("key1", "value1"),
-                    new SimpleEntry<String, String>("key2", "value2")))
+                    new SimpleEntry<>("key1", "value1"), new SimpleEntry<>("key2", "value2")))
             .build(),
         ChangeNotesStateProto.newBuilder()
             .setMetaId(SHA_BYTES)
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
index 24f5932..abb637c 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
@@ -46,8 +46,8 @@
 import {DiffPreferencesInfo} from '../../../types/diff';
 import {GrDiffHost} from '../../diff/gr-diff-host/gr-diff-host';
 import {GrDiffPreferencesDialog} from '../../diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog';
-import {GrDiffCursor} from '../../../embed/diff/gr-diff-cursor/gr-diff-cursor';
-import {GrDiffCursor as GrDiffCursorNew} from '../../../embed/diff-new/gr-diff-cursor/gr-diff-cursor';
+import {GrDiffCursor as GrDiffCursorNew} from '../../../embed/diff/gr-diff-cursor/gr-diff-cursor';
+import {GrDiffCursor} from '../../../embed/diff-old/gr-diff-cursor/gr-diff-cursor';
 import {GrCursorManager} from '../../shared/gr-cursor-manager/gr-cursor-manager';
 import {ChangeComments} from '../../diff/gr-comment-api/gr-comment-api';
 import {ParsedChangeInfo, PatchSetFile} from '../../../types/types';
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-results.ts b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
index d778546..b1c4c8e4 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-results.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
@@ -710,6 +710,7 @@
           changeNum: change._number,
           repo: change.project,
           patchNum: patchset,
+          checksPatchset: patchset,
           diffView: {path, lineNum: line},
         }),
         primary: true,
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
index 6892188..864f559 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -1446,6 +1446,10 @@
       diffView: {path: ctx.params[8]},
     };
     const queryMap = new URLSearchParams(ctx.querystring);
+    const checksPatchset = Number(queryMap.get('checksPatchset'));
+    if (Number.isInteger(checksPatchset) && checksPatchset > 0) {
+      state.checksPatchset = checksPatchset as PatchSetNumber;
+    }
     if (queryMap.has('forceReload')) state.forceReload = true;
     const address = this.parseLineAddress(ctx.hash);
     if (address) {
diff --git a/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog.ts b/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog.ts
index 8e30143..7723c66 100644
--- a/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog.ts
+++ b/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog.ts
@@ -7,7 +7,7 @@
 import '../../shared/gr-dialog/gr-dialog';
 import '../../shared/gr-icon/gr-icon';
 import '../../../embed/diff/gr-diff/gr-diff';
-import '../../../embed/diff-new/gr-diff/gr-diff';
+import '../../../embed/diff-old/gr-diff/gr-diff';
 import {navigationToken} from '../../core/gr-navigation/gr-navigation';
 import {
   NumericChangeId,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
index 2aae2ea..33c8c22 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
@@ -6,7 +6,7 @@
 import '../../shared/gr-comment-thread/gr-comment-thread';
 import '../../checks/gr-diff-check-result';
 import '../../../embed/diff/gr-diff/gr-diff';
-import '../../../embed/diff-new/gr-diff/gr-diff';
+import '../../../embed/diff-old/gr-diff/gr-diff';
 import {
   anyLineTooLong,
   getDiffLength,
@@ -46,8 +46,8 @@
   IgnoreWhitespaceType,
   WebLinkInfo,
 } from '../../../types/diff';
-import {GrDiff} from '../../../embed/diff/gr-diff/gr-diff';
-import {GrDiff as GrDiffNew} from '../../../embed/diff-new/gr-diff/gr-diff';
+import {GrDiff as GrDiffNew} from '../../../embed/diff/gr-diff/gr-diff';
+import {GrDiff} from '../../../embed/diff-old/gr-diff/gr-diff';
 import {DiffViewMode, Side, CommentSide} from '../../../constants/constants';
 import {FilesWebLinks} from '../gr-patch-range-select/gr-patch-range-select';
 import {GrCommentThread} from '../../shared/gr-comment-thread/gr-comment-thread';
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
index 7ab8c2c..0b14f4f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -53,8 +53,8 @@
   FilesWebLinks,
   PatchRangeChangeEvent,
 } from '../gr-patch-range-select/gr-patch-range-select';
-import {GrDiffCursor} from '../../../embed/diff/gr-diff-cursor/gr-diff-cursor';
-import {GrDiffCursor as GrDiffCursorNew} from '../../../embed/diff-new/gr-diff-cursor/gr-diff-cursor';
+import {GrDiffCursor as GrDiffCursorNew} from '../../../embed/diff/gr-diff-cursor/gr-diff-cursor';
+import {GrDiffCursor} from '../../../embed/diff-old/gr-diff-cursor/gr-diff-cursor';
 import {CommentSide, DiffViewMode, Side} from '../../../constants/constants';
 import {GrApplyFixDialog} from '../gr-apply-fix-dialog/gr-apply-fix-dialog';
 import {OpenFixPreviewEvent, ValueChangedEvent} from '../../../types/events';
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index 64dff29..348ea3b 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -8,7 +8,7 @@
 import '../gr-comment/gr-comment';
 import '../gr-icon/gr-icon';
 import '../../../embed/diff/gr-diff/gr-diff';
-import '../../../embed/diff-new/gr-diff/gr-diff';
+import '../../../embed/diff-old/gr-diff/gr-diff';
 import '../gr-copy-clipboard/gr-copy-clipboard';
 import {css, html, nothing, LitElement, PropertyValues} from 'lit';
 import {
@@ -74,6 +74,7 @@
 import {createChangeUrl, createDiffUrl} from '../../../models/views/change';
 import {userModelToken} from '../../../models/user/user-model';
 import {highlightServiceToken} from '../../../services/highlight/highlight-service';
+import {waitUntil} from '../../../utils/async-util';
 
 declare global {
   interface HTMLElementEventMap {
@@ -112,6 +113,9 @@
   @query('.comment-box')
   commentBox?: HTMLElement;
 
+  @query('gr-comment.draft')
+  draftElement?: GrComment;
+
   @queryAll('gr-comment')
   commentElements?: NodeList;
 
@@ -495,6 +499,7 @@
         : !this.unresolved);
     return html`
       <gr-comment
+        class=${classMap({draft: isDraft(comment)})}
         .comment=${comment}
         .comments=${this.thread!.comments}
         ?initially-collapsed=${initiallyCollapsed}
@@ -646,6 +651,15 @@
         }, 500);
       });
     }
+    if (this.thread && isDraft(this.getFirstComment())) {
+      const msg = this.getFirstComment()?.message ?? '';
+      if (msg.length === 0) this.editDraft();
+    }
+  }
+
+  private async editDraft() {
+    await waitUntil(() => !!this.draftElement);
+    this.draftElement!.edit();
   }
 
   private isDraft() {
@@ -797,6 +811,7 @@
     const newReply = createNewReply(replyingTo, content, unresolved);
     if (userWantsToEdit) {
       this.getCommentsModel().addNewDraft(newReply);
+      this.editDraft();
     } else {
       try {
         this.saving = true;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
index 1027a62..14ed24f 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
@@ -120,7 +120,11 @@
               robot-button-disabled=""
               show-patchset=""
             ></gr-comment>
-            <gr-comment robot-button-disabled="" show-patchset=""></gr-comment>
+            <gr-comment
+              class="draft"
+              robot-button-disabled=""
+              show-patchset=""
+            ></gr-comment>
           </div>
         </div>
       `
@@ -145,7 +149,11 @@
         <div id="container">
           <h3 class="assistive-tech-only">Draft Comment thread by Yoda</h3>
           <div class="comment-box" tabindex="0">
-            <gr-comment robot-button-disabled="" show-patchset=""></gr-comment>
+            <gr-comment
+              class="draft"
+              robot-button-disabled=""
+              show-patchset=""
+            ></gr-comment>
           </div>
         </div>
       `
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
index 74c5806..158799d 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -924,13 +924,6 @@
     if (this.permanentEditingMode) {
       this.edit();
     }
-    if (
-      isDraft(this.comment) &&
-      isNew(this.comment) &&
-      !isSaving(this.comment)
-    ) {
-      this.edit();
-    }
     if (isDraft(this.comment)) {
       this.collapsed = false;
     } else {
@@ -941,6 +934,10 @@
   override updated(changed: PropertyValues) {
     if (changed.has('editing')) {
       if (this.editing && !this.permanentEditingMode) {
+        // Note that this is a bit fragile, because we are relying on the
+        // comment to become visible soonish. If that does not happen, then we
+        // will be waiting indefinitely and grab focus at some point in the
+        // distant future.
         whenVisible(this, () => this.textarea?.putCursorAtEnd());
       }
     }
@@ -981,7 +978,7 @@
   }
 
   /** Enter editing mode. */
-  private edit() {
+  edit() {
     assert(isDraft(this.comment), 'only drafts are editable');
     if (this.editing) return;
     this.editing = true;
@@ -1065,6 +1062,8 @@
   }
 
   override focus() {
+    // Note that this may not work as intended, because the textarea is not
+    // rendered yet.
     this.textarea?.focus();
   }
 
diff --git a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.ts b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.ts
index 7779fff..95f1b8a 100644
--- a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.ts
+++ b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.ts
@@ -295,6 +295,8 @@
   }
 
   override focus() {
+    // Note that this may not work as intended, because the textarea is not
+    // rendered yet.
     this.textarea?.textarea.focus();
   }
 
@@ -627,7 +629,7 @@
     this.currentSearchString = '';
     this.closeDropdown();
     this.specialCharIndex = -1;
-    this.textarea?.textarea.focus();
+    this.focus();
   }
 
   private fireChangedEvents() {
diff --git a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section.ts b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section.ts
similarity index 96%
rename from polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section.ts
rename to polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section.ts
index 81fba83..e558295 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section.ts
@@ -124,8 +124,7 @@
   }
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define(
     'gr-context-controls-section',
     GrContextControlsSection
@@ -134,7 +133,6 @@
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-context-controls-section': LitElement;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section_test.ts b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section_test.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section_test.ts
index 5ac57e7..6a557fc 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls-section_test.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls-section_test.ts
@@ -4,7 +4,6 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../../test/common-test-setup';
-
 import './gr-context-controls-section';
 import {GrContextControlsSection} from './gr-context-controls-section';
 import {fixture, html, assert} from '@open-wc/testing';
diff --git a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls.ts b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls.ts
similarity index 98%
rename from polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls.ts
rename to polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls.ts
index 0ea6490..5695f4d 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls.ts
@@ -369,7 +369,7 @@
           buttonType: type,
           expandedLines: linesToExpand,
         });
-        fire(this, 'diff-context-expanded-internal-new', {
+        fire(this, 'diff-context-expanded-internal', {
           contextGroup: this.group,
           groups,
           numLines: this.numLines(),
@@ -515,15 +515,12 @@
     `;
   }
 }
-
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-context-controls', GrContextControls);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-context-controls': LitElement;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls_test.ts b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls_test.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls_test.ts
index 7f5827c..196afe5 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-context-controls/gr-context-controls_test.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-context-controls/gr-context-controls_test.ts
@@ -23,7 +23,6 @@
   let element: GrContextControls;
 
   setup(async () => {
-    // TODO(newdiff-cleanup): Remove cast when newdiff migration is complete.
     element = document.createElement(
       'gr-context-controls'
     ) as GrContextControls;
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-binary.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-binary.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-binary.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-binary.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-element.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-element.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-element.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-element.ts
index 009cbf9..e6de72d 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-element.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-element.ts
@@ -350,7 +350,7 @@
   init() {
     this.cleanup();
     this.diffElement?.addEventListener(
-      'diff-context-expanded-internal-new',
+      'diff-context-expanded-internal',
       this.onDiffContextExpanded
     );
     this.builder?.init();
@@ -367,7 +367,7 @@
     this.processor?.cancel();
     this.builder?.cleanup();
     this.diffElement?.removeEventListener(
-      'diff-context-expanded-internal-new',
+      'diff-context-expanded-internal',
       this.onDiffContextExpanded
     );
   }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-element_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-element_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-element_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-element_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-image.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-image.ts
similarity index 95%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-image.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-image.ts
index 869d600..d71d52a 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder-image.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder-image.ts
@@ -10,8 +10,8 @@
 import {html, LitElement, nothing} from 'lit';
 import {property, query, state} from 'lit/decorators.js';
 import {GrDiffBuilder} from './gr-diff-builder';
+import {createElementDiff, isNewDiff} from '../../diff/gr-diff/gr-diff-utils';
 import {GrDiffGroup} from '../gr-diff/gr-diff-group';
-import {isNewDiff, createElementDiff} from '../../diff/gr-diff/gr-diff-utils';
 
 // MIME types for images we allow showing. Do not include SVG, it can contain
 // arbitrary JavaScript.
@@ -45,7 +45,6 @@
   }
 
   private createImageDiffNew() {
-    // TODO(newdiff-cleanup): Remove cast when newdiff migration is complete.
     const imageDiff = document.createElement(
       'gr-diff-image-new'
     ) as GrDiffImageNew;
@@ -56,7 +55,6 @@
   }
 
   private createImageDiffOld() {
-    // TODO(newdiff-cleanup): Remove cast when newdiff migration is complete.
     const imageDiff = document.createElement(
       'gr-diff-image-old'
     ) as GrDiffImageOld;
@@ -268,15 +266,13 @@
     : '';
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-diff-image-new', GrDiffImageNew);
   customElements.define('gr-diff-image-old', GrDiffImageOld);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-diff-image-new': LitElement;
     'gr-diff-image-old': LitElement;
   }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder.ts
similarity index 98%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder.ts
index 43c7775..951466f 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-builder.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-builder.ts
@@ -34,7 +34,7 @@
 
 declare global {
   interface HTMLElementEventMap {
-    'diff-context-expanded-internal-new': CustomEvent<DiffContextExpandedEventDetail>;
+    'diff-context-expanded-internal': CustomEvent<DiffContextExpandedEventDetail>;
     'diff-context-expanded': CustomEvent<DiffContextExpandedExternalDetail>;
     'content-load-needed': CustomEvent<ContentLoadNeededEventDetail>;
   }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-row.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-row.ts
similarity index 98%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-row.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-row.ts
index 785f5a6..f2742c7 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-row.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-row.ts
@@ -443,7 +443,7 @@
   private renderText(side: Side) {
     const line = this.line(side);
     const lineNumber = this.lineNumber(side);
-    if (lineNumber === FILE || lineNumber === LOST) return;
+    if (typeof lineNumber !== 'number') return;
 
     // Note that `this.layersApplied` will wipe away the <gr-diff-text>, and
     // another rendering cycle will be initiated in `updated()`.
@@ -473,14 +473,12 @@
   }
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-diff-row', GrDiffRow);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-diff-row': LitElement;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-row_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-row_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-row_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-row_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-section.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-section.ts
similarity index 97%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-section.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-section.ts
index d80abd8..28919e8 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-section.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-section.ts
@@ -16,9 +16,9 @@
 } from '../../../api/diff';
 import {GrDiffGroup, GrDiffGroupType} from '../gr-diff/gr-diff-group';
 import {
-  isNewDiff,
   diffClasses,
   getResponsiveMode,
+  isNewDiff,
 } from '../../diff/gr-diff/gr-diff-utils';
 import {GrDiffRow} from './gr-diff-row';
 import '../gr-context-controls/gr-context-controls-section';
@@ -243,14 +243,12 @@
   }
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-diff-section', GrDiffSection);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-diff-section': LitElement;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-section_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-section_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-section_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-section_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text.ts
similarity index 95%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text.ts
index c447ee4..3878402 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text.ts
@@ -6,7 +6,7 @@
 import {LitElement, html, TemplateResult} from 'lit';
 import {property} from 'lit/decorators.js';
 import {styleMap} from 'lit/directives/style-map.js';
-import {isNewDiff, diffClasses} from '../../diff/gr-diff/gr-diff-utils';
+import {diffClasses, isNewDiff} from '../../diff/gr-diff/gr-diff-utils';
 
 const SURROGATE_PAIR = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
 
@@ -144,14 +144,12 @@
   }
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-diff-text', GrDiffText);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-diff-text': LitElement;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text_test.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text_test.ts
index 344240b..3858bed 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-builder/gr-diff-text_test.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-builder/gr-diff-text_test.ts
@@ -4,7 +4,6 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../../test/common-test-setup';
-
 import './gr-diff-text';
 import {GrDiffText} from './gr-diff-text';
 import {fixture, html, assert} from '@open-wc/testing';
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-cursor/gr-diff-cursor.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-cursor/gr-diff-cursor.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-cursor/gr-diff-cursor.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-cursor/gr-diff-cursor.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-cursor/gr-diff-cursor_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-cursor/gr-diff-cursor_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-cursor/gr-diff-cursor_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-cursor/gr-diff-cursor_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-annotation.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-annotation.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-annotation.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-annotation.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-annotation_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-annotation_test.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-annotation_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-annotation_test.ts
index 3e1ce66..f319a3c 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-annotation_test.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-annotation_test.ts
@@ -3,6 +3,7 @@
  * Copyright 2016 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+
 import '../../../test/common-test-setup';
 import {GrAnnotation} from './gr-annotation';
 import {
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-diff-highlight.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-diff-highlight.ts
similarity index 98%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-diff-highlight.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-diff-highlight.ts
index dad8df6..2c0663d 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-diff-highlight.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-diff-highlight.ts
@@ -18,13 +18,8 @@
   GrDiffThreadElement,
 } from '../../diff/gr-diff/gr-diff-utils';
 import {debounce, DelayedTask} from '../../../utils/async-util';
-import {
-  assert,
-  assertIsDefined,
-  queryAndAssert,
-} from '../../../utils/common-util';
+import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
 import {fire} from '../../../utils/event-util';
-import {FILE, LOST} from '../../../api/diff';
 
 interface SidedRange {
   side: Side;
@@ -312,8 +307,7 @@
     const side = getSideByLineEl(lineEl);
     if (!side) return null;
     const line = getLineNumberByChild(lineEl);
-    if (!line || line === FILE || line === LOST) return null;
-    assert(typeof line === 'number', 'line must be a number');
+    if (typeof line !== 'number') return null;
     const contentTd = this.diffBuilder.getContentTdByLineEl(lineEl);
     if (!contentTd) return null;
     const contentText = contentTd.querySelector('.contentText');
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-diff-highlight_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-diff-highlight_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-diff-highlight_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-diff-highlight_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-range-normalizer.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-range-normalizer.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-highlight/gr-range-normalizer.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-highlight/gr-range-normalizer.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-model/gr-diff-model.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-model/gr-diff-model.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-model/gr-diff-model.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-model/gr-diff-model.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-processor/gr-diff-processor.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-processor/gr-diff-processor.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-processor/gr-diff-processor.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-processor/gr-diff-processor.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-processor/gr-diff-processor_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-processor/gr-diff-processor_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-processor/gr-diff-processor_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-processor/gr-diff-processor_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-selection/gr-diff-selection.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-selection/gr-diff-selection.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-selection/gr-diff-selection.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-selection/gr-diff-selection.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff-selection/gr-diff-selection_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff-selection/gr-diff-selection_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff-selection/gr-diff-selection_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff-selection/gr-diff-selection_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-group.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-group.ts
similarity index 98%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-group.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-group.ts
index c11cfb6..771e298 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-group.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-group.ts
@@ -4,14 +4,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import {BLANK_LINE, GrDiffLine} from './gr-diff-line';
-import {
-  FILE,
-  GrDiffLineType,
-  LOST,
-  LineNumber,
-  LineRange,
-  Side,
-} from '../../../api/diff';
+import {GrDiffLineType, LineNumber, LineRange, Side} from '../../../api/diff';
 import {assertIsDefined, assert} from '../../../utils/common-util';
 import {untilRendered} from '../../../utils/dom-util';
 import {isDefined} from '../../../types/types';
@@ -503,8 +496,7 @@
     // untilRendered() promise.
     if (
       this.skip !== undefined ||
-      lineNumber === LOST ||
-      lineNumber === FILE ||
+      typeof lineNumber !== 'number' ||
       this.type === GrDiffGroupType.CONTEXT_CONTROL
     ) {
       return Promise.resolve();
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-group_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-group_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-group_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-group_test.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-line.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-line.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-line.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-line.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-styles.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-styles.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff-styles.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff-styles.ts
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff.ts
similarity index 99%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff.ts
index 1beaf6e..2aa8096 100644
--- a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff.ts
+++ b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff.ts
@@ -1109,14 +1109,12 @@
   return mutations.flatMap(mutation => [...mutation.removedNodes]);
 }
 
-// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (isNewDiff()) {
+if (!isNewDiff()) {
   customElements.define('gr-diff', GrDiff);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
-    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
     'gr-diff': LitElement;
   }
   interface HTMLElementEventMap {
diff --git a/polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff_test.ts b/polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff_test.ts
similarity index 100%
rename from polygerrit-ui/app/embed/diff-new/gr-diff/gr-diff_test.ts
rename to polygerrit-ui/app/embed/diff-old/gr-diff/gr-diff_test.ts
diff --git a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls-section.ts b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls-section.ts
index 132751f..36e1f1a 100644
--- a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls-section.ts
+++ b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls-section.ts
@@ -125,7 +125,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define(
     'gr-context-controls-section',
     GrContextControlsSection
diff --git a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
index 2639a3d..43c8113 100644
--- a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
+++ b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
@@ -369,7 +369,7 @@
           buttonType: type,
           expandedLines: linesToExpand,
         });
-        fire(this, 'diff-context-expanded-internal', {
+        fire(this, 'diff-context-expanded-internal-new', {
           contextGroup: this.group,
           groups,
           numLines: this.numLines(),
@@ -515,8 +515,9 @@
     `;
   }
 }
+
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-context-controls', GrContextControls);
 }
 
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts
index d907011..1452e0f 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts
@@ -350,7 +350,7 @@
   init() {
     this.cleanup();
     this.diffElement?.addEventListener(
-      'diff-context-expanded-internal',
+      'diff-context-expanded-internal-new',
       this.onDiffContextExpanded
     );
     this.builder?.init();
@@ -367,7 +367,7 @@
     this.processor?.cancel();
     this.builder?.cleanup();
     this.diffElement?.removeEventListener(
-      'diff-context-expanded-internal',
+      'diff-context-expanded-internal-new',
       this.onDiffContextExpanded
     );
   }
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-image.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-image.ts
index 400674d..eeb07d8 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-image.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-image.ts
@@ -10,8 +10,8 @@
 import {html, LitElement, nothing} from 'lit';
 import {property, query, state} from 'lit/decorators.js';
 import {GrDiffBuilder} from './gr-diff-builder';
-import {createElementDiff, isNewDiff} from '../gr-diff/gr-diff-utils';
 import {GrDiffGroup} from '../gr-diff/gr-diff-group';
+import {isNewDiff, createElementDiff} from '../gr-diff/gr-diff-utils';
 
 // MIME types for images we allow showing. Do not include SVG, it can contain
 // arbitrary JavaScript.
@@ -45,6 +45,7 @@
   }
 
   private createImageDiffNew() {
+    // TODO(newdiff-cleanup): Remove cast when newdiff migration is complete.
     const imageDiff = document.createElement(
       'gr-diff-image-new'
     ) as GrDiffImageNew;
@@ -55,6 +56,7 @@
   }
 
   private createImageDiffOld() {
+    // TODO(newdiff-cleanup): Remove cast when newdiff migration is complete.
     const imageDiff = document.createElement(
       'gr-diff-image-old'
     ) as GrDiffImageOld;
@@ -267,7 +269,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-diff-image-new', GrDiffImageNew);
   customElements.define('gr-diff-image-old', GrDiffImageOld);
 }
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder.ts
index d826755..bcc54d4 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder.ts
@@ -34,7 +34,7 @@
 
 declare global {
   interface HTMLElementEventMap {
-    'diff-context-expanded-internal': CustomEvent<DiffContextExpandedEventDetail>;
+    'diff-context-expanded-internal-new': CustomEvent<DiffContextExpandedEventDetail>;
     'diff-context-expanded': CustomEvent<DiffContextExpandedExternalDetail>;
     'content-load-needed': CustomEvent<ContentLoadNeededEventDetail>;
   }
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-row.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-row.ts
index ae0a937..51024da 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-row.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-row.ts
@@ -470,7 +470,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-diff-row', GrDiffRow);
 }
 
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-section.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-section.ts
index 97bec05..e02d62b 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-section.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-section.ts
@@ -16,9 +16,9 @@
 } from '../../../api/diff';
 import {GrDiffGroup, GrDiffGroupType} from '../gr-diff/gr-diff-group';
 import {
+  isNewDiff,
   diffClasses,
   getResponsiveMode,
-  isNewDiff,
 } from '../gr-diff/gr-diff-utils';
 import {GrDiffRow} from './gr-diff-row';
 import '../gr-context-controls/gr-context-controls-section';
@@ -244,7 +244,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-diff-section', GrDiffSection);
 }
 
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-text.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-text.ts
index 7c26ddc..2acedc8 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-text.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-text.ts
@@ -6,7 +6,7 @@
 import {LitElement, html, TemplateResult} from 'lit';
 import {property} from 'lit/decorators.js';
 import {styleMap} from 'lit/directives/style-map.js';
-import {diffClasses, isNewDiff} from '../gr-diff/gr-diff-utils';
+import {isNewDiff, diffClasses} from '../gr-diff/gr-diff-utils';
 
 const SURROGATE_PAIR = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
 
@@ -145,7 +145,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-diff-text', GrDiffText);
 }
 
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-highlight/gr-annotation_test.ts b/polygerrit-ui/app/embed/diff/gr-diff-highlight/gr-annotation_test.ts
index f319a3c..3e1ce66 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff-highlight/gr-annotation_test.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff-highlight/gr-annotation_test.ts
@@ -3,7 +3,6 @@
  * Copyright 2016 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-
 import '../../../test/common-test-setup';
 import {GrAnnotation} from './gr-annotation';
 import {
diff --git a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
index 8c1a687..edd68dc 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
@@ -25,7 +25,7 @@
   getResponsiveMode,
   isResponsive,
   isNewDiff,
-} from './gr-diff-utils';
+} from '../gr-diff/gr-diff-utils';
 import {BlameInfo, CommentRange, ImageInfo} from '../../../types/common';
 import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
 import {
@@ -1110,7 +1110,7 @@
 }
 
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
-if (!isNewDiff()) {
+if (isNewDiff()) {
   customElements.define('gr-diff', GrDiff);
 }
 
diff --git a/polygerrit-ui/app/models/views/change.ts b/polygerrit-ui/app/models/views/change.ts
index 713d401..127f77b 100644
--- a/polygerrit-ui/app/models/views/change.ts
+++ b/polygerrit-ui/app/models/views/change.ts
@@ -204,25 +204,33 @@
     childView: ChangeChildView.DIFF,
   });
 
-  const path = `/${encodeURL(state.diffView?.path ?? '')}`;
-
-  let suffix = '';
+  let path = `/${encodeURL(state.diffView?.path ?? '')}`;
   // TODO: Move creating of comment URLs to a separate function. We are
   // "abusing" the `commentId` property, which should only be used for pointing
   // to comment in the COMMENTS tab of the OVERVIEW page.
   if (state.commentId) {
-    suffix += `comment/${state.commentId}/`;
+    path += `comment/${state.commentId}/`;
   }
 
+  let queryParams = '';
+  const params = [];
+  if (state.checksPatchset && state.checksPatchset > 0) {
+    params.push(`checksPatchset=${state.checksPatchset}`);
+  }
+  if (params.length > 0) {
+    queryParams = '?' + params.join('&');
+  }
+
+  let hash = '';
   if (state.diffView?.lineNum) {
-    suffix += '#';
+    hash += '#';
     if (state.diffView?.leftSide) {
-      suffix += 'b';
+      hash += 'b';
     }
-    suffix += state.diffView.lineNum;
+    hash += state.diffView.lineNum;
   }
 
-  return `${createChangeUrlCommon(state)}${path}${suffix}`;
+  return `${createChangeUrlCommon(state)}${path}${queryParams}${hash}`;
 }
 
 export function createEditUrl(
diff --git a/polygerrit-ui/app/models/views/change_test.ts b/polygerrit-ui/app/models/views/change_test.ts
index 837e362..8e671d1 100644
--- a/polygerrit-ui/app/models/views/change_test.ts
+++ b/polygerrit-ui/app/models/views/change_test.ts
@@ -6,6 +6,7 @@
 import {assert} from '@open-wc/testing';
 import {
   BasePatchSetNum,
+  PatchSetNumber,
   RepoName,
   RevisionPatchSetNum,
 } from '../../api/rest-api';
@@ -77,59 +78,97 @@
     assert.equal(createChangeUrl(state), '/c/x%252B/y%252B/z%252B/w/+/42');
   });
 
-  test('createDiffUrl', () => {
-    const params: ChangeViewState = {
-      ...createDiffViewState(),
-      patchNum: 12 as RevisionPatchSetNum,
-      diffView: {path: 'x+y/path.cpp'},
-    };
-    assert.equal(
-      createDiffUrl(params),
-      '/c/test-project/+/42/12/x%252By/path.cpp'
-    );
+  suite('createDiffUrl', () => {
+    let params: ChangeViewState;
+    setup(() => {
+      params = {
+        ...createDiffViewState(),
+        patchNum: 12 as RevisionPatchSetNum,
+        diffView: {path: 'x+y/path.cpp'},
+      };
+    });
 
-    window.CANONICAL_PATH = '/base';
-    assert.equal(createDiffUrl(params).substring(0, 5), '/base');
-    window.CANONICAL_PATH = undefined;
+    test('CANONICAL_PATH', () => {
+      window.CANONICAL_PATH = '/base';
+      assert.equal(createDiffUrl(params).substring(0, 5), '/base');
+      window.CANONICAL_PATH = undefined;
+    });
 
-    params.repo = 'test' as RepoName;
-    assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%252By/path.cpp');
+    test('basic', () => {
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/12/x%252By/path.cpp'
+      );
+    });
 
-    params.basePatchNum = 6 as BasePatchSetNum;
-    assert.equal(createDiffUrl(params), '/c/test/+/42/6..12/x%252By/path.cpp');
+    test('repo', () => {
+      params.repo = 'test' as RepoName;
+      assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%252By/path.cpp');
+    });
 
-    params.diffView = {
-      path: 'foo bar/my+file.txt%',
-    };
-    params.patchNum = 2 as RevisionPatchSetNum;
-    delete params.basePatchNum;
-    assert.equal(
-      createDiffUrl(params),
-      '/c/test/+/42/2/foo+bar/my%252Bfile.txt%2525'
-    );
+    test('checks patchset', () => {
+      params.checksPatchset = 4 as PatchSetNumber;
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/12/x%252By/path.cpp?checksPatchset=4'
+      );
+    });
 
-    params.diffView = {
-      path: 'file.cpp',
-      lineNum: 123,
-    };
-    assert.equal(createDiffUrl(params), '/c/test/+/42/2/file.cpp#123');
+    test('base patchset', () => {
+      params.basePatchNum = 6 as BasePatchSetNum;
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/6..12/x%252By/path.cpp'
+      );
+    });
 
-    params.diffView = {
-      path: 'file.cpp',
-      lineNum: 123,
-      leftSide: true,
-    };
-    assert.equal(createDiffUrl(params), '/c/test/+/42/2/file.cpp#b123');
-  });
+    test('percent', () => {
+      params.diffView = {
+        path: 'foo bar/my+file.txt%',
+      };
+      params.patchNum = 2 as RevisionPatchSetNum;
+      delete params.basePatchNum;
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/2/foo+bar/my%252Bfile.txt%2525'
+      );
+    });
 
-  test('diff with repo name encoding', () => {
-    const params: ChangeViewState = {
-      ...createDiffViewState(),
-      patchNum: 12 as RevisionPatchSetNum,
-      repo: 'x+/y' as RepoName,
-      diffView: {path: 'x+y/path.cpp'},
-    };
-    assert.equal(createDiffUrl(params), '/c/x%252B/y/+/42/12/x%252By/path.cpp');
+    test('line right', () => {
+      params.diffView = {
+        path: 'file.cpp',
+        lineNum: 123,
+      };
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/12/file.cpp#123'
+      );
+    });
+
+    test('line left', () => {
+      params.diffView = {
+        path: 'file.cpp',
+        lineNum: 123,
+        leftSide: true,
+      };
+      assert.equal(
+        createDiffUrl(params),
+        '/c/test-project/+/42/12/file.cpp#b123'
+      );
+    });
+
+    test('diff with repo name encoding', () => {
+      const params: ChangeViewState = {
+        ...createDiffViewState(),
+        patchNum: 12 as RevisionPatchSetNum,
+        repo: 'x+/y' as RepoName,
+        diffView: {path: 'x+y/path.cpp'},
+      };
+      assert.equal(
+        createDiffUrl(params),
+        '/c/x%252B/y/+/42/12/x%252By/path.cpp'
+      );
+    });
   });
 
   test('createEditUrl', () => {
diff --git a/polygerrit-ui/package.json b/polygerrit-ui/package.json
index 6fa4d0f..e8bd3d8 100644
--- a/polygerrit-ui/package.json
+++ b/polygerrit-ui/package.json
@@ -29,7 +29,7 @@
     "test:browsers": "web-test-runner --playwright --browsers webkit firefox chromium",
     "test:coverage": "web-test-runner --coverage",
     "test:watch": "web-test-runner --watch",
-    "test:single": "web-test-runner --watch --files",
+    "test:single": "web-test-runner --watch --group default --files",
     "test:single:coverage": "web-test-runner --watch --coverage --files"
   },
   "license": "Apache-2.0",
diff --git a/polygerrit-ui/web-test-runner.config.mjs b/polygerrit-ui/web-test-runner.config.mjs
index 01b1a91..bd8d9ac 100644
--- a/polygerrit-ui/web-test-runner.config.mjs
+++ b/polygerrit-ui/web-test-runner.config.mjs
@@ -26,7 +26,14 @@
 const config = {
   files: [
     "app/**/*_test.{ts,js}",
-    "!app/embed/diff-new/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-context-controls/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-builder/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-cursor/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-highlight/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-model/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-processor/**/*_test.{ts,js}",
+    "!app/embed/diff/gr-diff-selection/**/*_test.{ts,js}",
     "!**/node_modules/**/*",
     ...(process.argv.includes("--run-screenshots")
       ? []
@@ -37,7 +44,7 @@
     {
       name: "new-diff",
       files: [
-        "app/embed/diff-new/**/*_test.{ts,js}",
+        "app/embed/diff/**/*_test.{ts,js}",
         "app/elements/change/gr-file-list/gr-file-list_test.{ts,js}",
         "app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_test.{ts,js}",
         "app/elements/diff/gr-diff-host/gr-diff-host_test.{ts,js}",