Merge commit '98c95296b91bcf0b752915b0b4e7372bb82c6030' into dev-release

Change-Id: I5a1deb67f5abf5345053808028b6387698bb15c4
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/DownloadAllDependenciesTask.kt b/d8_r8/commonBuildSrc/src/main/kotlin/DownloadAllDependenciesTask.kt
index 92c1af2..f05116d 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/DownloadAllDependenciesTask.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/DownloadAllDependenciesTask.kt
@@ -15,6 +15,7 @@
 import org.gradle.api.provider.Property
 import org.gradle.api.tasks.InputFiles
 import org.gradle.api.tasks.OutputDirectories
+import org.gradle.api.tasks.OutputFiles
 import org.gradle.api.tasks.TaskAction
 import org.gradle.internal.os.OperatingSystem
 import org.gradle.workers.WorkAction
@@ -36,6 +37,13 @@
     return _thirdPartyDeps!!.map { _root!!.resolve(it.path) }
   }
 
+  @OutputFiles
+  fun getOutputFiles(): List<File> {
+      return _thirdPartyDeps!!.map {
+        _root!!.resolve(it.sha1File.resolveSibling(it.sha1File.name.replace(".sha1", "")))
+      }
+  }
+
   @Inject
   protected abstract fun getWorkerExecutor(): WorkerExecutor?
 
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
index c0a9833..f8a35af 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
@@ -50,7 +50,6 @@
 
     fun setupTestTask(test: Test, isR8Lib: Boolean, r8Jar: File?, r8LibMappingFile: File?) {
       val project = test.project
-      test.systemProperty("USE_NEW_GRADLE_SETUP", "true")
       if (project.hasProperty("testfilter")) {
         val testFilter = project.property("testfilter").toString()
         test.filter.setFailOnNoMatchingTests(false)
diff --git a/d8_r8/test/build.gradle.kts b/d8_r8/test/build.gradle.kts
index d4489e8..4a1de06 100644
--- a/d8_r8/test/build.gradle.kts
+++ b/d8_r8/test/build.gradle.kts
@@ -179,45 +179,6 @@
             "r8lib.jar")
   }
 
-  val assembleRetraceLibNoDeps by registering(Exec::class) {
-    dependsOn(assembleR8LibNoDeps, mainDepsJarTask, r8WithRelocatedDepsTask)
-    val mainDepsJar = mainDepsJarTask.getSingleOutputFile()
-    val r8LibNoDepsJar = assembleR8LibNoDeps.getSingleOutputFile()
-    val r8WithRelocatedDepsJar = r8WithRelocatedDepsTask.getSingleOutputFile()
-    inputs.files(mainDepsJar, r8LibNoDepsJar, r8WithRelocatedDepsJar)
-    val inputMap = file("$r8LibNoDepsJar.map")
-    val outputJar = getRoot().resolveAll("build", "libs", "r8retrace-exclude-deps.jar")
-    outputs.file(outputJar)
-    commandLine = createR8LibCommandLine(
-            r8WithRelocatedDepsJar,
-            r8LibNoDepsJar,
-            outputJar,
-            listOf(getRoot().resolveAll("src", "main", "keep_retrace.txt")),
-            excludingDepsVariant = true,
-            debugVariant = true,
-            lib = listOf(mainDepsJar),
-            pgInputMap = inputMap)
-  }
-
-  val assembleRetraceLibWithRelocatedDeps by registering(Exec::class) {
-    dependsOn(assembleR8LibWithRelocatedDeps, mainDepsJarTask, r8WithRelocatedDepsTask)
-    val mainDepsJar = mainDepsJarTask.getSingleOutputFile()
-    val r8LibWithRelocatedDepsJar = assembleR8LibWithRelocatedDeps.getSingleOutputFile()
-    val r8WithRelocatedDepsJar = r8WithRelocatedDepsTask.getSingleOutputFile()
-    inputs.files(mainDepsJar, r8LibWithRelocatedDepsJar, r8WithRelocatedDepsJar)
-    val inputMap = file("$r8LibWithRelocatedDepsJar.map")
-    val outputJar = getRoot().resolveAll("build", "libs", "r8retrace.jar")
-    outputs.file(outputJar)
-    commandLine = createR8LibCommandLine(
-      r8WithRelocatedDepsJar,
-      r8LibWithRelocatedDepsJar,
-      outputJar,
-      listOf(getRoot().resolveAll("src", "main", "keep_retrace.txt")),
-      excludingDepsVariant = false,
-      debugVariant = true,
-      pgInputMap = inputMap)
-  }
-
   val resourceshrinkercli by registering(Exec::class) {
     dependsOn(r8WithRelocatedDepsTask)
     val r8 = r8WithRelocatedDepsTask.getSingleOutputFile()
@@ -318,9 +279,15 @@
             "r8lib-exclude-deps-testdeps-cf.jar")
   }
 
-  val unzipTests by registering(Copy::class) {
+  val cleanUnzipTests by registering(Delete::class) {
     dependsOn(packageTests)
     val outputDir = file("${buildDir}/unpacked/test")
+    setDelete(outputDir)
+  }
+
+  val unzipTests by registering(Copy::class) {
+    dependsOn(cleanUnzipTests, packageTests)
+    val outputDir = file("${buildDir}/unpacked/test")
     from(zipTree(packageTests.getSingleOutputFile()))
     into(outputDir)
   }
@@ -334,11 +301,23 @@
     into(outputDir)
   }
 
+  val cleanUnzipRewrittenTestsForR8LibWithRelocatedDeps by registering(Delete::class) {
+    val outputDir = file("${buildDir}/unpacked/rewrittentests-r8lib")
+    setDelete(outputDir)
+  }
+
   val unzipRewrittenTestsForR8LibWithRelocatedDeps by registering(Copy::class) {
+    dependsOn(cleanUnzipRewrittenTestsForR8LibWithRelocatedDeps)
     unzipRewrittenTestsForR8Lib(rewriteTestsForR8LibWithRelocatedDeps, "rewrittentests-r8lib")
   }
 
+  val cleanUnzipRewrittenTestsForR8LibNoDeps by registering(Delete::class) {
+    val outputDir = file("${buildDir}/unpacked/rewrittentests-r8lib-exclude-deps")
+    setDelete(outputDir)
+  }
+
   val unzipRewrittenTestsForR8LibNoDeps by registering(Copy::class) {
+    dependsOn(cleanUnzipRewrittenTestsForR8LibNoDeps)
     unzipRewrittenTestsForR8Lib(
             rewriteTestsForR8LibNoDeps, "rewrittentests-r8lib-exclude-deps")
   }
@@ -375,7 +354,6 @@
     systemProperty("EXAMPLES_JAVA_11_JAVAC_BUILD_DIR",
             getRoot().resolveAll("build", "test", "examplesJava11", "classes"))
     systemProperty("R8_RUNTIME_PATH", r8LibJar)
-    // TODO(b/270105162): This should change if running with retrace lib/r8lib.
     systemProperty("RETRACE_RUNTIME_PATH", r8LibJar)
     systemProperty("R8_DEPS", mainDepsJarTask.getSingleOutputFile())
     systemProperty("com.android.tools.r8.artprofilerewritingcompletenesscheck", "true")
diff --git a/d8_r8/test_modules/tests_bootstrap/build.gradle.kts b/d8_r8/test_modules/tests_bootstrap/build.gradle.kts
index bf64d96..b503fd3 100644
--- a/d8_r8/test_modules/tests_bootstrap/build.gradle.kts
+++ b/d8_r8/test_modules/tests_bootstrap/build.gradle.kts
@@ -26,9 +26,12 @@
 }
 
 val testsJava8Jar = projectTask("tests_java_8", "testJar")
+val keepAnnoJarTask = projectTask("keepanno", "jar")
+val keepAnnoCompileTask = projectTask("keepanno", "compileJava")
 val mainR8RelocatedTask = projectTask("main", "r8WithRelocatedDeps")
 
 dependencies {
+  implementation(keepAnnoJarTask.outputs.files)
   implementation(files(testsJava8Jar.outputs.files.getSingleFile()))
   implementation(projectTask("main", "jar").outputs.files)
   implementation(Deps.asm)
@@ -70,6 +73,7 @@
     dependsOn(mainR8RelocatedTask)
     systemProperty("TEST_DATA_LOCATION",
                    layout.buildDirectory.dir("classes/java/test").get().toString())
+    systemProperty("KEEP_ANNO_JAVAC_BUILD_DIR", keepAnnoCompileTask.outputs.files.getAsPath())
     systemProperty("R8_WITH_RELOCATED_DEPS", mainR8RelocatedTask.outputs.files.singleFile)
     systemProperty("R8_RUNTIME_PATH", mainR8RelocatedTask.outputs.files.singleFile)
   }
@@ -82,6 +86,7 @@
 
   val depsJar by registering(Jar::class) {
     dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
+    dependsOn(gradle.includedBuild("keepanno").task(":jar"))
     if (!project.hasProperty("no_internal")) {
       dependsOn(gradle.includedBuild("shared").task(":downloadDepsInternal"))
     }
diff --git a/d8_r8/test_modules/tests_bootstrap/settings.gradle.kts b/d8_r8/test_modules/tests_bootstrap/settings.gradle.kts
index b4fb012..aeb53ad 100644
--- a/d8_r8/test_modules/tests_bootstrap/settings.gradle.kts
+++ b/d8_r8/test_modules/tests_bootstrap/settings.gradle.kts
@@ -30,3 +30,4 @@
 includeBuild(root.resolve("shared"))
 includeBuild(root.resolve("main"))
 includeBuild(root.resolve("test_modules").resolve("tests_java_8"))
+includeBuild(root.resolve("keepanno"))
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepForApi.java b/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepForApi.java
index 44756ea..24b9c4f 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepForApi.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepForApi.java
@@ -12,7 +12,7 @@
  * Annotation to mark a class, field or method as part of a library API surface.
  *
  * <p>When a class is annotated, member patterns can be used to define which members are to be kept.
- * When no member patterns are specified the default pattern is to match all public and protected
+ * When no member patterns are specified the default pattern matches all public and protected
  * members.
  *
  * <p>When a member is annotated, the member patterns cannot be used as the annotated member itself
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
index 5f7f156..d3fc1ba 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
@@ -34,7 +34,6 @@
 import com.android.tools.r8.keepanno.ast.KeepFieldNamePattern;
 import com.android.tools.r8.keepanno.ast.KeepFieldPattern;
 import com.android.tools.r8.keepanno.ast.KeepFieldTypePattern;
-import com.android.tools.r8.keepanno.ast.KeepItemKind;
 import com.android.tools.r8.keepanno.ast.KeepItemPattern;
 import com.android.tools.r8.keepanno.ast.KeepItemReference;
 import com.android.tools.r8.keepanno.ast.KeepMemberAccessPattern;
@@ -491,10 +490,8 @@
         if (!descriptor.equals(itemDescriptor)) {
           throw new KeepEdgeException("@KeepForApi must reference its class context " + className);
         }
-        if (itemPattern.getKind().equals(KeepItemKind.ONLY_MEMBERS)) {
-          if (items.size() == 1) {
+        if (itemPattern.isMemberItemPattern() && items.size() == 1) {
             throw new KeepEdgeException("@KeepForApi kind must include its class");
-          }
         }
         if (!itemPattern.getExtendsPattern().isAny()) {
           throw new KeepEdgeException("@KeepForApi cannot define an 'extends' pattern.");
@@ -668,10 +665,8 @@
           throw new KeepEdgeException(
               "@" + getAnnotationName() + " must reference its class context " + className);
         }
-        if (itemPattern.getKind().equals(KeepItemKind.ONLY_MEMBERS)) {
-          if (items.size() == 1) {
-            throw new KeepEdgeException("@" + getAnnotationName() + " kind must include its class");
-          }
+        if (itemPattern.isMemberItemPattern() && items.size() == 1) {
+          throw new KeepEdgeException("@" + getAnnotationName() + " kind must include its class");
         }
         if (!itemPattern.getExtendsPattern().isAny()) {
           throw new KeepEdgeException(
@@ -701,7 +696,7 @@
     private final KeepEdgeMetaInfo.Builder metaInfoBuilder = KeepEdgeMetaInfo.builder();
     private final UserBindingsHelper bindingsHelper = new UserBindingsHelper();
     private final KeepConsequences.Builder consequences = KeepConsequences.builder();
-    private KeepItemKind kind = KeepItemKind.ONLY_MEMBERS;
+    private String kind = Kind.ONLY_MEMBERS;
 
     UsedByReflectionMemberVisitor(
         String annotationDescriptor,
@@ -739,13 +734,9 @@
           // The default value is obtained by not assigning a kind (e.g., null in the builder).
           break;
         case Kind.ONLY_CLASS:
-          kind = KeepItemKind.ONLY_CLASS;
-          break;
         case Kind.ONLY_MEMBERS:
-          kind = KeepItemKind.ONLY_MEMBERS;
-          break;
         case Kind.CLASS_AND_MEMBERS:
-          kind = KeepItemKind.CLASS_AND_MEMBERS;
+          kind = value;
           break;
         default:
           super.visitEnum(name, descriptor, value);
@@ -771,11 +762,11 @@
 
     @Override
     public void visitEnd() {
-      if (kind.equals(KeepItemKind.ONLY_CLASS)) {
+      if (Kind.ONLY_CLASS.equals(kind)) {
         throw new KeepEdgeException("@" + getAnnotationName() + " kind must include its member");
       }
-      assert context.getKind() == KeepItemKind.ONLY_MEMBERS;
-      if (kind.equals(KeepItemKind.CLASS_AND_MEMBERS)) {
+      assert context.isMemberItemPattern();
+      if (Kind.CLASS_AND_MEMBERS.equals(kind)) {
         consequences.addTarget(
             KeepTarget.builder()
                 .setItemPattern(
@@ -1436,21 +1427,24 @@
         assert !itemReference.isBindingReference();
         KeepItemPattern itemPattern = itemReference.asItemPattern();
         KeepItemPattern classPattern;
+        KeepItemPattern memberPattern;
         if (itemPattern.isClassItemPattern()) {
           classPattern = itemPattern;
+          memberPattern =
+              KeepItemPattern.builder()
+                  .copyFrom(itemPattern)
+                  .setMemberPattern(KeepMemberPattern.allMembers())
+                  .build();
         } else {
+          memberPattern = itemPattern;
           classPattern =
               KeepItemPattern.builder()
                   .copyFrom(itemPattern)
-                  .setKind(KeepItemKind.ONLY_CLASS)
                   .setMemberPattern(KeepMemberPattern.none())
                   .build();
         }
-        KeepItemPattern memberPattern =
-            KeepItemPattern.builder()
-                .copyFrom(itemPattern)
-                .setKind(KeepItemKind.ONLY_MEMBERS)
-                .build();
+        assert classPattern.isClassItemPattern();
+        assert memberPattern.isMemberItemPattern();
         return ImmutableList.of(
             KeepItemReference.fromItemPattern(classPattern),
             KeepItemReference.fromItemPattern(memberPattern));
@@ -1470,27 +1464,31 @@
       assert kind != null;
       if (Kind.CLASS_AND_MEMBERS.equals(kind)) {
         KeepItemPattern itemPattern = itemReference.asItemPattern();
+        KeepMemberPattern memberPattern;
         KeepItemPattern classPattern;
         if (itemPattern.isClassItemPattern()) {
+          memberPattern = KeepMemberPattern.allMembers();
           classPattern = itemPattern;
         } else {
+          memberPattern = itemPattern.getMemberPattern();
           classPattern =
               KeepItemPattern.builder()
                   .copyFrom(itemPattern)
-                  .setKind(KeepItemKind.ONLY_CLASS)
                   .setMemberPattern(KeepMemberPattern.none())
                   .build();
         }
         BindingSymbol symbol = getBindingsHelper().defineFreshBinding("CLASS", classPattern);
-        KeepItemPattern memberPattern =
+        KeepItemPattern memberItemPattern =
             KeepItemPattern.builder()
                 .copyFrom(itemPattern)
                 .setClassReference(KeepClassReference.fromBindingReference(symbol))
-                .setKind(KeepItemKind.ONLY_MEMBERS)
+                .setMemberPattern(memberPattern)
                 .build();
+        assert classPattern.isClassItemPattern();
+        assert memberItemPattern.isMemberItemPattern();
         return ImmutableList.of(
             KeepItemReference.fromItemPattern(classPattern),
-            KeepItemReference.fromItemPattern(memberPattern));
+            KeepItemReference.fromItemPattern(memberItemPattern));
       } else {
         return Collections.singletonList(itemReference);
       }
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
index dc8e7c9..ec3fb30 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
@@ -138,12 +138,6 @@
   }
 
   private void writeItem(AnnotationVisitor itemVisitor, KeepItemPattern item) {
-    if (item.isAny(
-        binding -> {
-          throw new Unimplemented();
-        })) {
-      throw new Unimplemented();
-    }
     KeepClassReference classReference = item.getClassReference();
     if (classReference.isBindingReference()) {
       throw new Unimplemented();
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
index 790fb9e..a3ba447 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
@@ -45,26 +45,6 @@
     bindings.forEach((name, binding) -> fn.accept(name, binding.getItem()));
   }
 
-  public boolean isAny(KeepItemReference itemReference) {
-    return itemReference.isBindingReference()
-        ? isAny(get(itemReference.asBindingReference()).getItem())
-        : isAny(itemReference.asItemPattern());
-  }
-
-  public boolean isAny(KeepItemPattern itemPattern) {
-    return itemPattern.isAny(this::isAnyClassNamePattern);
-  }
-
-  // If the outer-most item has been judged to be "any" then we internally only need to check
-  // that the class-name pattern itself is "any". The class-name could potentially reference names
-  // of other item bindings so this is a recursive search.
-  private boolean isAnyClassNamePattern(BindingSymbol bindingName) {
-    KeepClassReference classReference = get(bindingName).getItem().getClassReference();
-    return classReference.isBindingReference()
-        ? isAnyClassNamePattern(classReference.asBindingReference())
-        : classReference.asClassNamePattern().isAny();
-  }
-
   @Override
   public String toString() {
     return "{"
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
index b2e541a..3b11a28 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
@@ -37,11 +37,7 @@
  *   ITEM_REFERENCE  ::= BINDING_REFERENCE | ITEM_PATTERN
  *   CLASS_REFERENCE ::= BINDING_REFERENCE | QUALIFIED_CLASS_NAME_PATTERN
  *
- *   ITEM_PATTERN
- *     ::= any
- *       | ITEM_KIND class CLASS_REFERENCE extends EXTENDS_PATTERN { MEMBER_PATTERN }
- *
- *   ITEM_KIND ::= ONLY_CLASS | ONLY_MEMBERS | CLASS_AND_MEMBERS
+ *   ITEM_PATTERN ::= class CLASS_REFERENCE extends EXTENDS_PATTERN { MEMBER_PATTERN }
  *
  *   TYPE_PATTERN ::= any | exact type-descriptor
  *   PACKAGE_PATTERN ::= any | exact package-name
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemKind.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemKind.java
deleted file mode 100644
index 0d59769..0000000
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemKind.java
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.keepanno.ast;
-
-public enum KeepItemKind {
-  ONLY_CLASS,
-  ONLY_MEMBERS,
-  CLASS_AND_MEMBERS
-}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemPattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemPattern.java
index d81dde9..7634c68 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemPattern.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepItemPattern.java
@@ -6,7 +6,6 @@
 import com.android.tools.r8.keepanno.ast.KeepBindings.BindingSymbol;
 import java.util.Collection;
 import java.util.Objects;
-import java.util.function.Predicate;
 
 /**
  * A pattern for matching items in the program.
@@ -20,29 +19,28 @@
  */
 public class KeepItemPattern {
 
-  public static KeepItemPattern any() {
-    return builder().any().build();
+  public static KeepItemPattern anyClass() {
+    return builder().setMemberPattern(KeepMemberPattern.none()).build();
+  }
+
+  public static KeepItemPattern anyMember() {
+    return builder().setMemberPattern(KeepMemberPattern.allMembers()).build();
   }
 
   public static Builder builder() {
     return new Builder();
   }
 
-  public boolean isClassAndMemberPattern() {
-    return kind == KeepItemKind.CLASS_AND_MEMBERS;
-  }
-
   public boolean isClassItemPattern() {
-    return kind == KeepItemKind.ONLY_CLASS;
+    return memberPattern.isNone();
   }
 
   public boolean isMemberItemPattern() {
-    return kind == KeepItemKind.ONLY_MEMBERS;
+    return !isClassItemPattern();
   }
 
   public static class Builder {
 
-    private KeepItemKind kind = null;
     private KeepClassReference classReference =
         KeepClassReference.fromClassNamePattern(KeepQualifiedClassNamePattern.any());
     private KeepExtendsPattern extendsPattern = KeepExtendsPattern.any();
@@ -51,25 +49,11 @@
     private Builder() {}
 
     public Builder copyFrom(KeepItemPattern pattern) {
-      return setKind(pattern.getKind())
-          .setClassReference(pattern.getClassReference())
+      return setClassReference(pattern.getClassReference())
           .setExtendsPattern(pattern.getExtendsPattern())
           .setMemberPattern(pattern.getMemberPattern());
     }
 
-    public Builder any() {
-      kind = KeepItemKind.CLASS_AND_MEMBERS;
-      classReference = KeepClassReference.fromClassNamePattern(KeepQualifiedClassNamePattern.any());
-      extendsPattern = KeepExtendsPattern.any();
-      memberPattern = KeepMemberPattern.allMembers();
-      return this;
-    }
-
-    public Builder setKind(KeepItemKind kind) {
-      this.kind = kind;
-      return this;
-    }
-
     public Builder setClassReference(KeepClassReference classReference) {
       this.classReference = classReference;
       return this;
@@ -90,56 +74,27 @@
     }
 
     public KeepItemPattern build() {
-      if (kind == null) {
-        kind = memberPattern.isNone() ? KeepItemKind.ONLY_CLASS : KeepItemKind.ONLY_MEMBERS;
-      }
-      if (kind == KeepItemKind.ONLY_CLASS && !memberPattern.isNone()) {
-        throw new KeepEdgeException(
-            "Invalid kind ONLY_CLASS for item with member pattern: " + memberPattern);
-      }
-      if (kind == KeepItemKind.ONLY_MEMBERS && memberPattern.isNone()) {
-        throw new KeepEdgeException("Invalid kind ONLY_MEMBERS for item with no member pattern");
-      }
-      if (kind == KeepItemKind.CLASS_AND_MEMBERS && memberPattern.isNone()) {
-        throw new KeepEdgeException(
-            "Invalid kind CLASS_AND_MEMBERS for item with no member pattern");
-      }
-      return new KeepItemPattern(kind, classReference, extendsPattern, memberPattern);
+      return new KeepItemPattern(classReference, extendsPattern, memberPattern);
     }
   }
 
-  private final KeepItemKind kind;
   private final KeepClassReference classReference;
   private final KeepExtendsPattern extendsPattern;
   private final KeepMemberPattern memberPattern;
   // TODO: class annotations
 
   private KeepItemPattern(
-      KeepItemKind kind,
       KeepClassReference classReference,
       KeepExtendsPattern extendsPattern,
       KeepMemberPattern memberPattern) {
-    assert kind != null;
     assert classReference != null;
     assert extendsPattern != null;
     assert memberPattern != null;
-    this.kind = kind;
     this.classReference = classReference;
     this.extendsPattern = extendsPattern;
     this.memberPattern = memberPattern;
   }
 
-  public boolean isAny(Predicate<BindingSymbol> onReference) {
-    return kind.equals(KeepItemKind.CLASS_AND_MEMBERS)
-        && extendsPattern.isAny()
-        && memberPattern.isAllMembers()
-        && classReference.isAny(onReference);
-  }
-
-  public KeepItemKind getKind() {
-    return kind;
-  }
-
   public KeepClassReference getClassReference() {
     return classReference;
   }
@@ -157,37 +112,40 @@
   }
 
   @Override
-  @SuppressWarnings("EqualsGetClass")
   public boolean equals(Object obj) {
     if (this == obj) {
       return true;
     }
-    if (obj == null || getClass() != obj.getClass()) {
+    if (!(obj instanceof KeepItemPattern)) {
       return false;
     }
     KeepItemPattern that = (KeepItemPattern) obj;
-    return kind.equals(that.kind)
-        && classReference.equals(that.classReference)
+    return classReference.equals(that.classReference)
         && extendsPattern.equals(that.extendsPattern)
         && memberPattern.equals(that.memberPattern);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(kind, classReference, extendsPattern, memberPattern);
+    return Objects.hash(classReference, extendsPattern, memberPattern);
   }
 
   @Override
   public String toString() {
-    return "KeepClassPattern{"
-        + "kind="
-        + kind
-        + ", classReference="
-        + classReference
-        + ", extendsPattern="
-        + extendsPattern
-        + ", memberPattern="
-        + memberPattern
-        + '}';
+    StringBuilder builder = new StringBuilder();
+    if (isClassItemPattern()) {
+      builder.append("KeepClassPattern");
+    } else {
+      assert isMemberItemPattern();
+      builder.append("KeepMemberPattern");
+    }
+    builder.append("{ class=").append(classReference);
+    if (!extendsPattern.isAny()) {
+      builder.append(", extends=").append(extendsPattern);
+    }
+    if (!memberPattern.isNone()) {
+      builder.append(", members=").append(memberPattern);
+    }
+    return builder.append('}').toString();
   }
 }
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepEdgeNormalizer.java b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepEdgeNormalizer.java
index cf79e0f..9bd2c09 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepEdgeNormalizer.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepEdgeNormalizer.java
@@ -9,7 +9,6 @@
 import com.android.tools.r8.keepanno.ast.KeepCondition;
 import com.android.tools.r8.keepanno.ast.KeepConsequences;
 import com.android.tools.r8.keepanno.ast.KeepEdge;
-import com.android.tools.r8.keepanno.ast.KeepItemKind;
 import com.android.tools.r8.keepanno.ast.KeepItemPattern;
 import com.android.tools.r8.keepanno.ast.KeepItemReference;
 import com.android.tools.r8.keepanno.ast.KeepPreconditions;
@@ -119,10 +118,8 @@
 
   private KeepItemPattern getMemberItemPattern(
       KeepItemPattern fromPattern, KeepClassReference classReference) {
-    assert fromPattern.getKind().equals(KeepItemKind.ONLY_MEMBERS)
-        || fromPattern.getKind().equals(KeepItemKind.CLASS_AND_MEMBERS);
+    assert fromPattern.isMemberItemPattern();
     return KeepItemPattern.builder()
-        .setKind(fromPattern.getKind())
         .setClassReference(classReference)
         .setMemberPattern(fromPattern.getMemberPattern())
         .build();
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
index 3dffb77..5ad2ae3 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
@@ -297,15 +297,6 @@
     List<BindingSymbol> targetMembers = new ArrayList<>();
     for (BindingSymbol targetReference : targets) {
       KeepItemPattern item = bindings.get(targetReference).getItem();
-      if (bindings.isAny(item)) {
-        // If the target is "any item" then it contains any other target pattern.
-        memberPatterns.put(targetReference, item.getMemberPattern());
-        callback.accept(
-            memberPatterns,
-            Collections.singletonList(targetReference),
-            TargetKeepKind.CLASS_OR_MEMBERS);
-        return;
-      }
       if (item.isClassItemPattern()) {
         keepKind = TargetKeepKind.CLASS_AND_MEMBERS;
       } else {
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index 6991778..df0df7b 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -1,6 +1,6 @@
 {
   "identifier": "com.tools.android:desugar_jdk_libs_configuration:2.0.4",
-  "configuration_format_version": 100,
+  "configuration_format_version": 101,
   "required_compilation_api_level": 30,
   "synthesized_library_classes_package_prefix": "j$.",
   "support_all_callbacks_from_library": true,
@@ -192,20 +192,93 @@
         "java.io.UncheckedIOException"
       ],
       "emulate_interface": {
-        "java.lang.Iterable": "j$.lang.Iterable",
-        "java.util.Collection": "j$.util.Collection",
-        "java.util.Comparator": "j$.util.Comparator",
-        "java.util.Iterator": "j$.util.Iterator",
-        "java.util.List": "j$.util.List",
-        "java.util.Map": "j$.util.Map",
-        "java.util.Map$Entry": "j$.util.Map$Entry",
-        "java.util.Set": "j$.util.Set",
-        "java.util.SortedSet": "j$.util.SortedSet",
-        "java.util.concurrent.ConcurrentMap": "j$.util.concurrent.ConcurrentMap"
+        "java.lang.Iterable": {
+          "rewrittenType": "j$.lang.Iterable",
+          "emulatedMethods": [
+            "java.util.Spliterator java.lang.Iterable#spliterator()",
+            "void java.lang.Iterable#forEach(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.concurrent.ConcurrentMap": {
+          "rewrittenType": "j$.util.concurrent.ConcurrentMap",
+          "emulatedMethods": [
+            "void java.util.concurrent.ConcurrentMap#forEach(java.util.function.BiConsumer)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#getOrDefault(java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#computeIfAbsent(java.lang.Object, java.util.function.Function)",
+            "void java.util.concurrent.ConcurrentMap#replaceAll(java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#compute(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#computeIfPresent(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction)"
+          ]
+        },
+        "java.util.List": {
+          "rewrittenType": "j$.util.List",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.List#spliterator()",
+            "void java.util.List#sort(java.util.Comparator)",
+            "void java.util.List#replaceAll(java.util.function.UnaryOperator)"
+          ]
+        },
+        "java.util.Map": {
+          "rewrittenType": "j$.util.Map",
+          "emulatedMethods": [
+            "java.lang.Object java.util.Map#merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#putIfAbsent(java.lang.Object, java.lang.Object)",
+            "void java.util.Map#forEach(java.util.function.BiConsumer)",
+            "void java.util.Map#replaceAll(java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#computeIfAbsent(java.lang.Object, java.util.function.Function)",
+            "java.lang.Object java.util.Map#compute(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#computeIfPresent(java.lang.Object, java.util.function.BiFunction)",
+            "boolean java.util.Map#remove(java.lang.Object, java.lang.Object)",
+            "boolean java.util.Map#replace(java.lang.Object, java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.Map#replace(java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.Map#getOrDefault(java.lang.Object, java.lang.Object)"
+          ]
+        },
+        "java.util.Collection": {
+          "rewrittenType": "j$.util.Collection",
+          "emulatedMethods": [
+            "java.util.stream.Stream java.util.Collection#stream()",
+            "java.util.stream.Stream java.util.Collection#parallelStream()",
+            "java.util.Spliterator java.util.Collection#spliterator()",
+            "boolean java.util.Collection#removeIf(java.util.function.Predicate)",
+            "void java.util.Collection#forEach(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.Iterator": {
+          "rewrittenType": "j$.util.Iterator",
+          "emulatedMethods": [
+            "void java.util.Iterator#forEachRemaining(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.Map$Entry": {
+          "rewrittenType": "j$.util.Map$Entry"
+        },
+        "java.util.Set": {
+          "rewrittenType": "j$.util.Set",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.Set#spliterator()"
+          ]
+        },
+        "java.util.Comparator": {
+          "rewrittenType": "j$.util.Comparator",
+          "emulatedMethods": [
+            "java.util.Comparator java.util.Comparator#thenComparingDouble(java.util.function.ToDoubleFunction)",
+            "java.util.Comparator java.util.Comparator#thenComparingInt(java.util.function.ToIntFunction)",
+            "java.util.Comparator java.util.Comparator#reversed()",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.function.Function, java.util.Comparator)",
+            "java.util.Comparator java.util.Comparator#thenComparingLong(java.util.function.ToLongFunction)",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.Comparator)",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.function.Function)"
+          ]
+        },
+        "java.util.SortedSet": {
+          "rewrittenType": "j$.util.SortedSet",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.SortedSet#spliterator()"
+          ]
+        }
       },
-      "dont_rewrite": [
-        "void java.util.Iterator#remove()"
-      ],
       "retarget_method": {
         "java.util.Spliterator java.util.Arrays#spliterator(java.lang.Object[])": "java.util.DesugarArrays",
         "java.util.Spliterator java.util.Arrays#spliterator(java.lang.Object[], int, int)": "java.util.DesugarArrays",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_human_comments.md b/src/library_desugar/jdk11/desugar_jdk_libs_human_comments.md
index 9f79e04..5e59f31 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_human_comments.md
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_human_comments.md
@@ -232,11 +232,6 @@
 the code for the default and static methods, and a dispatch class which hold the
 code to support emulated dispatch for the default methods.
 
-### Flag dont_rewrite
-
-`methodNotToRewrite`
-D8/R8 ignroes the methods present here from the emulated interface.
-
 ### Flag wrapper_conversion
 
 `type`
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json b/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
index b0dc30e..d69ed9a 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
@@ -1,6 +1,6 @@
 {
   "identifier": "com.tools.android:desugar_jdk_libs_configuration_minimal:2.0.4",
-  "configuration_format_version": 100,
+  "configuration_format_version": 101,
   "required_compilation_api_level": 24,
   "synthesized_library_classes_package_prefix": "j$.",
   "support_all_callbacks_from_library": false,
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
index ebeda3f..29e4e26 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
@@ -1,6 +1,6 @@
 {
   "identifier": "com.tools.android:desugar_jdk_libs_configuration_nio:2.0.4",
-  "configuration_format_version": 100,
+  "configuration_format_version": 101,
   "required_compilation_api_level": 30,
   "synthesized_library_classes_package_prefix": "j$.",
   "support_all_callbacks_from_library": true,
@@ -347,16 +347,92 @@
         "java.nio.channels.SeekableByteChannel"
       ],
       "emulate_interface": {
-        "java.lang.Iterable": "j$.lang.Iterable",
-        "java.util.Collection": "j$.util.Collection",
-        "java.util.Comparator": "j$.util.Comparator",
-        "java.util.Iterator": "j$.util.Iterator",
-        "java.util.List": "j$.util.List",
-        "java.util.Map": "j$.util.Map",
-        "java.util.Map$Entry": "j$.util.Map$Entry",
-        "java.util.Set": "j$.util.Set",
-        "java.util.SortedSet": "j$.util.SortedSet",
-        "java.util.concurrent.ConcurrentMap": "j$.util.concurrent.ConcurrentMap"
+        "java.lang.Iterable": {
+          "rewrittenType": "j$.lang.Iterable",
+          "emulatedMethods": [
+            "java.util.Spliterator java.lang.Iterable#spliterator()",
+            "void java.lang.Iterable#forEach(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.concurrent.ConcurrentMap": {
+          "rewrittenType": "j$.util.concurrent.ConcurrentMap",
+          "emulatedMethods": [
+            "void java.util.concurrent.ConcurrentMap#forEach(java.util.function.BiConsumer)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#getOrDefault(java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#computeIfAbsent(java.lang.Object, java.util.function.Function)",
+            "void java.util.concurrent.ConcurrentMap#replaceAll(java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#compute(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#computeIfPresent(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.concurrent.ConcurrentMap#merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction)"
+          ]
+        },
+        "java.util.List": {
+          "rewrittenType": "j$.util.List",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.List#spliterator()",
+            "void java.util.List#sort(java.util.Comparator)",
+            "void java.util.List#replaceAll(java.util.function.UnaryOperator)"
+          ]
+        },
+        "java.util.Map": {
+          "rewrittenType": "j$.util.Map",
+          "emulatedMethods": [
+            "java.lang.Object java.util.Map#merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#putIfAbsent(java.lang.Object, java.lang.Object)",
+            "void java.util.Map#forEach(java.util.function.BiConsumer)",
+            "void java.util.Map#replaceAll(java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#computeIfAbsent(java.lang.Object, java.util.function.Function)",
+            "java.lang.Object java.util.Map#compute(java.lang.Object, java.util.function.BiFunction)",
+            "java.lang.Object java.util.Map#computeIfPresent(java.lang.Object, java.util.function.BiFunction)",
+            "boolean java.util.Map#remove(java.lang.Object, java.lang.Object)",
+            "boolean java.util.Map#replace(java.lang.Object, java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.Map#replace(java.lang.Object, java.lang.Object)",
+            "java.lang.Object java.util.Map#getOrDefault(java.lang.Object, java.lang.Object)"
+          ]
+        },
+        "java.util.Collection": {
+          "rewrittenType": "j$.util.Collection",
+          "emulatedMethods": [
+            "java.util.stream.Stream java.util.Collection#stream()",
+            "java.util.stream.Stream java.util.Collection#parallelStream()",
+            "java.util.Spliterator java.util.Collection#spliterator()",
+            "boolean java.util.Collection#removeIf(java.util.function.Predicate)",
+            "void java.util.Collection#forEach(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.Iterator": {
+          "rewrittenType": "j$.util.Iterator",
+          "emulatedMethods": [
+            "void java.util.Iterator#forEachRemaining(java.util.function.Consumer)"
+          ]
+        },
+        "java.util.Map$Entry": {
+          "rewrittenType": "j$.util.Map$Entry"
+        },
+        "java.util.Set": {
+          "rewrittenType": "j$.util.Set",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.Set#spliterator()"
+          ]
+        },
+        "java.util.Comparator": {
+          "rewrittenType": "j$.util.Comparator",
+          "emulatedMethods": [
+            "java.util.Comparator java.util.Comparator#thenComparingDouble(java.util.function.ToDoubleFunction)",
+            "java.util.Comparator java.util.Comparator#thenComparingInt(java.util.function.ToIntFunction)",
+            "java.util.Comparator java.util.Comparator#reversed()",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.function.Function, java.util.Comparator)",
+            "java.util.Comparator java.util.Comparator#thenComparingLong(java.util.function.ToLongFunction)",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.Comparator)",
+            "java.util.Comparator java.util.Comparator#thenComparing(java.util.function.Function)"
+          ]
+        },
+        "java.util.SortedSet": {
+          "rewrittenType": "j$.util.SortedSet",
+          "emulatedMethods": [
+            "java.util.Spliterator java.util.SortedSet#spliterator()"
+          ]
+        }
       },
       "dont_rewrite": [
         "void java.util.Iterator#remove()"
diff --git a/src/main/java/com/android/tools/r8/AndroidResourceConsumer.java b/src/main/java/com/android/tools/r8/AndroidResourceConsumer.java
index 634611f..23d7c2b 100644
--- a/src/main/java/com/android/tools/r8/AndroidResourceConsumer.java
+++ b/src/main/java/com/android/tools/r8/AndroidResourceConsumer.java
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@Keep
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface AndroidResourceConsumer {
 
   void accept(AndroidResourceOutput androidResource, DiagnosticsHandler diagnosticsHandler);
diff --git a/src/main/java/com/android/tools/r8/AndroidResourceInput.java b/src/main/java/com/android/tools/r8/AndroidResourceInput.java
index 9dd3133..9403c75 100644
--- a/src/main/java/com/android/tools/r8/AndroidResourceInput.java
+++ b/src/main/java/com/android/tools/r8/AndroidResourceInput.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.InputStream;
 
 /**
@@ -13,9 +14,10 @@
  * allows us to reason about resources, and transitively other resources and code throughout the
  * entire compilation pipeline.
  */
-@Keep
+@KeepForApi
 public interface AndroidResourceInput extends Resource {
-  @Keep
+
+  @KeepForApi
   enum Kind {
     // The AndroidManifest.xml file in proto format.
     MANIFEST,
diff --git a/src/main/java/com/android/tools/r8/AndroidResourceOutput.java b/src/main/java/com/android/tools/r8/AndroidResourceOutput.java
index 6b204b5..ce7fc10 100644
--- a/src/main/java/com/android/tools/r8/AndroidResourceOutput.java
+++ b/src/main/java/com/android/tools/r8/AndroidResourceOutput.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /**
  * Base interface for android resources (resource table, manifest, res folder files)
  *
@@ -11,7 +13,7 @@
  * allows us to reason about resources, and transitively other resources and code throughout the
  * entire compilation pipeline.
  */
-@Keep
+@KeepForApi
 public interface AndroidResourceOutput extends Resource {
   // The path, within the app, of the resource.
   ResourcePath getPath();
diff --git a/src/main/java/com/android/tools/r8/AndroidResourceProvider.java b/src/main/java/com/android/tools/r8/AndroidResourceProvider.java
index cb44ff0..1045f70 100644
--- a/src/main/java/com/android/tools/r8/AndroidResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/AndroidResourceProvider.java
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Collection;
 
 /** Android resource provider. */
-@Keep
+@KeepForApi
 public interface AndroidResourceProvider {
 
   // Provide all android resources
diff --git a/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java b/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
index dee63cc..d3ee009 100644
--- a/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
@@ -8,6 +8,7 @@
 
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -36,7 +37,7 @@
  * <p>The descriptor index is built eagerly upon creating the provider and subsequent requests for
  * resources in the descriptor set will then force the read of zip entry contents.
  */
-@Keep
+@KeepForApi
 public class ArchiveClassFileProvider implements ClassFileResourceProvider, Closeable {
   private final Path archive;
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java b/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
index d5dd240..1d98610 100644
--- a/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -27,14 +28,14 @@
 import java.util.zip.ZipFile;
 
 /** Provider for archives of program resources. */
-@KeepForSubclassing
+@KeepForApi
 public class ArchiveProgramResourceProvider implements ProgramResourceProvider {
 
   interface ArchiveEntryConsumer {
     void accept(ArchiveEntryOrigin entry, InputStream stream) throws IOException;
   }
 
-  @KeepForSubclassing
+  @KeepForApi
   public interface ZipFileSupplier {
     ZipFile open() throws IOException;
   }
diff --git a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceConsumer.java b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceConsumer.java
index f2c4b5d..9bb7f82 100644
--- a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceConsumer.java
+++ b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceConsumer.java
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.ArchiveBuilder;
 import com.android.tools.r8.utils.OutputBuilder;
 import java.nio.file.Path;
 
-@Keep
+@KeepForApi
 public class ArchiveProtoAndroidResourceConsumer implements AndroidResourceConsumer {
   private final OutputBuilder outputBuilder;
 
diff --git a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
index cacef7b..7af6e19 100644
--- a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.AndroidResourceInput.Kind;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.FileUtils;
@@ -26,7 +27,7 @@
  * <p>The descriptor index is built eagerly upon creating the provider and subsequent requests for
  * resources in the descriptor set will then force the read of zip entry contents.
  */
-@Keep
+@KeepForApi
 public class ArchiveProtoAndroidResourceProvider implements AndroidResourceProvider {
   private final Path archive;
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/AssertionsConfiguration.java b/src/main/java/com/android/tools/r8/AssertionsConfiguration.java
index 07513c9..a3c957b 100644
--- a/src/main/java/com/android/tools/r8/AssertionsConfiguration.java
+++ b/src/main/java/com/android/tools/r8/AssertionsConfiguration.java
@@ -4,11 +4,12 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.Reporter;
 
-@Keep
+@KeepForApi
 public class AssertionsConfiguration {
 
   private enum AssertionTransformation {
@@ -78,7 +79,7 @@
    * <p>A builder is obtained by calling {@link
    * BaseCompilerCommand.Builder#addAssertionsConfiguration}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder {
     Reporter reporter;
     private AssertionTransformation transformation;
diff --git a/src/main/java/com/android/tools/r8/BackportedMethodList.java b/src/main/java/com/android/tools/r8/BackportedMethodList.java
index f6644c9..1398cd5 100644
--- a/src/main/java/com/android/tools/r8/BackportedMethodList.java
+++ b/src/main/java/com/android/tools/r8/BackportedMethodList.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.DesugaredMethodsList;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.DesugaredMethodsListCommand;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.StringUtils;
@@ -44,7 +45,7 @@
  * The above generates the list of backported methods for a compilation with a min API of <code>
  * apiLevel</code> into the file <code>methods-list.txt</code>.
  */
-@Keep
+@KeepForApi
 public class BackportedMethodList {
 
   static final String USAGE_MESSAGE =
diff --git a/src/main/java/com/android/tools/r8/BackportedMethodListCommand.java b/src/main/java/com/android/tools/r8/BackportedMethodListCommand.java
index 1558357..485dd4f 100644
--- a/src/main/java/com/android/tools/r8/BackportedMethodListCommand.java
+++ b/src/main/java/com/android/tools/r8/BackportedMethodListCommand.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -35,7 +36,7 @@
  *     .build();
  * </pre>
  */
-@Keep
+@KeepForApi
 public class BackportedMethodListCommand {
 
   private final boolean printHelp;
@@ -184,7 +185,7 @@
     builder.setMinApiLevel(minApi);
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private final Reporter reporter;
diff --git a/src/main/java/com/android/tools/r8/BaseCommand.java b/src/main/java/com/android/tools/r8/BaseCommand.java
index dd6a740..cc4cffe 100644
--- a/src/main/java/com/android/tools/r8/BaseCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCommand.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.AbortException;
@@ -29,7 +30,7 @@
  * <p>For concrete builders, see for example {@link D8Command.Builder} and {@link
  * R8Command.Builder}.
  */
-@Keep
+@KeepForApi
 public abstract class BaseCommand {
 
   private final boolean printHelp;
@@ -103,7 +104,7 @@
    * @param <B> Concrete builder extending this base, e.g., {@link R8Command.Builder} or {@link
    *     D8Command.Builder}.
    */
-  @Keep
+  @KeepForApi
   public abstract static class Builder<C extends BaseCommand, B extends Builder<C, B>> {
 
     private final Reporter reporter;
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index 650ff31..c67603b 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.profile.art.ArtProfileConsumer;
 import com.android.tools.r8.profile.art.ArtProfileForRewriting;
@@ -44,7 +45,7 @@
  * <p>For concrete builders, see for example {@link D8Command.Builder} and {@link
  * R8Command.Builder}.
  */
-@Keep
+@KeepForApi
 public abstract class BaseCompilerCommand extends BaseCommand {
 
   private final CompilationMode mode;
@@ -268,7 +269,7 @@
    * @param <B> Concrete builder extending this base, e.g., {@link R8Command.Builder} or {@link
    *     D8Command.Builder}.
    */
-  @Keep
+  @KeepForApi
   public abstract static class Builder<C extends BaseCompilerCommand, B extends Builder<C, B>>
       extends BaseCommand.Builder<C, B> {
 
diff --git a/src/main/java/com/android/tools/r8/ByteBufferProvider.java b/src/main/java/com/android/tools/r8/ByteBufferProvider.java
index cf80266..495c4f6 100644
--- a/src/main/java/com/android/tools/r8/ByteBufferProvider.java
+++ b/src/main/java/com/android/tools/r8/ByteBufferProvider.java
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.nio.ByteBuffer;
 
 /** Interface to enable manual memory management for a pool of byte buffers. */
-@KeepForSubclassing
+@KeepForApi
 public interface ByteBufferProvider {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ByteDataView.java b/src/main/java/com/android/tools/r8/ByteDataView.java
index 65afbb1..6c6af5a 100644
--- a/src/main/java/com/android/tools/r8/ByteDataView.java
+++ b/src/main/java/com/android/tools/r8/ByteDataView.java
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Arrays;
 
 /** Byte data view of a buffer that is possibly larger than the data content. */
-@Keep
+@KeepForApi
 public final class ByteDataView {
   private byte[] buffer;
   private final int offset;
diff --git a/src/main/java/com/android/tools/r8/CancelCompilationChecker.java b/src/main/java/com/android/tools/r8/CancelCompilationChecker.java
index f08cde1..71c1248 100644
--- a/src/main/java/com/android/tools/r8/CancelCompilationChecker.java
+++ b/src/main/java/com/android/tools/r8/CancelCompilationChecker.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Client supplied checker to allow cancelling a compilation before completion. */
-@Keep
+@KeepForApi
 public interface CancelCompilationChecker {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ClassConflictResolver.java b/src/main/java/com/android/tools/r8/ClassConflictResolver.java
index 8136f17..7dc1a65 100644
--- a/src/main/java/com/android/tools/r8/ClassConflictResolver.java
+++ b/src/main/java/com/android/tools/r8/ClassConflictResolver.java
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 import java.util.Collection;
 
-@Keep
+@KeepForApi
 public interface ClassConflictResolver {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ClassFileConsumer.java b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
index fa3e5c4..ac8effc 100644
--- a/src/main/java/com/android/tools/r8/ClassFileConsumer.java
+++ b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.ArchiveBuilder;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.DirectoryBuilder;
@@ -24,7 +25,7 @@
  *
  * <p>This consumer can only be provided to R8.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface ClassFileConsumer extends ProgramConsumer {
 
   /**
@@ -51,7 +52,7 @@
   }
 
   /** Forwarding consumer to delegate to an optional existing consumer. */
-  @Keep
+  @KeepForApi
   class ForwardingConsumer implements ClassFileConsumer {
 
     private static final ClassFileConsumer EMPTY_CONSUMER = new ForwardingConsumer(null);
@@ -83,7 +84,7 @@
   }
 
   /** Consumer to write program resources to an output. */
-  @Keep
+  @KeepForApi
   class ArchiveConsumer extends ForwardingConsumer
       implements DataResourceConsumer, InternalProgramOutputPathConsumer {
     private final OutputBuilder outputBuilder;
@@ -164,7 +165,7 @@
   }
 
   /** Directory consumer to write program resources to a directory. */
-  @Keep
+  @KeepForApi
   class DirectoryConsumer extends ForwardingConsumer implements InternalProgramOutputPathConsumer {
     private final OutputBuilder outputBuilder;
     protected final boolean consumeDataResouces;
diff --git a/src/main/java/com/android/tools/r8/ClassFileResourceProvider.java b/src/main/java/com/android/tools/r8/ClassFileResourceProvider.java
index ab6a79d..a8c4a65 100644
--- a/src/main/java/com/android/tools/r8/ClassFileResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ClassFileResourceProvider.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.IOException;
 import java.util.Set;
 
@@ -13,7 +14,7 @@
  * only created on-demand when they are needed by the compiler. If never needed, the resource will
  * never be loaded.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface ClassFileResourceProvider {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
index 80f679b..3084ee0 100644
--- a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
+++ b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
@@ -4,8 +4,10 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 // This class is used by the Android Studio Gradle plugin and is thus part of the R8 API.
-@Keep
+@KeepForApi
 public class CompatProguardCommandBuilder extends R8Command.Builder {
   public CompatProguardCommandBuilder() {
     this(true);
diff --git a/src/main/java/com/android/tools/r8/CompilationFailedException.java b/src/main/java/com/android/tools/r8/CompilationFailedException.java
index d618dff..033b1da 100644
--- a/src/main/java/com/android/tools/r8/CompilationFailedException.java
+++ b/src/main/java/com/android/tools/r8/CompilationFailedException.java
@@ -3,11 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /**
  * Exception thrown when compilation failed to complete because of errors previously reported
  * through {@link com.android.tools.r8.DiagnosticsHandler}.
  */
-@Keep
+@KeepForApi
 public class CompilationFailedException extends Exception {
 
   private final boolean cancelled;
diff --git a/src/main/java/com/android/tools/r8/CompilationMode.java b/src/main/java/com/android/tools/r8/CompilationMode.java
index 9288a35..8adcb59 100644
--- a/src/main/java/com/android/tools/r8/CompilationMode.java
+++ b/src/main/java/com/android/tools/r8/CompilationMode.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Compilation mode. */
-@Keep
+@KeepForApi
 public enum CompilationMode {
   /** Preserves debugging information during compilation, eg, line-numbers and locals. */
   DEBUG,
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 36080ca..55a8199 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.ir.optimize.AssertionsRewriter;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
 import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
@@ -80,7 +81,7 @@
  * them to DEX bytecode (compiling from Java bytecode for such inputs and merging for DEX inputs),
  * and then writes the result to the directory or zip archive specified by {@code outputPath}.
  */
-@Keep
+@KeepForApi
 public final class D8 {
 
   private D8() {}
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index c210df5..211dfb5 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.inspector.Inspector;
 import com.android.tools.r8.inspector.internal.InspectorImpl;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.MapConsumer;
 import com.android.tools.r8.naming.ProguardMapStringConsumer;
 import com.android.tools.r8.origin.Origin;
@@ -60,7 +61,7 @@
  *     .build();
  * </pre>
  */
-@Keep
+@KeepForApi
 public final class D8Command extends BaseCompilerCommand {
 
   private static class DefaultD8DiagnosticsHandler implements DiagnosticsHandler {
@@ -85,7 +86,7 @@
    *
    * <p>A builder is obtained by calling {@link D8Command#builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder extends BaseCompilerCommand.Builder<D8Command, Builder> {
 
     private boolean intermediate = false;
diff --git a/src/main/java/com/android/tools/r8/DataDirectoryResource.java b/src/main/java/com/android/tools/r8/DataDirectoryResource.java
index ed944ae..78a0d49 100644
--- a/src/main/java/com/android/tools/r8/DataDirectoryResource.java
+++ b/src/main/java/com/android/tools/r8/DataDirectoryResource.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -12,7 +13,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
-@Keep
+@KeepForApi
 public interface DataDirectoryResource extends DataResource {
 
   static DataDirectoryResource fromName(String name, Origin origin) {
diff --git a/src/main/java/com/android/tools/r8/DataEntryResource.java b/src/main/java/com/android/tools/r8/DataEntryResource.java
index 855b7a1..e5c01cb 100644
--- a/src/main/java/com/android/tools/r8/DataEntryResource.java
+++ b/src/main/java/com/android/tools/r8/DataEntryResource.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -16,7 +17,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
-@Keep
+@KeepForApi
 public interface DataEntryResource extends DataResource {
 
   /** Get the bytes of the data entry resource. */
diff --git a/src/main/java/com/android/tools/r8/DataResource.java b/src/main/java/com/android/tools/r8/DataResource.java
index eac8b6c..6c9763f 100644
--- a/src/main/java/com/android/tools/r8/DataResource.java
+++ b/src/main/java/com/android/tools/r8/DataResource.java
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@Keep
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface DataResource extends Resource {
   char SEPARATOR = '/';
 
diff --git a/src/main/java/com/android/tools/r8/DataResourceConsumer.java b/src/main/java/com/android/tools/r8/DataResourceConsumer.java
index e306b9b..2a8880d 100644
--- a/src/main/java/com/android/tools/r8/DataResourceConsumer.java
+++ b/src/main/java/com/android/tools/r8/DataResourceConsumer.java
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@KeepForSubclassing
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface DataResourceConsumer {
 
   void accept(DataDirectoryResource directory, DiagnosticsHandler diagnosticsHandler);
diff --git a/src/main/java/com/android/tools/r8/DataResourceProvider.java b/src/main/java/com/android/tools/r8/DataResourceProvider.java
index 5e0a24f..ad77718 100644
--- a/src/main/java/com/android/tools/r8/DataResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/DataResourceProvider.java
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@KeepForSubclassing
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface DataResourceProvider {
 
-  @KeepForSubclassing
+  @KeepForApi
   interface Visitor {
     void visit(DataDirectoryResource directory);
     void visit(DataEntryResource file);
diff --git a/src/main/java/com/android/tools/r8/DesugarGraphConsumer.java b/src/main/java/com/android/tools/r8/DesugarGraphConsumer.java
index fd553b3..a50230b 100644
--- a/src/main/java/com/android/tools/r8/DesugarGraphConsumer.java
+++ b/src/main/java/com/android/tools/r8/DesugarGraphConsumer.java
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 
 /** Consumer for receiving dependency edges for desugaring. */
-@KeepForSubclassing
+@KeepForApi
 public interface DesugarGraphConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/DexFilePerClassFileConsumer.java b/src/main/java/com/android/tools/r8/DexFilePerClassFileConsumer.java
index 1675cb2..55f1936 100644
--- a/src/main/java/com/android/tools/r8/DexFilePerClassFileConsumer.java
+++ b/src/main/java/com/android/tools/r8/DexFilePerClassFileConsumer.java
@@ -5,6 +5,7 @@
 
 import static com.android.tools.r8.utils.FileUtils.DEX_EXTENSION;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.ArchiveBuilder;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.DirectoryBuilder;
@@ -31,7 +32,7 @@
  *
  * <p>This consumer receives DEX file content for each Java class-file input.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface DexFilePerClassFileConsumer extends ProgramConsumer, ByteBufferProvider {
 
   static final boolean SHOULD_COMBINE_SYNTHETIC_CLASSES = true;
@@ -93,7 +94,7 @@
   }
 
   /** Forwarding consumer to delegate to an optional existing consumer. */
-  @Keep
+  @KeepForApi
   class ForwardingConsumer implements DexFilePerClassFileConsumer {
 
     private static final DexFilePerClassFileConsumer EMPTY_CONSUMER = new ForwardingConsumer(null);
@@ -138,7 +139,7 @@
   }
 
   /** Consumer to write program resources to an output. */
-  @Keep
+  @KeepForApi
   class ArchiveConsumer extends ForwardingConsumer
       implements DataResourceConsumer, InternalProgramOutputPathConsumer {
     private final OutputBuilder outputBuilder;
@@ -231,7 +232,7 @@
   }
 
   /** Directory consumer to write program resources to a directory. */
-  @Keep
+  @KeepForApi
   class DirectoryConsumer extends ForwardingConsumer
       implements DataResourceConsumer, InternalProgramOutputPathConsumer {
     private final OutputBuilder outputBuilder;
diff --git a/src/main/java/com/android/tools/r8/DexIndexedConsumer.java b/src/main/java/com/android/tools/r8/DexIndexedConsumer.java
index 39f5b2e..9e7c06b 100644
--- a/src/main/java/com/android/tools/r8/DexIndexedConsumer.java
+++ b/src/main/java/com/android/tools/r8/DexIndexedConsumer.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.ArchiveBuilder;
@@ -34,7 +35,7 @@
  * <p>This consumer receives DEX file content using standard indexed-multidex for programs larger
  * than a single DEX file. This is the default consumer for DEX programs.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface DexIndexedConsumer extends ProgramConsumer, ByteBufferProvider {
 
   /**
@@ -78,7 +79,7 @@
   }
 
   /** Forwarding consumer to delegate to an optional existing consumer. */
-  @Keep
+  @KeepForApi
   class ForwardingConsumer implements DexIndexedConsumer {
 
     private static final DexIndexedConsumer EMPTY_CONSUMER = new ForwardingConsumer(null);
@@ -111,7 +112,7 @@
   }
 
   /** Consumer to write program resources to an output. */
-  @Keep
+  @KeepForApi
   class ArchiveConsumer extends ForwardingConsumer
       implements DataResourceConsumer, InternalProgramOutputPathConsumer {
     protected final OutputBuilder outputBuilder;
@@ -211,7 +212,7 @@
     }
   }
 
-  @Keep
+  @KeepForApi
   class DirectoryConsumer extends ForwardingConsumer
       implements DataResourceConsumer, InternalProgramOutputPathConsumer {
     private final Path directory;
diff --git a/src/main/java/com/android/tools/r8/Diagnostic.java b/src/main/java/com/android/tools/r8/Diagnostic.java
index 3184d54..bf05be1 100644
--- a/src/main/java/com/android/tools/r8/Diagnostic.java
+++ b/src/main/java/com/android/tools/r8/Diagnostic.java
@@ -3,13 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-/**
- * Interface for all diagnostic message produced by D8 and R8.
- */
-@Keep
+/** Interface for all diagnostic message produced by D8 and R8. */
+@KeepForApi
 public interface Diagnostic {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/DiagnosticsHandler.java b/src/main/java/com/android/tools/r8/DiagnosticsHandler.java
index a332327..88ad2c8 100644
--- a/src/main/java/com/android/tools/r8/DiagnosticsHandler.java
+++ b/src/main/java/com/android/tools/r8/DiagnosticsHandler.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import java.io.PrintStream;
@@ -12,7 +13,7 @@
  *
  * <p>During compilation the warning and info methods will be called.
  */
-@Keep
+@KeepForApi
 public interface DiagnosticsHandler {
 
   /** Should be considered private. */
diff --git a/src/main/java/com/android/tools/r8/DiagnosticsLevel.java b/src/main/java/com/android/tools/r8/DiagnosticsLevel.java
index a022b0d..9497a86 100644
--- a/src/main/java/com/android/tools/r8/DiagnosticsLevel.java
+++ b/src/main/java/com/android/tools/r8/DiagnosticsLevel.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Levels of diagnostics messages reported by the compiler. */
-@Keep
+@KeepForApi
 public enum DiagnosticsLevel {
   ERROR,
   WARNING,
diff --git a/src/main/java/com/android/tools/r8/DirectoryClassFileProvider.java b/src/main/java/com/android/tools/r8/DirectoryClassFileProvider.java
index 50aff3f..53f15ba 100644
--- a/src/main/java/com/android/tools/r8/DirectoryClassFileProvider.java
+++ b/src/main/java/com/android/tools/r8/DirectoryClassFileProvider.java
@@ -7,6 +7,7 @@
 import static com.android.tools.r8.utils.FileUtils.isClassFile;
 
 import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.Sets;
 import java.io.File;
@@ -15,11 +16,8 @@
 import java.util.HashSet;
 import java.util.Set;
 
-/**
- * Lazy resource provider returning class file resources based
- * on filesystem directory content.
- */
-@Keep
+/** Lazy resource provider returning class file resources based on filesystem directory content. */
+@KeepForApi
 public final class DirectoryClassFileProvider implements ClassFileResourceProvider {
   private final Path root;
 
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index 79ec8a5..99080f9 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.Marker;
 import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -37,7 +38,7 @@
  *       .build());
  * </pre>
  */
-@Keep
+@KeepForApi
 public class ExtractMarker {
 
   private static class MarkerInfoPrintConsumer implements MarkerInfoConsumer {
diff --git a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
index 831530f..c6d1968 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.Pair;
@@ -17,11 +18,11 @@
 import java.util.function.BiConsumer;
 
 /** Immutable command structure for an invocation of the {@link ExtractMarker} tool. */
-@Keep
+@KeepForApi
 public class ExtractMarkerCommand {
 
   /** Builder for constructing a {@link ExtractMarkerCommand}. */
-  @Keep
+  @KeepForApi
   public static class Builder {
     private boolean printHelp = false;
     private final List<Path> programFiles = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/FeatureSplit.java b/src/main/java/com/android/tools/r8/FeatureSplit.java
index 08f54e6..97e6cb2 100644
--- a/src/main/java/com/android/tools/r8/FeatureSplit.java
+++ b/src/main/java/com/android/tools/r8/FeatureSplit.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -27,7 +28,7 @@
  *     .build();
  * </pre>
  */
-@Keep
+@KeepForApi
 public class FeatureSplit {
 
   public static final FeatureSplit BASE =
@@ -85,7 +86,7 @@
    *
    * <p>A builder is obtained by calling addFeatureSplit on a {@link R8Command.Builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder {
     private ProgramConsumer programConsumer;
     private final List<ProgramResourceProvider> programResourceProviders = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 182d156..6f51728 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.profile.rewriting.ProfileCollectionAdditions;
 import com.android.tools.r8.shaking.Enqueuer;
 import com.android.tools.r8.shaking.EnqueuerFactory;
@@ -35,7 +36,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 
-@Keep
+@KeepForApi
 public class GenerateMainDexList {
   private final Timing timing = new Timing("maindex");
   private final InternalOptions options;
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
index 337fad7..b782e91 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.CommandLineOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.ProguardConfigurationParser;
@@ -23,7 +24,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class GenerateMainDexListCommand extends BaseCommand {
 
   private final List<ProguardConfigurationRule> mainDexKeepRules;
@@ -32,7 +33,7 @@
   private final DexItemFactory factory;
   private final Reporter reporter;
 
-  @Keep
+  @KeepForApi
   public static class Builder extends BaseCommand.Builder<GenerateMainDexListCommand, Builder> {
 
     private final DexItemFactory factory = new DexItemFactory();
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
index 1f982ce..88e9f55 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
 /**
@@ -18,7 +19,7 @@
  * application. It is valid to merge just the globals in such a final step. See {@code
  * GlobalSyntheticsResourceProvider}.
  */
-@Keep
+@KeepForApi
 public interface GlobalSyntheticsConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
index ef754ba..c9590ea 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
@@ -39,6 +39,7 @@
 import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
 import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaring;
 import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaringEventConsumer;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.RecordRewritingNamingLens;
 import com.android.tools.r8.naming.VarHandleDesugaringRewritingNamingLens;
 import com.android.tools.r8.origin.CommandLineOrigin;
@@ -68,7 +69,7 @@
  * The GlobalSyntheticsGenerator, a tool for generating a dex file for all possible global
  * synthetics.
  */
-@Keep
+@KeepForApi
 public class GlobalSyntheticsGenerator {
 
   @SuppressWarnings("ReferenceEquality")
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
index 1d85164..44f54ba 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AbortException;
 import com.android.tools.r8.utils.AndroidApiLevel;
@@ -25,7 +26,7 @@
 /**
  * Immutable command structure for an invocation of the {@link GlobalSyntheticsGenerator} compiler.
  */
-@Keep
+@KeepForApi
 public final class GlobalSyntheticsGeneratorCommand {
 
   private final ProgramConsumer programConsumer;
@@ -152,7 +153,7 @@
    *
    * <p>A builder is obtained by calling {@link GlobalSyntheticsGeneratorCommand#builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private ProgramConsumer programConsumer = null;
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsResourceProvider.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsResourceProvider.java
index 4cfdbb1..73a0841 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsResourceProvider.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import java.io.InputStream;
 
@@ -12,7 +13,7 @@
  * <p>The global synthetic information can only be obtained by consuming it from a previous
  * compilation unit for the same compiler version. See {@code GlobalSyntheticsConsumer}.
  */
-@Keep
+@KeepForApi
 public interface GlobalSyntheticsResourceProvider {
 
   /** Get the origin of the global synthetics resource. */
diff --git a/src/main/java/com/android/tools/r8/InputDependencyGraphConsumer.java b/src/main/java/com/android/tools/r8/InputDependencyGraphConsumer.java
index 20b0a30..9aa0b01 100644
--- a/src/main/java/com/android/tools/r8/InputDependencyGraphConsumer.java
+++ b/src/main/java/com/android/tools/r8/InputDependencyGraphConsumer.java
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import java.nio.file.Path;
 
 /** Consumer for receiving file dependencies from inputs. */
-@KeepForSubclassing
+@KeepForApi
 public interface InputDependencyGraphConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/JarSizeCompare.java b/src/main/java/com/android/tools/r8/JarSizeCompare.java
deleted file mode 100644
index 8e8388b..0000000
--- a/src/main/java/com/android/tools/r8/JarSizeCompare.java
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8;
-
-import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.ClassNamingForNameMapper;
-import com.android.tools.r8.naming.MemberNaming.FieldSignature;
-import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.AndroidAppConsumers;
-import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.ImmutableMap;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.BiConsumer;
-
-/**
- * JarSizeCompare outputs the class, method, field sizes of the given JAR files. For each input, a
- * ProGuard map can be passed that is used to resolve minified names.
- *
- * <p>By default, only shows methods where R8's DEX output is 5 or more instructions larger than
- * ProGuard+D8's output. Pass {@code --threshold 0} to display all methods.
- */
-public class JarSizeCompare {
-
-  private static final String USAGE =
-      "Arguments:\n"
-          + "    [--threshold <threshold>]\n"
-          + "    [--lib <lib.jar>]\n"
-          + "    --input <name1> <input1.jar> [<map1.txt>]\n"
-          + "    --input <name2> <input2.jar> [<map2.txt>] ...\n"
-          + "\n"
-          + "JarSizeCompare outputs the class, method, field sizes of the given JAR files.\n"
-          + "For each input, a ProGuard map can be passed that is used to resolve minified"
-          + " names.\n";
-
-  private static final ImmutableMap<String, String> R8_RELOCATIONS =
-      ImmutableMap.<String, String>builder()
-          .put("com.google.common", "com.android.tools.r8.com.google.common")
-          .put("com.google.gson", "com.android.tools.r8.com.google.gson")
-          .put("com.google.thirdparty", "com.android.tools.r8.com.google.thirdparty")
-          .put("org.apache.commons", "com.android.tools.r8.org.apache.commons")
-          .put("org.objectweb.asm", "com.android.tools.r8.org.objectweb.asm")
-          .put("it.unimi.dsi.fastutil", "com.android.tools.r8.it.unimi.dsi.fastutil")
-          .build();
-
-  private final List<Path> libraries;
-  private final List<InputParameter> inputParameters;
-  private final int threshold;
-  private final InternalOptions options;
-  private int pgIndex;
-  private int r8Index;
-
-  private JarSizeCompare(
-      List<Path> libraries, List<InputParameter> inputParameters, int threshold) {
-    this.libraries = libraries;
-    this.inputParameters = inputParameters;
-    this.threshold = threshold;
-    options = new InternalOptions();
-  }
-
-  public void run() throws Exception {
-    List<String> names = new ArrayList<>();
-    List<InputApplication> inputApplicationList = new ArrayList<>();
-    Timing timing = new Timing("JarSizeCompare");
-    for (InputParameter inputParameter : inputParameters) {
-      AndroidApp inputApp = inputParameter.getInputApp(libraries);
-      DexApplication input = inputParameter.getReader(options, inputApp, timing);
-      AndroidAppConsumers appConsumer = new AndroidAppConsumers();
-      D8.run(
-          D8Command.builder(inputApp)
-              .setMinApiLevel(AndroidApiLevel.P.getLevel())
-              .setProgramConsumer(appConsumer.wrapDexIndexedConsumer(null))
-              .build());
-      DexApplication d8Input = inputParameter.getReader(options, appConsumer.build(), timing);
-      InputApplication inputApplication =
-          new InputApplication(input, translateClassNames(input, input.classes()));
-      InputApplication d8Classes =
-          new InputApplication(input, translateClassNames(input, d8Input.classes()));
-      names.add(inputParameter.name + "-input");
-      inputApplicationList.add(inputApplication);
-      names.add(inputParameter.name + "-d8");
-      inputApplicationList.add(d8Classes);
-    }
-    if (threshold != 0) {
-      pgIndex = names.indexOf("pg-d8");
-      r8Index = names.indexOf("r8-d8");
-    }
-    Map<String, InputClass[]> inputClasses = new HashMap<>();
-    for (int i = 0; i < names.size(); i++) {
-      InputApplication classes = inputApplicationList.get(i);
-      for (String className : classes.getClasses()) {
-        inputClasses.computeIfAbsent(className, k -> new InputClass[names.size()])[i] =
-            classes.getInputClass(className);
-      }
-    }
-    for (Entry<String, Map<String, InputClass[]>> library : byLibrary(inputClasses)) {
-      System.out.println();
-      System.out.println("=".repeat(100));
-      String commonPrefix = getCommonPrefix(library.getValue().keySet());
-      if (library.getKey().isEmpty()) {
-        System.out.println("PROGRAM (" + commonPrefix + ")");
-      } else {
-        System.out.println("LIBRARY: " + library.getKey() + " (" + commonPrefix + ")");
-      }
-      printLibrary(library.getValue(), commonPrefix);
-    }
-  }
-
-  private Map<String, DexProgramClass> translateClassNames(
-      DexApplication input, Collection<DexProgramClass> classes) {
-    Map<String, DexProgramClass> result = new HashMap<>();
-    ClassNameMapper classNameMapper = input.getProguardMap();
-    for (DexProgramClass programClass : classes) {
-      ClassNamingForNameMapper classNaming;
-      if (classNameMapper == null) {
-        classNaming = null;
-      } else {
-        classNaming = classNameMapper.getClassNaming(programClass.type);
-      }
-      String type =
-          classNaming == null ? programClass.type.toSourceString() : classNaming.originalName;
-      result.put(type, programClass);
-    }
-    return result;
-  }
-
-  private String getCommonPrefix(Set<String> classes) {
-    if (classes.size() <= 1) {
-      return "";
-    }
-    String commonPrefix = null;
-    for (String clazz : classes) {
-      if (clazz.equals("r8.GeneratedOutlineSupport")) {
-        continue;
-      }
-      if (commonPrefix == null) {
-        commonPrefix = clazz;
-      } else {
-        int i = 0;
-        while (i < clazz.length()
-            && i < commonPrefix.length()
-            && clazz.charAt(i) == commonPrefix.charAt(i)) {
-          i++;
-        }
-        commonPrefix = commonPrefix.substring(0, i);
-      }
-    }
-    return commonPrefix;
-  }
-
-  private void printLibrary(Map<String, InputClass[]> classMap, String commonPrefix) {
-    List<Entry<String, InputClass[]>> classes = new ArrayList<>(classMap.entrySet());
-    classes.sort(Comparator.comparing(Entry::getKey));
-    for (Entry<String, InputClass[]> clazz : classes) {
-      printClass(
-          clazz.getKey().substring(commonPrefix.length()), new ClassCompare(clazz.getValue()));
-    }
-  }
-
-  private void printClass(String name, ClassCompare inputClasses) {
-    List<MethodSignature> methods = getMethods(inputClasses);
-    List<FieldSignature> fields = getFields(inputClasses);
-    if (methods.isEmpty() && fields.isEmpty()) {
-      return;
-    }
-    System.out.println(name);
-    for (MethodSignature sig : methods) {
-      printSignature(getMethodString(sig), inputClasses.sizes(sig));
-    }
-    for (FieldSignature sig : fields) {
-      printSignature(getFieldString(sig), inputClasses.sizes(sig));
-    }
-  }
-
-  private String getMethodString(MethodSignature sig) {
-    StringBuilder builder = new StringBuilder().append('(');
-    for (int i = 0; i < sig.parameters.length; i++) {
-      builder.append(DescriptorUtils.javaTypeToShorty(sig.parameters[i]));
-    }
-    builder.append(')').append(DescriptorUtils.javaTypeToShorty(sig.type)).append(' ');
-    return builder.append(sig.name).toString();
-  }
-
-  private String getFieldString(FieldSignature sig) {
-    return DescriptorUtils.javaTypeToShorty(sig.type) + ' ' + sig.name;
-  }
-
-  private void printSignature(String key, int[] sizes) {
-    System.out.print(padItem(key));
-    for (int size : sizes) {
-      System.out.print(padValue(size));
-    }
-    System.out.print('\n');
-  }
-
-  private List<MethodSignature> getMethods(ClassCompare inputClasses) {
-    List<MethodSignature> methods = new ArrayList<>();
-    for (MethodSignature methodSignature : inputClasses.getMethods()) {
-      if (threshold == 0 || methodExceedsThreshold(inputClasses, methodSignature)) {
-        methods.add(methodSignature);
-      }
-    }
-    return methods;
-  }
-
-  private boolean methodExceedsThreshold(
-      ClassCompare inputClasses, MethodSignature methodSignature) {
-    assert threshold > 0;
-    assert pgIndex != r8Index;
-    int pgSize = inputClasses.size(methodSignature, pgIndex);
-    int r8Size = inputClasses.size(methodSignature, r8Index);
-    return pgSize != -1 && r8Size != -1 && pgSize + threshold <= r8Size;
-  }
-
-  private List<FieldSignature> getFields(ClassCompare inputClasses) {
-    return threshold == 0 ? inputClasses.getFields() : Collections.emptyList();
-  }
-
-  private String padItem(String s) {
-    return String.format("%-52s", s);
-  }
-
-  private String padValue(int v) {
-    return String.format("%8s", v == -1 ? "---" : v);
-  }
-
-  private List<Map.Entry<String, Map<String, InputClass[]>>> byLibrary(
-      Map<String, InputClass[]> inputClasses) {
-    Map<String, Map<String, InputClass[]>> byLibrary = new HashMap<>();
-    for (Entry<String, InputClass[]> entry : inputClasses.entrySet()) {
-      Map<String, InputClass[]> library =
-          byLibrary.computeIfAbsent(getLibraryName(entry.getKey()), k -> new HashMap<>());
-      library.put(entry.getKey(), entry.getValue());
-    }
-    List<Entry<String, Map<String, InputClass[]>>> list = new ArrayList<>(byLibrary.entrySet());
-    list.sort(Comparator.comparing(Entry::getKey));
-    return list;
-  }
-
-  private String getLibraryName(String className) {
-    for (Entry<String, String> relocation : R8_RELOCATIONS.entrySet()) {
-      if (className.startsWith(relocation.getValue())) {
-        return relocation.getKey();
-      }
-    }
-    return "";
-  }
-
-  static class InputParameter {
-
-    private final String name;
-    private final Path jar;
-    private final Path map;
-
-    InputParameter(String name, Path jar, Path map) {
-      this.name = name;
-      this.jar = jar;
-      this.map = map;
-    }
-
-    DexApplication getReader(InternalOptions options, AndroidApp inputApp, Timing timing)
-        throws Exception {
-      ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
-      return applicationReader.read(map == null ? null : StringResource.fromFile(map)).toDirect();
-    }
-
-    AndroidApp getInputApp(List<Path> libraries) {
-      return AndroidApp.builder().addLibraryFiles(libraries).addProgramFiles(jar).build();
-    }
-  }
-
-  static class InputApplication {
-
-    private final DexApplication dexApplication;
-    private final Map<String, DexProgramClass> classMap;
-
-    private InputApplication(DexApplication dexApplication, Map<String, DexProgramClass> classMap) {
-      this.dexApplication = dexApplication;
-      this.classMap = classMap;
-    }
-
-    public Set<String> getClasses() {
-      return classMap.keySet();
-    }
-
-    private InputClass getInputClass(String type) {
-      DexProgramClass inputClass = classMap.get(type);
-      ClassNameMapper proguardMap = dexApplication.getProguardMap();
-      return new InputClass(inputClass, proguardMap);
-    }
-  }
-
-  static class InputClass {
-    private final DexProgramClass programClass;
-    private final ClassNameMapper proguardMap;
-
-    InputClass(DexClass dexClass, ClassNameMapper proguardMap) {
-      this.programClass = dexClass == null ? null : dexClass.asProgramClass();
-      this.proguardMap = proguardMap;
-    }
-
-    void forEachMethod(BiConsumer<MethodSignature, DexEncodedMethod> consumer) {
-      if (programClass == null) {
-        return;
-      }
-      programClass.forEachMethod(
-          dexEncodedMethod -> {
-            MethodSignature originalSignature =
-                proguardMap == null
-                    ? null
-                    : proguardMap.originalSignatureOf(dexEncodedMethod.getReference());
-            MethodSignature signature =
-                MethodSignature.fromDexMethod(dexEncodedMethod.getReference());
-            consumer.accept(
-                originalSignature == null ? signature : originalSignature, dexEncodedMethod);
-          });
-    }
-
-    void forEachField(BiConsumer<FieldSignature, DexEncodedField> consumer) {
-      if (programClass == null) {
-        return;
-      }
-      programClass.forEachField(
-          dexEncodedField -> {
-            FieldSignature originalSignature =
-                proguardMap == null
-                    ? null
-                    : proguardMap.originalSignatureOf(dexEncodedField.getReference());
-            FieldSignature signature = FieldSignature.fromDexField(dexEncodedField.getReference());
-            consumer.accept(
-                originalSignature == null ? signature : originalSignature, dexEncodedField);
-          });
-    }
-  }
-
-  private static class ClassCompare {
-    final Map<MethodSignature, DexEncodedMethod[]> methods = new HashMap<>();
-    final Map<FieldSignature, DexEncodedField[]> fields = new HashMap<>();
-    final int classes;
-
-    ClassCompare(InputClass[] inputs) {
-      for (int i = 0; i < inputs.length; i++) {
-        InputClass inputClass = inputs[i];
-        int finalI = i;
-        if (inputClass == null) {
-          continue;
-        }
-        inputClass.forEachMethod(
-            (sig, m) ->
-                methods.computeIfAbsent(sig, o -> new DexEncodedMethod[inputs.length])[finalI] = m);
-        inputClass.forEachField(
-            (sig, f) ->
-                fields.computeIfAbsent(sig, o -> new DexEncodedField[inputs.length])[finalI] = f);
-      }
-      classes = inputs.length;
-    }
-
-    List<MethodSignature> getMethods() {
-      List<MethodSignature> methods = new ArrayList<>(this.methods.keySet());
-      methods.sort(Comparator.comparing(MethodSignature::toString));
-      return methods;
-    }
-
-    List<FieldSignature> getFields() {
-      List<FieldSignature> fields = new ArrayList<>(this.fields.keySet());
-      fields.sort(Comparator.comparing(FieldSignature::toString));
-      return fields;
-    }
-
-    int size(MethodSignature method, int classIndex) {
-      DexEncodedMethod dexEncodedMethod = methods.get(method)[classIndex];
-      if (dexEncodedMethod == null) {
-        return -1;
-      }
-      Code code = dexEncodedMethod.getCode();
-      if (code == null) {
-        return 0;
-      }
-      if (code.isCfCode()) {
-        return code.asCfCode().getInstructions().size();
-      }
-      if (code.isDexCode()) {
-        return code.asDexCode().instructions.length;
-      }
-      throw new Unreachable();
-    }
-
-    int[] sizes(MethodSignature method) {
-      int[] result = new int[classes];
-      for (int i = 0; i < classes; i++) {
-        result[i] = size(method, i);
-      }
-      return result;
-    }
-
-    int size(FieldSignature field, int classIndex) {
-      return fields.get(field)[classIndex] == null ? -1 : 1;
-    }
-
-    int[] sizes(FieldSignature field) {
-      int[] result = new int[classes];
-      for (int i = 0; i < classes; i++) {
-        result[i] = size(field, i);
-      }
-      return result;
-    }
-  }
-
-  public static void main(String[] args) throws Exception {
-    JarSizeCompare program = JarSizeCompare.parse(args);
-    if (program == null) {
-      System.out.println(USAGE);
-    } else {
-      program.run();
-    }
-  }
-
-  public static JarSizeCompare parse(String[] args) {
-    int i = 0;
-    int threshold = 0;
-    List<Path> libraries = new ArrayList<>();
-    List<InputParameter> inputs = new ArrayList<>();
-    Set<String> names = new HashSet<>();
-    while (i < args.length) {
-      if (args[i].equals("--threshold") && i + 1 < args.length) {
-        threshold = Integer.parseInt(args[i + 1]);
-        i += 2;
-      } else if (args[i].equals("--lib") && i + 1 < args.length) {
-        libraries.add(Paths.get(args[i + 1]));
-        i += 2;
-      } else if (args[i].equals("--input") && i + 2 < args.length) {
-        String name = args[i + 1];
-        Path jar = Paths.get(args[i + 2]);
-        Path map = null;
-        if (i + 3 < args.length && !args[i + 3].startsWith("-")) {
-          map = Paths.get(args[i + 3]);
-          i += 4;
-        } else {
-          i += 3;
-        }
-        inputs.add(new InputParameter(name, jar, map));
-        if (!names.add(name)) {
-          System.out.println("Duplicate name: " + name);
-          return null;
-        }
-      } else {
-        return null;
-      }
-    }
-    if (inputs.size() < 2) {
-      return null;
-    }
-    if (threshold != 0 && (!names.contains("r8") || !names.contains("pg"))) {
-      System.out.println(
-          "You must either specify names \"pg\" and \"r8\" for input files "
-              + "or use \"--threshold 0\".");
-      return null;
-    }
-    return new JarSizeCompare(libraries, inputs, threshold);
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/JdkClassFileProvider.java b/src/main/java/com/android/tools/r8/JdkClassFileProvider.java
index bd40b44..28999a3 100644
--- a/src/main/java/com/android/tools/r8/JdkClassFileProvider.java
+++ b/src/main/java/com/android/tools/r8/JdkClassFileProvider.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -34,7 +35,7 @@
  * <code>lib/rt.jar</code> will be loaded. JDK's of version 9 or higher system module classes will
  * be loaded using <code>lib/jrt-fs.jar/<code>.
  */
-@Keep
+@KeepForApi
 public class JdkClassFileProvider implements ClassFileResourceProvider, Closeable {
   private Origin origin;
   private final Set<String> descriptors = new HashSet<>();
diff --git a/src/main/java/com/android/tools/r8/KeepForRetraceApi.java b/src/main/java/com/android/tools/r8/KeepForRetraceApi.java
deleted file mode 100644
index 5ed253c..0000000
--- a/src/main/java/com/android/tools/r8/KeepForRetraceApi.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8;
-
-@KeepForRetraceApi
-public @interface KeepForRetraceApi {}
diff --git a/src/main/java/com/android/tools/r8/KeepForSubclassing.java b/src/main/java/com/android/tools/r8/KeepForSubclassing.java
deleted file mode 100644
index 6e57114..0000000
--- a/src/main/java/com/android/tools/r8/KeepForSubclassing.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8;
-
-@Keep
-public @interface KeepForSubclassing {
-
-}
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 7950354..1c1e64c 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.ir.desugar.TypeRewriter;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAmender;
 import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
 import com.android.tools.r8.naming.VarHandleDesugaringRewritingNamingLens;
 import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
@@ -34,10 +35,8 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 
-/**
- * The L8 compiler.
- */
-@Keep
+/** The L8 compiler. */
+@KeepForApi
 public class L8 {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 679dd95..664eae4 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger;
 import com.android.tools.r8.inspector.Inspector;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.profile.art.ArtProfileForRewriting;
 import com.android.tools.r8.utils.AndroidApiLevel;
@@ -37,7 +38,7 @@
 import java.util.function.Consumer;
 
 /** Immutable command structure for an invocation of the {@link L8} library compiler. */
-@Keep
+@KeepForApi
 public final class L8Command extends BaseCompilerCommand {
 
   private final D8Command d8Command;
@@ -252,7 +253,7 @@
    *
    * <p>A builder is obtained by calling {@link L8Command#builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder extends BaseCompilerCommand.Builder<L8Command, Builder> {
 
     private final List<Pair<List<String>, Origin>> proguardConfigStrings = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/MapIdEnvironment.java b/src/main/java/com/android/tools/r8/MapIdEnvironment.java
index f1e4260..7278811 100644
--- a/src/main/java/com/android/tools/r8/MapIdEnvironment.java
+++ b/src/main/java/com/android/tools/r8/MapIdEnvironment.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Environment made available when defining a custom map id for a build. */
-@Keep
+@KeepForApi
 public interface MapIdEnvironment {
 
   /** Get the computed hash for the mapping file content. */
diff --git a/src/main/java/com/android/tools/r8/MapIdProvider.java b/src/main/java/com/android/tools/r8/MapIdProvider.java
index 9af775f..576400d 100644
--- a/src/main/java/com/android/tools/r8/MapIdProvider.java
+++ b/src/main/java/com/android/tools/r8/MapIdProvider.java
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /**
  * Interface for providing a custom map-id to the compiler.
  *
@@ -11,7 +13,7 @@
  * mapping file information for builds. For example, by including it in the source-file part of
  * program stacktraces. See {@code SourceFileProvider}.
  */
-@Keep
+@KeepForApi
 @FunctionalInterface
 public interface MapIdProvider {
 
diff --git a/src/main/java/com/android/tools/r8/MarkerInfo.java b/src/main/java/com/android/tools/r8/MarkerInfo.java
index 6c5925d..91b8d9a 100644
--- a/src/main/java/com/android/tools/r8/MarkerInfo.java
+++ b/src/main/java/com/android/tools/r8/MarkerInfo.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Information present in a given marker. */
-@Keep
+@KeepForApi
 public interface MarkerInfo {
 
   /** Get the tool that has generated the marker. */
diff --git a/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java b/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java
index 87342e4..d52d1d5 100644
--- a/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java
+++ b/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Interface for consumers of the marker information. */
-@Keep
+@KeepForApi
 public interface MarkerInfoConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java b/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java
index 1b2d500..8640785 100644
--- a/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java
+++ b/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import java.util.Collection;
 
 /** Information about which markers are present in a given input. */
-@Keep
+@KeepForApi
 public interface MarkerInfoConsumerData {
 
   Origin getInputOrigin();
diff --git a/src/main/java/com/android/tools/r8/OutputMode.java b/src/main/java/com/android/tools/r8/OutputMode.java
index 7092479..4a76273 100644
--- a/src/main/java/com/android/tools/r8/OutputMode.java
+++ b/src/main/java/com/android/tools/r8/OutputMode.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Enumeration of the possible output formats of compilation. */
-@Keep
+@KeepForApi
 public enum OutputMode {
 
   /** Produce DEX files using standard indexed-multidex for programs larger that a single file. */
diff --git a/src/main/java/com/android/tools/r8/ParseFlagInfo.java b/src/main/java/com/android/tools/r8/ParseFlagInfo.java
index 93e6c02..a9566ed 100644
--- a/src/main/java/com/android/tools/r8/ParseFlagInfo.java
+++ b/src/main/java/com/android/tools/r8/ParseFlagInfo.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 
 /**
@@ -11,7 +12,7 @@
  * <p>Note that this information is purly for usage information and is not an exact semantics of
  * flags.
  */
-@Keep
+@KeepForApi
 public interface ParseFlagInfo {
 
   /** Get the primary format description of the flag (including arguments). */
diff --git a/src/main/java/com/android/tools/r8/ParseFlagPrinter.java b/src/main/java/com/android/tools/r8/ParseFlagPrinter.java
index 3f30806..cc35672 100644
--- a/src/main/java/com/android/tools/r8/ParseFlagPrinter.java
+++ b/src/main/java/com/android/tools/r8/ParseFlagPrinter.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.StringUtils;
 import java.util.ArrayList;
 import java.util.List;
@@ -12,7 +13,7 @@
  *
  * <p>This utility can be used to support wrapping the compilers command-line interface.
  */
-@Keep
+@KeepForApi
 public class ParseFlagPrinter {
 
   private final List<ParseFlagInfo> flags = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/PartitionMapConsumer.java b/src/main/java/com/android/tools/r8/PartitionMapConsumer.java
index ea232d4..0fd3a7f 100644
--- a/src/main/java/com/android/tools/r8/PartitionMapConsumer.java
+++ b/src/main/java/com/android/tools/r8/PartitionMapConsumer.java
@@ -4,10 +4,11 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.MappingPartition;
 import com.android.tools.r8.retrace.MappingPartitionMetadata;
 
-@Keep
+@KeepForApi
 public interface PartitionMapConsumer extends Finishable {
 
   void acceptMappingPartition(MappingPartition mappingPartition);
diff --git a/src/main/java/com/android/tools/r8/ProgramConsumer.java b/src/main/java/com/android/tools/r8/ProgramConsumer.java
index b3143a0..1b75bed 100644
--- a/src/main/java/com/android/tools/r8/ProgramConsumer.java
+++ b/src/main/java/com/android/tools/r8/ProgramConsumer.java
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /**
  * Base for all program consumers to allow abstracting which concrete consumer is provided to D8/R8.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface ProgramConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ProgramResource.java b/src/main/java/com/android/tools/r8/ProgramResource.java
index 671c2c3..7d2aead 100644
--- a/src/main/java/com/android/tools/r8/ProgramResource.java
+++ b/src/main/java/com/android/tools/r8/ProgramResource.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.StreamUtils;
@@ -16,16 +17,16 @@
 /**
  * Represents program application resources.
  *
- * The content kind or format of a program resource can be either a Java class-file or an Android
- * DEX file. In both cases, the resource must be able to provide the content as a byte stream.
- * A resource may optionally include a set describing the class descriptors for each type that is
+ * <p>The content kind or format of a program resource can be either a Java class-file or an Android
+ * DEX file. In both cases, the resource must be able to provide the content as a byte stream. A
+ * resource may optionally include a set describing the class descriptors for each type that is
  * defined by the resource.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface ProgramResource extends Resource {
 
   /** Type of program-format kinds. */
-  @Keep
+  @KeepForApi
   enum Kind {
     /** Format-kind for Java class-file resources. */
     CF,
@@ -78,7 +79,7 @@
   Set<String> getClassDescriptors();
 
   /** File-based program resource. */
-  @Keep
+  @KeepForApi
   class FileResource implements ProgramResource {
     private final Origin origin;
     private final Kind kind;
@@ -127,7 +128,7 @@
   }
 
   /** Byte-content based program resource. */
-  @Keep
+  @KeepForApi
   class ByteResource implements ProgramResource {
     private final Origin origin;
     private final Kind kind;
diff --git a/src/main/java/com/android/tools/r8/ProgramResourceProvider.java b/src/main/java/com/android/tools/r8/ProgramResourceProvider.java
index b0620b1..f75e570 100644
--- a/src/main/java/com/android/tools/r8/ProgramResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ProgramResourceProvider.java
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.IOException;
 import java.util.Collection;
 
 /** Program resource provider. */
-@KeepForSubclassing
+@KeepForApi
 public interface ProgramResourceProvider {
 
   Collection<ProgramResource> getProgramResources() throws ResourceException;
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 8be855e..d0264fc 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -58,6 +58,7 @@
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
 import com.android.tools.r8.ir.optimize.templates.CfUtilityMethodsForCodeOptimizations;
 import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
 import com.android.tools.r8.kotlin.KotlinMetadataUtils;
 import com.android.tools.r8.naming.IdentifierMinifier;
@@ -166,7 +167,7 @@
  * them to DEX bytecode, using {@code androidJar} as the reference of the system runtime library,
  * and then writes the result to the directory or zip archive specified by {@code outputPath}.
  */
-@Keep
+@KeepForApi
 public class R8 {
 
   private final Timing timing;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 1decde2..b4ac86e 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.inspector.Inspector;
 import com.android.tools.r8.inspector.internal.InspectorImpl;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
 import com.android.tools.r8.keepanno.ast.KeepDeclaration;
 import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractor;
@@ -86,7 +87,7 @@
  *     .build();
  * </pre>
  */
-@Keep
+@KeepForApi
 public final class R8Command extends BaseCompilerCommand {
 
   /**
@@ -94,7 +95,7 @@
    *
    * <p>A builder is obtained by calling {@link R8Command#builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder extends BaseCompilerCommand.Builder<R8Command, Builder> {
 
     private static class DefaultR8DiagnosticsHandler implements DiagnosticsHandler {
@@ -134,7 +135,8 @@
     private final List<FeatureSplit> featureSplits = new ArrayList<>();
     private String synthesizedClassPrefix = "";
     private boolean enableMissingLibraryApiModeling = false;
-    private boolean enableExperimentalKeepAnnotations = false;
+    private boolean enableExperimentalKeepAnnotations =
+        System.getProperty("com.android.tools.r8.enableKeepAnnotations") != null;
     private SemanticVersion fakeCompilerVersion = null;
     private AndroidResourceProvider androidResourceProvider = null;
     private AndroidResourceConsumer androidResourceConsumer = null;
diff --git a/src/main/java/com/android/tools/r8/Resource.java b/src/main/java/com/android/tools/r8/Resource.java
index 50c50cc..cadabb5 100644
--- a/src/main/java/com/android/tools/r8/Resource.java
+++ b/src/main/java/com/android/tools/r8/Resource.java
@@ -4,22 +4,23 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 
 /**
  * Base interface for application resources.
  *
- * Resources are inputs to the compilation that are provided from outside sources, e.g., the
- * command-line interface or API clients such as gradle. Each resource has an associated
- * {@link Origin} which is some opaque description of where the resource comes from. The D8/R8
- * compiler does not assume any particular structure of origin and does not rely on it for
- * compilation. The origin will be provided to diagnostics handlers so that they may detail what
- * resource was cause of some particular error.
+ * <p>Resources are inputs to the compilation that are provided from outside sources, e.g., the
+ * command-line interface or API clients such as gradle. Each resource has an associated {@link
+ * Origin} which is some opaque description of where the resource comes from. The D8/R8 compiler
+ * does not assume any particular structure of origin and does not rely on it for compilation. The
+ * origin will be provided to diagnostics handlers so that they may detail what resource was cause
+ * of some particular error.
  *
- * The D8/R8 compilers uses default implementations for various file-system resources, but the
+ * <p>The D8/R8 compilers uses default implementations for various file-system resources, but the
  * client is free to provide their own.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface Resource {
   /**
    * Get the origin of the resource.
diff --git a/src/main/java/com/android/tools/r8/ResourceException.java b/src/main/java/com/android/tools/r8/ResourceException.java
index 2726b92..48d5b81 100644
--- a/src/main/java/com/android/tools/r8/ResourceException.java
+++ b/src/main/java/com/android/tools/r8/ResourceException.java
@@ -3,15 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 
 /**
  * Checked exception for resource related failures.
  *
- * For example, this is the expected exception that must be thrown if a resource fails to produce
+ * <p>For example, this is the expected exception that must be thrown if a resource fails to produce
  * its content. See {@link ProgramResource#getByteStream()} and {@link StringResource#getString()}.
  */
-@Keep
+@KeepForApi
 public class ResourceException extends Exception {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/ResourcePath.java b/src/main/java/com/android/tools/r8/ResourcePath.java
index eab4d7e..dafa2ef 100644
--- a/src/main/java/com/android/tools/r8/ResourcePath.java
+++ b/src/main/java/com/android/tools/r8/ResourcePath.java
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@Keep
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface ResourcePath {
 
   // The location within the apk, bundle or resource directory, e.g., res/xml/foo.xml
diff --git a/src/main/java/com/android/tools/r8/ResourceShrinker.java b/src/main/java/com/android/tools/r8/ResourceShrinker.java
index f23dddc..cbedb8f 100644
--- a/src/main/java/com/android/tools/r8/ResourceShrinker.java
+++ b/src/main/java/com/android/tools/r8/ResourceShrinker.java
@@ -47,6 +47,7 @@
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.ir.code.SingleConstant;
 import com.android.tools.r8.ir.code.WideConstant;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.utils.AndroidApp;
@@ -71,16 +72,17 @@
  *
  * <p>This class extracts all integer constants and string constants, which might refer to resource.
  * More specifically, we look for the following while analyzing dex:
+ *
  * <ul>
  *   <li>const instructions that might load integers or strings
- *   <li>static fields that have an initial value. This initial value might be integer, string,
- *   or array of integers.
+ *   <li>static fields that have an initial value. This initial value might be integer, string, or
+ *       array of integers.
  *   <li>integer array payloads. Only payloads referenced in fill-array-data instructions will be
- *   processed. More specifically, if a payload is referenced in fill-array-data, and we are able
- *   to determine that array is not array of integers, payload will be ignored. Otherwise, it will
- *   be processed once fill-array-data-payload instruction is encountered.
+ *       processed. More specifically, if a payload is referenced in fill-array-data, and we are
+ *       able to determine that array is not array of integers, payload will be ignored. Otherwise,
+ *       it will be processed once fill-array-data-payload instruction is encountered.
  *   <li>all annotations (class, field, method) that contain annotation element whose value is
- *   integer, string or array of integers are processed.
+ *       integer, string or array of integers are processed.
  * </ul>
  *
  * <p>Please note that switch payloads are not analyzed. Although they might contain integer
@@ -92,10 +94,10 @@
 
 // TODO(b/121121779) Remove keep if possible.
 @Deprecated
-@Keep
+@KeepForApi
 final public class ResourceShrinker {
 
-  @Keep
+  @KeepForApi
   public final static class Command extends BaseCommand {
 
     Command(AndroidApp app) {
@@ -108,7 +110,7 @@
     }
   }
 
-  @Keep
+  @KeepForApi
   public final static class Builder extends BaseCommand.Builder<Command, Builder> {
 
     @Override
@@ -126,7 +128,7 @@
    * Classes that would like to process data relevant to resource shrinking should implement this
    * interface.
    */
-  @KeepForSubclassing
+  @KeepForApi
   public interface ReferenceChecker {
 
     /**
diff --git a/src/main/java/com/android/tools/r8/SourceFileEnvironment.java b/src/main/java/com/android/tools/r8/SourceFileEnvironment.java
index 86a7211..263db17 100644
--- a/src/main/java/com/android/tools/r8/SourceFileEnvironment.java
+++ b/src/main/java/com/android/tools/r8/SourceFileEnvironment.java
@@ -3,8 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /** Environment made available when defining a custom map id for a build. */
-@Keep
+@KeepForApi
 public interface SourceFileEnvironment {
 
   /** Get the computed `id` for the mapping file. @See MapIdProvider */
diff --git a/src/main/java/com/android/tools/r8/SourceFileProvider.java b/src/main/java/com/android/tools/r8/SourceFileProvider.java
index a0a58cc..bed5a07 100644
--- a/src/main/java/com/android/tools/r8/SourceFileProvider.java
+++ b/src/main/java/com/android/tools/r8/SourceFileProvider.java
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
 /**
  * Interface for providing a custom source file to the compiler.
  *
@@ -10,7 +12,7 @@
  * output program. The source file attribute is present in the stacktraces computed by the JVM and
  * DEX runtimes, thus it can be used to identify builds.
  */
-@Keep
+@KeepForApi
 @FunctionalInterface
 public interface SourceFileProvider {
 
diff --git a/src/main/java/com/android/tools/r8/StringConsumer.java b/src/main/java/com/android/tools/r8/StringConsumer.java
index 2583572..c417223 100644
--- a/src/main/java/com/android/tools/r8/StringConsumer.java
+++ b/src/main/java/com/android/tools/r8/StringConsumer.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.ExceptionDiagnostic;
@@ -14,7 +15,7 @@
 import java.nio.file.Path;
 
 /** Interface for receiving String resource. */
-@KeepForSubclassing
+@KeepForApi
 public interface StringConsumer extends Finishable {
 
   /**
@@ -37,7 +38,7 @@
   }
 
   /** Empty consumer to request the production of the resource but ignore its value. */
-  @Keep
+  @KeepForApi
   class EmptyConsumer implements StringConsumer {
 
     private static final EmptyConsumer EMPTY_CONSUMER = new EmptyConsumer();
@@ -54,7 +55,7 @@
   }
 
   /** Forwarding consumer to delegate to an optional existing consumer. */
-  @Keep
+  @KeepForApi
   class ForwardingConsumer implements StringConsumer {
 
     private final StringConsumer consumer;
@@ -80,7 +81,7 @@
   }
 
   /** File consumer to write contents to a file-system file. */
-  @Keep // TODO(b/121121779) Consider deprecating the R8 provided file writing.
+  @KeepForApi
   class FileConsumer extends ForwardingConsumer {
 
     private final Path outputPath;
diff --git a/src/main/java/com/android/tools/r8/SwissArmyKnife.java b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
index b6eae99..b9dd50f 100644
--- a/src/main/java/com/android/tools/r8/SwissArmyKnife.java
+++ b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
@@ -50,9 +50,6 @@
       case "jardiff":
         JarDiff.main(shift(args));
         break;
-      case "jarsizecompare":
-        JarSizeCompare.main(shift(args));
-        break;
       case "maindex":
         GenerateMainDexList.main(shift(args));
         break;
diff --git a/src/main/java/com/android/tools/r8/SyntheticInfoConsumer.java b/src/main/java/com/android/tools/r8/SyntheticInfoConsumer.java
index 2bfc5b2..da1774f 100644
--- a/src/main/java/com/android/tools/r8/SyntheticInfoConsumer.java
+++ b/src/main/java/com/android/tools/r8/SyntheticInfoConsumer.java
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-@Keep
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+@KeepForApi
 public interface SyntheticInfoConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/SyntheticInfoConsumerData.java b/src/main/java/com/android/tools/r8/SyntheticInfoConsumerData.java
index be28596..a42b337 100644
--- a/src/main/java/com/android/tools/r8/SyntheticInfoConsumerData.java
+++ b/src/main/java/com/android/tools/r8/SyntheticInfoConsumerData.java
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
 /** Information about a compiler synthesized class. */
-@Keep
+@KeepForApi
 public interface SyntheticInfoConsumerData {
 
   /** Get the reference for the compiler synthesized class. */
diff --git a/src/main/java/com/android/tools/r8/TextInputStream.java b/src/main/java/com/android/tools/r8/TextInputStream.java
index 433df09..486e3d1 100644
--- a/src/main/java/com/android/tools/r8/TextInputStream.java
+++ b/src/main/java/com/android/tools/r8/TextInputStream.java
@@ -4,10 +4,11 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.InputStream;
 import java.nio.charset.Charset;
 
-@Keep
+@KeepForApi
 public interface TextInputStream {
 
   InputStream getInputStream();
diff --git a/src/main/java/com/android/tools/r8/TextOutputStream.java b/src/main/java/com/android/tools/r8/TextOutputStream.java
index 224d9da..c545c7f 100644
--- a/src/main/java/com/android/tools/r8/TextOutputStream.java
+++ b/src/main/java/com/android/tools/r8/TextOutputStream.java
@@ -4,10 +4,11 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
 
-@Keep
+@KeepForApi
 public interface TextOutputStream {
 
   OutputStream getOutputStream();
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiUnknownReferenceDiagnostic.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiUnknownReferenceDiagnostic.java
index fba87df..286d165 100644
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiUnknownReferenceDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiUnknownReferenceDiagnostic.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.androidapi;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class AndroidApiUnknownReferenceDiagnostic extends AndroidApiDiagnostic {
 
   private final DexReference reference;
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 74a107a..8232b0c 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -60,7 +60,6 @@
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
 public class ApplicationReader {
@@ -87,10 +86,8 @@
     return read((StringResource) null);
   }
 
-  public LazyLoadedDexApplication read(
-      StringResource proguardMap)
-      throws IOException {
-    ExecutorService executor = Executors.newSingleThreadExecutor();
+  public LazyLoadedDexApplication read(StringResource proguardMap) throws IOException {
+    ExecutorService executor = options.getThreadingModule().createSingleThreadedExecutorService();
     try {
       return read(proguardMap, executor);
     } finally {
diff --git a/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
index e1530bf..5db9876 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
-@Keep
+@KeepForApi
 public interface DefinitionClassContext extends DefinitionContext {
 
   /** Returns the reference of the class context. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java
index d05e123..19549be 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 
 /** A context that references a missing definition in the program, classpath, or library. */
-@Keep
+@KeepForApi
 public interface DefinitionContext {
 
   /** The origin of the context. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
index b3c4981..6cfce6b 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.FieldReference;
 
-@Keep
+@KeepForApi
 public interface DefinitionFieldContext extends DefinitionContext {
 
   /** Returns the reference of the field context. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
index 86742db..f64785d 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public interface DefinitionMethodContext extends DefinitionContext {
 
   /** Returns the reference of the method context. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java
index 41f255a..2d22b50 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
-@Keep
+@KeepForApi
 public interface MissingClassInfo extends MissingDefinitionInfo {
 
   /** Returns the reference of the missing class. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
index 03fe322..7bdbee8 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Collection;
 
 /**
  * Information about the contexts that references an item that was not part of the compilation unit.
  */
-@Keep
+@KeepForApi
 public interface MissingDefinitionInfo {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionsDiagnostic.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionsDiagnostic.java
index b3111be..d7ab801 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionsDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionsDiagnostic.java
@@ -5,14 +5,14 @@
 package com.android.tools.r8.diagnostic;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Collection;
 
 /**
  * Information about items that are not part of the compilation unit, but which are referenced from
  * a reachable program location.
  */
-@Keep
+@KeepForApi
 public interface MissingDefinitionsDiagnostic extends Diagnostic {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java
index 1ae6df1..70530de 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.FieldReference;
 
-@Keep
+@KeepForApi
 public interface MissingFieldInfo extends MissingDefinitionInfo {
 
   /** Returns the reference of the missing field. */
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java
index 3cf8cc0..51601b6 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.diagnostic;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public interface MissingMethodInfo extends MissingDefinitionInfo {
 
   /** Returns the reference of the missing method. */
diff --git a/src/main/java/com/android/tools/r8/errors/AssumeNoSideEffectsRuleForObjectMembersDiagnostic.java b/src/main/java/com/android/tools/r8/errors/AssumeNoSideEffectsRuleForObjectMembersDiagnostic.java
index cb4fafb..d6ccb95 100644
--- a/src/main/java/com/android/tools/r8/errors/AssumeNoSideEffectsRuleForObjectMembersDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/AssumeNoSideEffectsRuleForObjectMembersDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.MethodReference;
@@ -15,7 +15,7 @@
 import java.util.List;
 import java.util.Set;
 
-@Keep
+@KeepForApi
 public class AssumeNoSideEffectsRuleForObjectMembersDiagnostic implements Diagnostic {
 
   private final List<MethodReference> methods;
diff --git a/src/main/java/com/android/tools/r8/errors/AssumeValuesMissingStaticFieldDiagnostic.java b/src/main/java/com/android/tools/r8/errors/AssumeValuesMissingStaticFieldDiagnostic.java
index 38f6a46..1f65efd 100644
--- a/src/main/java/com/android/tools/r8/errors/AssumeValuesMissingStaticFieldDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/AssumeValuesMissingStaticFieldDiagnostic.java
@@ -4,13 +4,13 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class AssumeValuesMissingStaticFieldDiagnostic implements Diagnostic {
 
   private final DexType fieldHolder;
diff --git a/src/main/java/com/android/tools/r8/errors/CheckDiscardDiagnostic.java b/src/main/java/com/android/tools/r8/errors/CheckDiscardDiagnostic.java
index 82ab8f4..3f67044 100644
--- a/src/main/java/com/android/tools/r8/errors/CheckDiscardDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/CheckDiscardDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.shaking.GraphReporter;
@@ -15,7 +15,7 @@
 import java.io.PrintStream;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class CheckDiscardDiagnostic implements Diagnostic {
 
   private final List<String> messages;
diff --git a/src/main/java/com/android/tools/r8/errors/CheckEnumUnboxedDiagnostic.java b/src/main/java/com/android/tools/r8/errors/CheckEnumUnboxedDiagnostic.java
index 3339192..d30dbc7 100644
--- a/src/main/java/com/android/tools/r8/errors/CheckEnumUnboxedDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/CheckEnumUnboxedDiagnostic.java
@@ -5,16 +5,16 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.google.common.collect.ImmutableList;
 import java.util.Comparator;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class CheckEnumUnboxedDiagnostic implements Diagnostic {
 
   private final List<String> messages;
diff --git a/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java
index f9d49f0..6bcc568 100644
--- a/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java
@@ -4,11 +4,11 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public abstract class ClassFileOverflowDiagnostic implements Diagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java
index 5359ee0..15de75d 100644
--- a/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.MethodPosition;
 import com.android.tools.r8.position.Position;
@@ -13,7 +13,7 @@
  * Diagnostic information about a class file which could not be generated as the code size of a
  * method overflowed the limit.
  */
-@Keep
+@KeepForApi
 public class CodeSizeOverflowDiagnostic extends ClassFileOverflowDiagnostic {
 
   private final MethodReference method;
diff --git a/src/main/java/com/android/tools/r8/errors/ConstantDynamicDesugarDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ConstantDynamicDesugarDiagnostic.java
index d80b530..543e79b 100644
--- a/src/main/java/com/android/tools/r8/errors/ConstantDynamicDesugarDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/ConstantDynamicDesugarDiagnostic.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
 /** Common type for all diagnostics related to constant-dynamic desugaring. */
-@Keep
+@KeepForApi
 public class ConstantDynamicDesugarDiagnostic implements DesugarDiagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java
index 3c39f22..006cda5 100644
--- a/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 
@@ -11,7 +11,7 @@
  * Diagnostic information about a class file which could not be generated as the size of the
  * required constant pool overflowed the limit.
  */
-@Keep
+@KeepForApi
 public class ConstantPoolOverflowDiagnostic extends ClassFileOverflowDiagnostic {
 
   private final int constantPoolSize;
diff --git a/src/main/java/com/android/tools/r8/errors/DesugarDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DesugarDiagnostic.java
index 27b5a39..b541ff1 100644
--- a/src/main/java/com/android/tools/r8/errors/DesugarDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/DesugarDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** Common interface type for all diagnostics related to desugaring. */
-@Keep
+@KeepForApi
 public interface DesugarDiagnostic extends Diagnostic {}
diff --git a/src/main/java/com/android/tools/r8/errors/DexFileOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DexFileOverflowDiagnostic.java
index 9427603..1930a3a 100644
--- a/src/main/java/com/android/tools/r8/errors/DexFileOverflowDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/DexFileOverflowDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.dex.VirtualFile;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
@@ -16,7 +16,7 @@
  * compiling for legacy multidex but there are too many classes that need to fit in the main DEX
  * file, e.g., classes.dex.
  */
-@Keep
+@KeepForApi
 public class DexFileOverflowDiagnostic implements Diagnostic {
   private final boolean hasMainDexSpecification;
   private final long numOfMethods;
diff --git a/src/main/java/com/android/tools/r8/errors/DuplicateTypeInProgramAndLibraryDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DuplicateTypeInProgramAndLibraryDiagnostic.java
index 5af3923..27ba93f 100644
--- a/src/main/java/com/android/tools/r8/errors/DuplicateTypeInProgramAndLibraryDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/DuplicateTypeInProgramAndLibraryDiagnostic.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class DuplicateTypeInProgramAndLibraryDiagnostic extends DuplicateTypesDiagnostic {
 
   public DuplicateTypeInProgramAndLibraryDiagnostic(
diff --git a/src/main/java/com/android/tools/r8/errors/DuplicateTypesDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DuplicateTypesDiagnostic.java
index 6aa7234..dde2df2 100644
--- a/src/main/java/com/android/tools/r8/errors/DuplicateTypesDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/DuplicateTypesDiagnostic.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.ClassReference;
@@ -12,7 +12,7 @@
 import com.android.tools.r8.utils.StringUtils;
 import java.util.Collection;
 
-@Keep
+@KeepForApi
 public class DuplicateTypesDiagnostic implements Diagnostic {
 
   private final ClassReference type;
diff --git a/src/main/java/com/android/tools/r8/errors/IgnoredBackportMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/IgnoredBackportMethodDiagnostic.java
index 8f56ecf..f3b5171 100644
--- a/src/main/java/com/android/tools/r8/errors/IgnoredBackportMethodDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/IgnoredBackportMethodDiagnostic.java
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public class IgnoredBackportMethodDiagnostic implements DesugarDiagnostic {
 
   private final DexMethod backport;
diff --git a/src/main/java/com/android/tools/r8/errors/IncompleteNestNestDesugarDiagnosic.java b/src/main/java/com/android/tools/r8/errors/IncompleteNestNestDesugarDiagnosic.java
index c888069..0a59a42 100644
--- a/src/main/java/com/android/tools/r8/errors/IncompleteNestNestDesugarDiagnosic.java
+++ b/src/main/java/com/android/tools/r8/errors/IncompleteNestNestDesugarDiagnosic.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class IncompleteNestNestDesugarDiagnosic extends NestDesugarDiagnostic {
 
   public IncompleteNestNestDesugarDiagnosic(Origin origin, Position position, String message) {
diff --git a/src/main/java/com/android/tools/r8/errors/InlinableStaticFinalFieldPreconditionDiagnostic.java b/src/main/java/com/android/tools/r8/errors/InlinableStaticFinalFieldPreconditionDiagnostic.java
index 45b40d2..833d7b6 100644
--- a/src/main/java/com/android/tools/r8/errors/InlinableStaticFinalFieldPreconditionDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/InlinableStaticFinalFieldPreconditionDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.FieldReference;
@@ -16,7 +16,7 @@
 import java.util.Collection;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class InlinableStaticFinalFieldPreconditionDiagnostic implements Diagnostic {
 
   private final ProguardIfRule rule;
diff --git a/src/main/java/com/android/tools/r8/errors/InterfaceDesugarDiagnostic.java b/src/main/java/com/android/tools/r8/errors/InterfaceDesugarDiagnostic.java
index afc2115..6156e58 100644
--- a/src/main/java/com/android/tools/r8/errors/InterfaceDesugarDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/InterfaceDesugarDiagnostic.java
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** Common interface type for all diagnostics related to interface-method desugaring. */
-@Keep
+@KeepForApi
 public interface InterfaceDesugarDiagnostic extends DesugarDiagnostic {}
diff --git a/src/main/java/com/android/tools/r8/errors/InterfaceDesugarMissingTypeDiagnostic.java b/src/main/java/com/android/tools/r8/errors/InterfaceDesugarMissingTypeDiagnostic.java
index b3f3fd6..33487ab 100644
--- a/src/main/java/com/android/tools/r8/errors/InterfaceDesugarMissingTypeDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/InterfaceDesugarMissingTypeDiagnostic.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.ClassReference;
@@ -11,7 +11,7 @@
 /**
  * Diagnostic for missing types needed for correct desugaring of default/static interface methods.
  */
-@Keep
+@KeepForApi
 public class InterfaceDesugarMissingTypeDiagnostic implements DesugarDiagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/errors/InvalidLibrarySuperclassDiagnostic.java b/src/main/java/com/android/tools/r8/errors/InvalidLibrarySuperclassDiagnostic.java
index 2392f0a..d120176 100644
--- a/src/main/java/com/android/tools/r8/errors/InvalidLibrarySuperclassDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/InvalidLibrarySuperclassDiagnostic.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.ClassReference;
@@ -16,7 +16,7 @@
  * Diagnostic for super types of library classes which are not library classes but required for
  * desugaring.
  */
-@Keep
+@KeepForApi
 public class InvalidLibrarySuperclassDiagnostic implements DesugarDiagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/errors/MissingNestHostNestDesugarDiagnostic.java b/src/main/java/com/android/tools/r8/errors/MissingNestHostNestDesugarDiagnostic.java
index 2b3cbab..483467b 100644
--- a/src/main/java/com/android/tools/r8/errors/MissingNestHostNestDesugarDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/MissingNestHostNestDesugarDiagnostic.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class MissingNestHostNestDesugarDiagnostic extends NestDesugarDiagnostic {
 
   public MissingNestHostNestDesugarDiagnostic(Origin origin, Position position, String message) {
diff --git a/src/main/java/com/android/tools/r8/errors/NestDesugarDiagnostic.java b/src/main/java/com/android/tools/r8/errors/NestDesugarDiagnostic.java
index 8662eee..c2ee108 100644
--- a/src/main/java/com/android/tools/r8/errors/NestDesugarDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/NestDesugarDiagnostic.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class NestDesugarDiagnostic implements DesugarDiagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
index 10d8c1f..95cf81e 100644
--- a/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/ProguardKeepRuleDiagnostic.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** Base interface for diagnostics related to proguard keep rules. */
-@Keep
+@KeepForApi
 public interface ProguardKeepRuleDiagnostic extends Diagnostic {}
diff --git a/src/main/java/com/android/tools/r8/errors/StartupClassesNonStartupFractionDiagnostic.java b/src/main/java/com/android/tools/r8/errors/StartupClassesNonStartupFractionDiagnostic.java
index e024130..b59f642 100644
--- a/src/main/java/com/android/tools/r8/errors/StartupClassesNonStartupFractionDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/StartupClassesNonStartupFractionDiagnostic.java
@@ -5,9 +5,9 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.profile.startup.profile.StartupProfile;
@@ -15,7 +15,7 @@
 import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class StartupClassesNonStartupFractionDiagnostic implements Diagnostic {
 
   private final int numberOfStartupClasses;
diff --git a/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java
index 00290a2..c200087 100644
--- a/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/StartupClassesOverflowDiagnostic.java
@@ -5,13 +5,13 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-@Keep
+@KeepForApi
 public class StartupClassesOverflowDiagnostic implements Diagnostic {
 
   private final int numberOfStartupDexFiles;
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedConstDynamicDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedConstDynamicDiagnostic.java
index b75f686..513d395 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedConstDynamicDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedConstDynamicDiagnostic.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.utils.InternalOptions;
 
-@Keep
+@KeepForApi
 public class UnsupportedConstDynamicDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodHandleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodHandleDiagnostic.java
index 375adf1..2850821 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodHandleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodHandleDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.constantMethodHandleApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedConstMethodHandleDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodTypeDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodTypeDiagnostic.java
index 5809011..f31a632 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodTypeDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedConstMethodTypeDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.constantMethodTypeApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedConstMethodTypeDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedDefaultInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedDefaultInterfaceMethodDiagnostic.java
index 6905dcc..77f64f5 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedDefaultInterfaceMethodDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedDefaultInterfaceMethodDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.defaultInterfaceMethodsApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedDefaultInterfaceMethodDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedDesugaredLibraryConfigurationVersionDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedDesugaredLibraryConfigurationVersionDiagnostic.java
index 7e2455a..736a075 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedDesugaredLibraryConfigurationVersionDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedDesugaredLibraryConfigurationVersionDiagnostic.java
@@ -4,11 +4,11 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedDesugaredLibraryConfigurationVersionDiagnostic implements Diagnostic {
 
   private static final String dagRoot = "https://developer.android.com";
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedFeatureDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedFeatureDiagnostic.java
index 1ac0482..c3be292 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedFeatureDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedFeatureDiagnostic.java
@@ -4,12 +4,12 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.utils.AndroidApiLevel;
 
-@Keep
+@KeepForApi
 public abstract class UnsupportedFeatureDiagnostic implements Diagnostic {
 
   public static String makeMessage(
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokeCustomDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokeCustomDiagnostic.java
index ca67569..27fb2e9 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokeCustomDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokeCustomDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.invokeCustomApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedInvokeCustomDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicMethodHandleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicMethodHandleDiagnostic.java
index 23718f3..b88f49b 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicMethodHandleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicMethodHandleDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.invokePolymorphicOnMethodHandleApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedInvokePolymorphicMethodHandleDiagnostic
     extends UnsupportedFeatureDiagnostic {
 
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicVarHandleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicVarHandleDiagnostic.java
index 49f73a6..8f3f111 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicVarHandleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedInvokePolymorphicVarHandleDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.invokePolymorphicOnVarHandleApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedInvokePolymorphicVarHandleDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedMainDexListUsageDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedMainDexListUsageDiagnostic.java
index 9bcbcba..fdaa15c 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedMainDexListUsageDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedMainDexListUsageDiagnostic.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.errors;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
@@ -13,7 +13,7 @@
  *
  * <p>See b/181858113 for context.
  */
-@Keep
+@KeepForApi
 public class UnsupportedMainDexListUsageDiagnostic implements Diagnostic {
   private final Origin origin;
 
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedPrivateInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedPrivateInterfaceMethodDiagnostic.java
index 0a52151..79fe57d 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedPrivateInterfaceMethodDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedPrivateInterfaceMethodDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.privateInterfaceMethodsApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedPrivateInterfaceMethodDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnsupportedStaticInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnsupportedStaticInterfaceMethodDiagnostic.java
index 3220744..1e6734f 100644
--- a/src/main/java/com/android/tools/r8/errors/UnsupportedStaticInterfaceMethodDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnsupportedStaticInterfaceMethodDiagnostic.java
@@ -5,11 +5,11 @@
 
 import static com.android.tools.r8.utils.InternalOptions.staticInterfaceMethodsApiLevel;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class UnsupportedStaticInterfaceMethodDiagnostic extends UnsupportedFeatureDiagnostic {
 
   // API: MUST NOT CHANGE!
diff --git a/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java b/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
index 2d2b326..ae1f370 100644
--- a/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/errors/UnusedProguardKeepRuleDiagnostic.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.errors;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
 
-@Keep
+@KeepForApi
 public class UnusedProguardKeepRuleDiagnostic implements ProguardKeepRuleDiagnostic {
 
   private final ProguardConfigurationRule rule;
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
index 7baa5fa..86f1b88 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/AnnotationGraphNode.java
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Objects;
 
-@Keep
+@KeepForApi
 public final class AnnotationGraphNode extends GraphNode {
 
   private final GraphNode annotatedNode;
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
index fa55609..2ce20ed 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/ClassGraphNode.java
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
-@Keep
+@KeepForApi
 public final class ClassGraphNode extends GraphNode {
 
   private final ClassReference reference;
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
index 836058f..723016e 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/FieldGraphNode.java
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.FieldReference;
 
-@Keep
+@KeepForApi
 public final class FieldGraphNode extends GraphNode {
 
   private final FieldReference reference;
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
index 3c7bda1..5de4325 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphConsumer.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.KeepForSubclassing;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@KeepForSubclassing
+@KeepForApi
 public interface GraphConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
index 640035a..603fbf1 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/GraphNode.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public abstract class GraphNode {
 
   private static final GraphNode CYCLE =
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
index 67feaf7..a75a45f 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/KeepRuleGraphNode.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.position.TextPosition;
@@ -16,7 +16,7 @@
 
 // Note: this could potentially be merged with ConditionalKeepRuleGraphNode
 // and an empty precondition set.
-@Keep
+@KeepForApi
 public final class KeepRuleGraphNode extends GraphNode {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java b/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
index 7a92a91..bf42338 100644
--- a/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
+++ b/src/main/java/com/android/tools/r8/experimental/graphinfo/MethodGraphNode.java
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.experimental.graphinfo;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public final class MethodGraphNode extends GraphNode {
 
   private final MethodReference reference;
diff --git a/src/main/java/com/android/tools/r8/inspector/BooleanValueInspector.java b/src/main/java/com/android/tools/r8/inspector/BooleanValueInspector.java
index 105f577..ff8226d 100644
--- a/src/main/java/com/android/tools/r8/inspector/BooleanValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/BooleanValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface BooleanValueInspector extends ValueInspector {
   boolean getBooleanValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/ByteValueInspector.java b/src/main/java/com/android/tools/r8/inspector/ByteValueInspector.java
index 045476d..d375f1d 100644
--- a/src/main/java/com/android/tools/r8/inspector/ByteValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/ByteValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface ByteValueInspector extends ValueInspector {
   byte getByteValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/CharValueInspector.java b/src/main/java/com/android/tools/r8/inspector/CharValueInspector.java
index 05d5c2b..a9f16c0 100644
--- a/src/main/java/com/android/tools/r8/inspector/CharValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/CharValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface CharValueInspector extends ValueInspector {
   char getCharValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/ClassInspector.java b/src/main/java/com/android/tools/r8/inspector/ClassInspector.java
index 6234592..5cbf8e8 100644
--- a/src/main/java/com/android/tools/r8/inspector/ClassInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/ClassInspector.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import java.util.function.Consumer;
 
 /** Inspector for a class or interface definition. */
-@Keep
+@KeepForApi
 public interface ClassInspector {
 
   /** Get the class reference for the class of this inspector. */
diff --git a/src/main/java/com/android/tools/r8/inspector/DoubleValueInspector.java b/src/main/java/com/android/tools/r8/inspector/DoubleValueInspector.java
index e9ac7e1..5d5b294 100644
--- a/src/main/java/com/android/tools/r8/inspector/DoubleValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/DoubleValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface DoubleValueInspector extends ValueInspector {
   double getDoubleValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/FieldInspector.java b/src/main/java/com/android/tools/r8/inspector/FieldInspector.java
index 5d2e656..9bacff4 100644
--- a/src/main/java/com/android/tools/r8/inspector/FieldInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/FieldInspector.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.FieldReference;
 import java.util.Optional;
 
 /** Inspector for a field definition. */
-@Keep
+@KeepForApi
 public interface FieldInspector {
 
   /** Get the field reference for the field of this inspector. */
diff --git a/src/main/java/com/android/tools/r8/inspector/FloatValueInspector.java b/src/main/java/com/android/tools/r8/inspector/FloatValueInspector.java
index a7be463..8ba7de3 100644
--- a/src/main/java/com/android/tools/r8/inspector/FloatValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/FloatValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface FloatValueInspector extends ValueInspector {
   float getFloatValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/Inspector.java b/src/main/java/com/android/tools/r8/inspector/Inspector.java
index 880b450..9313f21 100644
--- a/src/main/java/com/android/tools/r8/inspector/Inspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/Inspector.java
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.function.Consumer;
 
 /** Inspector providing access to various parts of an application. */
-@Keep
+@KeepForApi
 public interface Inspector {
 
   /** Iterate all classes and interfaces defined by the program (order unspecified). */
diff --git a/src/main/java/com/android/tools/r8/inspector/IntValueInspector.java b/src/main/java/com/android/tools/r8/inspector/IntValueInspector.java
index 6b43ac8..4b8530e 100644
--- a/src/main/java/com/android/tools/r8/inspector/IntValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/IntValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface IntValueInspector extends ValueInspector {
   int getIntValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/LongValueInspector.java b/src/main/java/com/android/tools/r8/inspector/LongValueInspector.java
index 987721e..3a911ee 100644
--- a/src/main/java/com/android/tools/r8/inspector/LongValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/LongValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface LongValueInspector extends ValueInspector {
   long getLongValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/MethodInspector.java b/src/main/java/com/android/tools/r8/inspector/MethodInspector.java
index 41cc8de..587fafa 100644
--- a/src/main/java/com/android/tools/r8/inspector/MethodInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/MethodInspector.java
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 
 /** Inspector for a method definition. */
-@Keep
+@KeepForApi
 public interface MethodInspector {
 
   /** Get the method reference for the method of this inspector. */
diff --git a/src/main/java/com/android/tools/r8/inspector/ShortValueInspector.java b/src/main/java/com/android/tools/r8/inspector/ShortValueInspector.java
index 6b01df3..519e01f 100644
--- a/src/main/java/com/android/tools/r8/inspector/ShortValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/ShortValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface ShortValueInspector extends ValueInspector {
   short getShortValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/StringValueInspector.java b/src/main/java/com/android/tools/r8/inspector/StringValueInspector.java
index 5336948..7d47ab0 100644
--- a/src/main/java/com/android/tools/r8/inspector/StringValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/StringValueInspector.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface StringValueInspector extends ValueInspector {
   String getStringValue();
 }
diff --git a/src/main/java/com/android/tools/r8/inspector/ValueInspector.java b/src/main/java/com/android/tools/r8/inspector/ValueInspector.java
index 84f1fe0..a60db9c 100644
--- a/src/main/java/com/android/tools/r8/inspector/ValueInspector.java
+++ b/src/main/java/com/android/tools/r8/inspector/ValueInspector.java
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.inspector;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.TypeReference;
 
 /** Inspector for a JVM representable value. */
-@Keep
+@KeepForApi
 public interface ValueInspector {
 
   /** Get the type reference describing the type of the value. */
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/NullOrAbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/NullOrAbstractValue.java
index 6eaf130..85534f3 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/NullOrAbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/NullOrAbstractValue.java
@@ -14,6 +14,7 @@
   private final AbstractValue value;
 
   private NullOrAbstractValue(AbstractValue value) {
+    assert !value.isSingleNumberValue();
     this.value = value;
   }
 
@@ -44,9 +45,14 @@
   }
 
   @Override
-  public NullOrAbstractValue rewrittenWithLens(
+  public AbstractValue rewrittenWithLens(
       AppView<AppInfoWithLiveness> appView, DexType newType, GraphLens lens, GraphLens codeLens) {
-    return new NullOrAbstractValue(value.rewrittenWithLens(appView, newType, lens, codeLens));
+    AbstractValue rewrittenValue = value.rewrittenWithLens(appView, newType, lens, codeLens);
+    if (rewrittenValue.isSingleNumberValue()) {
+      // Reference type rewritten to primitive.
+      return unknown();
+    }
+    return new NullOrAbstractValue(rewrittenValue);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/DexConstantOptimizer.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/DexConstantOptimizer.java
index 51f6094..740c180 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/DexConstantOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/DexConstantOptimizer.java
@@ -232,6 +232,10 @@
   }
 
   private void shortenLiveRanges(IRCode code, ConstantCanonicalizer canonicalizer) {
+    if (options.debug) {
+      // Shorten live ranges seems to regress code size in debug mode.
+      return;
+    }
     if (options.testing.disableShortenLiveRanges) {
       return;
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
index 8f7f2b6..d993797 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.TopLevelFlagsBuilder;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.memberparser.HumanFieldParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.memberparser.HumanMethodParser;
 import com.android.tools.r8.origin.Origin;
@@ -35,7 +36,7 @@
 
 public class HumanDesugaredLibrarySpecificationParser {
 
-  public static final int CURRENT_HUMAN_CONFIGURATION_FORMAT_VERSION = 100;
+  public static final int CURRENT_HUMAN_CONFIGURATION_FORMAT_VERSION = 101;
 
   static final String IDENTIFIER_KEY = "identifier";
   static final String REQUIRED_COMPILATION_API_LEVEL_KEY = "required_compilation_api_level";
@@ -49,6 +50,8 @@
   static final String API_LEVEL_BELOW_OR_EQUAL_KEY = "api_level_below_or_equal";
   static final String API_LEVEL_GREATER_OR_EQUAL_KEY = "api_level_greater_or_equal";
   static final String API_GENERIC_TYPES_CONVERSION = "api_generic_types_conversion";
+  static final String REWRITTEN_TYPE_KEY = "rewrittenType";
+  static final String EMULATED_METHODS_KEY = "emulatedMethods";
   static final String WRAPPER_CONVERSION_KEY = "wrapper_conversion";
   static final String WRAPPER_CONVERSION_EXCLUDING_KEY = "wrapper_conversion_excluding";
   static final String CUSTOM_CONVERSION_KEY = "custom_conversion";
@@ -63,7 +66,6 @@
       "retarget_method_with_emulated_dispatch";
   static final String REWRITE_DERIVED_PREFIX_KEY = "rewrite_derived_prefix";
   static final String EMULATE_INTERFACE_KEY = "emulate_interface";
-  static final String DONT_REWRITE_KEY = "dont_rewrite";
   static final String DONT_RETARGET_KEY = "dont_retarget";
   static final String BACKPORT_KEY = "backport";
   static final String AMEND_LIBRARY_METHOD_KEY = "amend_library_method";
@@ -343,9 +345,15 @@
     if (jsonFlagSet.has(EMULATE_INTERFACE_KEY)) {
       for (Map.Entry<String, JsonElement> itf :
           jsonFlagSet.get(EMULATE_INTERFACE_KEY).getAsJsonObject().entrySet()) {
-        builder.putEmulatedInterface(
-            stringDescriptorToDexType(itf.getKey()),
-            stringDescriptorToDexType(itf.getValue().getAsString()));
+        if (itf.getValue().isJsonPrimitive()) {
+          builder.putLegacyEmulatedInterface(
+              stringDescriptorToDexType(itf.getKey()),
+              stringDescriptorToDexType(itf.getValue().getAsString()));
+        } else {
+          builder.putSpecifiedEmulatedInterface(
+              stringDescriptorToDexType(itf.getKey()),
+              parseEmulatedInterfaceDescriptor(itf.getValue()));
+        }
       }
     }
     if (jsonFlagSet.has(CUSTOM_CONVERSION_KEY)) {
@@ -369,12 +377,6 @@
             parseMethods(wrapper.getValue().getAsJsonArray()));
       }
     }
-    if (jsonFlagSet.has(DONT_REWRITE_KEY)) {
-      JsonArray dontRewrite = jsonFlagSet.get(DONT_REWRITE_KEY).getAsJsonArray();
-      for (JsonElement rewrite : dontRewrite) {
-        builder.addDontRewriteInvocation(parseMethod(rewrite.getAsString()));
-      }
-    }
     if (jsonFlagSet.has(DONT_RETARGET_KEY)) {
       JsonArray dontRetarget = jsonFlagSet.get(DONT_RETARGET_KEY).getAsJsonArray();
       for (JsonElement rewrite : dontRetarget) {
@@ -397,6 +399,21 @@
     }
   }
 
+  private HumanEmulatedInterfaceDescriptor parseEmulatedInterfaceDescriptor(JsonElement value) {
+    JsonObject jsonObject = value.getAsJsonObject();
+    DexType rewrittenType =
+        stringDescriptorToDexType(required(jsonObject, REWRITTEN_TYPE_KEY).getAsString());
+    Set<DexMethod> emulatedMethods = Sets.newIdentityHashSet();
+    if (jsonObject.has(EMULATED_METHODS_KEY)) {
+      JsonArray methods = jsonObject.get(EMULATED_METHODS_KEY).getAsJsonArray();
+      for (JsonElement method : methods) {
+        methodParser.parseMethod(method.getAsString());
+        emulatedMethods.add(methodParser.getMethod());
+      }
+    }
+    return new HumanEmulatedInterfaceDescriptor(rewrittenType, emulatedMethods);
+  }
+
   private Set<DexMethod> parseMethods(JsonArray array) {
     Set<DexMethod> methods = Sets.newIdentityHashSet();
     for (JsonElement method : array) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
index cae75f2..daf641b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification;
 
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.FieldAccessFlags;
@@ -27,7 +28,7 @@
   private final Set<String> dontRewritePrefix;
   private final Set<String> maintainPrefix;
   private final Map<String, Map<String, String>> rewriteDerivedPrefix;
-  private final Map<DexType, DexType> emulatedInterfaces;
+  private final Map<DexType, HumanEmulatedInterfaceDescriptor> emulatedInterfaces;
   private final Map<DexField, DexField> retargetStaticField;
   private final Map<DexMethod, DexType> covariantRetarget;
   private final Map<DexMethod, DexType> retargetMethodToType;
@@ -37,7 +38,6 @@
   private final Map<DexMethod, DexMethod[]> apiGenericTypesConversion;
   private final Map<DexType, DexType> legacyBackport;
   private final Map<DexType, DexType> customConversions;
-  private final Set<DexMethod> dontRewriteInvocation;
   private final Set<DexType> dontRetarget;
   private final Map<DexType, Set<DexMethod>> wrapperConversions;
   private final Set<DexMethod> neverOutlineApi;
@@ -49,7 +49,7 @@
       Set<String> dontRewritePrefix,
       Set<String> maintainPrefix,
       Map<String, Map<String, String>> rewriteDerivedPrefix,
-      Map<DexType, DexType> emulateLibraryInterface,
+      Map<DexType, HumanEmulatedInterfaceDescriptor> emulateLibraryInterface,
       Map<DexField, DexField> retargetStaticField,
       Map<DexMethod, DexType> covariantRetarget,
       Map<DexMethod, DexType> retargetMethodToType,
@@ -59,7 +59,6 @@
       Map<DexMethod, DexMethod[]> apiGenericTypesConversion,
       Map<DexType, DexType> legacyBackport,
       Map<DexType, DexType> customConversion,
-      Set<DexMethod> dontRewriteInvocation,
       Set<DexType> dontRetarget,
       Map<DexType, Set<DexMethod>> wrapperConversion,
       Set<DexMethod> neverOutlineApi,
@@ -79,7 +78,6 @@
     this.apiGenericTypesConversion = apiGenericTypesConversion;
     this.legacyBackport = legacyBackport;
     this.customConversions = customConversion;
-    this.dontRewriteInvocation = dontRewriteInvocation;
     this.dontRetarget = dontRetarget;
     this.wrapperConversions = wrapperConversion;
     this.neverOutlineApi = neverOutlineApi;
@@ -104,13 +102,92 @@
         ImmutableMap.of(),
         ImmutableMap.of(),
         ImmutableSet.of(),
-        ImmutableSet.of(),
         ImmutableMap.of(),
         ImmutableSet.of(),
         ImmutableMap.of(),
         ImmutableMap.of());
   }
 
+  public static class HumanEmulatedInterfaceDescriptor {
+    private final DexType rewrittenType;
+    private final Set<DexMethod> emulatedMethods;
+
+    public HumanEmulatedInterfaceDescriptor(DexType rewrittenType, Set<DexMethod> emulatedMethods) {
+      this.rewrittenType = rewrittenType;
+      this.emulatedMethods = emulatedMethods;
+    }
+
+    public boolean isLegacy() {
+      return false;
+    }
+
+    public DexType getRewrittenType() {
+      return rewrittenType;
+    }
+
+    public Set<DexMethod> getEmulatedMethods() {
+      return emulatedMethods;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!(obj instanceof HumanEmulatedInterfaceDescriptor)) {
+        return false;
+      }
+      HumanEmulatedInterfaceDescriptor other = (HumanEmulatedInterfaceDescriptor) obj;
+      return rewrittenType.isIdenticalTo(other.getRewrittenType())
+          && getEmulatedMethods().equals(other.getEmulatedMethods());
+    }
+
+    @Override
+    public int hashCode() {
+      return 7 * rewrittenType.hashCode() + getEmulatedMethods().hashCode();
+    }
+
+    public HumanEmulatedInterfaceDescriptor merge(HumanEmulatedInterfaceDescriptor other) {
+      if (!rewrittenType.isIdenticalTo(other.getRewrittenType())) {
+        throw new UnsupportedOperationException(
+            "Emulated interface descriptor can only be merged on the same rewritten type.");
+      }
+      ImmutableSet.Builder<DexMethod> builder = ImmutableSet.builder();
+      builder.addAll(getEmulatedMethods());
+      builder.addAll(other.getEmulatedMethods());
+      return new HumanEmulatedInterfaceDescriptor(rewrittenType, builder.build());
+    }
+
+    public boolean containsEmulatedMethod(DexMethod reference, DexItemFactory factory) {
+      return getEmulatedMethods().contains(reference);
+    }
+  }
+
+  // TODO(b/309735284): Temporary work-around.
+  public static class LegacyHumanEmulatedInterfaceDescriptor
+      extends HumanEmulatedInterfaceDescriptor {
+
+    public LegacyHumanEmulatedInterfaceDescriptor(DexType rewrittenType) {
+      super(rewrittenType, ImmutableSet.of());
+    }
+
+    @Override
+    public boolean isLegacy() {
+      return true;
+    }
+
+    @Override
+    public HumanEmulatedInterfaceDescriptor merge(HumanEmulatedInterfaceDescriptor other) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean containsEmulatedMethod(DexMethod reference, DexItemFactory factory) {
+      // Equivalence for parsing specification with format version 100.
+      DexMethod dontRewrite =
+          factory.createMethod(
+              factory.iteratorType, factory.createProto(factory.voidType), "remove");
+      return !reference.isIdenticalTo(dontRewrite);
+    }
+  }
+
   public static Builder builder(Reporter reporter, Origin origin) {
     return new Builder(reporter, origin);
   }
@@ -133,7 +210,6 @@
         apiGenericTypesConversion,
         legacyBackport,
         customConversions,
-        dontRewriteInvocation,
         dontRetarget,
         wrapperConversions,
         neverOutlineApi,
@@ -157,7 +233,7 @@
     return rewriteDerivedPrefix;
   }
 
-  public Map<DexType, DexType> getEmulatedInterfaces() {
+  public Map<DexType, HumanEmulatedInterfaceDescriptor> getEmulatedInterfaces() {
     return emulatedInterfaces;
   }
 
@@ -201,10 +277,6 @@
     return customConversions;
   }
 
-  public Set<DexMethod> getDontRewriteInvocation() {
-    return dontRewriteInvocation;
-  }
-
   public Set<DexType> getDontRetarget() {
     return dontRetarget;
   }
@@ -241,7 +313,7 @@
     private final Set<String> dontRewritePrefix;
     private final Set<String> maintainPrefix;
     private final Map<String, Map<String, String>> rewriteDerivedPrefix;
-    private final Map<DexType, DexType> emulatedInterfaces;
+    private final Map<DexType, HumanEmulatedInterfaceDescriptor> emulatedInterfaces;
     private final Map<DexField, DexField> retargetStaticField;
     private final Map<DexMethod, DexType> covariantRetarget;
     private final Map<DexMethod, DexType> retargetMethodToType;
@@ -251,7 +323,6 @@
     private final Map<DexMethod, DexMethod[]> apiGenericTypesConversion;
     private final Map<DexType, DexType> legacyBackport;
     private final Map<DexType, DexType> customConversions;
-    private final Set<DexMethod> dontRewriteInvocation;
     private final Set<DexType> dontRetarget;
     private final Map<DexType, Set<DexMethod>> wrapperConversions;
     private final Set<DexMethod> neverOutlineApi;
@@ -277,7 +348,6 @@
           new IdentityHashMap<>(),
           new IdentityHashMap<>(),
           Sets.newIdentityHashSet(),
-          Sets.newIdentityHashSet(),
           new IdentityHashMap<>(),
           Sets.newIdentityHashSet(),
           new IdentityHashMap<>(),
@@ -291,7 +361,7 @@
         Set<String> dontRewritePrefix,
         Set<String> maintainPrefix,
         Map<String, Map<String, String>> rewriteDerivedPrefix,
-        Map<DexType, DexType> emulateLibraryInterface,
+        Map<DexType, HumanEmulatedInterfaceDescriptor> emulateLibraryInterface,
         Map<DexField, DexField> retargetStaticField,
         Map<DexMethod, DexType> covariantRetarget,
         Map<DexMethod, DexType> retargetMethodToType,
@@ -301,7 +371,6 @@
         Map<DexMethod, DexMethod[]> apiConversionCollection,
         Map<DexType, DexType> backportCoreLibraryMember,
         Map<DexType, DexType> customConversions,
-        Set<DexMethod> dontRewriteInvocation,
         Set<DexType> dontRetargetLibMember,
         Map<DexType, Set<DexMethod>> wrapperConversions,
         Set<DexMethod> neverOutlineApi,
@@ -325,8 +394,6 @@
       this.apiGenericTypesConversion = new IdentityHashMap<>(apiConversionCollection);
       this.legacyBackport = new IdentityHashMap<>(backportCoreLibraryMember);
       this.customConversions = new IdentityHashMap<>(customConversions);
-      this.dontRewriteInvocation = Sets.newIdentityHashSet();
-      this.dontRewriteInvocation.addAll(dontRewriteInvocation);
       this.dontRetarget = Sets.newIdentityHashSet();
       this.dontRetarget.addAll(dontRetargetLibMember);
       this.wrapperConversions = new IdentityHashMap<>(wrapperConversions);
@@ -383,15 +450,25 @@
       return this;
     }
 
-    public Builder putEmulatedInterface(DexType interfaceType, DexType rewrittenType) {
+    public Builder putLegacyEmulatedInterface(DexType interfaceType, DexType rewrittenType) {
       put(
           emulatedInterfaces,
           interfaceType,
-          rewrittenType,
+          new LegacyHumanEmulatedInterfaceDescriptor(rewrittenType),
           HumanDesugaredLibrarySpecificationParser.EMULATE_INTERFACE_KEY);
       return this;
     }
 
+    public Builder putSpecifiedEmulatedInterface(
+        DexType interfaceType, HumanEmulatedInterfaceDescriptor newDescriptor) {
+      assert newDescriptor != null;
+      HumanEmulatedInterfaceDescriptor oldDescriptor = emulatedInterfaces.get(interfaceType);
+      HumanEmulatedInterfaceDescriptor mergedDescriptor =
+          oldDescriptor == null ? newDescriptor : newDescriptor.merge(oldDescriptor);
+      emulatedInterfaces.put(interfaceType, mergedDescriptor);
+      return this;
+    }
+
     public Builder putCustomConversion(DexType dexType, DexType conversionType) {
       put(
           customConversions,
@@ -482,11 +559,6 @@
       return this;
     }
 
-    public Builder addDontRewriteInvocation(DexMethod dontRewrite) {
-      dontRewriteInvocation.add(dontRewrite);
-      return this;
-    }
-
     public Builder addDontRetargetLibMember(DexType dontRetargetLibMember) {
       dontRetarget.add(dontRetargetLibMember);
       return this;
@@ -523,7 +595,6 @@
           ImmutableMap.copyOf(apiGenericTypesConversion),
           ImmutableMap.copyOf(legacyBackport),
           ImmutableMap.copyOf(customConversions),
-          ImmutableSet.copyOf(dontRewriteInvocation),
           ImmutableSet.copyOf(dontRetarget),
           ImmutableMap.copyOf(wrapperConversions),
           ImmutableSet.copyOf(neverOutlineApi),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationFlagDeduplicator.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationFlagDeduplicator.java
index 269be28..cb907d1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationFlagDeduplicator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationFlagDeduplicator.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.ApiLevelRange;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.Reporter;
 import java.util.HashSet;
@@ -88,11 +89,11 @@
     deduplicateRewritePrefix(flags, otherFlags, commonBuilder, builder);
     deduplicateRewriteDifferentPrefix(flags, otherFlags, commonBuilder, builder);
 
-    deduplicateFlags(
+    deduplicateEmulatedInterfaceFlags(
         flags.getEmulatedInterfaces(),
         otherFlags.getEmulatedInterfaces(),
-        commonBuilder::putEmulatedInterface,
-        builder::putEmulatedInterface);
+        commonBuilder::putSpecifiedEmulatedInterface,
+        builder::putSpecifiedEmulatedInterface);
     deduplicateFlags(
         flags.getRetargetMethodToType(),
         otherFlags.getRetargetMethodToType(),
@@ -115,11 +116,6 @@
         builder::putCustomConversion);
 
     deduplicateFlags(
-        flags.getDontRewriteInvocation(),
-        otherFlags.getDontRewriteInvocation(),
-        commonBuilder::addDontRewriteInvocation,
-        builder::addDontRewriteInvocation);
-    deduplicateFlags(
         flags.getDontRetarget(),
         otherFlags.getDontRetarget(),
         commonBuilder::addDontRetargetLibMember,
@@ -214,6 +210,22 @@
   }
 
   @SuppressWarnings("ReferenceEquality")
+  private static <T extends DexItem> void deduplicateEmulatedInterfaceFlags(
+      Map<T, HumanEmulatedInterfaceDescriptor> flags,
+      Map<T, HumanEmulatedInterfaceDescriptor> otherFlags,
+      BiConsumer<T, HumanEmulatedInterfaceDescriptor> common,
+      BiConsumer<T, HumanEmulatedInterfaceDescriptor> specific) {
+    flags.forEach(
+        (k, v) -> {
+          if (otherFlags.get(k) == v) {
+            common.accept(k, v);
+          } else {
+            specific.accept(k, v);
+          }
+        });
+  }
+
+  @SuppressWarnings("ReferenceEquality")
   private static <T extends DexItem> void deduplicateFlags(
       Map<T, DexType> flags,
       Map<T, DexType> otherFlags,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.java
index 2096b33..d5dc102 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.java
@@ -14,8 +14,8 @@
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.CURRENT_HUMAN_CONFIGURATION_FORMAT_VERSION;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.CUSTOM_CONVERSION_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.DONT_RETARGET_KEY;
-import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.DONT_REWRITE_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.DONT_REWRITE_PREFIX_KEY;
+import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.EMULATED_METHODS_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.EMULATE_INTERFACE_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.IDENTIFIER_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.LIBRARY_FLAGS_KEY;
@@ -28,6 +28,7 @@
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.RETARGET_STATIC_FIELD_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.REWRITE_DERIVED_PREFIX_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.REWRITE_PREFIX_KEY;
+import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.REWRITTEN_TYPE_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.SHRINKER_CONFIG_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.SUPPORT_ALL_CALLBACKS_FROM_LIBRARY_KEY;
 import static com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecificationParser.SYNTHESIZED_LIBRARY_CLASSES_PACKAGE_PREFIX_KEY;
@@ -116,10 +117,18 @@
         toJson.put(MAINTAIN_PREFIX_KEY, stringSetToString(flags.getMaintainPrefix()));
       }
       if (!flags.getEmulatedInterfaces().isEmpty()) {
-        toJson.put(EMULATE_INTERFACE_KEY, mapToString(flags.getEmulatedInterfaces()));
-      }
-      if (!flags.getDontRewriteInvocation().isEmpty()) {
-        toJson.put(DONT_REWRITE_KEY, setToString(flags.getDontRewriteInvocation()));
+        TreeMap<String, Map<String, Object>> emulatedInterfaces = new TreeMap<>();
+        flags
+            .getEmulatedInterfaces()
+            .forEach(
+                (itf, descriptor) -> {
+                  TreeMap<String, Object> value = new TreeMap<>();
+                  assert !descriptor.isLegacy();
+                  emulatedInterfaces.put(toString(itf), value);
+                  value.put(REWRITTEN_TYPE_KEY, toString(descriptor.getRewrittenType()));
+                  value.put(EMULATED_METHODS_KEY, setToString(descriptor.getEmulatedMethods()));
+                });
+        toJson.put(EMULATE_INTERFACE_KEY, emulatedInterfaces);
       }
       if (!flags.getRetargetStaticField().isEmpty()) {
         toJson.put(RETARGET_STATIC_FIELD_KEY, mapToString(flags.getRetargetStaticField()));
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsList.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsList.java
index 49ab63a..c050445 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsList.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsList.java
@@ -6,22 +6,20 @@
 
 import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ProgramResourceProvider;
 import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.StringResource;
 import com.android.tools.r8.Version;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.Reporter;
-import com.android.tools.r8.utils.ThreadUtils;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
-import java.util.concurrent.ExecutorService;
 
-@Keep
+@KeepForApi
 public class DesugaredMethodsList extends GenerateDesugaredLibraryLintFiles {
 
   private final AndroidApiLevel minApi;
@@ -51,23 +49,18 @@
       System.out.println("DesugaredMethodsList " + Version.getVersionString());
       return;
     }
-    ExecutorService executorService = ThreadUtils.getExecutorService(ThreadUtils.NOT_SPECIFIED);
-    try {
-      ExceptionUtils.withD8CompilationHandler(
-          command.getReporter(),
-          () ->
-              new DesugaredMethodsList(
-                      command.getMinApi(),
-                      command.isAndroidPlatformBuild(),
-                      command.getReporter(),
-                      command.getDesugarLibrarySpecification(),
-                      command.getDesugarLibraryImplementation(),
-                      command.getOutputConsumer(),
-                      command.getLibrary())
-                  .run());
-    } finally {
-      executorService.shutdown();
-    }
+    ExceptionUtils.withD8CompilationHandler(
+        command.getReporter(),
+        () ->
+            new DesugaredMethodsList(
+                    command.getMinApi(),
+                    command.isAndroidPlatformBuild(),
+                    command.getReporter(),
+                    command.getDesugarLibrarySpecification(),
+                    command.getDesugarLibraryImplementation(),
+                    command.getOutputConsumer(),
+                    command.getLibrary())
+                .run());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsListCommand.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsListCommand.java
index f5152cb..1eb157f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsListCommand.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/DesugaredMethodsListCommand.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.ArchiveProgramResourceProvider;
 import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ParseFlagInfo;
 import com.android.tools.r8.ParseFlagInfoImpl;
 import com.android.tools.r8.ParseFlagPrinter;
@@ -16,6 +15,7 @@
 import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.StringResource;
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.StringDiagnostic;
@@ -28,7 +28,7 @@
 import java.util.Collection;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public class DesugaredMethodsListCommand {
 
   private final boolean help;
@@ -131,7 +131,7 @@
     return new Builder(diagnosticsHandler);
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private int minApi = AndroidApiLevel.B.getLevel();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/EmulatedInterfaceDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/EmulatedInterfaceDescriptor.java
index 80ca5b3..e3a9dff 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/EmulatedInterfaceDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/EmulatedInterfaceDescriptor.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
+import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import java.util.Objects;
 
@@ -34,6 +35,18 @@
     return emulatedMethods;
   }
 
+  public EmulatedInterfaceDescriptor merge(EmulatedInterfaceDescriptor other) {
+    if (!rewrittenType.isIdenticalTo(other.getRewrittenType())) {
+      throw new UnsupportedOperationException(
+          "Emulated interface descriptor can only be merged on the same rewritten type.");
+    }
+    ImmutableMap.Builder<DexMethod, EmulatedDispatchMethodDescriptor> builder =
+        ImmutableMap.builder();
+    builder.putAll(getEmulatedMethods());
+    builder.putAll(other.getEmulatedMethods());
+    return new EmulatedInterfaceDescriptor(rewrittenType, builder.build());
+  }
+
   @Override
   public Object[] toJsonStruct(
       MultiAPILevelMachineDesugaredLibrarySpecificationJsonExporter exporter) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
index d27ba9b..f28dae7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
@@ -362,8 +362,8 @@
         emulatedVirtualRetargetThroughEmulatedInterface = ImmutableMap.builder();
     private final ImmutableMap.Builder<DexMethod, DexMethod[]> apiGenericTypesConversion =
         ImmutableMap.builder();
-    private final ImmutableMap.Builder<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces =
-        ImmutableMap.builder();
+    private final Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces =
+        new IdentityHashMap<>();
     private final LinkedHashMap<DexType, WrapperDescriptor> wrappers = new LinkedHashMap<>();
     private final ImmutableMap.Builder<DexType, DexType> legacyBackport = ImmutableMap.builder();
     private final ImmutableSet.Builder<DexType> dontRetarget = ImmutableSet.builder();
@@ -409,8 +409,12 @@
       nonEmulatedVirtualRetarget.put(src, dest);
     }
 
-    public void putEmulatedInterface(DexType src, EmulatedInterfaceDescriptor descriptor) {
-      emulatedInterfaces.put(src, descriptor);
+    public void putEmulatedInterface(DexType src, EmulatedInterfaceDescriptor newDescriptor) {
+      assert newDescriptor != null;
+      EmulatedInterfaceDescriptor oldDescriptor = emulatedInterfaces.get(src);
+      EmulatedInterfaceDescriptor mergedDescriptor =
+          oldDescriptor == null ? newDescriptor : newDescriptor.merge(oldDescriptor);
+      emulatedInterfaces.put(src, mergedDescriptor);
     }
 
     public void putEmulatedVirtualRetarget(DexMethod src, EmulatedDispatchMethodDescriptor dest) {
@@ -487,7 +491,7 @@
           emulatedVirtualRetarget.build(),
           emulatedVirtualRetargetThroughEmulatedInterface.build(),
           apiGenericTypesConversion.build(),
-          emulatedInterfaces.build(),
+          ImmutableMap.copyOf(emulatedInterfaces),
           wrappers,
           legacyBackport.build(),
           dontRetarget.build(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineEmulatedInterfaceConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineEmulatedInterfaceConverter.java
index 6cb30a4..c908340 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineEmulatedInterfaceConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineEmulatedInterfaceConverter.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedInterfaceDescriptor;
@@ -43,9 +44,9 @@
       AppInfoWithClassHierarchy appInfo,
       MachineRewritingFlags.Builder builder,
       BiConsumer<String, Set<? extends DexReference>> warnConsumer) {
-    Map<DexType, DexType> emulateInterfaces = rewritingFlags.getEmulatedInterfaces();
-    Set<DexMethod> dontRewriteInvocation = rewritingFlags.getDontRewriteInvocation();
-    processEmulatedInterfaceHierarchy(appInfo, emulateInterfaces);
+    Map<DexType, HumanEmulatedInterfaceDescriptor> emulateInterfaces =
+        rewritingFlags.getEmulatedInterfaces();
+    processEmulatedInterfaceHierarchy(appInfo, emulateInterfaces.keySet());
     for (DexType itf : emulateInterfaces.keySet()) {
       DexClass itfClass = appInfo.contextIndependentDefinitionFor(itf);
       if (itfClass == null) {
@@ -53,15 +54,20 @@
         continue;
       }
       Map<DexMethod, EmulatedDispatchMethodDescriptor> emulatedMethods = new IdentityHashMap<>();
+      HumanEmulatedInterfaceDescriptor humanDescriptor = emulateInterfaces.get(itf);
       itfClass.forEachClassMethodMatching(
-          m -> m.isDefaultMethod() && !dontRewriteInvocation.contains(m.getReference()),
+          m ->
+              m.isDefaultMethod()
+                  && humanDescriptor.containsEmulatedMethod(
+                      m.getReference(), appInfo.dexItemFactory()),
           method ->
               emulatedMethods.put(
                   method.getReference(),
                   computeEmulatedDispatchDescriptor(
                       method.getReference(), rewritingFlags, appInfo)));
       builder.putEmulatedInterface(
-          itf, new EmulatedInterfaceDescriptor(emulateInterfaces.get(itf), emulatedMethods));
+          itf,
+          new EmulatedInterfaceDescriptor(humanDescriptor.getRewrittenType(), emulatedMethods));
     }
     warnConsumer.accept("Missing emulated interfaces: ", missingEmulatedInterface);
   }
@@ -74,7 +80,10 @@
         appInfo
             .dexItemFactory()
             .createMethod(
-                rewritingFlags.getEmulatedInterfaces().get(method.getHolderType()),
+                rewritingFlags
+                    .getEmulatedInterfaces()
+                    .get(method.getHolderType())
+                    .getRewrittenType(),
                 method.getProto(),
                 method.getName());
     DerivedMethod interfaceMethod = new DerivedMethod(itfDexMethod);
@@ -148,9 +157,9 @@
   }
 
   private void processEmulatedInterfaceHierarchy(
-      AppInfoWithClassHierarchy appInfo, Map<DexType, DexType> emulateInterfaces) {
+      AppInfoWithClassHierarchy appInfo, Set<DexType> emulateInterfaces) {
     Set<DexType> processed = Sets.newIdentityHashSet();
-    ArrayList<DexType> emulatedInterfacesSorted = new ArrayList<>(emulateInterfaces.keySet());
+    ArrayList<DexType> emulatedInterfacesSorted = new ArrayList<>(emulateInterfaces);
     emulatedInterfacesSorted.sort(DexType::compareTo);
     for (DexType interfaceType : emulatedInterfacesSorted) {
       processEmulatedInterfaceHierarchy(appInfo, emulateInterfaces, interfaceType, processed);
@@ -159,7 +168,7 @@
 
   private void processEmulatedInterfaceHierarchy(
       AppInfoWithClassHierarchy appInfo,
-      Map<DexType, DexType> emulateInterfaces,
+      Set<DexType> emulateInterfaces,
       DexType interfaceType,
       Set<DexType> processed) {
     if (processed.contains(interfaceType)) {
@@ -175,7 +184,7 @@
         WorkList.newIdentityWorkList(Arrays.asList(theInterface.interfaces.values));
     while (!workList.isEmpty()) {
       DexType next = workList.next();
-      if (emulateInterfaces.containsKey(next)) {
+      if (emulateInterfaces.contains(next)) {
         processEmulatedInterfaceHierarchy(appInfo, emulateInterfaces, next, processed);
         emulatedInterfaceHierarchy.get(next).add(interfaceType);
         DexClass nextClass = appInfo.definitionFor(next);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
index ae3214b..d7bef31 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.ImmutableMap;
@@ -120,8 +121,10 @@
         });
   }
 
-  private void rewriteEmulatedInterface(Map<DexType, DexType> emulateLibraryInterface) {
-    emulateLibraryInterface.forEach(builder::rewriteDerivedTypeOnly);
+  private void rewriteEmulatedInterface(
+      Map<DexType, HumanEmulatedInterfaceDescriptor> emulateLibraryInterface) {
+    emulateLibraryInterface.forEach(
+        (k, v) -> builder.rewriteDerivedTypeOnly(k, v.getRewrittenType()));
   }
 
   private void rewriteValues(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineRetargetConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineRetargetConverter.java
index 1197688..9eaeb9d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineRetargetConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineRetargetConverter.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
@@ -248,7 +249,8 @@
       AppInfoWithClassHierarchy appInfo,
       HumanRewritingFlags humanRewritingFlags) {
     // Answers true if this method is already managed through emulated interface dispatch.
-    Map<DexType, DexType> emulateLibraryInterface = humanRewritingFlags.getEmulatedInterfaces();
+    Map<DexType, HumanEmulatedInterfaceDescriptor> emulateLibraryInterface =
+        humanRewritingFlags.getEmulatedInterfaces();
     if (emulateLibraryInterface.isEmpty()) {
       return false;
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
index 5feb934..c36af1c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.ApiLevelRange;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags.HumanEmulatedInterfaceDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanTopLevelFlags;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.MultiAPILevelHumanDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.MultiAPILevelHumanDesugaredLibrarySpecificationFlagDeduplicator;
@@ -32,6 +33,7 @@
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -201,7 +203,12 @@
     flags
         .getRewritePrefix()
         .forEach((prefix, rewritten) -> rewritePrefix(builder, prefix, rewritten));
-    flags.getEmulateLibraryInterface().forEach(builder::putEmulatedInterface);
+    flags
+        .getEmulateLibraryInterface()
+        .forEach(
+            (type, rewrittenType) ->
+                convertEmulatedInterface(
+                    builder, app, type, rewrittenType, flags.getDontRewriteInvocation()));
     flags.getBackportCoreLibraryMember().forEach(builder::putLegacyBackport);
     flags.getCustomConversions().forEach(builder::putCustomConversion);
     flags.getDontRetargetLibMember().forEach(builder::addDontRetargetLibMember);
@@ -209,14 +216,27 @@
     flags
         .getRetargetCoreLibMember()
         .forEach((name, typeMap) -> convertRetargetCoreLibMember(builder, app, name, typeMap));
-    flags
-        .getDontRewriteInvocation()
-        .forEach(pair -> convertDontRewriteInvocation(builder, app, pair));
     HumanRewritingFlags humanFlags = builder.build();
     timing.end();
     return humanFlags;
   }
 
+  private void convertEmulatedInterface(
+      HumanRewritingFlags.Builder builder,
+      DexApplication app,
+      DexType type,
+      DexType rewrittenType,
+      List<Pair<DexType, DexString>> dontRewriteInvocation) {
+    DexClass dexClass = app.definitionFor(type);
+    Set<DexMethod> emulatedMethods = Sets.newIdentityHashSet();
+    Set<DexMethod> dontRewrite = convertDontRewriteInvocation(builder, app, dontRewriteInvocation);
+    dexClass
+        .virtualMethods(m -> m.isDefaultMethod() && !dontRewrite.contains(m.getReference()))
+        .forEach(m -> emulatedMethods.add(m.getReference()));
+    builder.putSpecifiedEmulatedInterface(
+        type, new HumanEmulatedInterfaceDescriptor(rewrittenType, emulatedMethods));
+  }
+
   private void rewritePrefix(HumanRewritingFlags.Builder builder, String prefix, String rewritten) {
     // Legacy hacks: The human specification matches on class' types so we need different
     // rewritings.
@@ -239,15 +259,21 @@
     builder.putRewritePrefix(prefix, rewritten);
   }
 
-  private void convertDontRewriteInvocation(
-      HumanRewritingFlags.Builder builder, DexApplication app, Pair<DexType, DexString> pair) {
-    DexClass dexClass = app.definitionFor(pair.getFirst());
-    assert dexClass != null;
-    List<DexClassAndMethod> methodsWithName =
-        findMethodsWithName(pair.getSecond(), dexClass, builder, app);
-    for (DexClassAndMethod dexClassAndMethod : methodsWithName) {
-      builder.addDontRewriteInvocation(dexClassAndMethod.getReference());
+  private Set<DexMethod> convertDontRewriteInvocation(
+      HumanRewritingFlags.Builder builder,
+      DexApplication app,
+      List<Pair<DexType, DexString>> dontRewriteInvocation) {
+    Set<DexMethod> result = Sets.newIdentityHashSet();
+    for (Pair<DexType, DexString> pair : dontRewriteInvocation) {
+      DexClass dexClass = app.definitionFor(pair.getFirst());
+      assert dexClass != null;
+      List<DexClassAndMethod> methodsWithName =
+          findMethodsWithName(pair.getSecond(), dexClass, builder, app);
+      for (DexClassAndMethod dexClassAndMethod : methodsWithName) {
+        result.add(dexClassAndMethod.getReference());
+      }
     }
+    return result;
   }
 
   @SuppressWarnings("MixedMutabilityReturnType")
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterDiagnostic.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterDiagnostic.java
index ce17cc0..dddbe5e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterDiagnostic.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.ir.optimize;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class ServiceLoaderRewriterDiagnostic implements Diagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
index 21fca73..9617c85 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
@@ -67,7 +67,10 @@
   }
 
   private MutableFieldOptimizationInfo setAbstractValue(AbstractValue abstractValue) {
-    assert getAbstractValue().isUnknown() || abstractValue.isNonTrivial();
+    assert getAbstractValue().isUnknown()
+        || abstractValue.isNonTrivial()
+        || (getAbstractValue().isNullOrAbstractValue()
+            && getAbstractValue().asNullOrAbstractValue().getNonNullValue().isSingleFieldValue());
     this.abstractValue = abstractValue;
     return this;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningDiagnostic.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningDiagnostic.java
index 9d0e1d1..12a82bb 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningDiagnostic.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.ir.optimize.inliner;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class WhyAreYouNotInliningDiagnostic implements Diagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/APIConversionCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/APIConversionCfCodeProvider.java
index 9bd1ba2..1233526 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/APIConversionCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/APIConversionCfCodeProvider.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.cf.code.CfLoad;
 import com.android.tools.r8.cf.code.CfReturn;
 import com.android.tools.r8.cf.code.CfReturnVoid;
+import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexField;
@@ -94,7 +95,7 @@
     generatePushReceiver(instructions, isStatic);
     generateParameterConvertAndLoads(instructions, isStatic);
     generateForwardingCall(instructions);
-    generateReturnConversion(instructions);
+    generateReturnConversion(instructions, isStatic);
     generateReturn(instructions);
     return standardCfCodeFromInstructions(instructions);
   }
@@ -108,12 +109,29 @@
     }
   }
 
-  private void generateReturnConversion(List<CfInstruction> instructions) {
+  private void generateReturnConversion(List<CfInstruction> instructions, boolean isStatic) {
     if (returnConversion != null) {
-      instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, returnConversion, false));
+      generateConversion(instructions, returnConversion, isStatic);
     }
   }
 
+  private void generateConversion(
+      List<CfInstruction> instructions, DexMethod conversion, boolean isStatic) {
+    if (conversion.getArity() == 2) {
+      // If there is a second parameter, D8/R8 passes the  receiver as the second parameter.
+      if (isStatic) {
+        throw new CompilationError("Unsupported conversion with two parameters on static method");
+      }
+      generatePushReceiver(instructions, isStatic);
+    } else if (conversion.getArity() != 1) {
+      throw new CompilationError(
+          "Unsupported conversion with invalid number of parameters ("
+              + conversion.getArity()
+              + ")");
+    }
+    instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, conversion, false));
+  }
+
   private void generateForwardingCall(List<CfInstruction> instructions) {
     instructions.add(new CfInvoke(forwardCallOpcode, forwardMethod, itfCall));
   }
@@ -125,7 +143,7 @@
       ValueType valueType = valueTypeFromForwardMethod(forwardMethod.getParameter(i));
       instructions.add(new CfLoad(valueType, localIndex));
       if (parameterConversions[i] != null) {
-        instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, parameterConversions[i], false));
+        generateConversion(instructions, parameterConversions[i], isStatic);
       }
       localIndex += valueType.isWide() ? 2 : 1;
     }
diff --git a/src/main/java/com/android/tools/r8/naming/MapVersion.java b/src/main/java/com/android/tools/r8/naming/MapVersion.java
index 0698a2e..2b3b13b 100644
--- a/src/main/java/com/android/tools/r8/naming/MapVersion.java
+++ b/src/main/java/com/android/tools/r8/naming/MapVersion.java
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.mappinginformation.MapVersionMappingInformation;
 import com.android.tools.r8.utils.structural.Ordered;
 
-@Keep
+@KeepForApi
 public enum MapVersion implements Ordered<MapVersion> {
   MAP_VERSION_UNKNOWN("unknown"),
   MAP_VERSION_NONE("none"),
diff --git a/src/main/java/com/android/tools/r8/naming/MappingComposeException.java b/src/main/java/com/android/tools/r8/naming/MappingComposeException.java
index f443d0e..33c3382 100644
--- a/src/main/java/com/android/tools/r8/naming/MappingComposeException.java
+++ b/src/main/java/com/android/tools/r8/naming/MappingComposeException.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.naming;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public class MappingComposeException extends Exception {
 
   public MappingComposeException(String message) {
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformationDiagnostics.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformationDiagnostics.java
index cc0da51..fb06257 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformationDiagnostics.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/MappingInformationDiagnostics.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.naming.mappinginformation;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.position.TextPosition;
 
-@Keep
+@KeepForApi
 public class MappingInformationDiagnostics implements Diagnostic {
 
   private final String message;
diff --git a/src/main/java/com/android/tools/r8/origin/ArchiveEntryOrigin.java b/src/main/java/com/android/tools/r8/origin/ArchiveEntryOrigin.java
index 37ae662..2deafeb 100644
--- a/src/main/java/com/android/tools/r8/origin/ArchiveEntryOrigin.java
+++ b/src/main/java/com/android/tools/r8/origin/ArchiveEntryOrigin.java
@@ -4,12 +4,10 @@
 
 package com.android.tools.r8.origin;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-/**
- * Origin representing an entry in an archive.
- */
-@Keep
+/** Origin representing an entry in an archive. */
+@KeepForApi
 public class ArchiveEntryOrigin extends Origin {
 
   final String entryName;
diff --git a/src/main/java/com/android/tools/r8/origin/Origin.java b/src/main/java/com/android/tools/r8/origin/Origin.java
index 0f3d320..9f05156 100644
--- a/src/main/java/com/android/tools/r8/origin/Origin.java
+++ b/src/main/java/com/android/tools/r8/origin/Origin.java
@@ -4,26 +4,26 @@
 
 package com.android.tools.r8.origin;
 
-import com.android.tools.r8.KeepForSubclassing;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * Origin description of a resource.
  *
- * <p>An origin is a list of parts that describe where a resource originates from. The first part
- * is the most recent part and is associated with the present resource, each successive part is
- * then associated with the context of the previous part.
+ * <p>An origin is a list of parts that describe where a resource originates from. The first part is
+ * the most recent part and is associated with the present resource, each successive part is then
+ * associated with the context of the previous part.
  *
- * <p>For example, for a class file, say {@code my/class/Foo.class}, that is contained within a
- * jar archive, say {@code myjar.jar}, the Origin of of this resource will be {@code
+ * <p>For example, for a class file, say {@code my/class/Foo.class}, that is contained within a jar
+ * archive, say {@code myjar.jar}, the Origin of of this resource will be {@code
  * myjar.jar:my/class/Foo.class} where each part is separated by a colon.
  *
  * <p>There are two top-most origins which have no parent: {@code Origin.root()} and {@code
  * Origin.unknown()}. The former is the parent of any file path, while the latter is an unknown
  * origin (e.g., for generated resources of raw bytes).
  */
-@KeepForSubclassing
+@KeepForApi
 public abstract class Origin implements Comparable<Origin> {
 
   private static final Origin ROOT =
diff --git a/src/main/java/com/android/tools/r8/origin/PathOrigin.java b/src/main/java/com/android/tools/r8/origin/PathOrigin.java
index 0ff8080..491b5de 100644
--- a/src/main/java/com/android/tools/r8/origin/PathOrigin.java
+++ b/src/main/java/com/android/tools/r8/origin/PathOrigin.java
@@ -4,13 +4,11 @@
 
 package com.android.tools.r8.origin;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.nio.file.Path;
 
-/**
- * Path component in an origin description.
- */
-@Keep
+/** Path component in an origin description. */
+@KeepForApi
 public class PathOrigin extends Origin {
 
   private final Path path;
diff --git a/src/main/java/com/android/tools/r8/position/MethodPosition.java b/src/main/java/com/android/tools/r8/position/MethodPosition.java
index 12a7d8d..efb4226 100644
--- a/src/main/java/com/android/tools/r8/position/MethodPosition.java
+++ b/src/main/java/com/android/tools/r8/position/MethodPosition.java
@@ -3,17 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.position;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.TypeReference;
 import java.util.List;
 import java.util.stream.Collectors;
 
 /** A {@link Position} denoting a method. */
-@Keep
+@KeepForApi
 public class MethodPosition implements Position {
 
   private final MethodReference method;
diff --git a/src/main/java/com/android/tools/r8/position/Position.java b/src/main/java/com/android/tools/r8/position/Position.java
index 1fae6e6..cd77f3c 100644
--- a/src/main/java/com/android/tools/r8/position/Position.java
+++ b/src/main/java/com/android/tools/r8/position/Position.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.position;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * Represent a position in a resource, it can for example be line in a text file or the byte offset
  * in a binary stream.
  */
-@Keep
+@KeepForApi
 public interface Position {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/position/TextPosition.java b/src/main/java/com/android/tools/r8/position/TextPosition.java
index 730bd75..3b4a69e 100644
--- a/src/main/java/com/android/tools/r8/position/TextPosition.java
+++ b/src/main/java/com/android/tools/r8/position/TextPosition.java
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.position;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
- * A {@link Position} in a text file determined by line and column.
- * Line and column numbers start at 1.
+ * A {@link Position} in a text file determined by line and column. Line and column numbers start at
+ * 1.
  */
-@Keep
+@KeepForApi
 public class TextPosition implements Position {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/position/TextRange.java b/src/main/java/com/android/tools/r8/position/TextRange.java
index 62c5c39..ed69268 100644
--- a/src/main/java/com/android/tools/r8/position/TextRange.java
+++ b/src/main/java/com/android/tools/r8/position/TextRange.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.position;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public class TextRange implements Position {
   private final TextPosition start;
   private final TextPosition end;
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
index 57a7856..20f9443 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.TextInputStream;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.function.Consumer;
 
 /** API for building an ART profile. */
-@Keep
+@KeepForApi
 public interface ArtProfileBuilder {
 
   /** API for adding information about a class rule to the compiler. */
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
index eaeab93..a5259f9 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
 /** API for defining a class rule for an ART profile. */
-@Keep
+@KeepForApi
 public interface ArtProfileClassRuleBuilder {
 
   ArtProfileClassRuleBuilder setClassReference(ClassReference classReference);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
index 7ba6bbe..6dcde1d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleInfo.java
@@ -4,7 +4,8 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
 
-@Keep
+@KeepForApi(kind = KeepItemKind.ONLY_CLASS)
 public interface ArtProfileClassRuleInfo {}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
index b395a12..d1ea7f8 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
@@ -5,14 +5,14 @@
 package com.android.tools.r8.profile.art;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.TextOutputStream;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * API for consuming an ART profile provided by the compiler, which has been rewritten to match the
  * residual, optimized app.
  */
-@Keep
+@KeepForApi
 public interface ArtProfileConsumer {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
index 4bae3b3..d8c15c6 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 import java.util.function.Consumer;
 
 /** API for defining a method rule for an ART profile. */
-@Keep
+@KeepForApi
 public interface ArtProfileMethodRuleBuilder {
 
   ArtProfileMethodRuleBuilder setMethodReference(MethodReference methodReference);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfo.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfo.java
index 6a176ab..ddf9a92 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfo.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfo.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface ArtProfileMethodRuleInfo {
 
   /** Returns true if this method rule method rule is flagged as hot ('H'). */
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
index 11f8b42..13f122c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** API for providing metadata related to a method rule for an ART profile. */
-@Keep
+@KeepForApi
 public interface ArtProfileMethodRuleInfoBuilder {
 
   ArtProfileMethodRuleInfoBuilder setIsHot(boolean isHot);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java
index 87450e5..0192f9c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.Resource;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** API for providing an ART profile to the compiler. */
-@Keep
+@KeepForApi
 public interface ArtProfileProvider extends Resource {
 
   void getArtProfile(ArtProfileBuilder profileBuilder);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
index beab144..d5b349c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 
@@ -13,7 +13,7 @@
  * #acceptClassRule} and {@link #acceptMethodRule} for each class and method rule (respectively) in
  * the profile.
  */
-@Keep
+@KeepForApi
 public interface ArtProfileRuleConsumer {
 
   /** Provides information about a specific class rule to the consumer. */
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRulePredicate.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRulePredicate.java
index ea843f2..3fc6194 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRulePredicate.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRulePredicate.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public interface ArtProfileRulePredicate {
 
   boolean testClassRule(ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo);
diff --git a/src/main/java/com/android/tools/r8/profile/art/HumanReadableArtProfileParserBuilder.java b/src/main/java/com/android/tools/r8/profile/art/HumanReadableArtProfileParserBuilder.java
index 9caa97e..e8b58dd 100644
--- a/src/main/java/com/android/tools/r8/profile/art/HumanReadableArtProfileParserBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/HumanReadableArtProfileParserBuilder.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.profile.art;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * A builder for configuring a parser for the human-readable ART profile format.
@@ -12,7 +12,7 @@
  * @see <a href="https://developer.android.com/topic/performance/baselineprofiles">ART Baseline
  *     Profiles</a>
  */
-@Keep
+@KeepForApi
 public interface HumanReadableArtProfileParserBuilder {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/profile/art/diagnostic/HumanReadableArtProfileParserErrorDiagnostic.java b/src/main/java/com/android/tools/r8/profile/art/diagnostic/HumanReadableArtProfileParserErrorDiagnostic.java
index d93b5f6..4fba1b9 100644
--- a/src/main/java/com/android/tools/r8/profile/art/diagnostic/HumanReadableArtProfileParserErrorDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/profile/art/diagnostic/HumanReadableArtProfileParserErrorDiagnostic.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.profile.art.diagnostic;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class HumanReadableArtProfileParserErrorDiagnostic implements Diagnostic {
 
   private final String rule;
diff --git a/src/main/java/com/android/tools/r8/references/ArrayReference.java b/src/main/java/com/android/tools/r8/references/ArrayReference.java
index 6699f2b..bcd7a94 100644
--- a/src/main/java/com/android/tools/r8/references/ArrayReference.java
+++ b/src/main/java/com/android/tools/r8/references/ArrayReference.java
@@ -3,15 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 import java.util.Objects;
 
 /** Reference to an array type. */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public final class ArrayReference implements TypeReference {
 
   private final int dimensions;
diff --git a/src/main/java/com/android/tools/r8/references/ClassReference.java b/src/main/java/com/android/tools/r8/references/ClassReference.java
index 392b4a4..08891ae 100644
--- a/src/main/java/com/android/tools/r8/references/ClassReference.java
+++ b/src/main/java/com/android/tools/r8/references/ClassReference.java
@@ -3,13 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 
 /** Reference to a class type or interface type. */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public final class ClassReference implements TypeReference {
 
   private final String descriptor;
diff --git a/src/main/java/com/android/tools/r8/references/FieldReference.java b/src/main/java/com/android/tools/r8/references/FieldReference.java
index 90f4b91..4e09c36 100644
--- a/src/main/java/com/android/tools/r8/references/FieldReference.java
+++ b/src/main/java/com/android/tools/r8/references/FieldReference.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.Objects;
 
 /**
@@ -13,8 +12,7 @@
  * <p>A field reference is always fully qualified with both a qualified holder type as well as the
  * type of the field.
  */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public final class FieldReference {
   private final ClassReference holderClass;
   private final String fieldName;
diff --git a/src/main/java/com/android/tools/r8/references/MethodReference.java b/src/main/java/com/android/tools/r8/references/MethodReference.java
index 3339916..788f1d9 100644
--- a/src/main/java/com/android/tools/r8/references/MethodReference.java
+++ b/src/main/java/com/android/tools/r8/references/MethodReference.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.StringUtils.BraceType;
 import java.util.List;
@@ -16,8 +15,7 @@
  * <p>A method reference is always fully qualified with both a qualified holder type as well as its
  * full list of formal parameters.
  */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public final class MethodReference {
   private final ClassReference holderClass;
   private final String methodName;
diff --git a/src/main/java/com/android/tools/r8/references/PackageReference.java b/src/main/java/com/android/tools/r8/references/PackageReference.java
index 2d1ce52..1bb9752 100644
--- a/src/main/java/com/android/tools/r8/references/PackageReference.java
+++ b/src/main/java/com/android/tools/r8/references/PackageReference.java
@@ -4,14 +4,12 @@
 
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 import java.util.Objects;
 
 /** Reference to a package. */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public class PackageReference {
 
   private final String packageName;
diff --git a/src/main/java/com/android/tools/r8/references/PrimitiveReference.java b/src/main/java/com/android/tools/r8/references/PrimitiveReference.java
index f7fe50a..5b399c4 100644
--- a/src/main/java/com/android/tools/r8/references/PrimitiveReference.java
+++ b/src/main/java/com/android/tools/r8/references/PrimitiveReference.java
@@ -3,12 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public abstract class PrimitiveReference implements TypeReference {
 
   static final PrimitiveReference BOOL =
diff --git a/src/main/java/com/android/tools/r8/references/Reference.java b/src/main/java/com/android/tools/r8/references/Reference.java
index d5071d2..a5d015d 100644
--- a/src/main/java/com/android/tools/r8/references/Reference.java
+++ b/src/main/java/com/android/tools/r8/references/Reference.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.ImmutableList;
 import java.lang.reflect.Constructor;
@@ -23,8 +22,7 @@
  *
  * <p>No guarantees are made on identity and all references must be compared by {@code equals}.
  */
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public final class Reference {
 
   public static PrimitiveReference BOOL = PrimitiveReference.BOOL;
diff --git a/src/main/java/com/android/tools/r8/references/TypeReference.java b/src/main/java/com/android/tools/r8/references/TypeReference.java
index 36099b9..8318760 100644
--- a/src/main/java/com/android/tools/r8/references/TypeReference.java
+++ b/src/main/java/com/android/tools/r8/references/TypeReference.java
@@ -3,12 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.references;
 
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForRetraceApi;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.DescriptorUtils;
 
-@Keep
-@KeepForRetraceApi
+@KeepForApi
 public interface TypeReference {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/relocator/Relocator.java b/src/main/java/com/android/tools/r8/relocator/Relocator.java
index 37abb59..a0824ca 100644
--- a/src/main/java/com/android/tools/r8/relocator/Relocator.java
+++ b/src/main/java/com/android/tools/r8/relocator/Relocator.java
@@ -7,7 +7,6 @@
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
 
 import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.Marker;
 import com.android.tools.r8.dex.Marker.Tool;
@@ -16,6 +15,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.AndroidApp;
@@ -27,7 +27,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 
-@Keep
+@KeepForApi
 public class Relocator {
 
   private Relocator() {}
diff --git a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
index 1684616..312bead 100644
--- a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
+++ b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
@@ -11,9 +11,9 @@
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.references.ClassReference;
@@ -41,7 +41,7 @@
 import java.util.Collection;
 import java.util.Set;
 
-@Keep
+@KeepForApi
 public class RelocatorCommand {
 
   private static final String THREAD_COUNT_FLAG = "--thread-count";
@@ -167,7 +167,7 @@
     return mapping;
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private final AndroidApp.Builder app;
diff --git a/src/main/java/com/android/tools/r8/retrace/FinishedPartitionMappingCallback.java b/src/main/java/com/android/tools/r8/retrace/FinishedPartitionMappingCallback.java
index 6c4c906..40befd9 100644
--- a/src/main/java/com/android/tools/r8/retrace/FinishedPartitionMappingCallback.java
+++ b/src/main/java/com/android/tools/r8/retrace/FinishedPartitionMappingCallback.java
@@ -5,13 +5,13 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /***
  * Interface for registering a callback when a retracing operation is finished.
  */
 @FunctionalInterface
-@Keep
+@KeepForApi
 public interface FinishedPartitionMappingCallback {
 
   FinishedPartitionMappingCallback EMPTY_INSTANCE = diagnosticsHandler -> {};
diff --git a/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java b/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
index 97d77be..1bfd06c 100644
--- a/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
+++ b/src/main/java/com/android/tools/r8/retrace/IllegalClassNameLookupException.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public class IllegalClassNameLookupException extends RuntimeException {
 
   private final String typeName;
diff --git a/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java b/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java
index 86e81e1..c991de0 100644
--- a/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java
+++ b/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public final class InvalidMappingFileException extends RuntimeException {
 
   public InvalidMappingFileException(Throwable throwable) {
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingPartition.java b/src/main/java/com/android/tools/r8/retrace/MappingPartition.java
index a925cc3..dd5b49a 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingPartition.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingPartition.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface MappingPartition {
 
   String getKey();
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java b/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java
index 9b8c0a1..020ccf7 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingPartitionFromKeySupplier.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /***
  * Supplier to provide the bytes for a partition specified by a key. Retrace guarantee that the
@@ -13,7 +13,7 @@
  *
  */
 @FunctionalInterface
-@Keep
+@KeepForApi
 public interface MappingPartitionFromKeySupplier {
 
   byte[] get(String key);
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingPartitionMetadata.java b/src/main/java/com/android/tools/r8/retrace/MappingPartitionMetadata.java
index 32fc36d..146e536 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingPartitionMetadata.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingPartitionMetadata.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface MappingPartitionMetadata {
 
   byte[] getBytes();
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingSupplier.java b/src/main/java/com/android/tools/r8/retrace/MappingSupplier.java
index 598f71f..d5060a2 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingSupplier.java
@@ -5,10 +5,10 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.MappingSupplierInternal;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface MappingSupplier<T extends MappingSupplier<T>>
     extends MappingSupplierBase<T>, MappingSupplierInternal {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java b/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
index ba04547..ce65453 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingSupplierAsync.java
@@ -5,9 +5,9 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface MappingSupplierAsync<T extends MappingSupplierAsync<T>>
     extends MappingSupplierBase<T> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingSupplierBase.java b/src/main/java/com/android/tools/r8/retrace/MappingSupplierBase.java
index 53ed349..36b0d82 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingSupplierBase.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingSupplierBase.java
@@ -6,12 +6,12 @@
 
 import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.Finishable;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public interface MappingSupplierBase<T extends MappingSupplierBase<T>> extends Finishable {
 
   /***
diff --git a/src/main/java/com/android/tools/r8/retrace/MappingSupplierBuilder.java b/src/main/java/com/android/tools/r8/retrace/MappingSupplierBuilder.java
index 2a8a646..523f3aa 100644
--- a/src/main/java/com/android/tools/r8/retrace/MappingSupplierBuilder.java
+++ b/src/main/java/com/android/tools/r8/retrace/MappingSupplierBuilder.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public abstract class MappingSupplierBuilder<
     P extends MappingSupplier<P>, T extends MappingSupplierBuilder<P, T>> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/Partition.java b/src/main/java/com/android/tools/r8/retrace/Partition.java
index 1582b5e..37e4684 100644
--- a/src/main/java/com/android/tools/r8/retrace/Partition.java
+++ b/src/main/java/com/android/tools/r8/retrace/Partition.java
@@ -8,11 +8,11 @@
 import static com.android.tools.r8.utils.ExceptionUtils.withMainProgramHandler;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ParseFlagInfo;
 import com.android.tools.r8.ParseFlagInfoImpl;
 import com.android.tools.r8.ParseFlagPrinter;
 import com.android.tools.r8.Version;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.utils.OptionsParsing;
 import com.android.tools.r8.utils.OptionsParsing.ParseContext;
 import com.android.tools.r8.utils.PartitionMapZipContainer;
@@ -24,7 +24,7 @@
 import java.util.List;
 
 /** A tool for creating a partition-map from a proguard map. */
-@Keep
+@KeepForApi
 public class Partition {
 
   private static final String USAGE_MESSAGE =
diff --git a/src/main/java/com/android/tools/r8/retrace/PartitionCommand.java b/src/main/java/com/android/tools/r8/retrace/PartitionCommand.java
index 3c5db33..ef47fda 100644
--- a/src/main/java/com/android/tools/r8/retrace/PartitionCommand.java
+++ b/src/main/java/com/android/tools/r8/retrace/PartitionCommand.java
@@ -5,10 +5,10 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.PartitionMapConsumer;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public class PartitionCommand {
 
   private final DiagnosticsHandler diagnosticsHandler;
@@ -41,7 +41,7 @@
     return new Builder(new DiagnosticsHandler() {});
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private final DiagnosticsHandler diagnosticsHandler;
diff --git a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
index d89ce17..6b6446d 100644
--- a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplier.java
@@ -5,14 +5,14 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.MapVersion;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.retrace.internal.PartitionMappingSupplierBase;
 
-@Keep
+@KeepForApi
 public class PartitionMappingSupplier extends PartitionMappingSupplierBase<PartitionMappingSupplier>
     implements MappingSupplier<PartitionMappingSupplier> {
 
@@ -41,7 +41,7 @@
    *
    * @param classReference The minified class reference allowed to be lookup up.
    */
-  @Keep
+  @KeepForApi
   @Override
   public PartitionMappingSupplier registerClassUse(
       DiagnosticsHandler diagnosticsHandler, ClassReference classReference) {
@@ -53,7 +53,7 @@
    *
    * @param methodReference The minified method reference allowed to be lookup up.
    */
-  @Keep
+  @KeepForApi
   @Override
   public PartitionMappingSupplier registerMethodUse(
       DiagnosticsHandler diagnosticsHandler, MethodReference methodReference) {
@@ -65,7 +65,7 @@
    *
    * @param fieldReference The minified field reference allowed to be lookup up.
    */
-  @Keep
+  @KeepForApi
   @Override
   public PartitionMappingSupplier registerFieldUse(
       DiagnosticsHandler diagnosticsHandler, FieldReference fieldReference) {
@@ -99,7 +99,7 @@
     return new NoMetadataBuilder(mapVersion);
   }
 
-  @Keep
+  @KeepForApi
   public abstract static class NoMetadataBuilderBase<B extends NoMetadataBuilderBase<B>>
       extends PartitionMappingSupplierBuilderBase<B> {
 
@@ -120,7 +120,7 @@
     }
   }
 
-  @Keep
+  @KeepForApi
   public static class NoMetadataBuilder extends NoMetadataBuilderBase<NoMetadataBuilder> {
 
     private NoMetadataBuilder(MapVersion fallbackMapVersion) {
@@ -147,7 +147,7 @@
     }
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder extends NoMetadataBuilderBase<Builder> {
 
     private byte[] metadata;
diff --git a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierAsync.java b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierAsync.java
index 6c16ab7..5093d80 100644
--- a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierAsync.java
+++ b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierAsync.java
@@ -5,14 +5,14 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.MapVersion;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.retrace.internal.PartitionMappingSupplierBase;
 
-@Keep
+@KeepForApi
 public class PartitionMappingSupplierAsync
     extends PartitionMappingSupplierBase<PartitionMappingSupplierAsync>
     implements MappingSupplierAsync<PartitionMappingSupplierAsync> {
@@ -38,7 +38,6 @@
    *
    * @param classReference The minified class reference allowed to be lookup up.
    */
-  @Keep
   @Override
   public PartitionMappingSupplierAsync registerClassUse(
       DiagnosticsHandler diagnosticsHandler, ClassReference classReference) {
@@ -50,7 +49,6 @@
    *
    * @param methodReference The minified method reference allowed to be lookup up.
    */
-  @Keep
   @Override
   public PartitionMappingSupplierAsync registerMethodUse(
       DiagnosticsHandler diagnosticsHandler, MethodReference methodReference) {
@@ -62,7 +60,6 @@
    *
    * @param fieldReference The minified field reference allowed to be lookup up.
    */
-  @Keep
   @Override
   public PartitionMappingSupplierAsync registerFieldUse(
       DiagnosticsHandler diagnosticsHandler, FieldReference fieldReference) {
@@ -84,7 +81,7 @@
     return createRetracerFromPartitionSupplier(diagnosticsHandler, supplier);
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder extends PartitionMappingSupplierBuilderBase<Builder> {
 
     private byte[] metadata;
diff --git a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierBuilderBase.java b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierBuilderBase.java
index 1dc2e14..c684ddc 100644
--- a/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/retrace/PartitionMappingSupplierBuilderBase.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.naming.MapVersion;
 
-@Keep
+@KeepForApi
 public abstract class PartitionMappingSupplierBuilderBase<
     T extends PartitionMappingSupplierBuilderBase<T>> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java b/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java
index 89c6161..75c5ded 100644
--- a/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java
+++ b/src/main/java/com/android/tools/r8/retrace/PrepareMappingPartitionsCallback.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /***
  * Callback to be called to prepare all partitions registered by
@@ -12,7 +12,7 @@
  * {@link MappingPartitionFromKeySupplier}.
  */
 @FunctionalInterface
-@Keep
+@KeepForApi
 public interface PrepareMappingPartitionsCallback {
 
   PrepareMappingPartitionsCallback EMPTY_INSTANCE = () -> {};
diff --git a/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitioner.java b/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitioner.java
index 5805ae8..541f6da0 100644
--- a/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitioner.java
+++ b/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitioner.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.ProguardMapPartitionerOnClassNameToText.ProguardMapPartitionerBuilderImpl;
 import java.io.IOException;
 
-@Keep
+@KeepForApi
 public interface ProguardMapPartitioner {
 
   MappingPartitionMetadata run() throws IOException;
diff --git a/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitionerBuilder.java b/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitionerBuilder.java
index a7d9df8..ce347be 100644
--- a/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitionerBuilder.java
+++ b/src/main/java/com/android/tools/r8/retrace/ProguardMapPartitionerBuilder.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.function.Consumer;
 
-@Keep
+@KeepForApi
 public interface ProguardMapPartitionerBuilder<
     B extends ProguardMapPartitionerBuilder<B, P>, P extends ProguardMapPartitioner> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/ProguardMapProducer.java b/src/main/java/com/android/tools/r8/retrace/ProguardMapProducer.java
index 6e73c56..679e93c 100644
--- a/src/main/java/com/android/tools/r8/retrace/ProguardMapProducer.java
+++ b/src/main/java/com/android/tools/r8/retrace/ProguardMapProducer.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.google.common.primitives.Bytes;
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
@@ -16,7 +16,7 @@
 import java.nio.file.Path;
 
 /** Interface for producing a string format of a mapping file. */
-@Keep
+@KeepForApi
 public interface ProguardMapProducer {
 
   InputStream get() throws IOException;
diff --git a/src/main/java/com/android/tools/r8/retrace/ProguardMappingSupplier.java b/src/main/java/com/android/tools/r8/retrace/ProguardMappingSupplier.java
index 7b3e657..5edd21f 100644
--- a/src/main/java/com/android/tools/r8/retrace/ProguardMappingSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/ProguardMappingSupplier.java
@@ -4,17 +4,17 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.ProguardMappingSupplierBuilderImpl;
 
-@Keep
+@KeepForApi
 public abstract class ProguardMappingSupplier implements MappingSupplier<ProguardMappingSupplier> {
 
   public static Builder builder() {
     return new ProguardMappingSupplierBuilderImpl();
   }
 
-  @Keep
+  @KeepForApi
   public abstract static class Builder
       extends MappingSupplierBuilder<ProguardMappingSupplier, Builder> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java b/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java
index e411883..76dc9c8 100644
--- a/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java
+++ b/src/main/java/com/android/tools/r8/retrace/RegisterMappingPartitionCallback.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /***
  * Interface for registering a mapping partition to be used later.
  */
 @FunctionalInterface
-@Keep
+@KeepForApi
 public interface RegisterMappingPartitionCallback {
 
   RegisterMappingPartitionCallback EMPTY_INSTANCE = key -> {};
diff --git a/src/main/java/com/android/tools/r8/retrace/Retrace.java b/src/main/java/com/android/tools/r8/retrace/Retrace.java
index 4646f16..933b60a 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -8,11 +8,11 @@
 
 import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ParseFlagInfo;
 import com.android.tools.r8.ParseFlagInfoImpl;
 import com.android.tools.r8.ParseFlagPrinter;
 import com.android.tools.r8.Version;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.RetraceAbortException;
 import com.android.tools.r8.retrace.internal.RetraceBase;
 import com.android.tools.r8.retrace.internal.StackTraceElementStringProxy;
@@ -44,7 +44,7 @@
  * <p>This is the interface for getting de-obfuscating stack traces, similar to the proguard retrace
  * tool.
  */
-@Keep
+@KeepForApi
 public class Retrace<T, ST extends StackTraceElementProxy<T, ST>> extends RetraceBase<T, ST> {
 
   private static final String USAGE_MESSAGE =
@@ -426,7 +426,7 @@
     return new Builder<>();
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder<T, ST extends StackTraceElementProxy<T, ST>>
       extends RetraceBuilderBase<Builder<T, ST>, T, ST> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceAsync.java b/src/main/java/com/android/tools/r8/retrace/RetraceAsync.java
index 00e07bd..90afa4f 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceAsync.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceAsync.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.RetraceBase;
 import java.util.List;
 
 /** An async retrace tool for obfuscated stack traces. */
-@Keep
+@KeepForApi
 public class RetraceAsync<T, ST extends StackTraceElementProxy<T, ST>> extends RetraceBase<T, ST> {
 
   private final MappingSupplierAsync<?> mappingSupplier;
@@ -97,7 +97,7 @@
             context);
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder<T, ST extends StackTraceElementProxy<T, ST>>
       extends RetraceBuilderBase<Builder<T, ST>, T, ST> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceAsyncAction.java b/src/main/java/com/android/tools/r8/retrace/RetraceAsyncAction.java
index a6088e8..8a7c41b 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceAsyncAction.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceAsyncAction.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceAsyncAction {
 
   void execute(MappingPartitionFromKeySupplier supplier);
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceAsyncResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceAsyncResult.java
index 146c3df..2e663a1 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceAsyncResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceAsyncResult.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceAsyncResult<T> {
 
   T getResult(MappingPartitionFromKeySupplier supplier);
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceBuilderBase.java b/src/main/java/com/android/tools/r8/retrace/RetraceBuilderBase.java
index 1deadfe..b4fd983 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceBuilderBase.java
@@ -5,9 +5,9 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public abstract class RetraceBuilderBase<
     B extends RetraceBuilderBase<B, T, ST>, T, ST extends StackTraceElementProxy<T, ST>> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
index f7830c3..2dbe0f0 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.TypeReference;
 import java.util.List;
 import java.util.OptionalInt;
 
-@Keep
+@KeepForApi
 public interface RetraceClassElement extends RetraceElement<RetraceClassResult> {
 
   RetracedClassReference getRetracedClass();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
index c2bd31a..7ff088e 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.TypeReference;
 import java.util.List;
 import java.util.OptionalInt;
 
-@Keep
+@KeepForApi
 public interface RetraceClassResult extends RetraceResult<RetraceClassElement> {
 
   RetraceFieldResult lookupField(String fieldName);
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java b/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
index c491aba..c4ccca6 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
@@ -5,13 +5,13 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.StackTraceRegularExpressionParser;
 import com.android.tools.r8.utils.Box;
 import java.util.List;
 import java.util.function.Consumer;
 
-@Keep
+@KeepForApi
 public class RetraceCommand {
 
   private final StackTraceSupplier stackTraceSupplier;
@@ -72,7 +72,7 @@
     return new Builder(new DiagnosticsHandler() {});
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private boolean isVerbose;
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceElement.java
index d069fcc..916d4a6 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceElement.java
@@ -3,14 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.KeepForSubclassing;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * Base interface for any element in a retrace result.
  *
  * <p>The element represents an unambiguous retracing.
  */
-@KeepForSubclassing
+@KeepForApi
 public interface RetraceElement<R extends RetraceResult<?>> {
 
   R getParentResult();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java b/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java
index 94b61ee..2c03560 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFailedException.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * Exception thrown when retrace failed to complete because of errors previously reported through
  * {@link com.android.tools.r8.DiagnosticsHandler}.
  */
-@Keep
+@KeepForApi
 public class RetraceFailedException extends Exception {
 
   public RetraceFailedException() {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
index d51e175..d722b04 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceFieldElement extends RetraceElement<RetraceFieldResult> {
 
   boolean isUnknown();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
index 0dc3cc5..9fcc57b 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceFieldResult extends RetraceResult<RetraceFieldElement> {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
index a985fe1..d03c075 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
-@Keep
+@KeepForApi
 public interface RetraceFrameElement extends RetraceElement<RetraceFrameResult> {
 
   boolean isUnknown();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
index bfe0967..ea18505 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceFrameResult extends RetraceResult<RetraceFrameElement> {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java
index ace1b86..53a9e1c 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidRewriteFrameDiagnostics.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class RetraceInvalidRewriteFrameDiagnostics implements Diagnostic {
 
   private final int numberOfFramesToRemove;
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceInvalidStackTraceLineDiagnostics.java b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidStackTraceLineDiagnostics.java
index e18c6e6..cd6f603 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceInvalidStackTraceLineDiagnostics.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceInvalidStackTraceLineDiagnostics.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.position.TextPosition;
 
-@Keep
+@KeepForApi
 public class RetraceInvalidStackTraceLineDiagnostics implements Diagnostic {
 
   private static final String NULL_STACK_TRACE_LINE_MESSAGE = "The stack trace line is <null>";
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
index 132a200..05b946c 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceMethodElement extends RetraceElement<RetraceMethodResult> {
 
   boolean isUnknown();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
index f06fad3..feff0ad 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.OptionalInt;
 
-@Keep
+@KeepForApi
 public interface RetraceMethodResult extends RetraceResult<RetraceMethodElement> {
 
   RetraceFrameResult narrowByPosition(RetraceStackTraceContext context, OptionalInt position);
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceOptions.java b/src/main/java/com/android/tools/r8/retrace/RetraceOptions.java
index 513b39f..3258ac7 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceOptions.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceOptions.java
@@ -7,13 +7,13 @@
 import static com.android.tools.r8.retrace.internal.StackTraceRegularExpressionParser.DEFAULT_REGULAR_EXPRESSION;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * The base options for running retrace with support for continuously retrace strings without
  * parsing the proguard map multiple times.
  */
-@Keep
+@KeepForApi
 public class RetraceOptions {
 
   private final boolean isVerbose;
@@ -72,7 +72,7 @@
     return DEFAULT_REGULAR_EXPRESSION;
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private boolean isVerbose;
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracePartitionException.java b/src/main/java/com/android/tools/r8/retrace/RetracePartitionException.java
index d441e22..c463226 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracePartitionException.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracePartitionException.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public class RetracePartitionException extends RuntimeException {
 
   public RetracePartitionException(String message) {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceResult.java
index cda85ce..dbafd92 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceResult.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Stream;
@@ -17,7 +17,7 @@
  * itself provide methods for providing contextual information to further restrict the ambiguity of
  * the result.
  */
-@Keep
+@KeepForApi
 public interface RetraceResult<E extends RetraceElement<?>> {
 
   /** Basic operation over 'elements' which represent a possible non-ambiguous retracing. */
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceResultWithContext.java b/src/main/java/com/android/tools/r8/retrace/RetraceResultWithContext.java
index 3961591..6c468d4 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceResultWithContext.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceResultWithContext.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceResultWithContext {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResult.java
index b788289..f63e73f 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -17,7 +17,7 @@
  * https://r8.googlesource.com/r8/+/main/doc/retrace.md for what information Retrace uses to discard
  * frames.
  */
-@Keep
+@KeepForApi
 public interface RetraceStackFrameAmbiguousResult<T> {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResultWithContext.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResultWithContext.java
index f856cbd..9d8c1c4 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResultWithContext.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameAmbiguousResultWithContext.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceStackFrameAmbiguousResultWithContext<T>
     extends RetraceStackFrameAmbiguousResult<T>, RetraceResultWithContext {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResult.java
index ac0b6fb..b6a6551 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -14,7 +14,7 @@
  * <p>It is guaranteed to be non-ambiguous. It can have more than one frame if it is an inline or an
  * outline expansion. It can be empty, fx. if the frames are compiler synthesized.
  */
-@Keep
+@KeepForApi
 public interface RetraceStackFrameResult<T> {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResultWithContext.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResultWithContext.java
index 4a63db0..95a0138 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResultWithContext.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackFrameResultWithContext.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceStackFrameResultWithContext<T>
     extends RetraceStackFrameResult<T>, RetraceResultWithContext {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java
index 5af984a..3083865 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceContext.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.RetraceStackTraceContextImpl;
 
-@Keep
+@KeepForApi
 public interface RetraceStackTraceContext {
 
   static RetraceStackTraceContext empty() {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxy.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxy.java
index 714e2b9..c77d194 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxy.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public interface RetraceStackTraceElementProxy<T, ST extends StackTraceElementProxy<T, ST>>
     extends Comparable<RetraceStackTraceElementProxy<T, ST>> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxyResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxyResult.java
index 1db1f08..9ab2eab 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxyResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceElementProxyResult.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.stream.Stream;
 
-@Keep
+@KeepForApi
 public interface RetraceStackTraceElementProxyResult<T, ST extends StackTraceElementProxy<T, ST>> {
 
   Stream<? extends RetraceStackTraceElementProxy<T, ST>> stream();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceResult.java
index adcb09a..02d079b 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTraceResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -13,7 +13,7 @@
  *
  * <p>The number of elements is the same as the number of input frames.
  */
-@Keep
+@KeepForApi
 public interface RetraceStackTraceResult<T> extends RetraceResultWithContext {
 
   /**
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionElement.java
index 1af093c..8ef3268 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionElement.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceThrownExceptionElement
     extends RetraceElement<RetraceThrownExceptionResult> {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionResult.java
index b53ec9b..4cfe5e0 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceThrownExceptionResult.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceThrownExceptionResult
     extends RetraceResult<RetraceThrownExceptionElement> {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceTypeElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceTypeElement.java
index 2df0a4c..ceb061b 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceTypeElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceTypeElement.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceTypeElement extends RetraceElement<RetraceTypeResult> {
 
   RetracedTypeReference getType();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
index 7925ff6..69f9605 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceTypeResult extends RetraceResult<RetraceTypeElement> {}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java
index 2afa333..49c36bf 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownJsonMappingInformationResult.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
-@Keep
+@KeepForApi
 public interface RetraceUnknownJsonMappingInformationResult {
 
   /** Basic operation over 'elements' which represent a possible non-ambiguous retracing. */
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMapVersionDiagnostic.java b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMapVersionDiagnostic.java
index 9c1142b..4a9fcaf 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMapVersionDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMapVersionDiagnostic.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.Version;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class RetraceUnknownMapVersionDiagnostic implements Diagnostic {
 
   private final String versionName;
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java
index 3bba032..363e917 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUnknownMappingInformationElement.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetraceUnknownMappingInformationElement {
 
   String getIdentifier();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedClassMemberReference.java b/src/main/java/com/android/tools/r8/retrace/RetracedClassMemberReference.java
index b4067b7..a2671bb 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedClassMemberReference.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedClassMemberReference.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetracedClassMemberReference {
 
   RetracedClassReference getHolderClass();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedClassReference.java b/src/main/java/com/android/tools/r8/retrace/RetracedClassReference.java
index 2c030f7..b943a50 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedClassReference.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedClassReference.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
-@Keep
+@KeepForApi
 public interface RetracedClassReference {
 
   boolean isUnknown();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedFieldReference.java b/src/main/java/com/android/tools/r8/retrace/RetracedFieldReference.java
index 1e942d7..6e2ec15 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedFieldReference.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedFieldReference.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.TypeReference;
 
-@Keep
+@KeepForApi
 public interface RetracedFieldReference extends RetracedClassMemberReference {
 
   boolean isUnknown();
@@ -19,7 +19,7 @@
 
   String getFieldName();
 
-  @Keep
+  @KeepForApi
   interface KnownRetracedFieldReference extends RetracedFieldReference {
 
     TypeReference getFieldType();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedMethodReference.java b/src/main/java/com/android/tools/r8/retrace/RetracedMethodReference.java
index d6644cb..1542606 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedMethodReference.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedMethodReference.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.TypeReference;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public interface RetracedMethodReference
     extends RetracedClassMemberReference, Comparable<RetracedMethodReference> {
 
@@ -25,7 +25,7 @@
 
   int getOriginalPositionOrDefault(int defaultPosition);
 
-  @Keep
+  @KeepForApi
   interface KnownRetracedMethodReference extends RetracedMethodReference {
 
     boolean isVoid();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedSingleFrame.java b/src/main/java/com/android/tools/r8/retrace/RetracedSingleFrame.java
index 3b17336..ecefee9 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedSingleFrame.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedSingleFrame.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetracedSingleFrame {
 
   RetracedMethodReference getMethodReference();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java b/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
index d677cb8..1331bc7 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
-@Keep
+@KeepForApi
 public interface RetracedSourceFile {
 
   boolean hasRetraceResult();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedTypeReference.java b/src/main/java/com/android/tools/r8/retrace/RetracedTypeReference.java
index f167483..5c29891 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedTypeReference.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedTypeReference.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.TypeReference;
 
-@Keep
+@KeepForApi
 public interface RetracedTypeReference {
 
   boolean isVoid();
diff --git a/src/main/java/com/android/tools/r8/retrace/Retracer.java b/src/main/java/com/android/tools/r8/retrace/Retracer.java
index 633b143..bc764c6 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retracer.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retracer.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
@@ -13,7 +13,7 @@
 import java.util.OptionalInt;
 
 /** This is the main api interface for retrace. */
-@Keep
+@KeepForApi
 public interface Retracer {
 
   RetraceClassResult retraceClass(ClassReference classReference);
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
index 263ca19..2d852fd 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.references.TypeReference;
@@ -13,7 +13,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@Keep
+@KeepForApi
 public abstract class StackTraceElementProxy<T, ST extends StackTraceElementProxy<T, ST>> {
 
   public abstract boolean hasClassName();
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
index e792ef0..fc6dcf2 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.StackTraceElementProxyRetracerImpl;
 
-@Keep
+@KeepForApi
 public interface StackTraceElementProxyRetracer<T, ST extends StackTraceElementProxy<T, ST>> {
 
   RetraceStackTraceElementProxyResult<T, ST> retrace(ST element, RetraceStackTraceContext context);
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceLineParser.java b/src/main/java/com/android/tools/r8/retrace/StackTraceLineParser.java
index 92d1dca..910dd0f 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceLineParser.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceLineParser.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.StackTraceElementStringProxy;
 import com.android.tools.r8.retrace.internal.StackTraceRegularExpressionParser;
 
-@Keep
+@KeepForApi
 public interface StackTraceLineParser<T, ST extends StackTraceElementProxy<T, ST>> {
 
   ST parse(T stackTraceLine);
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceSupplier.java b/src/main/java/com/android/tools/r8/retrace/StackTraceSupplier.java
index 9940c5c..573f6d7 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceSupplier.java
@@ -4,10 +4,10 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.util.List;
 
-@Keep
+@KeepForApi
 @FunctionalInterface
 public interface StackTraceSupplier {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/StreamSupplier.java b/src/main/java/com/android/tools/r8/retrace/StreamSupplier.java
index 4a51497..2b351e9 100644
--- a/src/main/java/com/android/tools/r8/retrace/StreamSupplier.java
+++ b/src/main/java/com/android/tools/r8/retrace/StreamSupplier.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.retrace;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /**
  * Supplier of input lines to be retraced.
@@ -12,7 +12,7 @@
  * @param <E> the type of the {@link Throwable}
  */
 @FunctionalInterface
-@Keep
+@KeepForApi
 public interface StreamSupplier<E extends Throwable> {
 
   String getNext() throws E;
diff --git a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
index 3f37a84..2229315 100644
--- a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.retrace.internal.RetraceStackFrameResultWithContextImpl;
 import com.android.tools.r8.retrace.internal.StackTraceElementStringProxy;
 import com.android.tools.r8.utils.StringUtils;
@@ -20,7 +20,7 @@
  * Specialized Retrace class for retracing string retraces, with special handling for appending
  * additional information into the strings, such as OR's for ambiguous lines.
  */
-@Keep
+@KeepForApi
 public class StringRetrace extends Retrace<String, StackTraceElementStringProxy> {
 
   StringRetrace(
diff --git a/src/main/java/com/android/tools/r8/startup/StartupClassBuilder.java b/src/main/java/com/android/tools/r8/startup/StartupClassBuilder.java
index 43a63b4..b390a0c 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupClassBuilder.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.startup;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 
 /** Interface for providing information about a startup class to the compiler. */
-@Keep
+@KeepForApi
 public interface StartupClassBuilder {
 
   StartupClassBuilder setClassReference(ClassReference classReference);
diff --git a/src/main/java/com/android/tools/r8/startup/StartupMethodBuilder.java b/src/main/java/com/android/tools/r8/startup/StartupMethodBuilder.java
index 0c1efe2..6cdf52e 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupMethodBuilder.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.startup;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.MethodReference;
 
 /** Interface for providing information about a startup method to the compiler. */
-@Keep
+@KeepForApi
 public interface StartupMethodBuilder {
 
   StartupMethodBuilder setMethodReference(MethodReference methodReference);
diff --git a/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java b/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
index 3ee53c7..cc59960 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupProfileBuilder.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.startup;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.TextInputStream;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.profile.art.HumanReadableArtProfileParserBuilder;
 import java.util.function.Consumer;
 
 /** Interface for providing a startup profile to the compiler. */
-@Keep
+@KeepForApi
 public interface StartupProfileBuilder {
 
   /** API for adding information about a startup class to the compiler. */
diff --git a/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java b/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
index 39ad8fc..b77e1c0 100644
--- a/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
+++ b/src/main/java/com/android/tools/r8/startup/StartupProfileProvider.java
@@ -4,11 +4,11 @@
 
 package com.android.tools.r8.startup;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.Resource;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 
 /** Interface for providing a startup profile to the compiler. */
-@Keep
+@KeepForApi
 public interface StartupProfileProvider extends Resource {
 
   /** Provides the startup profile by callbacks to the given {@param startupProfileBuilder}. */
diff --git a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
index 144e210..c5ab7a9 100644
--- a/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/startup/diagnostic/MissingStartupProfileItemsDiagnostic.java
@@ -5,10 +5,10 @@
 package com.android.tools.r8.startup.diagnostic;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.profile.startup.profile.StartupProfileClassRule;
@@ -19,7 +19,7 @@
 import java.util.List;
 import java.util.Set;
 
-@Keep
+@KeepForApi
 public class MissingStartupProfileItemsDiagnostic implements Diagnostic {
 
   private final List<DexReference> missingStartupItems;
diff --git a/src/main/java/com/android/tools/r8/threading/ThreadingModule.java b/src/main/java/com/android/tools/r8/threading/ThreadingModule.java
index 25f31bd..1525e70 100644
--- a/src/main/java/com/android/tools/r8/threading/ThreadingModule.java
+++ b/src/main/java/com/android/tools/r8/threading/ThreadingModule.java
@@ -4,8 +4,14 @@
 
 package com.android.tools.r8.threading;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.KeepTarget;
+import com.android.tools.r8.keepanno.annotations.MemberAccessFlags;
+import com.android.tools.r8.keepanno.annotations.UsedByReflection;
+import com.android.tools.r8.keepanno.annotations.UsesReflection;
+import com.android.tools.r8.threading.providers.blocking.ThreadingModuleBlockingProvider;
+import com.android.tools.r8.threading.providers.singlethreaded.ThreadingModuleSingleThreadedProvider;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -16,11 +22,18 @@
  * Threading module interface to enable non-blocking usage of R8.
  *
  * <p>The threading module has multiple implementations outside the main R8 jar. The concrete
- * implementations are loaded via a Java service loader. Since these implementations are dynamically
- * loaded the interface they implement must be kept.
+ * implementations are loaded via reflection. Since these implementations are dynamically loaded the
+ * interface they implement must be kept.
  */
-@Keep
+@UsedByReflection(
+    kind = KeepItemKind.CLASS_AND_MEMBERS,
+    memberAccess = {MemberAccessFlags.PUBLIC})
 public interface ThreadingModule {
+
+  ExecutorService createSingleThreadedExecutorService();
+
+  ExecutorService createThreadedExecutorService(int threadCount);
+
   <T> Future<T> submit(Callable<T> task, ExecutorService executorService) throws ExecutionException;
 
   <T> void awaitFutures(List<Future<T>> futures) throws ExecutionException;
@@ -28,12 +41,25 @@
   class Loader {
 
     // Splitting up the names to make reflective identification unlikely.
+    // We explicitly don't want R8 to optimize out the reflective lookup.
     private static final String PACKAGE = "com.android.tools.r8.threading.providers";
     private static final String[] IMPLEMENTATIONS = {
       "blocking.ThreadingModuleBlockingProvider",
       "singlethreaded.ThreadingModuleSingleThreadedProvider"
     };
 
+    @UsesReflection({
+      @KeepTarget(
+          kind = KeepItemKind.CLASS_AND_MEMBERS,
+          classConstant = ThreadingModuleBlockingProvider.class,
+          methodName = "<init>",
+          methodParameters = {}),
+      @KeepTarget(
+          kind = KeepItemKind.CLASS_AND_MEMBERS,
+          classConstant = ThreadingModuleSingleThreadedProvider.class,
+          methodName = "<init>",
+          methodParameters = {})
+    })
     public static ThreadingModuleProvider load() {
       for (String implementation : IMPLEMENTATIONS) {
         String name = PACKAGE + "." + implementation;
diff --git a/src/main/java/com/android/tools/r8/threading/ThreadingModuleProvider.java b/src/main/java/com/android/tools/r8/threading/ThreadingModuleProvider.java
index ea401c9..290f23e 100644
--- a/src/main/java/com/android/tools/r8/threading/ThreadingModuleProvider.java
+++ b/src/main/java/com/android/tools/r8/threading/ThreadingModuleProvider.java
@@ -4,14 +4,18 @@
 
 package com.android.tools.r8.threading;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.MemberAccessFlags;
+import com.android.tools.r8.keepanno.annotations.UsedByReflection;
 
 /**
  * Interface to obtain a threading module.
  *
- * <p>The provider is loaded via Java service loader so its interface must be kept.
+ * <p>The provider is loaded via reflection so its interface must be kept.
  */
-@Keep
+@UsedByReflection(
+    kind = KeepItemKind.CLASS_AND_MEMBERS,
+    memberAccess = {MemberAccessFlags.PUBLIC})
 public interface ThreadingModuleProvider {
 
   ThreadingModule create();
diff --git a/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlocking.java b/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlocking.java
index 326c946..6445817 100644
--- a/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlocking.java
+++ b/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlocking.java
@@ -10,11 +10,24 @@
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
 public class ThreadingModuleBlocking implements ThreadingModule {
 
   @Override
+  public ExecutorService createSingleThreadedExecutorService() {
+    return Executors.newSingleThreadExecutor();
+  }
+
+  @Override
+  public ExecutorService createThreadedExecutorService(int threadCount) {
+    // Note Executors.newSingleThreadExecutor() is not used when just one thread is used. See
+    // b/67338394.
+    return Executors.newWorkStealingPool(threadCount);
+  }
+
+  @Override
   public <T> Future<T> submit(Callable<T> task, ExecutorService executorService) {
     return executorService.submit(task);
   }
diff --git a/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlockingProvider.java b/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlockingProvider.java
index d5a0ccb..0c390ee 100644
--- a/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlockingProvider.java
+++ b/src/main/java/com/android/tools/r8/threading/providers/blocking/ThreadingModuleBlockingProvider.java
@@ -4,11 +4,9 @@
 
 package com.android.tools.r8.threading.providers.blocking;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.threading.ThreadingModule;
 import com.android.tools.r8.threading.ThreadingModuleProvider;
 
-@Keep
 public class ThreadingModuleBlockingProvider implements ThreadingModuleProvider {
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreaded.java b/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreaded.java
index 0e47c03..2afc6db 100644
--- a/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreaded.java
+++ b/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreaded.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.threading.ThreadingModule;
 import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -15,6 +16,18 @@
 public class ThreadingModuleSingleThreaded implements ThreadingModule {
 
   @Override
+  public ExecutorService createSingleThreadedExecutorService() {
+    // The executor service is ignored in submit. It should never be used so we just pass null.
+    // TODO(b/304992619): We should refactor the code base to internalize the executor in a type.
+    return MoreExecutors.newDirectExecutorService();
+  }
+
+  @Override
+  public ExecutorService createThreadedExecutorService(int threadCount) {
+    return createSingleThreadedExecutorService();
+  }
+
+  @Override
   public <T> Future<T> submit(Callable<T> task, ExecutorService executorService)
       throws ExecutionException {
     try {
diff --git a/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreadedProvider.java b/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreadedProvider.java
index 8044511..b7a5633 100644
--- a/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreadedProvider.java
+++ b/src/main/java/com/android/tools/r8/threading/providers/singlethreaded/ThreadingModuleSingleThreadedProvider.java
@@ -4,11 +4,9 @@
 
 package com.android.tools.r8.threading.providers.singlethreaded;
 
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.threading.ThreadingModule;
 import com.android.tools.r8.threading.ThreadingModuleProvider;
 
-@Keep
 public class ThreadingModuleSingleThreadedProvider implements ThreadingModuleProvider {
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
index ad30e62..50a016c 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferences.java
@@ -6,7 +6,6 @@
 import static com.android.tools.r8.utils.CovariantReturnTypeUtils.modelLibraryMethodsWithCovariantReturnTypes;
 
 import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ProgramResource;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.ProgramResourceProvider;
@@ -17,6 +16,7 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.CommandLineOrigin;
 import com.android.tools.r8.shaking.MainDexInfo;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
@@ -31,7 +31,7 @@
 import java.util.Set;
 import java.util.function.Consumer;
 
-@Keep
+@KeepForApi
 public class TraceReferences {
 
   public static void run(TraceReferencesCommand command) throws CompilationFailedException {
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCheckConsumer.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCheckConsumer.java
index 6912b15..8ab96e8 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCheckConsumer.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCheckConsumer.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.tracereferences;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
 import com.android.tools.r8.diagnostic.internal.DefinitionContextUtils;
@@ -13,6 +12,7 @@
 import com.android.tools.r8.diagnostic.internal.MissingDefinitionsDiagnosticImpl;
 import com.android.tools.r8.diagnostic.internal.MissingFieldInfoImpl;
 import com.android.tools.r8.diagnostic.internal.MissingMethodInfoImpl;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
@@ -28,7 +28,7 @@
  * com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic} as an error, if any missing
  * definitions were found.
  */
-@Keep
+@KeepForApi
 public class TraceReferencesCheckConsumer extends TraceReferencesConsumer.ForwardingConsumer {
 
   private final Map<ClassReference, Map<Object, DefinitionContext>> missingClassesContexts =
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCommand.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCommand.java
index ddd9e3f..28deeb3 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCommand.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesCommand.java
@@ -13,12 +13,12 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ProgramResource;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.ProgramResourceProvider;
 import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.dump.DumpOptions;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.ArchiveResourceProvider;
@@ -42,7 +42,7 @@
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 
-@Keep
+@KeepForApi
 public class TraceReferencesCommand {
   private final boolean printHelp;
   private final boolean printVersion;
@@ -116,7 +116,7 @@
     return printVersion;
   }
 
-  @Keep
+  @KeepForApi
   public static class Builder {
 
     private boolean printHelp = false;
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesConsumer.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesConsumer.java
index e5251f7..2f6e23d 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesConsumer.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesConsumer.java
@@ -4,22 +4,21 @@
 package com.android.tools.r8.tracereferences;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.KeepForSubclassing;
 import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.PackageReference;
 
 /** Consumer interface for recording references */
-@KeepForSubclassing
+@KeepForApi
 public interface TraceReferencesConsumer {
 
   /**
    * Interface for asking for the access flags for a traced reference when the definition is present
    */
-  @Keep
+  @KeepForApi
   interface AccessFlags {
     boolean isStatic();
 
@@ -34,21 +33,21 @@
    * Interface for asking for additional class information for a traced class when the definition is
    * found.
    */
-  @Keep
+  @KeepForApi
   interface ClassAccessFlags extends AccessFlags {
     boolean isInterface();
 
     boolean isEnum();
   }
 
-  @Keep
+  @KeepForApi
   interface FieldAccessFlags extends AccessFlags {}
 
-  @Keep
+  @KeepForApi
   interface MethodAccessFlags extends AccessFlags {}
 
   /** Interface implemented by all references reported */
-  @Keep
+  @KeepForApi
   interface TracedReference<T, F> {
     /** Returns if the reference does not have a definition in the program traced. */
     boolean isMissingDefinition();
@@ -67,13 +66,13 @@
     F getAccessFlags();
   }
 
-  @Keep
+  @KeepForApi
   interface TracedClass extends TracedReference<ClassReference, ClassAccessFlags> {}
 
-  @Keep
+  @KeepForApi
   interface TracedField extends TracedReference<FieldReference, FieldAccessFlags> {}
 
-  @Keep
+  @KeepForApi
   interface TracedMethod extends TracedReference<MethodReference, MethodAccessFlags> {}
 
   /**
@@ -140,7 +139,7 @@
   }
 
   /** Forwarding consumer to delegate to an optional existing consumer. */
-  @Keep
+  @KeepForApi
   class ForwardingConsumer implements TraceReferencesConsumer {
 
     private static final TraceReferencesConsumer EMPTY_CONSUMER = new ForwardingConsumer(null);
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
index 52ea13c..40fe9c3 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
@@ -4,9 +4,9 @@
 package com.android.tools.r8.tracereferences;
 
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.StringConsumer.FileConsumer;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.tracereferences.internal.TraceReferencesResult;
 import java.nio.file.Path;
 
@@ -23,7 +23,7 @@
  *     .build();
  * </pre>
  */
-@Keep
+@KeepForApi
 public class TraceReferencesKeepRules extends TraceReferencesConsumer.ForwardingConsumer {
 
   private final TraceReferencesResult.Builder traceReferencesResultBuilder;
@@ -49,7 +49,7 @@
    *
    * <p>A builder is obtained by calling {@link TraceReferencesKeepRules#builder}.
    */
-  @Keep
+  @KeepForApi
   public static class Builder {
     private StringConsumer consumer;
     private boolean allowObfuscation;
diff --git a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
index 9311d46..6532b8f 100644
--- a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
@@ -8,12 +8,12 @@
 import com.android.tools.r8.DataDirectoryResource;
 import com.android.tools.r8.DataEntryResource;
 import com.android.tools.r8.DataResourceProvider;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ProgramResource;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.ProgramResourceProvider;
 import com.android.tools.r8.ResourceException;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -33,7 +33,7 @@
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
 
-@Keep // TODO(b/121121779) Remove keep-annotation.
+@KeepForApi
 public class ArchiveResourceProvider implements ProgramResourceProvider, DataResourceProvider {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionDiagnostic.java b/src/main/java/com/android/tools/r8/utils/ExceptionDiagnostic.java
index a73aeb5..e170d55 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionDiagnostic.java
@@ -5,8 +5,8 @@
 package com.android.tools.r8.utils;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
 import com.android.tools.r8.ResourceException;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
@@ -18,7 +18,7 @@
  * conversion to a diagnostic, the full exception stack can be obtained in the suppressed exceptions
  * on the inner-most cause.
  */
-@Keep
+@KeepForApi
 public class ExceptionDiagnostic implements Diagnostic {
 
   private final Throwable cause;
diff --git a/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java b/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java
index 009c490..98112ed 100644
--- a/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.utils;
 
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 
-@Keep
+@KeepForApi
 public class StackTraceUtils {
 
   private static final String pathToWriteStacktrace =
diff --git a/src/main/java/com/android/tools/r8/utils/StringDiagnostic.java b/src/main/java/com/android/tools/r8/utils/StringDiagnostic.java
index 6476a5a..6067092 100644
--- a/src/main/java/com/android/tools/r8/utils/StringDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/utils/StringDiagnostic.java
@@ -4,20 +4,20 @@
 package com.android.tools.r8.utils;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
 /**
  * A diagnostic message.
  *
- * <p>This string diagnostic is used to report various error messages from the compiler. There is
- * no guarantee that the message will remain the same or that the issue will continue to be reported
- * by way of a {@link StringDiagnostic}. If there is a need to reliably identify a particular kind
- * of error which is currently reported via a {@link StringDiagnostic}, then please file a feature
+ * <p>This string diagnostic is used to report various error messages from the compiler. There is no
+ * guarantee that the message will remain the same or that the issue will continue to be reported by
+ * way of a {@link StringDiagnostic}. If there is a need to reliably identify a particular kind of
+ * error which is currently reported via a {@link StringDiagnostic}, then please file a feature
  * request on D8/R8.
  */
-@Keep
+@KeepForApi
 public class StringDiagnostic implements Diagnostic {
 
   private final Origin origin;
diff --git a/src/main/java/com/android/tools/r8/utils/ThreadUtils.java b/src/main/java/com/android/tools/r8/utils/ThreadUtils.java
index 8a28293..8a34b5a 100644
--- a/src/main/java/com/android/tools/r8/utils/ThreadUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ThreadUtils.java
@@ -12,7 +12,6 @@
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ForkJoinPool;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -214,26 +213,27 @@
         executorService);
   }
 
-  static ExecutorService getExecutorServiceForProcessors(int processors) {
+  static ExecutorService getExecutorServiceForProcessors(
+      int processors, ThreadingModule threadingModule) {
     // This heuristic is based on measurements on a 32 core (hyper-threaded) machine.
     int threads = processors <= 2 ? processors : (int) Math.ceil(Integer.min(processors, 16) / 2.0);
-    return getExecutorServiceForThreads(threads);
+    return getExecutorServiceForThreads(threads, threadingModule);
   }
 
-  static ExecutorService getExecutorServiceForThreads(int threads) {
-    // Note Executors.newSingleThreadExecutor() is not used when just one thread is used. See
-    // b/67338394.
-    return Executors.newWorkStealingPool(threads);
+  static ExecutorService getExecutorServiceForThreads(
+      int threads, ThreadingModule threadingModule) {
+    return threadingModule.createThreadedExecutorService(threads);
   }
 
-  public static ExecutorService getExecutorService(int threads) {
+  public static ExecutorService getExecutorService(int threads, ThreadingModule threadingModule) {
     return threads == NOT_SPECIFIED
-        ? getExecutorServiceForProcessors(Runtime.getRuntime().availableProcessors())
-        : getExecutorServiceForThreads(threads);
+        ? getExecutorServiceForProcessors(
+            Runtime.getRuntime().availableProcessors(), threadingModule)
+        : getExecutorServiceForThreads(threads, threadingModule);
   }
 
   public static ExecutorService getExecutorService(InternalOptions options) {
-    return getExecutorService(options.threadCount);
+    return getExecutorService(options.threadCount, options.getThreadingModule());
   }
 
   public static int getNumberOfThreads(ExecutorService service) {
diff --git a/src/main/java/com/android/tools/r8/utils/UnverifiableCfCodeDiagnostic.java b/src/main/java/com/android/tools/r8/utils/UnverifiableCfCodeDiagnostic.java
index 1724acc..866a15e 100644
--- a/src/main/java/com/android/tools/r8/utils/UnverifiableCfCodeDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/utils/UnverifiableCfCodeDiagnostic.java
@@ -4,12 +4,12 @@
 package com.android.tools.r8.utils;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.references.MethodReference;
 
-@Keep
+@KeepForApi
 public class UnverifiableCfCodeDiagnostic implements Diagnostic {
 
   private final MethodReference methodReference;
diff --git a/src/main/java/com/android/tools/r8/utils/positions/NotSupportedMapVersionForMappingComposeDiagnostic.java b/src/main/java/com/android/tools/r8/utils/positions/NotSupportedMapVersionForMappingComposeDiagnostic.java
index 285046c..1e672a8 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/NotSupportedMapVersionForMappingComposeDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/NotSupportedMapVersionForMappingComposeDiagnostic.java
@@ -5,11 +5,11 @@
 package com.android.tools.r8.utils.positions;
 
 import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.Keep;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 
-@Keep
+@KeepForApi
 public class NotSupportedMapVersionForMappingComposeDiagnostic implements Diagnostic {
 
   @Override
diff --git a/src/main/keep.txt b/src/main/keep.txt
index 3e23b48..2aba17e 100644
--- a/src/main/keep.txt
+++ b/src/main/keep.txt
@@ -2,14 +2,8 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-# TODO(b/204058761): Remove when we can use test proguard options.
--keep @com.android.tools.r8.Keep class * { public *; }
--keep @com.android.tools.r8.KeepForSubclassing class * { public *; protected *; }
 -keepclasseswithmembers class * { @com.android.tools.r8.KeepMethodForCompileDump <methods>; }
 
-# Keep all things that can be reached from the retrace api and keep the annotation
--keep @com.android.tools.r8.KeepForRetraceApi class * { public *; }
-
 -keep public class com.android.tools.r8.D8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.R8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.ExtractMarker { public static void main(java.lang.String[]); }
diff --git a/src/main/keep_retrace.txt b/src/main/keep_retrace.txt
deleted file mode 100644
index 6ddb273..0000000
--- a/src/main/keep_retrace.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# The retrace api is separated out without repackaging which is why this broad
-# rule is used.
--keep public class com.android.tools.r8.retrace.* {
-     public <methods>;
-     public <fields>;
- }
--keepattributes SourceFile, LineNumberTable, InnerClasses, EnclosingMethod, Exceptions, Signature
--keepparameternames
-
--repackageclasses com.android.tools.r8.retrace_internal
-
-# Keep all things that can be reached from the retrace api
--keep @com.android.tools.r8.KeepForRetraceApi class * { public *; }
-
--keep,allowshrinking @com.android.tools.r8.Keep class * { public *; }
--keep,allowshrinking @com.android.tools.r8.KeepForSubclassing class * { public *; protected *; }
-
--keep public class com.android.tools.r8.Version { public static final java.lang.String LABEL; }
--keep public class com.android.tools.r8.Version { public static java.lang.String getVersionString(); }
--keep public class com.android.tools.r8.Version { public static int getMajorVersion(); }
--keep public class com.android.tools.r8.Version { public static int getMinorVersion(); }
--keep public class com.android.tools.r8.Version { public static int getPatchVersion(); }
--keep public class com.android.tools.r8.Version { public static java.lang.String getPreReleaseString(); }
--keep public class com.android.tools.r8.Version { public static boolean isDevelopmentVersion(); }
diff --git a/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapCurrentEqualityTest.java b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapCurrentEqualityTest.java
index a6c99f8..1f30ddf 100644
--- a/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapCurrentEqualityTest.java
+++ b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapCurrentEqualityTest.java
@@ -114,8 +114,9 @@
           .addProgramFiles(ToolHelper.getR8WithRelocatedDeps())
           .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
           .addKeepRuleFiles(MAIN_KEEP)
+          .enableExperimentalKeepAnnotations()
           // TODO(b/176783536, b/270105162): Get a hold of dependencies in new gradle setup.
-          .applyIf(ToolHelper.isNewGradleSetup(), R8TestBuilder::allowUnusedDontWarnPatterns)
+          .apply(R8TestBuilder::allowUnusedDontWarnPatterns)
           .compile()
           .apply(c -> FileUtils.writeTextFile(map, c.getProguardMap()))
           .writeToZip(jar);
diff --git a/src/test/bootstrap/com/android/tools/r8/bootstrap/WhyAreYouKeepingAllTest.java b/src/test/bootstrap/com/android/tools/r8/bootstrap/WhyAreYouKeepingAllTest.java
index f5155e6..514db55 100644
--- a/src/test/bootstrap/com/android/tools/r8/bootstrap/WhyAreYouKeepingAllTest.java
+++ b/src/test/bootstrap/com/android/tools/r8/bootstrap/WhyAreYouKeepingAllTest.java
@@ -12,7 +12,6 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.dex.Marker.Backend;
 import com.android.tools.r8.utils.StringUtils;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -55,7 +54,7 @@
         // results.
         .collectStdoutWithoutForwarding()
         // TODO(b/176783536, b/270105162): Get a hold of dependencies in new gradle setup.
-        .applyIf(ToolHelper.isNewGradleSetup(), R8TestBuilder::allowUnusedDontWarnPatterns)
+        .apply(R8TestBuilder::allowUnusedDontWarnPatterns)
         .compile()
         .assertStdoutThatMatches(containsString("referenced in keep rule"))
         // TODO(b/124655065): We should always know the reason for keeping.
diff --git a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
index e549627..a0821d2 100644
--- a/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
+++ b/src/test/java/com/android/tools/r8/KotlinCompilerTool.java
@@ -365,9 +365,7 @@
       }
     }
     ProcessBuilder builder = new ProcessBuilder(commandLineAndHasherConsumers.cmdline);
-    if (ToolHelper.isNewGradleSetup()) {
-      builder.directory(new File(ToolHelper.getProjectRoot()));
-    }
+    builder.directory(new File(ToolHelper.getProjectRoot()));
     ProcessResult processResult = ToolHelper.runProcess(builder);
     if (CommandResultCache.isEnabled() && output.toFile().isFile()) {
       CommandResultCache.getInstance().putResult(processResult, cacheLookupKey, output);
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 6c31a91..efbc507 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import static com.android.tools.r8.TestCondition.compilers;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -13,7 +14,6 @@
 import com.android.tools.r8.ToolHelper.DexVm.Kind;
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.ArtErrorParser;
@@ -170,14 +170,6 @@
           .put(
               "802-deoptimization",
               TestCondition.match(TestCondition.runtimesUpTo(DexVm.Version.V4_4_4)))
-          // TODO(b/144975341): Triage
-          .put(
-              "134-reg-promotion",
-              TestCondition.match(TestCondition.runtimes(DexVm.Version.V10_0_0)))
-          // TODO(b/197078742): Triage - test OOMs.
-          .put(
-              "134-reg-promotion",
-              TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
           // TODO(b/197078746): Triage - fails with "java.lang.NoSuchMethodException:
           //  org.apache.harmony.dalvik.ddmc.DdmVmInternal.enableRecentAllocations [boolean]"
           .put(
@@ -638,6 +630,23 @@
           .put(
               "104-growth-limit",
               TestCondition.match(TestCondition.R8_COMPILER, TestCondition.RELEASE_MODE))
+          // Fails with OOM, seemingly due to GC not collecting unreachable array after writing
+          // null to static field.
+          .put(
+              "134-reg-promotion",
+              TestCondition.or(
+                  TestCondition.match(
+                      compilers(CompilerUnderTest.R8),
+                      TestCondition.runtimes(DexVm.Version.V10_0_0, DexVm.Version.V12_0_0)),
+                  TestCondition.match(
+                      compilers(CompilerUnderTest.D8_AFTER_R8CF, CompilerUnderTest.R8_AFTER_D8),
+                      TestCondition.runtimes(
+                          DexVm.Version.V4_0_4,
+                          DexVm.Version.V8_1_0,
+                          DexVm.Version.V9_0_0,
+                          DexVm.Version.V10_0_0,
+                          DexVm.Version.V12_0_0,
+                          DexVm.Version.DEFAULT))))
           .put(
               "461-get-reference-vreg",
               TestCondition.match(
@@ -835,8 +844,7 @@
               "201-built-in-except-detail-messages",
               TestCondition.or(
                   TestCondition.match(
-                      TestCondition.compilers(
-                          CompilerUnderTest.D8, CompilerUnderTest.D8_AFTER_R8CF),
+                      compilers(CompilerUnderTest.D8, CompilerUnderTest.D8_AFTER_R8CF),
                       TestCondition.runtimes(
                           DexVm.Version.V4_0_4,
                           DexVm.Version.V4_4_4,
@@ -846,15 +854,14 @@
                           DexVm.Version.V13_0_0,
                           DexVm.Version.V14_0_0)),
                   TestCondition.match(
-                      TestCondition.compilers(
+                      compilers(
                           CompilerUnderTest.R8,
                           CompilerUnderTest.R8CF,
                           CompilerUnderTest.R8_AFTER_D8))))
           // Class.forName() that fails due to verification error is removed.
           .put(
               "412-new-array",
-              TestCondition.match(
-                  TestCondition.compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8)))
+              TestCondition.match(compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8)))
           // Array index out of bounds exception.
           .put("449-checker-bce", TestCondition.any())
           // Fails: get_vreg_jni.cc:46] Check failed: value == 42u (value=314630384, 42u=42)
@@ -912,8 +919,7 @@
           // Class.forName() that fails due to linkage error is removed.
           .put(
               "587-inline-class-error",
-              TestCondition.match(
-                  TestCondition.compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8)))
+              TestCondition.match(compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8)))
           // Array index out of bounds exception.
           .put("602-deoptimizeable", TestCondition.any())
           // Array index out of bounds exception.
@@ -1525,7 +1531,7 @@
   }
 
   private static CompilationMode defaultCompilationMode(CompilerUnderTest compilerUnderTest) {
-    CompilationMode compilationMode = null;
+    CompilationMode compilationMode;
     switch (compilerUnderTest) {
       case R8:
       case R8CF:
@@ -1814,68 +1820,6 @@
     }
   }
 
-  private static boolean isAuxClassFile(String fileName, String auxClassFileBase) {
-    return fileName.endsWith(".class")
-        && (fileName.startsWith(auxClassFileBase + "$")
-        || fileName.startsWith(auxClassFileBase + "_"));
-  }
-
-
-  private static Runtime getRuntime(TestRuntime vm) {
-    if (vm.isCf()) {
-      return Runtime.JAVA;
-    } else if (vm.isDex()) {
-      return Runtime.fromDexVmVersion(vm.asDex().getVm().getVersion());
-    } else {
-      throw new Unreachable();
-    }
-  }
-
-  private static class VmSpec {
-    final TestRuntime vm;
-    final TestSpecification spec;
-
-    private VmSpec(TestRuntime vm, TestSpecification testSpecification) {
-      this.vm = vm;
-      this.spec = testSpecification;
-    }
-  }
-
-  private static class VmErrors {
-    private final Set<TestRuntime> failedVms = new HashSet<>();
-    private StringBuilder message;
-
-    private void addShouldHaveFailedError(CompilerUnderTest compilerUnderTest, TestRuntime vm) {
-      addFailure(vm);
-      message.append(
-          "FAILURE: Test should have failed on "
-              + vm
-              + " after compiling with "
-              + compilerUnderTest
-              + ".\n");
-    }
-
-    private void addFailedOnRunError(
-        CompilerUnderTest compilerUnderTest, TestRuntime vm, AssertionError error) {
-      addFailure(vm);
-      message.append(
-          "FAILURE: Test failed on "
-              + vm
-              + " after compiling with "
-              + compilerUnderTest
-              + ", error:\n"
-              + error.getMessage()
-              + "\n");
-    }
-
-    private void addFailure(TestRuntime vm) {
-      if (message == null) {
-        message = new StringBuilder();
-      }
-      failedVms.add(vm);
-    }
-  }
-
   protected void runArtTest(DexVm dexVm, CompilerUnderTest compilerUnderTest) throws Throwable {
     CompilerUnderTest firstCompilerUnderTest =
         compilerUnderTest == CompilerUnderTest.R8_AFTER_D8
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index d55e5c5..b24f608 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -15,7 +15,6 @@
 import com.android.tools.r8.dexsplitter.SplitterTestBase.SplitRunner;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
-import com.android.tools.r8.keepanno.KeepEdgeAnnotationsTest;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.profile.art.ArtProfileConsumer;
@@ -754,7 +753,7 @@
 
   public T enableExperimentalKeepAnnotations() {
     builder.addClasspathResourceProvider(
-        DirectoryClassFileProvider.fromDirectory(KeepEdgeAnnotationsTest.getKeepAnnoPath()));
+        DirectoryClassFileProvider.fromDirectory(ToolHelper.getKeepAnnoPath()));
     builder.setEnableExperimentalKeepAnnotations(true);
     return self();
   }
diff --git a/src/test/java/com/android/tools/r8/TestCondition.java b/src/test/java/com/android/tools/r8/TestCondition.java
index a23c980..aec73f4 100644
--- a/src/test/java/com/android/tools/r8/TestCondition.java
+++ b/src/test/java/com/android/tools/r8/TestCondition.java
@@ -7,7 +7,6 @@
 import com.android.tools.r8.R8RunArtTestsTest.DexTool;
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.errors.Unreachable;
-import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -67,10 +66,6 @@
           throw new Unreachable();
       }
     }
-
-    static boolean isArt(Runtime runtime) {
-      return EnumSet.range(LOWEST_ART_VERSION, HIGHEST_ART_VERSION).contains(runtime);
-    }
   }
 
   static class ToolSet {
@@ -93,7 +88,7 @@
 
   static class RuntimeSet {
 
-    private EnumSet<Runtime> set;
+    private final EnumSet<Runtime> set;
 
     public RuntimeSet(EnumSet<Runtime> set) {
       this.set = set;
@@ -137,8 +132,6 @@
           CompilerUnderTest.R8CF);
   public static final CompilerSet R8DEX_COMPILER =
       compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8);
-  public static final CompilerSet R8_NOT_AFTER_D8_COMPILER =
-      compilers(CompilerUnderTest.R8, CompilerUnderTest.D8_AFTER_R8CF, CompilerUnderTest.R8CF);
   public static final CompilerSet R8CF = compilers(CompilerUnderTest.R8CF);
 
   public static final CompilationModeSet DEBUG_MODE =
@@ -196,30 +189,6 @@
     return RuntimeSet.fromDexVmVersionSet(EnumSet.range(DexVm.Version.first(), upto));
   }
 
-  public static RuntimeSet artRuntimesUpTo(Runtime upto) {
-    assert Runtime.isArt(upto);
-    return new RuntimeSet(EnumSet.range(Runtime.LOWEST_ART_VERSION, upto));
-  }
-
-  public static RuntimeSet artRuntimesUpToAndJava(Runtime upto) {
-    return runtimes(
-        Sets.union(artRuntimesUpTo(upto).set, runtimes(Runtime.JAVA).set).toArray(new Runtime[0]));
-  }
-
-  public static RuntimeSet runtimesFrom(DexVm.Version start) {
-    return RuntimeSet.fromDexVmVersionSet(EnumSet.range(start, DexVm.Version.last()));
-  }
-
-  public static RuntimeSet artRuntimesFrom(Runtime start) {
-    assert Runtime.isArt(start);
-    return new RuntimeSet(EnumSet.range(start, Runtime.HIGHEST_ART_VERSION));
-  }
-
-  public static RuntimeSet artRuntimesFromAndJava(Runtime start) {
-    return runtimes(
-        Sets.union(artRuntimesFrom(start).set, runtimes(Runtime.JAVA).set).toArray(new Runtime[0]));
-  }
-
   public static RuntimeSet and(RuntimeSet... sets) {
     return new RuntimeSet(
         EnumSet.copyOf(
diff --git a/src/test/java/com/android/tools/r8/TestRuntime.java b/src/test/java/com/android/tools/r8/TestRuntime.java
index 77e4e22..76d8566 100644
--- a/src/test/java/com/android/tools/r8/TestRuntime.java
+++ b/src/test/java/com/android/tools/r8/TestRuntime.java
@@ -43,7 +43,7 @@
     JDK17("jdk17", 61),
     JDK18("jdk18", 62),
     JDK20("jdk20", 64),
-    ;
+    JDK21("jdk21", 65);
 
     /** This should generally be the latest checked in CF runtime we fully support. */
     private static final CfVm DEFAULT = JDK11;
@@ -97,12 +97,14 @@
       Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "openjdk-9.0.4");
   private static final Path JDK11_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-11");
   private static final Path JDK17_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-17");
+  private static final Path JDK21_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-21");
   private static final Map<CfVm, Path> jdkPaths =
       ImmutableMap.of(
           CfVm.JDK8, JDK8_PATH,
           CfVm.JDK9, JDK9_PATH,
           CfVm.JDK11, JDK11_PATH,
-          CfVm.JDK17, JDK17_PATH);
+          CfVm.JDK17, JDK17_PATH,
+          CfVm.JDK21, JDK21_PATH);
 
   public static CfRuntime getCheckedInJdk(CfVm vm) {
     if (vm == CfVm.JDK8) {
@@ -151,10 +153,18 @@
     return new CfRuntime(CfVm.JDK17, getCheckedInJdkHome(CfVm.JDK17));
   }
 
+  public static CfRuntime getCheckedInJdk21() {
+    return new CfRuntime(CfVm.JDK21, getCheckedInJdkHome(CfVm.JDK21));
+  }
+
   public static List<CfRuntime> getCheckedInCfRuntimes() {
     CfRuntime[] jdks =
         new CfRuntime[] {
-          getCheckedInJdk8(), getCheckedInJdk9(), getCheckedInJdk11(), getCheckedInJdk17(),
+          getCheckedInJdk8(),
+          getCheckedInJdk9(),
+          getCheckedInJdk11(),
+          getCheckedInJdk17(),
+          getCheckedInJdk21()
         };
     Builder<CfRuntime> builder = ImmutableList.builder();
     for (CfRuntime jdk : jdks) {
@@ -209,6 +219,9 @@
     if (version.equals("11") || version.startsWith("11.")) {
       return new CfRuntime(CfVm.JDK11, Paths.get(home));
     }
+    if (version.equals("17") || version.startsWith("17.")) {
+      return new CfRuntime(CfVm.JDK17, Paths.get(home));
+    }
     throw new Unimplemented("No support for JDK version: " + version);
   }
 
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index f1f836b..c03fadc 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -99,10 +99,6 @@
 
 public class ToolHelper {
 
-  public static boolean isNewGradleSetup() {
-    return "true".equals(System.getProperty("USE_NEW_GRADLE_SETUP"));
-  }
-
   public static String getProjectRoot() {
     String current = System.getProperty("user.dir");
     if (!current.contains("d8_r8")) {
@@ -146,9 +142,7 @@
     }
 
     public static TestDataSourceSet computeLegacyOrGradleSpecifiedLocation() {
-      return isNewGradleSetup()
-          ? TestDataSourceSet.SPECIFIED_BY_GRADLE_PROPERTY
-          : TestDataSourceSet.LEGACY;
+      return TestDataSourceSet.SPECIFIED_BY_GRADLE_PROPERTY;
     }
   }
 
@@ -178,33 +172,23 @@
   public static final String SMALI_BUILD_DIR = THIRD_PARTY_DIR + "smali/";
 
   public static String getExamplesJava11BuildDir() {
-    // TODO(b/270105162): This changes when new gradle setup is default.
-    if (ToolHelper.isNewGradleSetup()) {
-      assert System.getProperty("EXAMPLES_JAVA_11_JAVAC_BUILD_DIR") != null;
-      return System.getProperty("EXAMPLES_JAVA_11_JAVAC_BUILD_DIR");
-    } else {
-      return BUILD_DIR + "classes/java/examplesJava11/";
-    }
+    assert System.getProperty("EXAMPLES_JAVA_11_JAVAC_BUILD_DIR") != null;
+    return System.getProperty("EXAMPLES_JAVA_11_JAVAC_BUILD_DIR");
   }
 
   public static Path getR8MainPath() {
-    // TODO(b/270105162): This changes when new gradle setup is default.
-    if (ToolHelper.isNewGradleSetup()) {
-      assert System.getProperty("R8_RUNTIME_PATH") != null;
-      return Paths.get(System.getProperty("R8_RUNTIME_PATH"));
-    } else {
-      return isTestingR8Lib() ? R8LIB_JAR : R8_JAR_OLD;
-    }
+    assert System.getProperty("R8_RUNTIME_PATH") != null;
+    return Paths.get(System.getProperty("R8_RUNTIME_PATH"));
   }
 
   public static Path getRetracePath() {
-    // TODO(b/270105162): This changes when new gradle setup is default.
-    if (ToolHelper.isNewGradleSetup()) {
-      assert System.getProperty("RETRACE_RUNTIME_PATH") != null;
-      return Paths.get(System.getProperty("RETRACE_RUNTIME_PATH"));
-    } else {
-      return isTestingR8Lib() ? ToolHelper.R8_RETRACE_JAR : ToolHelper.R8_JAR_OLD;
-    }
+    assert System.getProperty("RETRACE_RUNTIME_PATH") != null;
+    return Paths.get(System.getProperty("RETRACE_RUNTIME_PATH"));
+  }
+
+  public static Path getKeepAnnoPath() {
+    assert System.getProperty("KEEP_ANNO_JAVAC_BUILD_DIR") != null;
+    return Paths.get(System.getProperty("KEEP_ANNO_JAVAC_BUILD_DIR").split(File.pathSeparator)[0]);
   }
 
   public static final Path CHECKED_IN_R8_17_WITH_DEPS =
@@ -264,7 +248,6 @@
   public static final Path RETRACE_MAPS_DIR = Paths.get(THIRD_PARTY_DIR, "r8mappings");
 
   // TODO(b/270105162): These should be removed when finished transitioning.
-  public static final Path R8_JAR_OLD = Paths.get(LIBS_DIR, "r8.jar");
   public static final Path R8_WITH_RELOCATED_DEPS_17_JAR =
       Paths.get(LIBS_DIR, "r8_with_relocated_deps_17.jar");
   public static final Path R8LIB_JAR = Paths.get(LIBS_DIR, "r8lib.jar");
@@ -273,22 +256,15 @@
   public static final Path R8LIB_EXCLUDE_DEPS_JAR = Paths.get(LIBS_DIR, "r8lib-exclude-deps.jar");
   public static final Path R8LIB_EXCLUDE_DEPS_MAP =
       Paths.get(LIBS_DIR, "r8lib-exclude-deps.jar.map");
-  public static final Path R8_RETRACE_JAR = Paths.get(LIBS_DIR, "r8retrace.jar");
 
   public static Path getDeps() {
-    if (isNewGradleSetup()) {
-      return Paths.get(System.getProperty("R8_DEPS"));
-    } else {
-      return Paths.get(LIBS_DIR, "deps_all.jar");
-    }
+    assert System.getProperty("R8_DEPS") != null;
+    return Paths.get(System.getProperty("R8_DEPS"));
   }
 
   public static Path getR8WithRelocatedDeps() {
-    if (isNewGradleSetup()) {
-      return Paths.get(System.getProperty("R8_WITH_RELOCATED_DEPS"));
-    } else {
-      return Paths.get(LIBS_DIR, "r8_with_relocated_deps.jar");
-    }
+    assert System.getProperty("R8_WITH_RELOCATED_DEPS") != null;
+    return Paths.get(System.getProperty("R8_WITH_RELOCATED_DEPS"));
   }
 
   public static final String DESUGARED_LIB_RELEASES_DIR =
@@ -481,7 +457,7 @@
         return shortName;
       }
 
-      private String shortName;
+      private final String shortName;
     }
 
     public String toString() {
@@ -584,9 +560,7 @@
         result.add("/bin/bash");
       }
       result.add(getExecutable());
-      for (String option : options) {
-        result.add(option);
-      }
+      result.addAll(options);
       for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
         StringBuilder builder = new StringBuilder("-D");
         builder.append(entry.getKey());
@@ -698,7 +672,7 @@
       }
     }
 
-    public ProcessResult getCachedResults() throws IOException {
+    public ProcessResult getCachedResults() {
       if (!useCache()) {
         return null;
       }
@@ -1171,17 +1145,6 @@
     return ""; //never here
   }
 
-  public static String toolsDir() {
-    String osName = System.getProperty("os.name");
-    if (osName.equals("Mac OS X")) {
-      return "mac";
-    } else if (osName.contains("Windows")) {
-      return "windows";
-    } else {
-      return "linux";
-    }
-  }
-
   public static String getProguard5Script() {
     if (isWindows()) {
       return PROGUARD + ".bat";
@@ -1775,10 +1738,6 @@
     return compatSink.build();
   }
 
-  public static void runL8(L8Command command) throws CompilationFailedException {
-    runL8(command, options -> {});
-  }
-
   public static void runL8(L8Command command, Consumer<InternalOptions> optionsModifier)
       throws CompilationFailedException {
     InternalOptions internalOptions = command.getInternalOptions();
@@ -1791,7 +1750,8 @@
         command.getR8Command());
   }
 
-  public static void addFilteredAndroidJar(BaseCommand.Builder builder, AndroidApiLevel apiLevel) {
+  public static void addFilteredAndroidJar(
+      BaseCommand.Builder<?, ?> builder, AndroidApiLevel apiLevel) {
     addFilteredAndroidJar(getAppBuilder(builder), apiLevel);
   }
 
@@ -2351,13 +2311,6 @@
     return result.stdout;
   }
 
-  public static String checkArtOutputIdentical(String file1, String file2, String mainClass,
-      DexVm version)
-      throws IOException {
-    return checkArtOutputIdentical(Collections.singletonList(file1),
-        Collections.singletonList(file2), mainClass, null, version);
-  }
-
   public static String checkArtOutputIdentical(List<String> files1, List<String> files2,
       String mainClass,
       Consumer<ArtCommandBuilder> extras,
@@ -2410,7 +2363,7 @@
   }
 
   // Checked in VMs for which dex2oat should work specified in decreasing order.
-  private static List<DexVm> SUPPORTED_DEX2OAT_VMS =
+  private static final List<DexVm> SUPPORTED_DEX2OAT_VMS =
       ImmutableList.of(DexVm.ART_12_0_0_HOST, DexVm.ART_6_0_1_HOST);
 
   public static ProcessResult runDex2OatRaw(Path file, Path outFile, DexVm targetVm)
@@ -2457,8 +2410,7 @@
     ProcessBuilder builder = new ProcessBuilder(command);
     builder.directory(getDexVmPath(vm).toFile());
     builder.environment().put("LD_LIBRARY_PATH", getDexVmLibPath(vm).toString());
-    ProcessResult processResult = runProcess(builder);
-    return processResult;
+    return runProcess(builder);
   }
 
   public static ProcessResult runProguardRaw(
@@ -2509,11 +2461,6 @@
     return runProguardRaw(getProguard5Script(), inJar, outJar, config, map);
   }
 
-  public static ProcessResult runProguardRaw(Path inJar, Path outJar, Path config, Path map)
-      throws IOException {
-    return runProguardRaw(getProguard5Script(), inJar, outJar, ImmutableList.of(config), map);
-  }
-
   public static String runProguard(Path inJar, Path outJar, Path config, Path map)
       throws IOException {
     return runProguard(inJar, outJar, ImmutableList.of(config), map);
@@ -2539,16 +2486,6 @@
     return runProguardRaw(getProguard6Script(), inJar, outJar, lib, ImmutableList.of(config), map);
   }
 
-  public static String runProguard6(Path inJar, Path outJar, Path config, Path map)
-      throws IOException {
-    return runProguard6(inJar, outJar, ImmutableList.of(config), map);
-  }
-
-  public static String runProguard6(Path inJar, Path outJar, List<Path> configs, Path map)
-      throws IOException {
-    return runProguard(getProguard6Script(), inJar, outJar, configs, map);
-  }
-
   public static ProcessResult runRetraceRaw(Path retracePath, Path map, Path stackTrace)
       throws IOException {
     List<String> command = new ArrayList<>();
diff --git a/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java b/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
index 80457af..8a24f74 100644
--- a/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
+++ b/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
@@ -372,7 +372,6 @@
   }
 
   protected static void setUpSystemPropertiesForMain(TestDataSourceSet sourceSet) {
-    System.setProperty("USE_NEW_GRADLE_SETUP", "true");
     System.setProperty("TEST_DATA_LOCATION", sourceSet.getBuildDir().toString());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTest.java b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTest.java
index 9441ae2..33ff65c 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTest.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTest.java
@@ -109,12 +109,8 @@
 
   public Path getPathForClass(Class<?> clazz) {
     String file = clazz.getName().replace('.', '/') + ".class";
-    if (System.getProperty("TEST_DATA_LOCATION") != null) {
-      return Paths.get(System.getProperty("TEST_DATA_LOCATION"), file);
-    } else {
-      assert System.getProperty("USE_NEW_GRADLE_SETUP") == null;
-      return Paths.get("build", "classes", "java", "test", file);
-    }
+    assert System.getProperty("TEST_DATA_LOCATION") != null;
+    return Paths.get(System.getProperty("TEST_DATA_LOCATION"), file);
   }
 
   public byte[] getBytesForClass(Class<?> clazz) throws IOException {
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/AbstractBackportTest.java b/src/test/java/com/android/tools/r8/desugar/backports/AbstractBackportTest.java
index b935de4..dbea395 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/AbstractBackportTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/AbstractBackportTest.java
@@ -12,12 +12,14 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.D8TestRunResult;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ThrowingConsumer;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
@@ -180,15 +182,20 @@
 
   @Test
   public void testD8() throws Exception {
+    testD8(D8TestRunResult::assertSuccess);
+  }
+
+  public void testD8(ThrowingConsumer<D8TestRunResult, RuntimeException> runResultConsumer)
+      throws Exception {
     parameters.assumeDexRuntime();
     testForD8()
         .setMinApi(parameters)
         .apply(this::configureProgram)
         .setIncludeClassesChecksum(true)
         .compileWithExpectedDiagnostics(this::checkDiagnostics)
+        .inspect(this::assertDesugaring)
         .run(parameters.getRuntime(), testClassName)
-        .assertSuccess()
-        .inspect(this::assertDesugaring);
+        .apply(runResultConsumer);
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java
index 8ffb905..7404eed 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/LongBackportJava9Test.java
@@ -5,13 +5,17 @@
 package com.android.tools.r8.desugar.backports;
 
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static org.hamcrest.CoreMatchers.containsString;
 
+import com.android.tools.r8.SingleTestRunResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
@@ -39,4 +43,16 @@
 
     registerTarget(AndroidApiLevel.T, 17);
   }
+
+  @Test
+  @Override
+  public void testD8() throws Exception {
+    testD8(
+        runResult ->
+            runResult.applyIf(
+                parameters.getDexRuntimeVersion().isEqualTo(Version.V6_0_1)
+                    && parameters.getApiLevel().isGreaterThan(AndroidApiLevel.B),
+                rr -> rr.assertFailureWithErrorThatMatches(containsString("SIGSEGV")),
+                SingleTestRunResult::assertSuccess));
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/PartialDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/PartialDesugaringTest.java
index 74ac232..7d29fa4 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/PartialDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/PartialDesugaringTest.java
@@ -217,10 +217,14 @@
         && api.isLessThan(AndroidApiLevel.T)) {
       expectedFailures.addAll(FAILURES_FILE_STORE);
     }
-    if (librarySpecification != JDK11_MINIMAL
-        && api.isGreaterThanOrEqualTo(AndroidApiLevel.N)
-        && api.isLessThan(AndroidApiLevel.T)) {
-      expectedFailures.addAll(FAILURES_TO_ARRAY);
+    if (librarySpecification != JDK11_MINIMAL && api.isLessThan(AndroidApiLevel.T)) {
+      if (librarySpecification == JDK8) {
+        if (api.isGreaterThanOrEqualTo(AndroidApiLevel.N)) {
+          expectedFailures.addAll(FAILURES_TO_ARRAY);
+        }
+      } else {
+        expectedFailures.addAll(FAILURES_TO_ARRAY);
+      }
     }
     if (jdk11NonMinimal
         && api.isGreaterThanOrEqualTo(AndroidApiLevel.O)
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
index 53ffbd1..e2c0f74 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
@@ -292,9 +292,6 @@
 
     assertEquals(humanRewritingFlags1.getDontRetarget(), humanRewritingFlags2.getDontRetarget());
     assertEquals(
-        humanRewritingFlags1.getDontRewriteInvocation(),
-        humanRewritingFlags2.getDontRewriteInvocation());
-    assertEquals(
         humanRewritingFlags1.getWrapperConversions(), humanRewritingFlags2.getWrapperConversions());
 
     assertEquals(
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
index cdc0788..cb2370b 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.test;
 
+import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.D8TestBuilder;
@@ -58,7 +59,7 @@
   private String l8ExtraKeepRules = "";
   private Consumer<InternalOptions> l8OptionModifier = ConsumerUtils.emptyConsumer();
   private boolean l8FinalPrefixVerification = true;
-  private boolean overrideDefaultLibraryFiles = false;
+  private boolean overrideDefaultLibrary = false;
   private CustomLibrarySpecification customLibrarySpecification = null;
   private TestingKeepRuleConsumer keepRuleConsumer = null;
   private List<ExternalArtProfile> l8ResidualArtProfiles = new ArrayList<>();
@@ -163,11 +164,18 @@
    * library files.
    */
   public DesugaredLibraryTestBuilder<T> overrideLibraryFiles(Path... files) {
-    overrideDefaultLibraryFiles = true;
+    overrideDefaultLibrary = true;
     builder.addLibraryFiles(files);
     return this;
   }
 
+  public DesugaredLibraryTestBuilder<T> overrideLibraryProvider(
+      ClassFileResourceProvider provider) {
+    overrideDefaultLibrary = true;
+    builder.addLibraryProvider(provider);
+    return this;
+  }
+
   public DesugaredLibraryTestBuilder<T> addProgramFiles(Collection<Path> files) {
     builder.addProgramFiles(files);
     return this;
@@ -373,7 +381,7 @@
   }
 
   private void prepareCompilation() {
-    if (overrideDefaultLibraryFiles) {
+    if (overrideDefaultLibrary) {
       return;
     }
     builder.addLibraryFiles(libraryDesugaringSpecification.getLibraryFiles());
diff --git a/src/test/java/com/android/tools/r8/dex/TryCatchRangeOverflowTest.java b/src/test/java/com/android/tools/r8/dex/TryCatchRangeOverflowTest.java
index e9caf80..6e9d85c 100644
--- a/src/test/java/com/android/tools/r8/dex/TryCatchRangeOverflowTest.java
+++ b/src/test/java/com/android/tools/r8/dex/TryCatchRangeOverflowTest.java
@@ -20,28 +20,28 @@
 import com.android.tools.r8.ir.code.InstructionListIterator;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import java.util.Arrays;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
 // Regression test for b/297320921
 @RunWith(Parameterized.class)
 public class TryCatchRangeOverflowTest extends TestBase {
 
-  private final TestParameters parameters;
+  @Parameter(0)
+  public TestParameters parameters;
 
-  @Parameterized.Parameters(name = "{0}")
+  @Parameters(name = "{0}")
   public static TestParametersCollection data() {
     return getTestParameters().withDefaultDexRuntime().withMinimumApiLevel().build();
   }
 
-  public TryCatchRangeOverflowTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
   // Each add/2addr instruction has size 1, so we add have as many instruction minus some padding
   // to make room for the instructions before and after but still in the same block.
   // Notice that this value may change if the generated code by the compiler changes. It must then
@@ -80,7 +80,10 @@
       compile(addCount)
           .run(parameters.getRuntime(), TestClass.class)
           .assertSuccessWithOutputLines("" + addCount)
-          .inspect(inspector -> checkTryCatchHandlers(2, inspector));
+          .inspect(
+              inspector ->
+                  checkTryCatchHandlers(
+                      1 + BooleanUtils.intValue(addCount > UNSPLIT_LIMIT + 1), inspector));
     }
   }
 
@@ -112,16 +115,17 @@
     compile(addCount)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutputLines("" + addCount)
-        .inspect(inspector -> checkTryCatchHandlers(3, inspector));
+        .inspect(inspector -> checkTryCatchHandlers(2, inspector));
   }
 
-  private D8TestBuilder compile(int addCount) throws Exception {
+  private D8TestBuilder compile(int addCount) {
     return testForD8(Backend.DEX)
         .addProgramClasses(TestClass.class)
         .addOptionsModification(
             o ->
                 o.testing.irModifier =
                     (code, appView) -> amendCodeWithAddInstructions(addCount, code))
+        .debug()
         .setMinApi(parameters);
   }
 
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/IdempotentFunctionCallCanonicalizationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/IdempotentFunctionCallCanonicalizationTest.java
index 8fa15d0..da15c99 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/IdempotentFunctionCallCanonicalizationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/IdempotentFunctionCallCanonicalizationTest.java
@@ -198,8 +198,8 @@
 
     D8TestRunResult result =
         testForD8()
-            .debug()
             .addProgramClasses(MAIN)
+            .release()
             .setMinApi(parameters)
             .run(parameters.getRuntime(), MAIN)
             .assertSuccessWithOutput(JAVA_OUTPUT);
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java
index 5c22e9f..fd8154f 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java
@@ -34,7 +34,6 @@
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
-import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -68,16 +67,6 @@
     }
   }
 
-  public static Path getKeepAnnoPath() {
-    // TODO(b/270105162): This changes when new gradle setup is default.
-    if (ToolHelper.isNewGradleSetup()) {
-      return Paths.get(
-          System.getProperty("KEEP_ANNO_JAVAC_BUILD_DIR").split(File.pathSeparator)[0]);
-    } else {
-      return Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "keepanno");
-    }
-  }
-
   private static List<Class<?>> getTestClasses() {
     return ImmutableList.of(
         KeepClassAndDefaultConstructorSource.class,
@@ -112,7 +101,7 @@
     Path out =
         JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
             .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
-            .addClasspathFiles(getKeepAnnoPath())
+            .addClasspathFiles(ToolHelper.getKeepAnnoPath())
             .addClassNames(Collections.singletonList(typeName(source)))
             .addClasspathFiles(Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "test"))
             .addClasspathFiles(ToolHelper.getR8WithRelocatedDeps())
@@ -137,7 +126,7 @@
         JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
             .addSourceFiles(ToolHelper.getSourceFileForTestClass(source))
             .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
-            .addClasspathFiles(getKeepAnnoPath())
+            .addClasspathFiles(ToolHelper.getKeepAnnoPath())
             .addClasspathFiles(ToolHelper.getDeps())
             .compile();
     testForJvm(parameters)
diff --git a/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java b/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
index 64f9378..602ee63 100644
--- a/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
@@ -45,22 +45,34 @@
         KeepEdge.builder()
             .setConsequences(
                 KeepConsequences.builder()
-                    .addTarget(KeepTarget.builder().setItemPattern(KeepItemPattern.any()).build())
+                    .addTarget(
+                        KeepTarget.builder().setItemPattern(KeepItemPattern.anyClass()).build())
+                    .addTarget(
+                        KeepTarget.builder().setItemPattern(KeepItemPattern.anyMember()).build())
                     .build())
             .build();
-    assertEquals(StringUtils.unixLines("-keep class * { *; }"), extract(edge));
+    assertEquals(
+        StringUtils.unixLines(
+            "-keep class * { void finalize(); }", "-keepclassmembers class * { *; }"),
+        extract(edge));
   }
 
   @Test
   public void testSoftPinViaDisallow() {
+    KeepOptions disallowOptions = KeepOptions.disallow(KeepOption.OPTIMIZING);
     KeepEdge edge =
         KeepEdge.builder()
             .setConsequences(
                 KeepConsequences.builder()
                     .addTarget(
                         KeepTarget.builder()
-                            .setItemPattern(KeepItemPattern.any())
-                            .setOptions(KeepOptions.disallow(KeepOption.OPTIMIZING))
+                            .setItemPattern(KeepItemPattern.anyClass())
+                            .setOptions(disallowOptions)
+                            .build())
+                    .addTarget(
+                        KeepTarget.builder()
+                            .setItemPattern(KeepItemPattern.anyMember())
+                            .setOptions(disallowOptions)
                             .build())
                     .build())
             .build();
@@ -70,26 +82,37 @@
     String allows = String.join(",allow", options);
     // The "any" item will be split in two rules, one for the targeted types and one for the
     // targeted members.
-    assertEquals(StringUtils.unixLines("-keep,allow" + allows + " class * { *; }"), extract(edge));
+    assertEquals(
+        StringUtils.unixLines(
+            "-keep,allow" + allows + " class * { void finalize(); }",
+            "-keepclassmembers,allow" + allows + " class * { *; }"),
+        extract(edge));
   }
 
   @Test
   public void testSoftPinViaAllow() {
+    KeepOptions allowOptions = KeepOptions.allow(KeepOption.OBFUSCATING, KeepOption.SHRINKING);
     KeepEdge edge =
         KeepEdge.builder()
             .setConsequences(
                 KeepConsequences.builder()
                     .addTarget(
                         KeepTarget.builder()
-                            .setItemPattern(KeepItemPattern.any())
-                            .setOptions(
-                                KeepOptions.allow(KeepOption.OBFUSCATING, KeepOption.SHRINKING))
+                            .setItemPattern(KeepItemPattern.anyClass())
+                            .setOptions(allowOptions)
+                            .build())
+                    .addTarget(
+                        KeepTarget.builder()
+                            .setItemPattern(KeepItemPattern.anyMember())
+                            .setOptions(allowOptions)
                             .build())
                     .build())
             .build();
     // Allow is just the ordered list of options.
     assertEquals(
-        StringUtils.unixLines("-keep,allowshrinking,allowobfuscation class * { *; }"),
+        StringUtils.unixLines(
+            "-keep,allowshrinking,allowobfuscation class * { void finalize(); }",
+            "-keepclassmembers,allowshrinking,allowobfuscation class * { *; }"),
         extract(edge));
   }
 
diff --git a/src/test/java/com/android/tools/r8/regress/b115552239/B115552239.java b/src/test/java/com/android/tools/r8/regress/b115552239/B115552239.java
index 5cffb1a..cabd159 100644
--- a/src/test/java/com/android/tools/r8/regress/b115552239/B115552239.java
+++ b/src/test/java/com/android/tools/r8/regress/b115552239/B115552239.java
@@ -10,7 +10,11 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.D8Command;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.code.DexCmpgFloat;
 import com.android.tools.r8.dex.code.DexIfGez;
@@ -26,6 +30,9 @@
 import java.util.Arrays;
 import java.util.concurrent.ExecutionException;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 class TestClass {
   public float f(float d) {
@@ -36,7 +43,17 @@
   }
 }
 
-public class B115552239 {
+@RunWith(Parameterized.class)
+public class B115552239 extends TestBase {
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public B115552239(TestParameters parameters) {
+    parameters.assertNoneRuntime();
+  }
 
   private MethodSubject compileTestClassAndGetMethod(int apiLevel)
       throws IOException, CompilationFailedException {
@@ -44,7 +61,8 @@
         ToolHelper.runD8(
             D8Command.builder()
                 .addClassProgramData(ToolHelper.getClassAsBytes(TestClass.class), Origin.unknown())
-                .setMinApiLevel(apiLevel));
+                .setMinApiLevel(apiLevel)
+                .setMode(CompilationMode.RELEASE));
     CodeInspector inspector = new CodeInspector(app);
     ClassSubject clazz = inspector.clazz(TestClass.class);
     assertThat(clazz, isPresent());
@@ -72,8 +90,7 @@
   }
 
   @Test
-  public void lowering()
-      throws IOException, CompilationFailedException, ExecutionException {
+  public void lowering() throws IOException, CompilationFailedException {
     MethodSubject method = compileTestClassAndGetMethod(AndroidApiLevel.M.getLevel());
     boolean previousWasCmp = false;
     DexInstruction[] instructions = method.getMethod().getCode().asDexCode().instructions;
diff --git a/src/test/java/com/android/tools/r8/utils/NumberOfThreadsTest.java b/src/test/java/com/android/tools/r8/utils/NumberOfThreadsTest.java
deleted file mode 100644
index 4613f76..0000000
--- a/src/test/java/com/android/tools/r8/utils/NumberOfThreadsTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.utils;
-
-import org.junit.Test;
-
-public class NumberOfThreadsTest {
-
-  @Test(expected = IllegalArgumentException.class)
-  public void zeroProcessorTest() {
-    ThreadUtils.getExecutorServiceForProcessors(0).shutdown();
-  }
-
-  @Test
-  public void singleProcessorTest() {
-    ThreadUtils.getExecutorServiceForProcessors(1).shutdown();
-  }
-
-  @Test
-  public void twoProcessorsTest() {
-    ThreadUtils.getExecutorServiceForProcessors(2).shutdown();
-  }
-
-}
diff --git a/src/test/java/com/android/tools/r8/utils/Smali.java b/src/test/java/com/android/tools/r8/utils/Smali.java
index ade911f..29c6b92 100644
--- a/src/test/java/com/android/tools/r8/utils/Smali.java
+++ b/src/test/java/com/android/tools/r8/utils/Smali.java
@@ -108,7 +108,7 @@
     InternalOptions options = new InternalOptions();
     options.setMinApiLevel(AndroidApiLevel.getAndroidApiLevel(apiLevel));
     options.programConsumer = consumer;
-    ExecutorService executor = ThreadUtils.getExecutorService(1);
+    ExecutorService executor = options.getThreadingModule().createThreadedExecutorService(1);
     try {
       DexApplication dexApp = new ApplicationReader(app, options, Timing.empty()).read(executor);
       ApplicationWriter writer =
diff --git a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1 b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
index 1f5ebb0..009f4e4 100644
--- a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
+++ b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
@@ -1 +1 @@
-28372bad4c1dc0bd9f0615d14def4dd687c3e6c6
\ No newline at end of file
+9de592304071fa794e07e9e8d955aa4ae62cdef1
\ No newline at end of file
diff --git a/tools/archive.py b/tools/archive.py
index eb4ab98..fd250dd 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -175,7 +175,6 @@
                 utils.GRADLE_TASK_R8LIB, utils.GRADLE_TASK_R8LIB_NO_DEPS,
                 utils.GRADLE_TASK_THREADING_MODULE_BLOCKING,
                 utils.GRADLE_TASK_THREADING_MODULE_SINGLE_THREADED,
-                utils.GRADLE_TASK_RETRACE, utils.GRADLE_TASK_RETRACE_NO_DEPS,
                 utils.GRADLE_TASK_SOURCE_JAR,
                 utils.GRADLE_TASK_SWISS_ARMY_KNIFE, '-Pno_internal'
             ])
@@ -243,10 +242,6 @@
             utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL_MAVEN_ZIP,
             utils.DESUGAR_CONFIGURATION_JDK11_MAVEN_ZIP,
             utils.DESUGAR_CONFIGURATION_JDK11_NIO_MAVEN_ZIP, utils.R8_SRC_JAR,
-            utils.R8RETRACE_JAR, utils.R8RETRACE_JAR + '.map',
-            utils.R8RETRACE_JAR + '_map.zip', utils.R8RETRACE_EXCLUDE_DEPS_JAR,
-            utils.R8RETRACE_EXCLUDE_DEPS_JAR + '.map',
-            utils.R8RETRACE_EXCLUDE_DEPS_JAR + '_map.zip',
             utils.KEEPANNO_ANNOTATIONS_JAR,
             utils.GENERATED_LICENSE,
             'd8_r8/main/build/spdx/r8.spdx.json'
diff --git a/tools/create_r8lib.py b/tools/create_r8lib.py
index 93bfcbd..e8bf4f2 100755
--- a/tools/create_r8lib.py
+++ b/tools/create_r8lib.py
@@ -94,6 +94,7 @@
         cmd.extend([
             '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'
         ])
+    cmd.append('-Dcom.android.tools.r8.enableKeepAnnotations=1')
     cmd.extend(['-cp', args.r8compiler, 'com.android.tools.r8.R8'])
     cmd.append(args.r8jar)
     if args.debug_variant:
diff --git a/tools/r8_get.py b/tools/r8_get.py
index 44cc9f1..4dfc924 100755
--- a/tools/r8_get.py
+++ b/tools/r8_get.py
@@ -21,13 +21,18 @@
         '--outdir',
         help='Output directory to place the r8.jar in (default cwd).',
         default=None)
+    parser.add_argument(
+        '--nolib',
+        help='Use the non-lib distribution (default uses the lib distribution)',
+        default=False,
+        action='store_true')
     return parser.parse_args()
 
 
 def main():
     args = parse_arguments()
     outdir = args.outdir if args.outdir else ''
-    print(compiledump.download_distribution(args.version, True, outdir))
+    print(compiledump.download_distribution(args.version, args, outdir))
     return 0
 
 
diff --git a/tools/r8_release.py b/tools/r8_release.py
index f55181e..a5d7a4c 100755
--- a/tools/r8_release.py
+++ b/tools/r8_release.py
@@ -99,10 +99,6 @@
                       'is the same as exiting release (%s).' % old_version)
                     sys.exit(1)
 
-                subprocess.check_call(
-                    ['git', 'cl', 'new-branch',
-                     'release-%s' % version])
-
                 if args.dev_pre_cherry_pick:
                     for pre_commit in args.dev_pre_cherry_pick:
                         subprocess.check_call(
@@ -316,6 +312,13 @@
     assert args.version
     assert os.path.exists(args.studio), ("Could not find STUDIO path %s" %
                                          args.studio)
+    if (not args.studio.endswith('-dev')
+        and not args.studio.endswith('-dev/')
+        and not args.studio_legacy_release):
+        print("Please use the new release process, see go/r8-release-prebuilts. "
+            + "If for some reason the legacy release process is needed "
+            + "pass --studio-legacy-release")
+        sys.exit(1)
 
     def release_studio(options):
         print("Releasing for STUDIO")
@@ -421,9 +424,6 @@
             g4_open('src.jar')
             g4_open('lib.jar')
             g4_open('lib.jar.map')
-            g4_open('retrace_full.jar')
-            g4_open('retrace_lib.jar')
-            g4_open('retrace_lib.jar.map')
             g4_open('desugar_jdk_libs_configuration.jar')
             g4_open('threading-module-blocking.jar')
             g4_open('threading-module-single-threaded.jar')
@@ -431,9 +431,6 @@
                           'r8-full-exclude-deps.jar',
                           'full.jar')
             download_file(options.version,
-                          'r8-full-exclude-deps.jar',
-                          'retrace_full.jar')
-            download_file(options.version,
                           'r8-src.jar',
                           'src.jar')
             download_file(options.version,
@@ -446,12 +443,6 @@
                           'desugar_jdk_libs_configuration.jar',
                           'desugar_jdk_libs_configuration.jar')
             download_file(options.version,
-                          'r8retrace-exclude-deps.jar',
-                          'retrace_lib.jar')
-            download_file(options.version,
-                          'r8retrace-exclude-deps.jar.map',
-                          'retrace_lib.jar.map')
-            download_file(options.version,
                           'threading-module-blocking.jar',
                           'threading-module-blocking.jar')
             download_file(options.version,
@@ -461,7 +452,7 @@
                 g4_open('METADATA')
                 metadata_path = os.path.join(third_party_r8, 'METADATA')
                 match_count = 0
-                match_count_expected = 12
+                match_count_expected = 11
                 version_match_regexp = r'[1-9]\.[0-9]{1,2}\.[0-9]{1,3}-dev'
                 for line in open(metadata_path, 'r'):
                     result = re.search(version_match_regexp, line)
@@ -502,74 +493,6 @@
     return release_google3
 
 
-def prepare_google3_retrace(args):
-    assert args.version
-    # Check if an existing client exists.
-    if not args.use_existing_work_branch:
-        check_no_google3_client(args, args.p4_client)
-
-    def release_google3_retrace(options):
-        print("Releasing Retrace for Google 3")
-        if options.dry_run:
-            return 'DryRun: omitting g3 release for %s' % options.version
-
-        google3_base = subprocess.check_output(
-            ['p4', 'g4d', '-f', args.p4_client]).decode('utf-8').rstrip()
-        third_party_r8 = os.path.join(google3_base, 'third_party', 'java', 'r8')
-        with utils.ChangedWorkingDirectory(third_party_r8):
-            # download files
-            g4_open('retrace_full.jar')
-            g4_open('retrace_lib.jar')
-            g4_open('retrace_lib.jar.map')
-            download_file(options.version, 'r8-full-exclude-deps.jar',
-                          'retrace_full.jar')
-            download_file(options.version, 'r8retrace-exclude-deps.jar',
-                          'retrace_lib.jar')
-            download_file(options.version, 'r8lib-exclude-deps.jar.map',
-                          'retrace_lib.jar.map')
-            g4_open('METADATA')
-            metadata_path = os.path.join(third_party_r8, 'METADATA')
-            match_count = 0
-            version_match_regexp = r'[1-9]\.[0-9]{1,2}\.[0-9]{1,3}-dev/r8retrace-exclude-deps.jar'
-            for line in open(metadata_path, 'r'):
-                result = re.search(version_match_regexp, line)
-                if result:
-                    match_count = match_count + 1
-            if match_count != 1:
-                print((
-                    "Could not find the previous retrace release string to replace in "
-                    +
-                    "METADATA. Expected to find is mentioned 1 times. Please update %s "
-                    + "manually and run again with options --google3retrace " +
-                    "--use-existing-work-branch.") % metadata_path)
-                sys.exit(1)
-            sed(version_match_regexp,
-                options.version + "/r8retrace-exclude-deps.jar", metadata_path)
-            subprocess.check_output('chmod u+w *', shell=True)
-
-        with utils.ChangedWorkingDirectory(google3_base):
-            blaze_result = blaze_run(
-                '//third_party/java/r8:retrace -- --version')
-
-            print(blaze_result)
-            assert options.version in blaze_result
-
-            if not options.no_upload:
-                change_result = g4_change(options.version)
-                change_result += 'Run \'(g4d ' + args.p4_client \
-                                 + ' && tap_presubmit -p all --train -c ' \
-                                 + get_cl_id(change_result) + ')\' for running TAP global' \
-                                 + ' presubmit using the train.\n' \
-                                 + 'Run \'(g4d ' + args.p4_client \
-                                 + ' && tap_presubmit -p all --notrain --detach --email' \
-                                 + ' --skip_flaky_targets --skip_already_failing -c ' \
-                                 + get_cl_id(change_result) + ')\' for running an isolated' \
-                                 + ' TAP global presubmit.'
-                return change_result
-
-    return release_google3_retrace
-
-
 def update_desugar_library_in_studio(args):
     assert os.path.exists(args.studio), ("Could not find STUDIO path %s" %
                                          args.studio)
@@ -1040,6 +963,10 @@
         metavar=('<path>'),
         help='Release for studio by setting the path to a studio '
         'checkout')
+    result.add_argument('--studio-legacy-release',
+                        default=False,
+                        action='store_true',
+                        help='Allow Studio release using the legacy process')
     result.add_argument('--aosp',
                         metavar=('<path>'),
                         help='Release for aosp by setting the path to the '
@@ -1052,10 +979,6 @@
                         default=False,
                         action='store_true',
                         help='Release for google 3')
-    result.add_argument('--google3retrace',
-                        default=False,
-                        action='store_true',
-                        help='Release retrace for google 3')
     result.add_argument('--p4-client',
                         default='update-r8',
                         metavar=('<client name>'),
@@ -1130,8 +1053,6 @@
 
     if args.google3:
         targets_to_run.append(prepare_google3(args))
-    if args.google3retrace:
-        targets_to_run.append(prepare_google3_retrace(args))
     if args.studio and not args.update_desugar_library_in_studio:
         targets_to_run.append(prepare_studio(args))
     if args.aosp:
diff --git a/tools/retrace.py b/tools/retrace.py
index 6642224..911c646 100755
--- a/tools/retrace.py
+++ b/tools/retrace.py
@@ -188,7 +188,7 @@
         )
 
     if not r8jar:
-        r8jar = utils.R8_JAR if no_r8lib else utils.R8RETRACE_JAR
+        r8jar = utils.R8_JAR if no_r8lib else utils.R8LIB
 
     retrace_args += [
         '-cp', r8jar, 'com.android.tools.r8.retrace.Retrace', map_path
diff --git a/tools/run_benchmark.py b/tools/run_benchmark.py
index f98c8b7..7e0c692 100755
--- a/tools/run_benchmark.py
+++ b/tools/run_benchmark.py
@@ -132,7 +132,6 @@
         cmd.append('-Dcom.android.tools.r8.printtimes=1')
     if not options.golem:
         cmd.extend([
-            '-DUSE_NEW_GRADLE_SETUP=true',
             f'-DTEST_DATA_LOCATION={utils.REPO_ROOT}/d8_r8/test_modules/tests_java_8/build/classes/java/test'
         ])
     cmd.extend(['-cp', ':'.join([r8jar] + testjars)])
diff --git a/tools/run_on_app_dump.py b/tools/run_on_app_dump.py
index 902c675..c06e878 100755
--- a/tools/run_on_app_dump.py
+++ b/tools/run_on_app_dump.py
@@ -23,7 +23,7 @@
 import update_prebuilds_in_android
 import utils
 
-GOLEM_BUILD_TARGETS = [utils.GRADLE_TASK_R8LIB, utils.GRADLE_TASK_RETRACE]
+GOLEM_BUILD_TARGETS = [utils.GRADLE_TASK_R8LIB]
 SHRINKERS = ['r8', 'r8-full', 'r8-nolib', 'r8-nolib-full']
 
 
@@ -1287,7 +1287,7 @@
         elif options.version == 'main':
             if not options.no_build:
                 gradle.RunGradle([
-                    utils.GRADLE_TASK_RETRACE, utils.GRADLE_TASK_R8,
+                    utils.GRADLE_TASK_R8,
                     '-Pno_internal'
                 ])
                 build_r8lib = False
diff --git a/tools/utils.py b/tools/utils.py
index 4b84f58..597f8b1 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -48,8 +48,6 @@
 GRADLE_TASK_R8LIB_NO_DEPS = ':test:assembleR8LibNoDeps'
 GRADLE_TASK_THREADING_MODULE_BLOCKING = ':main:threadingModuleBlockingJar'
 GRADLE_TASK_THREADING_MODULE_SINGLE_THREADED = ':main:threadingModuleSingleThreadedJar'
-GRADLE_TASK_RETRACE = ':test:assembleRetraceLibWithRelocatedDeps'
-GRADLE_TASK_RETRACE_NO_DEPS = ':test:assembleRetraceLibNoDeps'
 GRADLE_TASK_SOURCE_JAR = ':test:packageSources'
 GRADLE_TASK_SWISS_ARMY_KNIFE = ':main:swissArmyKnife'
 GRADLE_TASK_TEST = ':test:test'
@@ -69,8 +67,6 @@
 R8_FULL_EXCLUDE_DEPS_JAR = os.path.join(LIBS, 'r8-full-exclude-deps.jar')
 THREADING_MODULE_BLOCKING_JAR = os.path.join(LIBS, 'threading-module-blocking.jar')
 THREADING_MODULE_SINGLE_THREADED_JAR = os.path.join(LIBS, 'threading-module-single-threaded.jar')
-R8RETRACE_JAR = os.path.join(LIBS, 'r8retrace.jar')
-R8RETRACE_EXCLUDE_DEPS_JAR = os.path.join(LIBS, 'r8retrace-exclude-deps.jar')
 R8_TESTS_JAR = os.path.join(LIBS, 'r8tests.jar')
 R8LIB_TESTS_JAR = os.path.join(LIBS, 'r8libtestdeps-cf.jar')
 R8_TESTS_DEPS_JAR = os.path.join(LIBS, 'test_deps_all.jar')
@@ -678,13 +674,13 @@
                             configuration)
         if (configuration_format_version != 3 and
                 configuration_format_version != 5 and
-                configuration_format_version != (200 if is_for_maven else 100)):
+                configuration_format_version != (200 if is_for_maven else 101)):
             raise Exception(
                 'Unsupported "configuration_format_version" "%s" found in %s' %
                 (configuration_format_version, configuration))
         version = configuration_json.get('version')
         if not version:
-            if configuration_format_version == (200 if is_for_maven else 100):
+            if configuration_format_version == (200 if is_for_maven else 101):
                 identifier = configuration_json.get('identifier')
                 if not identifier:
                     raise Exception('No "identifier" found in ' + configuration)
@@ -704,7 +700,7 @@
             else:
                 raise Exception('No "version" found in ' + configuration)
         else:
-            if configuration_format_version == (200 if is_for_maven else 100):
+            if configuration_format_version == (200 if is_for_maven else 101):
                 raise Exception('No "version" expected in ' + configuration)
         # Disallow prerelease, as older R8 versions cannot parse it causing hard to
         # understand errors.