Merge commit '8bbb7f953bd996e6fbe91f2d306f2dca74de43fa' into dev-release
diff --git a/build.gradle b/build.gradle
index 4428f58..693cdba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -334,6 +334,7 @@
                 "openjdk/jdk-11-test",
                 "proguard/proguard5.2.1",
                 "proguard/proguard6.0.1",
+                "proguard/proguard-7.0.0",
                 "r8",
                 "r8-releases/2.0.74",
                 "r8mappings",
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index 0b1fead..c8d6295 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -49,6 +49,11 @@
     return extractMarker(appBuilder.build());
   }
 
+  public static Collection<Marker> extractMarkerFromJarFile(Path file)
+      throws IOException, ExecutionException {
+    return extractMarker(AndroidApp.builder().addProgramFile(file).build());
+  }
+
   public static int extractDexSize(Path file) throws IOException, ResourceException {
     AndroidApp.Builder appBuilder = AndroidApp.builder();
     addDexResources(appBuilder, file);
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index e116676..48f2f7a 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -25,6 +25,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.function.BiPredicate;
 import java.util.function.Consumer;
 
 /** Immutable command structure for an invocation of the {@link L8} library compiler. */
@@ -86,6 +87,8 @@
       StringConsumer mainDexListConsumer,
       int minApiLevel,
       Reporter diagnosticsHandler,
+      boolean encodeChecksum,
+      BiPredicate<String, Long> dexClassChecksumFilter,
       DesugaredLibraryConfiguration libraryConfiguration,
       List<AssertionsConfiguration> assertionsConfiguration,
       List<Consumer<Inspector>> outputInspections,
@@ -100,8 +103,8 @@
         diagnosticsHandler,
         DesugarState.ON,
         false,
-        false,
-        (name, checksum) -> true,
+        encodeChecksum,
+        dexClassChecksumFilter,
         assertionsConfiguration,
         outputInspections,
         threadCount);
@@ -296,6 +299,8 @@
                     libraryConfiguration.getSynthesizedLibraryClassesPackagePrefix())
                 .setMinApiLevel(getMinApiLevel())
                 .setMode(getMode())
+                .setIncludeClassesChecksum(getIncludeClassesChecksum())
+                .setDexClassChecksumFilter(getDexClassChecksumFilter())
                 .setProgramConsumer(getProgramConsumer());
         for (ClassFileResourceProvider libraryResourceProvider :
             inputs.getLibraryResourceProviders()) {
@@ -316,6 +321,8 @@
                     libraryConfiguration.getSynthesizedLibraryClassesPackagePrefix())
                 .setMinApiLevel(getMinApiLevel())
                 .setMode(getMode())
+                .setIncludeClassesChecksum(getIncludeClassesChecksum())
+                .setDexClassChecksumFilter(getDexClassChecksumFilter())
                 .setProgramConsumer(getProgramConsumer());
         for (ClassFileResourceProvider libraryResourceProvider :
             inputs.getLibraryResourceProviders()) {
@@ -332,6 +339,8 @@
           getMainDexListConsumer(),
           getMinApiLevel(),
           getReporter(),
+          getIncludeClassesChecksum(),
+          getDexClassChecksumFilter(),
           libraryConfiguration,
           getAssertionsConfiguration(),
           getOutputInspections(),
diff --git a/src/main/java/com/android/tools/r8/dex/Marker.java b/src/main/java/com/android/tools/r8/dex/Marker.java
index 1484f02..e15a4eb 100644
--- a/src/main/java/com/android/tools/r8/dex/Marker.java
+++ b/src/main/java/com/android/tools/r8/dex/Marker.java
@@ -88,6 +88,9 @@
                 new StringDiagnostic(
                     "Merging program compiled with multiple desugared libraries."));
         }
+        if (identifier.equals(NO_LIBRARY_DESUGARING) && marker.tool == Tool.R8) {
+          continue;
+        }
         desugaredLibraryIdentifiers.add(identifier);
       }
     }
@@ -131,6 +134,10 @@
     return this;
   }
 
+  public boolean hasMinApi() {
+    return jsonObject.has(MIN_API);
+  }
+
   public Long getMinApi() {
     return jsonObject.get(MIN_API).getAsLong();
   }
@@ -141,6 +148,10 @@
     return this;
   }
 
+  public boolean hasDesugaredLibraryIdentifiers() {
+    return jsonObject.has(DESUGARED_LIBRARY_IDENTIFIERS);
+  }
+
   public String[] getDesugaredLibraryIdentifiers() {
     if (jsonObject.has(DESUGARED_LIBRARY_IDENTIFIERS)) {
       JsonArray array = jsonObject.get(DESUGARED_LIBRARY_IDENTIFIERS).getAsJsonArray();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index cfb48f2..be1bbfd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -50,10 +50,10 @@
 
   private final AppView<?> appView;
   private final Map<DexMethod, DexMethod> retargetLibraryMember = new IdentityHashMap<>();
-  // Map virtualRewrites hold a methodName->method mapping for virtual methods which are
-  // rewritten while the holder is non final but no superclass implement the method. In this case
-  // d8 needs to force resolution of given methods to see if the invoke needs to be rewritten.
-  private final Map<DexString, List<DexMethod>> virtualRewrites = new IdentityHashMap<>();
+  // Map nonFinalRewrite hold a methodName -> method mapping for methods which are rewritten while
+  // the holder is non final. In this case d8 needs to force resolution of given methods to see if
+  // the invoke needs to be rewritten.
+  private final Map<DexString, List<DexMethod>> nonFinalHolderRewrites = new IdentityHashMap<>();
   // Non final virtual library methods requiring generation of emulated dispatch.
   private final Set<DexEncodedMethod> emulatedDispatchMethods = Sets.newIdentityHashSet();
 
@@ -107,7 +107,7 @@
       InvokeMethod invoke = instruction.asInvokeMethod();
       DexMethod retarget = getRetargetLibraryMember(invoke.getInvokedMethod());
       if (retarget == null) {
-        if (!matchesVirtualRewrite(invoke.getInvokedMethod())) {
+        if (!matchesNonFinalHolderRewrite(invoke.getInvokedMethod())) {
           continue;
         }
         // We need to force resolution, even on d8, to know if the invoke has to be rewritten.
@@ -128,7 +128,7 @@
 
       // Due to emulated dispatch, we have to rewrite invoke-super differently or we end up in
       // infinite loops. We do direct resolution. This is a very uncommon case.
-      if (invoke.isInvokeSuper() && matchesVirtualRewrite(invoke.getInvokedMethod())) {
+      if (invoke.isInvokeSuper() && matchesNonFinalHolderRewrite(invoke.getInvokedMethod())) {
         DexEncodedMethod dexEncodedMethod =
             appView
                 .appInfoForDesugaring()
@@ -163,8 +163,8 @@
     return retargetLibraryMember.get(method);
   }
 
-  private boolean matchesVirtualRewrite(DexMethod method) {
-    List<DexMethod> dexMethods = virtualRewrites.get(method.name);
+  private boolean matchesNonFinalHolderRewrite(DexMethod method) {
+    List<DexMethod> dexMethods = nonFinalHolderRewrites.get(method.name);
     if (dexMethods == null) {
       return false;
     }
@@ -188,17 +188,19 @@
             DexType newHolder = retargetCoreLibMember.get(methodName).get(inType);
             List<DexEncodedMethod> found = findDexEncodedMethodsWithName(methodName, typeClass);
             for (DexEncodedMethod encodedMethod : found) {
-              if (!encodedMethod.isStatic()) {
-                virtualRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
-                virtualRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
-                if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
-                  // In this case interface method rewriter takes care of it.
-                  continue;
-                } else if (!encodedMethod.isFinal()) {
-                  // Virtual rewrites require emulated dispatch for inheritance.
-                  // The call is rewritten to the dispatch holder class instead.
-                  handleEmulateDispatch(appView, encodedMethod);
-                  newHolder = dispatchHolderTypeFor(encodedMethod);
+              if (!typeClass.isFinal()) {
+                nonFinalHolderRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
+                nonFinalHolderRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
+                if (!encodedMethod.isStatic()) {
+                  if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
+                    // In this case interface method rewriter takes care of it.
+                    continue;
+                  } else if (!encodedMethod.isFinal()) {
+                    // Virtual rewrites require emulated dispatch for inheritance.
+                    // The call is rewritten to the dispatch holder class instead.
+                    handleEmulateDispatch(appView, encodedMethod);
+                    newHolder = dispatchHolderTypeFor(encodedMethod);
+                  }
                 }
               }
               DexProto proto = encodedMethod.method.proto;
diff --git a/src/test/java/com/android/tools/r8/GenerateMainDexListTestBuilder.java b/src/test/java/com/android/tools/r8/GenerateMainDexListTestBuilder.java
index e0f3cea..6b5829b 100644
--- a/src/test/java/com/android/tools/r8/GenerateMainDexListTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/GenerateMainDexListTestBuilder.java
@@ -56,6 +56,16 @@
     throw new Unimplemented("No support for run class path");
   }
 
+  @Override
+  public GenerateMainDexListTestBuilder addClasspathClasses(Collection<Class<?>> classes) {
+    throw new Unimplemented("No support for class path");
+  }
+
+  @Override
+  public GenerateMainDexListTestBuilder addClasspathFiles(Collection<Path> files) {
+    throw new Unimplemented("No support for class path");
+  }
+
   public GenerateMainDexListRunResult run() throws CompilationFailedException {
     return new GenerateMainDexListRunResult(GenerateMainDexList.run(builder.build()));
   }
diff --git a/src/test/java/com/android/tools/r8/JvmTestBuilder.java b/src/test/java/com/android/tools/r8/JvmTestBuilder.java
index 18571d0..97e244b 100644
--- a/src/test/java/com/android/tools/r8/JvmTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/JvmTestBuilder.java
@@ -82,6 +82,16 @@
   }
 
   @Override
+  public JvmTestBuilder addClasspathClasses(Collection<Class<?>> classes) {
+    return addClasspath(writeClassesToJar(classes));
+  }
+
+  @Override
+  public JvmTestBuilder addClasspathFiles(Collection<Path> files) {
+    return addClasspath(files);
+  }
+
+  @Override
   public JvmTestBuilder addRunClasspathFiles(Collection<Path> files) {
     return addClasspath(files);
   }
diff --git a/src/test/java/com/android/tools/r8/MarkerMatcher.java b/src/test/java/com/android/tools/r8/MarkerMatcher.java
index 90aec54..13065b7 100644
--- a/src/test/java/com/android/tools/r8/MarkerMatcher.java
+++ b/src/test/java/com/android/tools/r8/MarkerMatcher.java
@@ -117,6 +117,20 @@
     };
   }
 
+  public static Matcher<Marker> markerHasMinApi() {
+    return new MarkerMatcher() {
+      @Override
+      protected boolean eval(Marker marker) {
+        return marker.hasMinApi();
+      }
+
+      @Override
+      protected void explain(Description description) {
+        description.appendText(Marker.MIN_API + " found");
+      }
+    };
+  }
+
   public static Matcher<Marker> markerHasChecksums(boolean value) {
     return new MarkerMatcher() {
       @Override
@@ -165,6 +179,25 @@
     };
   }
 
+  public static Matcher<Marker> markerHasDesugaredLibraryIdentifier() {
+    return markerHasDesugaredLibraryIdentifier(true);
+  }
+
+  public static Matcher<Marker> markerHasDesugaredLibraryIdentifier(boolean value) {
+    return new MarkerMatcher() {
+      @Override
+      protected boolean eval(Marker marker) {
+        return marker.hasDesugaredLibraryIdentifiers() == value;
+      }
+
+      @Override
+      protected void explain(Description description) {
+        description.appendText(
+            Marker.DESUGARED_LIBRARY_IDENTIFIERS + (value ? " found" : " not found"));
+      }
+    };
+  }
+
   @Override
   protected boolean matchesSafely(Marker marker) {
     return eval(marker);
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 78eaabf..b764451 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -193,17 +193,22 @@
   }
 
   public TestBuilder<? extends TestRunResult<?>, ?> testForRuntime(
-      TestRuntime runtime, AndroidApiLevel apiLevel) {
+      TestRuntime runtime, Consumer<D8TestBuilder> d8TestBuilderConsumer) {
     if (runtime.isCf()) {
       return testForJvm();
     } else {
       assert runtime.isDex();
       D8TestBuilder d8TestBuilder = testForD8();
-      d8TestBuilder.setMinApi(apiLevel);
+      d8TestBuilderConsumer.accept(d8TestBuilder);
       return d8TestBuilder;
     }
   }
 
+  public TestBuilder<? extends TestRunResult<?>, ?> testForRuntime(
+      TestRuntime runtime, AndroidApiLevel apiLevel) {
+    return testForRuntime(runtime, d8TestBuilder -> d8TestBuilder.setMinApi(apiLevel));
+  }
+
   public TestBuilder<? extends TestRunResult<?>, ?> testForRuntime(TestParameters parameters) {
     return testForRuntime(parameters.getRuntime(), parameters.getApiLevel());
   }
diff --git a/src/test/java/com/android/tools/r8/TestBuilder.java b/src/test/java/com/android/tools/r8/TestBuilder.java
index 21ab2b1..d56f4d9 100644
--- a/src/test/java/com/android/tools/r8/TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestBuilder.java
@@ -131,6 +131,18 @@
     return addLibraryFiles(Arrays.asList(files));
   }
 
+  public T addClasspathClasses(Class<?>... classes) {
+    return addClasspathClasses(Arrays.asList(classes));
+  }
+
+  public abstract T addClasspathClasses(Collection<Class<?>> classes);
+
+  public T addClasspathFiles(Path... files) {
+    return addClasspathFiles(Arrays.asList(files));
+  }
+
+  public abstract T addClasspathFiles(Collection<Path> files);
+
   public final T addTestingAnnotationsAsProgramClasses() {
     return addProgramClasses(getTestingAnnotations());
   }
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index ce6c9fb..9d6b1c8 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -23,7 +23,6 @@
 import java.io.PrintStream;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -339,18 +338,6 @@
     return super.addLibraryProvider(provider);
   }
 
-  public T addClasspathClasses(Class<?>... classes) {
-    return addClasspathClasses(Arrays.asList(classes));
-  }
-
-  public abstract T addClasspathClasses(Collection<Class<?>> classes);
-
-  public T addClasspathFiles(Path... files) {
-    return addClasspathFiles(Arrays.asList(files));
-  }
-
-  public abstract T addClasspathFiles(Collection<Path> files);
-
   public T noDesugaring() {
     builder.setDisableDesugaring(true);
     return self();
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedFieldTest.java b/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedFieldTest.java
new file mode 100644
index 0000000..efc344e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedFieldTest.java
@@ -0,0 +1,122 @@
+// Copyright (c) 2020, 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.compatproguard.ifrules;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.TestShrinkerBuilder;
+import com.android.tools.r8.shaking.methods.MethodsTestBase.Shrinker;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ConditionalOnInlinedFieldTest extends TestBase {
+
+  static class A {
+
+    int field = 42;
+
+    void method(String name, int field) throws Exception {
+      if (field == 42) {
+        Class<?> clazz = Class.forName(name);
+        Object object = clazz.getDeclaredConstructor().newInstance();
+        clazz.getDeclaredMethod("method").invoke(object);
+      }
+    }
+  }
+
+  static class B {
+    void method() {
+      System.out.println("B::method");
+    }
+  }
+
+  static class MainWithFieldReference {
+
+    public static void main(String[] args) throws Exception {
+      A a = new A();
+      a.method(args[0], a.field);
+    }
+  }
+
+  static class MainWithoutFieldReference {
+
+    public static void main(String[] args) throws Exception {
+      A a = new A();
+      a.method(args[0], 42);
+    }
+  }
+
+  private static String EXPECTED = StringUtils.lines("B::method");
+
+  @Parameters(name = "{0}, {1}, ref:{2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        Shrinker.values(), getTestParameters().withCfRuntimes().build(), BooleanUtils.values());
+  }
+
+  private final Shrinker shrinker;
+  private final TestParameters parameters;
+  private final boolean withFieldReference;
+
+  public ConditionalOnInlinedFieldTest(
+      Shrinker shrinker, TestParameters parameters, boolean withFieldReference) {
+    this.shrinker = shrinker;
+    this.parameters = parameters;
+    this.withFieldReference = withFieldReference;
+  }
+
+  private Class<?> getMain() {
+    return withFieldReference ? MainWithFieldReference.class : MainWithoutFieldReference.class;
+  }
+
+  @Test
+  public void testReference() throws Exception {
+    testForJvm()
+        .addProgramClasses(getMain(), A.class, B.class)
+        .run(parameters.getRuntime(), getMain(), B.class.getTypeName())
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  private TestShrinkerBuilder<?, ?, ?, ?, ?> buildShrinker() throws Exception {
+    TestShrinkerBuilder<?, ?, ?, ?, ?> builder;
+    if (shrinker == Shrinker.Proguard) {
+      builder =
+          testForProguard()
+              .addKeepRules("-dontwarn " + ConditionalOnInlinedFieldTest.class.getTypeName());
+    } else if (shrinker == Shrinker.R8Compat) {
+      builder = testForR8Compat(parameters.getBackend());
+    } else {
+      builder = testForR8(parameters.getBackend());
+    }
+    return builder
+        .addProgramClasses(getMain(), A.class, B.class)
+        .addKeepMainRule(getMain())
+        .addKeepRules(
+            "-if class "
+                + A.class.getTypeName()
+                + " { int field; }"
+                + " -keep class "
+                + B.class.getTypeName()
+                + " { void <init>(); void method(); }");
+  }
+
+  @Test
+  public void testConditionalOnField() throws Exception {
+    TestRunResult<?> result =
+        buildShrinker().compile().run(parameters.getRuntime(), getMain(), B.class.getTypeName());
+    if (!withFieldReference && shrinker != Shrinker.Proguard) {
+      // Without the reference we expect an error. For some reason PG keeps in any case.
+      result.assertFailureWithErrorThatThrows(ClassNotFoundException.class);
+    } else {
+      result.assertSuccessWithOutput(EXPECTED);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedTest.java b/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedTest.java
new file mode 100644
index 0000000..faa9eda
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/compatproguard/ifrules/ConditionalOnInlinedTest.java
@@ -0,0 +1,124 @@
+// Copyright (c) 2020, 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.compatproguard.ifrules;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.TestShrinkerBuilder;
+import com.android.tools.r8.shaking.methods.MethodsTestBase.Shrinker;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ConditionalOnInlinedTest extends TestBase {
+
+  static class A {
+    void method(String name) throws Exception {
+      Class<?> clazz = Class.forName(name);
+      Object object = clazz.getDeclaredConstructor().newInstance();
+      clazz.getDeclaredMethod("method").invoke(object);
+    }
+  }
+
+  static class B {
+    void method() {
+      System.out.println("B::method");
+    }
+  }
+
+  static class Main {
+    public static void main(String[] args) throws Exception {
+      new A().method(args[0]);
+    }
+  }
+
+  private static Class<?> MAIN_CLASS = Main.class;
+  private static Collection<Class<?>> CLASSES = ImmutableList.of(MAIN_CLASS, A.class, B.class);
+
+  private static String EXPECTED = StringUtils.lines("B::method");
+
+  @Parameters(name = "{0}, {1}")
+  public static List<Object[]> data() {
+    return buildParameters(Shrinker.values(), getTestParameters().withCfRuntimes().build());
+  }
+
+  private final Shrinker shrinker;
+  private final TestParameters parameters;
+
+  public ConditionalOnInlinedTest(Shrinker shrinker, TestParameters parameters) {
+    this.shrinker = shrinker;
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testReference() throws Exception {
+    testForJvm()
+        .addProgramClasses(CLASSES)
+        .run(parameters.getRuntime(), MAIN_CLASS, B.class.getTypeName())
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  private TestShrinkerBuilder<?, ?, ?, ?, ?> buildShrinker() throws Exception {
+    TestShrinkerBuilder<?, ?, ?, ?, ?> builder;
+    if (shrinker == Shrinker.Proguard) {
+      builder =
+          testForProguard()
+              .addKeepRules("-dontwarn " + ConditionalOnInlinedTest.class.getTypeName());
+    } else if (shrinker == Shrinker.R8Compat) {
+      builder = testForR8Compat(parameters.getBackend());
+    } else {
+      builder = testForR8(parameters.getBackend());
+    }
+    return builder.addProgramClasses(CLASSES).addKeepMainRule(MAIN_CLASS);
+  }
+
+  @Test
+  public void testConditionalOnClass() throws Exception {
+    TestRunResult<?> result =
+        buildShrinker()
+            .addKeepRules(
+                "-if class "
+                    + A.class.getTypeName()
+                    + " -keep class "
+                    + B.class.getTypeName()
+                    + " { void <init>(); void method(); }")
+            .compile()
+            .run(parameters.getRuntime(), MAIN_CLASS, B.class.getTypeName());
+    if (shrinker != Shrinker.Proguard) {
+      // TODO(b/160136641): The conditional rule fails to apply after class A is inlined/removed.
+      result.assertFailureWithErrorThatThrows(ClassNotFoundException.class);
+    } else {
+      result.assertSuccessWithOutput(EXPECTED);
+    }
+  }
+
+  @Test
+  public void testConditionalOnClassAndMethod() throws Exception {
+    TestRunResult<?> result =
+        buildShrinker()
+            .addKeepRules(
+                "-if class "
+                    + A.class.getTypeName()
+                    + " { void method(java.lang.String); }"
+                    + " -keep class "
+                    + B.class.getTypeName()
+                    + " { void <init>(); void method(); }")
+            .compile()
+            .run(parameters.getRuntime(), MAIN_CLASS, B.class.getTypeName());
+    if (shrinker == Shrinker.Proguard) {
+      // In this case PG appears to not actually keep the consequent, but it does remain renamed
+      // in the output.
+      result.assertFailureWithErrorThatThrows(ClassNotFoundException.class);
+    } else {
+      result.assertSuccessWithOutput(EXPECTED);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java b/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
index 6a1e059..aab82f0 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.compatproguard.reflection;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -468,15 +468,17 @@
             readClasses(A.class, mainClass), keepMainProguardConfiguration(mainClass), backend);
     CodeInspector inspector = new CodeInspector(output);
 
-    assertThat(inspector.clazz(A.class).method("void", "method0", ImmutableList.of()), isRenamed());
+    assertThat(
+        inspector.clazz(A.class).method("void", "method0", ImmutableList.of()),
+        isPresentAndRenamed());
     assertThat(
         inspector.clazz(A.class).method("void", "method1", ImmutableList.of("java.lang.String")),
-        isRenamed());
+        isPresentAndRenamed());
     assertThat(
         inspector
             .clazz(A.class)
             .method("void", "method2", ImmutableList.of("java.lang.String", "java.lang.String")),
-        isRenamed());
+        isPresentAndRenamed());
 
     assertEquals(runOnJava(mainClass), runOnVM(output, mainClass, backend));
   }
@@ -495,7 +497,9 @@
     AndroidApp output = ToolHelper.runR8(builder.build());
     CodeInspector inspector = new CodeInspector(output);
 
-    assertThat(inspector.clazz(A.class).method("void", "method0", ImmutableList.of()), isRenamed());
+    assertThat(
+        inspector.clazz(A.class).method("void", "method0", ImmutableList.of()),
+        isPresentAndRenamed());
 
     // The reference run on the Java VM will succeed, whereas the run on the R8 output will fail
     // as in this test we fail to recognize the reflective call. To compare the output of the
@@ -535,7 +539,7 @@
         .forAllMethods(
             m -> {
               if (!m.isInstanceInitializer()) {
-                assertThat(m, isRenamed());
+                assertThat(m, isPresentAndRenamed());
               }
             });
 
@@ -556,7 +560,7 @@
         .forAllMethods(
             m -> {
               if (!m.isInstanceInitializer()) {
-                assertThat(m, isRenamed());
+                assertThat(m, isPresentAndRenamed());
               }
             });
 
diff --git a/src/test/java/com/android/tools/r8/desugar/DefaultInterfaceWithIdentifierNameString.java b/src/test/java/com/android/tools/r8/desugar/DefaultInterfaceWithIdentifierNameString.java
index 211050e..9eb054c 100644
--- a/src/test/java/com/android/tools/r8/desugar/DefaultInterfaceWithIdentifierNameString.java
+++ b/src/test/java/com/android/tools/r8/desugar/DefaultInterfaceWithIdentifierNameString.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.desugar;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -54,9 +54,9 @@
 
   private void inspect(CodeInspector inspector) {
     ClassSubject classSubject = inspector.clazz(A.class);
-    assertThat(classSubject, isRenamed());
+    assertThat(classSubject, isPresentAndRenamed());
     ClassSubject companionClassSubject = inspector.companionClassFor(I.class);
-    assertThat(companionClassSubject, isRenamed());
+    assertThat(companionClassSubject, isPresentAndRenamed());
     companionClassSubject
         .allMethods()
         .forEach(
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibaryChecksumsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
similarity index 70%
rename from src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibaryChecksumsTest.java
rename to src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
index 8280f92..6aff20f 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibaryChecksumsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryChecksumsTest.java
@@ -3,10 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.desugar.desugaredlibrary;
 
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertTrue;
-
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.L8;
 import com.android.tools.r8.L8Command;
@@ -16,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.errors.CompilationError;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
@@ -26,14 +21,14 @@
 import org.junit.runners.Parameterized;
 
 @RunWith(Parameterized.class)
-public class DesugaredLibaryChecksumsTest extends TestBase {
+public class DesugaredLibraryChecksumsTest extends TestBase {
 
   @Parameterized.Parameters(name = "{0}")
   public static TestParametersCollection data() {
     return getTestParameters().withNoneRuntime().build();
   }
 
-  public DesugaredLibaryChecksumsTest(TestParameters parameters) {
+  public DesugaredLibraryChecksumsTest(TestParameters parameters) {
     parameters.assertNoneRuntime();
   }
 
@@ -52,16 +47,9 @@
             .setMinApiLevel(AndroidApiLevel.B.getLevel())
             .setOutput(out, OutputMode.DexIndexed)
             .build());
-
-    try {
-      CodeInspector inspector = new CodeInspector(out);
-      for (FoundClassSubject clazz : inspector.allClasses()) {
-        assertTrue(clazz.getDexProgramClass().getChecksum() > 0);
-      }
-    } catch (CompilationError e) {
-      // TODO(b/158746302): Desugared library should support checksums.
-      //  also, the failure should have occured in the L8.run above!
-      assertThat(e.getMessage(), containsString("has no checksum"));
+    CodeInspector inspector = new CodeInspector(out);
+    for (FoundClassSubject clazz : inspector.allClasses()) {
+      clazz.getDexProgramClass().getChecksum();
     }
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
index 03052cc..f485a25 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
@@ -4,22 +4,35 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary;
 
+import static com.android.tools.r8.MarkerMatcher.assertMarkersMatch;
+import static com.android.tools.r8.MarkerMatcher.markerCompilationMode;
+import static com.android.tools.r8.MarkerMatcher.markerHasDesugaredLibraryIdentifier;
+import static com.android.tools.r8.MarkerMatcher.markerHasMinApi;
+import static com.android.tools.r8.MarkerMatcher.markerTool;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.D8TestCompileResult;
 import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.ExtractMarker;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.desugar.desugaredlibrary.jdktests.Jdk11DesugaredLibraryTestBase;
+import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
+import org.hamcrest.Matcher;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -69,6 +82,47 @@
         .assertSuccessWithOutputLines(JAVA_RESULT);
   }
 
+  @Test
+  public void testMergeDesugaredWithShrunkenLib() throws Exception {
+    // Compile a library with R8 to CF.
+    Path shrunkenLib =
+        testForR8(Backend.CF)
+            .addProgramClasses(Part2.class)
+            .addKeepClassRules(Part2.class)
+            .compile()
+            .writeToZip();
+
+    // R8 class file output marker has no library desugaring identifier.
+    Matcher<Marker> libraryMatcher =
+        allOf(
+            markerTool(Tool.R8),
+            markerCompilationMode(CompilationMode.RELEASE),
+            not(markerHasMinApi()),
+            not(markerHasDesugaredLibraryIdentifier()));
+    assertMarkersMatch(
+        ExtractMarker.extractMarkerFromJarFile(shrunkenLib), ImmutableList.of(libraryMatcher));
+
+    // Build an app with the R8 compiled library.
+    Path app =
+        testForD8()
+            .addProgramFiles(buildPart1DesugaredLibrary(), shrunkenLib)
+            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
+            .setMinApi(parameters.getApiLevel())
+            .enableCoreLibraryDesugaring(parameters.getApiLevel())
+            .compile()
+            .writeToZip();
+
+    // The app has both the R8 marker from the library compilation and the D8 marker from dexing.
+    Matcher<Marker> d8Matcher =
+        allOf(
+            markerTool(Tool.D8),
+            markerHasMinApi(),
+            markerHasDesugaredLibraryIdentifier(
+                parameters.getApiLevel().isLessThan(AndroidApiLevel.O)));
+    assertMarkersMatch(
+        ExtractMarker.extractMarkerFromDexFile(app), ImmutableList.of(libraryMatcher, d8Matcher));
+  }
+
   private void assertError(TestDiagnosticMessages m) {
     List<Diagnostic> errors = m.getErrors();
     if (expectError()) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
index 32bbe65..c2d88b0 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
@@ -123,19 +123,12 @@
       System.out.println(myAtomicInteger.updateAndGet(x -> x + 100));
       System.out.println("145");
 
-      try {
-        MyDateNoOverride.from(myCal.toInstant());
-        System.out.println("b/159441805 fixed");
-      } catch (NoSuchMethodError e) {
-        // TODO(b/159441805): Should not throw.
-      }
-
-      try {
-        MyDateOverride.from(myCal.toInstant());
-        System.out.println("b/159441805 fixed");
-      } catch (NoSuchMethodError e) {
-        // TODO(b/159441805): Should not throw.
-      }
+      Date date1 = MyDateNoOverride.from(myCal.toInstant());
+      System.out.println(date1.toInstant());
+      System.out.println("1990-03-22T00:00:00Z");
+      Date date2 = MyDateOverride.from(myCal.toInstant());
+      System.out.println(date2.toInstant());
+      System.out.println("1990-03-22T00:00:00Z");
 
       System.out.println(MyDateDoubleOverride.from(myCal.toInstant()).toInstant());
       System.out.println("1970-01-02T10:17:36.788Z");
diff --git a/src/test/java/com/android/tools/r8/dexfilemerger/NonAsciiClassNameChecksumTest.java b/src/test/java/com/android/tools/r8/dexfilemerger/NonAsciiClassNameChecksumTest.java
index b91a645..351a74e 100644
--- a/src/test/java/com/android/tools/r8/dexfilemerger/NonAsciiClassNameChecksumTest.java
+++ b/src/test/java/com/android/tools/r8/dexfilemerger/NonAsciiClassNameChecksumTest.java
@@ -5,7 +5,6 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.TestBase;
@@ -83,7 +82,7 @@
   private void checkIncludesChecksum(CodeInspector inspector, Class<?> clazz) {
     ClassSubject classSubject = inspector.clazz(getTransformedName(clazz));
     assertThat(classSubject, isPresent());
-    assertTrue(classSubject.getDexProgramClass().asProgramClass().getChecksum() > 0);
+    classSubject.getDexProgramClass().getChecksum();
   }
 
   static class TaestClass {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
index 1c9148a..ec3c011 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
@@ -6,7 +6,7 @@
 
 import static com.android.tools.r8.ir.optimize.inliner.testclasses.InliningIntoVisibilityBridgeTestClasses.getClassA;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -74,8 +74,7 @@
       assertThat(classSubject, isPresent());
 
       MethodSubject methodSubject = classSubject.uniqueMethodWithName("method");
-      assertThat(methodSubject, isPresent());
-      assertThat(methodSubject, isRenamed());
+      assertThat(methodSubject, isPresentAndRenamed());
       assertEquals(neverInline, methodSubject.isBridge());
       assertEquals(neverInline, methodSubject.isSynthetic());
     }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java
index 11c47de..0b65d77 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnnotationTest.java
@@ -5,9 +5,9 @@
 package com.android.tools.r8.kotlin.metadata;
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -150,12 +150,11 @@
   private void inspect(CodeInspector inspector) {
     // Assert that foo is renamed.
     ClassSubject foo = inspector.clazz(PKG_LIB + ".Foo");
-    assertThat(foo, isRenamed());
+    assertThat(foo, isPresentAndRenamed());
     assertEquals(FOO_FINAL_NAME, foo.getFinalName());
     // Assert that bar exists and is not renamed.
     ClassSubject bar = inspector.clazz(PKG_LIB + ".Bar");
-    assertThat(bar, isPresent());
-    assertThat(bar, isNotRenamed());
+    assertThat(bar, isPresentAndNotRenamed());
     // Check that the annotation type on the type alias has been renamed
     inspectTypeAliasAnnotation(inspector, foo, bar);
   }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java
index f4ee57a..14cbe0b 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteAnonymousTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.kotlin.metadata;
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.TestParameters;
@@ -108,6 +108,6 @@
     System.out.println(
         KotlinMetadataWriter.kotlinMetadataToString("", clazz.getKotlinClassMetadata()));
     ClassSubject anonymousClass = inspector.clazz(PKG + ".anonymous_lib.Test$internalProp$1");
-    assertThat(anonymousClass, isRenamed());
+    assertThat(anonymousClass, isPresentAndRenamed());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java
index 90b74f9..d5b9fd0 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteFlexibleUpperBoundTest.java
@@ -6,8 +6,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -120,11 +120,10 @@
     // We are checking that A is renamed, and that the flexible upper bound information is
     // reflecting that.
     ClassSubject a = inspector.clazz(PKG_LIB + ".A");
-    assertThat(a, isRenamed());
+    assertThat(a, isPresentAndRenamed());
 
     ClassSubject flexibleUpperBound = inspector.clazz(PKG_LIB + ".FlexibleUpperBound");
-    assertThat(flexibleUpperBound, isPresent());
-    assertThat(flexibleUpperBound, not(isRenamed()));
+    assertThat(flexibleUpperBound, isPresentAndNotRenamed());
 
     List<KmPropertySubject> properties = flexibleUpperBound.getKmClass().getProperties();
     assertEquals(1, properties.size());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java
index 4aa0a2c..2103f0d 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInClasspathTypeTest.java
@@ -6,8 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -129,11 +129,10 @@
     String extraClassName = PKG + ".classpath_lib_ext.Extra";
 
     ClassSubject impl = inspector.clazz(implClassName);
-    assertThat(impl, isRenamed());
+    assertThat(impl, isPresentAndRenamed());
 
     ClassSubject implKt = inspector.clazz(implKtClassName);
-    assertThat(implKt, isPresent());
-    assertThat(implKt, not(isRenamed()));
+    assertThat(implKt, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = implKt.getKmPackage();
     assertThat(kmPackage, isPresent());
@@ -142,8 +141,7 @@
     assertThat(kmFunction, isExtensionFunction());
 
     ClassSubject extra = inspector.clazz(extraClassName);
-    assertThat(extra, isPresent());
-    assertThat(extra, not(isRenamed()));
+    assertThat(extra, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = extra.getKmClass();
     assertThat(kmClass, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java
index 38a6815..4c49518 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInCompanionTest.java
@@ -5,7 +5,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -170,15 +171,13 @@
 
     ClassSubject sup = inspector.clazz(superClassName);
     if (keptAll) {
-      assertThat(sup, isPresent());
-      assertThat(sup, not(isRenamed()));
+      assertThat(sup, isPresentAndNotRenamed());
     } else {
-      assertThat(sup, isRenamed());
+      assertThat(sup, isPresentAndRenamed());
     }
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -192,21 +191,18 @@
 
     // The backing field for the property in the companion, with @JvmField
     FieldSubject elt2 = impl.uniqueFieldWithName("elt2");
-    assertThat(elt2, isPresent());
-    assertThat(elt2, not(isRenamed()));
+    assertThat(elt2, isPresentAndNotRenamed());
 
     FieldSubject companionObject = impl.uniqueFieldWithName("Companion");
-    assertThat(companionObject, isPresent());
-    assertThat(companionObject, not(isRenamed()));
+    assertThat(companionObject, isPresentAndNotRenamed());
     assertEquals(companionObject.getFinalName(), kmClass.getCompanionObject());
 
     // Bridge for the property in the companion that needs a backing field.
     MethodSubject elt1Bridge = impl.uniqueMethodWithName("access$getElt1$cp");
     if (keptAll) {
-      assertThat(elt1Bridge, isPresent());
-      assertThat(elt1Bridge, not(isRenamed()));
+      assertThat(elt1Bridge, isPresentAndNotRenamed());
     } else {
-      assertThat(elt1Bridge, isRenamed());
+      assertThat(elt1Bridge, isPresentAndRenamed());
     }
 
     // With @JvmField, no bridge is added.
@@ -218,8 +214,7 @@
     assertThat(fooBridge, not(isPresent()));
 
     ClassSubject companion = inspector.clazz(companionClassName);
-    assertThat(companion, isPresent());
-    assertThat(companion, not(isRenamed()));
+    assertThat(companion, isPresentAndNotRenamed());
 
     List<String> nestedClassDescriptors = kmClass.getNestedClassDescriptors();
     assertEquals(1, nestedClassDescriptors.size());
@@ -236,19 +231,16 @@
     assertThat(kmProperty, isPresent());
 
     MethodSubject elt1Getter = companion.uniqueMethodWithName("getElt1");
-    assertThat(elt1Getter, isPresent());
-    assertThat(elt1Getter, not(isRenamed()));
+    assertThat(elt1Getter, isPresentAndNotRenamed());
 
     // Note that there is no getter for property with @JvmField.
     MethodSubject elt2Getter = companion.uniqueMethodWithName("getElt2");
     assertThat(elt2Getter, not(isPresent()));
 
     MethodSubject fooGetter = companion.uniqueMethodWithName("getFoo");
-    assertThat(fooGetter, isPresent());
-    assertThat(fooGetter, not(isRenamed()));
+    assertThat(fooGetter, isPresentAndNotRenamed());
 
     MethodSubject barSetter = companion.uniqueMethodWithName("setBar");
-    assertThat(barSetter, isPresent());
-    assertThat(barSetter, not(isRenamed()));
+    assertThat(barSetter, isPresentAndNotRenamed());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java
index 41d1f09..4f8b4a4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionFunctionTest.java
@@ -6,7 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -127,8 +128,7 @@
     assertThat(inspector.clazz(superClassName), not(isPresent()));
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -180,12 +180,10 @@
     String bClassName = PKG + ".extension_function_lib.B";
 
     ClassSubject sup = inspector.clazz(superClassName);
-    assertThat(sup, isPresent());
-    assertThat(sup, isRenamed());
+    assertThat(sup, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -206,8 +204,7 @@
     assertThat(impl, isPresent());
 
     ClassSubject bKt = inspector.clazz(bKtClassName);
-    assertThat(bKt, isPresent());
-    assertThat(bKt, not(isRenamed()));
+    assertThat(bKt, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = bKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java
index c627171..9e81bf2 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInExtensionPropertyTest.java
@@ -7,7 +7,8 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionProperty;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNotNull;
@@ -124,8 +125,7 @@
     assertThat(inspector.clazz(superClassName), not(isPresent()));
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -137,8 +137,7 @@
     assertThat(kmFunction, not(isExtensionFunction()));
 
     ClassSubject bKt = inspector.clazz(bKtClassName);
-    assertThat(bKt, isPresent());
-    assertThat(bKt, not(isRenamed()));
+    assertThat(bKt, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = bKt.getKmPackage();
     assertThat(kmPackage, isPresent());
@@ -187,11 +186,10 @@
     String bKtClassName = PKG + ".extension_property_lib.BKt";
 
     ClassSubject sup = inspector.clazz(superClassName);
-    assertThat(sup, isRenamed());
+    assertThat(sup, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -202,8 +200,7 @@
         supertype -> supertype.getFinalDescriptor().equals(sup.getFinalDescriptor())));
 
     ClassSubject bKt = inspector.clazz(bKtClassName);
-    assertThat(bKt, isPresent());
-    assertThat(bKt, not(isRenamed()));
+    assertThat(bKt, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = bKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java
index 7cfa4a7..dcb6dbe 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionTest.java
@@ -6,7 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -122,8 +123,7 @@
     assertThat(inspector.clazz(superClassName), not(isPresent()));
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
@@ -133,8 +133,7 @@
         supertype -> supertype.getFinalDescriptor().contains("Super")));
 
     ClassSubject bKt = inspector.clazz(bKtClassName);
-    assertThat(bKt, isPresent());
-    assertThat(bKt, not(isRenamed()));
+    assertThat(bKt, isPresentAndNotRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = bKt.getKmPackage();
@@ -183,10 +182,10 @@
     String bKtClassName = PKG + ".function_lib.BKt";
 
     ClassSubject sup = inspector.clazz(superClassName);
-    assertThat(sup, isRenamed());
+    assertThat(sup, isPresentAndRenamed());
 
     MethodSubject foo = sup.uniqueMethodWithName("foo");
-    assertThat(foo, isRenamed());
+    assertThat(foo, isPresentAndRenamed());
 
     KmClassSubject kmClass = sup.getKmClass();
     assertThat(kmClass, isPresent());
@@ -198,8 +197,7 @@
     assertEquals(foo.getJvmMethodSignatureAsString(), kmFunction.signature().asString());
 
     ClassSubject impl = inspector.clazz(bClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     kmClass = impl.getKmClass();
@@ -211,8 +209,7 @@
         supertype -> supertype.getFinalDescriptor().equals(sup.getFinalDescriptor())));
 
     ClassSubject bKt = inspector.clazz(bKtClassName);
-    assertThat(bKt, isPresent());
-    assertThat(bKt, not(isRenamed()));
+    assertThat(bKt, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = bKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
index 79ad6e5..4cd9b6a 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithDefaultValueTest.java
@@ -6,8 +6,7 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -120,16 +119,13 @@
     String libClassName = PKG + ".default_value_lib.LibKt";
 
     ClassSubject libKt = inspector.clazz(libClassName);
-    assertThat(libKt, isPresent());
-    assertThat(libKt, not(isRenamed()));
+    assertThat(libKt, isPresentAndNotRenamed());
 
     MethodSubject methodSubject = libKt.uniqueMethodWithName("applyMap");
-    assertThat(methodSubject, isPresent());
-    assertThat(methodSubject, not(isRenamed()));
+    assertThat(methodSubject, isPresentAndNotRenamed());
 
     methodSubject = libKt.uniqueMethodWithName("applyMap$default");
-    assertThat(methodSubject, isPresent());
-    assertThat(methodSubject, not(isRenamed()));
+    assertThat(methodSubject, isPresentAndNotRenamed());
 
     KmPackageSubject kmPackage = libKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java
index d82b5c6..0914a23 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInFunctionWithVarargTest.java
@@ -6,7 +6,7 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -123,20 +123,16 @@
     String libClassName = PKG + ".vararg_lib.LibKt";
 
     ClassSubject cls = inspector.clazz(className);
-    assertThat(cls, isPresent());
-    assertThat(cls, not(isRenamed()));
+    assertThat(cls, isPresentAndNotRenamed());
 
     MethodSubject foo = cls.uniqueMethodWithName("foo");
-    assertThat(foo, isPresent());
-    assertThat(foo, not(isRenamed()));
+    assertThat(foo, isPresentAndNotRenamed());
 
     ClassSubject libKt = inspector.clazz(libClassName);
-    assertThat(libKt, isPresent());
-    assertThat(libKt, not(isRenamed()));
+    assertThat(libKt, isPresentAndNotRenamed());
 
     MethodSubject bar = libKt.uniqueMethodWithName("bar");
-    assertThat(bar, isPresent());
-    assertThat(bar, not(isRenamed()));
+    assertThat(bar, isPresentAndNotRenamed());
 
     KmPackageSubject kmPackage = libKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
index 12b361b..159bf66 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
@@ -5,10 +5,9 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.anyOf;
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -122,8 +121,7 @@
   private void inspect(CodeInspector inspector) {
     String extClassName = PKG + ".libtype_lib_ext.ExtKt";
     ClassSubject ext = inspector.clazz(extClassName);
-    assertThat(ext, isPresent());
-    assertThat(ext, not(isRenamed()));
+    assertThat(ext, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = ext.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java
index 09d62d7..45a419d 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInMultifileClassTest.java
@@ -6,7 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -121,11 +122,9 @@
     String utilClassName = PKG + ".multifileclass_lib.UtilKt";
 
     ClassSubject util = inspector.clazz(utilClassName);
-    assertThat(util, isPresent());
-    assertThat(util, not(isRenamed()));
+    assertThat(util, isPresentAndNotRenamed());
     MethodSubject commaJoinOfInt = util.uniqueMethodWithName("commaSeparatedJoinOfInt");
-    assertThat(commaJoinOfInt, isPresent());
-    assertThat(commaJoinOfInt, not(isRenamed()));
+    assertThat(commaJoinOfInt, isPresentAndNotRenamed());
     MethodSubject joinOfInt = util.uniqueMethodWithName("joinOfInt");
     assertThat(joinOfInt, not(isPresent()));
 
@@ -167,14 +166,11 @@
     String utilClassName = PKG + ".multifileclass_lib.UtilKt";
 
     ClassSubject util = inspector.clazz(utilClassName);
-    assertThat(util, isPresent());
-    assertThat(util, not(isRenamed()));
+    assertThat(util, isPresentAndNotRenamed());
     MethodSubject commaJoinOfInt = util.uniqueMethodWithName("commaSeparatedJoinOfInt");
-    assertThat(commaJoinOfInt, isPresent());
-    assertThat(commaJoinOfInt, not(isRenamed()));
+    assertThat(commaJoinOfInt, isPresentAndNotRenamed());
     MethodSubject joinOfInt = util.uniqueMethodWithName("joinOfInt");
-    assertThat(joinOfInt, isPresent());
-    assertThat(joinOfInt, isRenamed());
+    assertThat(joinOfInt, isPresentAndRenamed());
 
     inspectMetadataForFacade(inspector, util);
 
@@ -195,19 +191,18 @@
     for (String partClassName : partClassNames) {
       ClassSubject partClass =
           inspector.clazz(DescriptorUtils.getJavaTypeFromBinaryName(partClassName));
-      assertThat(partClass, isRenamed());
+      assertThat(partClass, isPresentAndRenamed());
     }
   }
 
   private void inspectSignedKt(CodeInspector inspector) {
     String signedClassName = PKG + ".multifileclass_lib.UtilKt__SignedKt";
     ClassSubject signed = inspector.clazz(signedClassName);
-    assertThat(signed, isRenamed());
+    assertThat(signed, isPresentAndRenamed());
     MethodSubject commaJoinOfInt = signed.uniqueMethodWithName("commaSeparatedJoinOfInt");
-    assertThat(commaJoinOfInt, isPresent());
-    assertThat(commaJoinOfInt, not(isRenamed()));
+    assertThat(commaJoinOfInt, isPresentAndNotRenamed());
     MethodSubject joinOfInt = signed.uniqueMethodWithName("joinOfInt");
-    assertThat(joinOfInt, isRenamed());
+    assertThat(joinOfInt, isPresentAndRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = signed.getKmPackage();
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
index 3c218fe..eada4da 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInNestedClassTest.java
@@ -6,8 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -119,28 +119,30 @@
     String nestedClassName = outerClassName + "$Nested";
 
     ClassSubject inner = inspector.clazz(innerClassName);
-    assertThat(inner, isPresent());
-    assertThat(inner, not(isRenamed()));
+    assertThat(inner, isPresentAndNotRenamed());
 
     ClassSubject nested = inspector.clazz(nestedClassName);
-    assertThat(nested, isRenamed());
+    assertThat(nested, isPresentAndRenamed());
 
     ClassSubject outer = inspector.clazz(outerClassName);
-    assertThat(outer, isPresent());
-    assertThat(outer, not(isRenamed()));
+    assertThat(outer, isPresentAndNotRenamed());
 
     KmClassSubject kmClass = outer.getKmClass();
     assertThat(kmClass, isPresent());
 
     assertFalse(kmClass.getNestedClassDescriptors().isEmpty());
-    kmClass.getNestedClassDescriptors().forEach(nestedClassDescriptor -> {
-      ClassSubject nestedClass = inspector.clazz(descriptorToJavaType(nestedClassDescriptor));
-      if (nestedClass.getOriginalName().contains("Inner")) {
-        assertThat(nestedClass, not(isRenamed()));
-      } else {
-        assertThat(nestedClass, isRenamed());
-      }
-      assertEquals(nestedClassDescriptor, nestedClass.getFinalDescriptor());
-    });
+    kmClass
+        .getNestedClassDescriptors()
+        .forEach(
+            nestedClassDescriptor -> {
+              ClassSubject nestedClass =
+                  inspector.clazz(descriptorToJavaType(nestedClassDescriptor));
+              if (nestedClass.getOriginalName().contains("Inner")) {
+                assertThat(nestedClass, isPresentAndNotRenamed());
+              } else {
+                assertThat(nestedClass, isPresentAndRenamed());
+              }
+              assertEquals(nestedClassDescriptor, nestedClass.getFinalDescriptor());
+            });
   }
 }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java
index 53c8e4f..b4ae665 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInParameterTypeTest.java
@@ -5,8 +5,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -112,11 +112,10 @@
     String implClassName = PKG + ".parametertype_lib.Impl";
 
     ClassSubject itf = inspector.clazz(itfClassName);
-    assertThat(itf, isRenamed());
+    assertThat(itf, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(implClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
index f97fd1c..c479093 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTest.java
@@ -6,7 +6,8 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionProperty;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static junit.framework.TestCase.assertNull;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -116,14 +117,12 @@
   private void inspectGetterOnly(CodeInspector inspector) {
     String personClassName = PKG + ".fragile_property_lib.Person";
     ClassSubject person = inspector.clazz(personClassName);
-    assertThat(person, isPresent());
-    assertThat(person, not(isRenamed()));
+    assertThat(person, isPresentAndNotRenamed());
 
     FieldSubject backingField = person.uniqueFieldWithName("name");
-    assertThat(backingField, isRenamed());
+    assertThat(backingField, isPresentAndRenamed());
     MethodSubject getterForName = person.uniqueMethodWithName("getName");
-    assertThat(getterForName, isPresent());
-    assertThat(getterForName, not(isRenamed()));
+    assertThat(getterForName, isPresentAndNotRenamed());
     MethodSubject setterForName = person.uniqueMethodWithName("setName");
     assertThat(setterForName, not(isPresent()));
 
@@ -213,8 +212,7 @@
   private void inspectSetterOnly(CodeInspector inspector) {
     String personClassName = PKG + ".fragile_property_lib.Person";
     ClassSubject person = inspector.clazz(personClassName);
-    assertThat(person, isPresent());
-    assertThat(person, not(isRenamed()));
+    assertThat(person, isPresentAndNotRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = person.getKmClass();
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java
index dea1c4a..eb9ff61 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInPropertyTypeTest.java
@@ -5,8 +5,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -110,11 +110,10 @@
     String implClassName = PKG + ".propertytype_lib.Impl";
 
     ClassSubject itf = inspector.clazz(itfClassName);
-    assertThat(itf, isRenamed());
+    assertThat(itf, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(implClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
index f474cf1..bb77f38 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
@@ -6,9 +6,9 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromKotlinClassifier;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -115,8 +115,7 @@
   private void inspect(CodeInspector inspector) {
     String pkg = getClass().getPackage().getName();
     ClassSubject kept = inspector.clazz(pkg + ".anno.Kept");
-    assertThat(kept, isPresent());
-    assertThat(kept, not(isRenamed()));
+    assertThat(kept, isPresentAndNotRenamed());
     // API entry is kept, hence @Metadata exists.
     KmClassSubject kmClass = kept.getKmClass();
     assertThat(kmClass, isPresent());
@@ -127,7 +126,7 @@
     assertThat(anno, isPresent());
 
     ClassSubject renamed = inspector.clazz(pkg + ".anno.Renamed");
-    assertThat(renamed, isRenamed());
+    assertThat(renamed, isPresentAndRenamed());
     // @Anno is kept.
     anno = renamed.annotation(annoName);
     assertThat(anno, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java
index 63fc38d..47b0b82 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInReturnTypeTest.java
@@ -5,8 +5,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -112,11 +112,10 @@
     String implClassName = PKG + ".returntype_lib.Impl";
 
     ClassSubject itf = inspector.clazz(itfClassName);
-    assertThat(itf, isRenamed());
+    assertThat(itf, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(implClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
index 318a765..1bb1c44 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSealedClassTest.java
@@ -7,9 +7,9 @@
 import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -122,26 +122,27 @@
     String libClassName = PKG + ".sealed_lib.LibKt";
 
     ClassSubject num = inspector.clazz(numClassName);
-    assertThat(num, isRenamed());
+    assertThat(num, isPresentAndRenamed());
 
     ClassSubject expr = inspector.clazz(exprClassName);
-    assertThat(expr, isPresent());
-    assertThat(expr, not(isRenamed()));
+    assertThat(expr, isPresentAndNotRenamed());
 
     KmClassSubject kmClass = expr.getKmClass();
     assertThat(kmClass, isPresent());
 
     assertFalse(kmClass.getSealedSubclassDescriptors().isEmpty());
-    kmClass.getSealedSubclassDescriptors().forEach(sealedSubclassDescriptor -> {
-      ClassSubject sealedSubclass =
-          inspector.clazz(descriptorToJavaType(sealedSubclassDescriptor));
-      assertThat(sealedSubclass, isRenamed());
-      assertEquals(sealedSubclassDescriptor, sealedSubclass.getFinalDescriptor());
-    });
+    kmClass
+        .getSealedSubclassDescriptors()
+        .forEach(
+            sealedSubclassDescriptor -> {
+              ClassSubject sealedSubclass =
+                  inspector.clazz(descriptorToJavaType(sealedSubclassDescriptor));
+              assertThat(sealedSubclass, isPresentAndRenamed());
+              assertEquals(sealedSubclassDescriptor, sealedSubclass.getFinalDescriptor());
+            });
 
     ClassSubject libKt = inspector.clazz(libClassName);
-    assertThat(expr, isPresent());
-    assertThat(expr, not(isRenamed()));
+    assertThat(expr, isPresentAndNotRenamed());
 
     KmPackageSubject kmPackage = libKt.getKmPackage();
     assertThat(kmPackage, isPresent());
@@ -184,15 +185,13 @@
     String libClassName = PKG + ".sealed_lib.LibKt";
 
     ClassSubject expr = inspector.clazz(exprClassName);
-    assertThat(expr, isPresent());
-    assertThat(expr, not(isRenamed()));
+    assertThat(expr, isPresentAndNotRenamed());
 
     KmClassSubject kmClass = expr.getKmClass();
     assertThat(kmClass, isPresent());
 
     ClassSubject libKt = inspector.clazz(libClassName);
-    assertThat(expr, isPresent());
-    assertThat(expr, not(isRenamed()));
+    assertThat(expr, isPresentAndNotRenamed());
 
     KmPackageSubject kmPackage = libKt.getKmPackage();
     assertThat(kmPackage, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java
index 8eb76bb..578a7ec 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInSuperTypeTest.java
@@ -5,7 +5,8 @@
 
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
@@ -114,8 +115,7 @@
     assertThat(inspector.clazz(itfClassName), not(isPresent()));
 
     ClassSubject impl = inspector.clazz(implClassName);
-    assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
@@ -160,11 +160,11 @@
     String implClassName = PKG + ".supertype_lib.Impl";
 
     ClassSubject itf = inspector.clazz(itfClassName);
-    assertThat(itf, isRenamed());
+    assertThat(itf, isPresentAndRenamed());
 
     ClassSubject impl = inspector.clazz(implClassName);
     assertThat(impl, isPresent());
-    assertThat(impl, not(isRenamed()));
+    assertThat(impl, isPresentAndNotRenamed());
     // API entry is kept, hence the presence of Metadata.
     KmClassSubject kmClass = impl.getKmClass();
     assertThat(kmClass, isPresent());
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java
index 2c14c8d..ac4085f 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeAliasTest.java
@@ -6,11 +6,11 @@
 import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isDexClass;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertTrue;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.TestParameters;
@@ -168,15 +168,13 @@
     String libKtClassName = packageName + ".LibKt";
 
     ClassSubject itf = inspector.clazz(itfClassName);
-    assertThat(itf, isRenamed());
+    assertThat(itf, isPresentAndRenamed());
 
     ClassSubject libKt = inspector.clazz(libKtClassName);
-    assertThat(libKt, isPresent());
-    assertThat(libKt, not(isRenamed()));
+    assertThat(libKt, isPresentAndNotRenamed());
 
     MethodSubject seq = libKt.uniqueMethodWithName("seq");
-    assertThat(seq, isPresent());
-    assertThat(seq, not(isRenamed()));
+    assertThat(seq, isPresentAndNotRenamed());
 
     // API entry is kept, hence the presence of Metadata.
     KmPackageSubject kmPackage = libKt.getKmPackage();
@@ -219,7 +217,7 @@
 
     // Check that Arr has been renamed.
     ClassSubject arr = inspector.clazz(packageName + ".Arr");
-    assertThat(arr, isRenamed());
+    assertThat(arr, isPresentAndRenamed());
 
     ClassSubject libKt = inspector.clazz(libKtClassName);
     KmPackageSubject kmPackage = libKt.getKmPackage();
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
index df35c97..52ae0b3 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
@@ -7,7 +7,7 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isDexClass;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isExtensionFunction;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -171,7 +171,7 @@
     assertThat(someClass, isPresent());
     ClassSubject classThatShouldBeObfuscated =
         inspector.clazz(LIB_PKG + "ClassThatWillBeObfuscated");
-    assertThat(classThatShouldBeObfuscated, isRenamed());
+    assertThat(classThatShouldBeObfuscated, isPresentAndRenamed());
 
     // Check that the type-parameters of Invariant is marked as INVARIANT.
     ClassSubject invariant = inspector.clazz(LIB_PKG + "Invariant");
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
index 043a48a..dec2ff2 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
@@ -4,7 +4,8 @@
 package com.android.tools.r8.kotlin.metadata;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -59,14 +60,12 @@
             .run(parameters.getRuntime(), mainClassName);
     CodeInspector inspector = result.inspector();
     ClassSubject clazz = inspector.clazz(mainClassName);
-    assertThat(clazz, isPresent());
-    assertThat(clazz, not(isRenamed()));
+    assertThat(clazz, isPresentAndNotRenamed());
     // Main class is kept, hence the presence of Metadata.
     AnnotationSubject annotationSubject = clazz.annotation(METADATA_TYPE);
     assertThat(annotationSubject, isPresent());
     ClassSubject impl1 = inspector.clazz(implementer1ClassName);
-    assertThat(impl1, isPresent());
-    assertThat(impl1, isRenamed());
+    assertThat(impl1, isPresentAndRenamed());
     // All other classes can be renamed, hence the absence of Metadata;
     assertThat(impl1.annotation(METADATA_TYPE), not(isPresent()));
   }
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
index 123744d..447ed7e 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListOutputTest.java
@@ -4,32 +4,29 @@
 
 package com.android.tools.r8.maindexlist;
 
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer;
-import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.OutputMode;
-import com.android.tools.r8.R8Command;
 import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.StringConsumer.FileConsumer;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.StringDiagnostic;
 import com.google.common.collect.ImmutableList;
-import java.io.IOException;
 import java.nio.file.Path;
 import java.util.stream.Collectors;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class MainDexListOutputTest extends TestBase {
 
   interface MyConsumer<T> {
@@ -67,50 +64,45 @@
     }
   }
 
-  class Reporter implements DiagnosticsHandler {
-    int errorCount = 0;
-
-    @Override
-    public void error(Diagnostic error) {
-      errorCount++;
-      assertTrue(error instanceof StringDiagnostic);
-      assertTrue(error.getDiagnosticMessage().contains("main-dex"));
-    }
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
   }
 
-  @Test
+  public MainDexListOutputTest(TestParameters parameters) {
+    parameters.assertNoneRuntime();
+  }
+
+  @Test(expected = CompilationFailedException.class)
   public void testNoMainDex() throws Exception {
-    Reporter reporter = new Reporter();
-    try {
-      Path mainDexListOutput = temp.getRoot().toPath().resolve("main-dex-output.txt");
-      R8Command.builder(reporter)
-          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
-          .addClassProgramData(
-              ToolHelper.getClassAsBytes(HelloWorldMain.class), Origin.unknown())
-          .setMainDexListOutputPath(mainDexListOutput)
-          .build();
-      fail("Expect to fail");
-    } catch (CompilationFailedException e) {
-      assertEquals(1, reporter.errorCount);
-      assertThat(
-          e.getCause().getMessage(),
-          containsString("--main-dex-list-output require --main-dex-rules and/or --main-dex-list"));
-    }
+    Path mainDexListOutput = temp.getRoot().toPath().resolve("main-dex-output.txt");
+    testForR8(Backend.DEX)
+        .addProgramClasses(HelloWorldMain.class)
+        .setMainDexListConsumer(new FileConsumer(mainDexListOutput))
+        .setMinApi(AndroidApiLevel.K)
+        .compileWithExpectedDiagnostics(
+            diagnostics ->
+                diagnostics
+                    .assertOnlyErrors()
+                    .assertErrorsMatch(
+                        diagnosticMessage(
+                            containsString(
+                                "--main-dex-list-output require --main-dex-rules and/or"
+                                    + " --main-dex-list"))));
   }
 
   @Test
   public void testWithMainDex() throws Exception {
     Path mainDexRules = writeTextToTempFile(keepMainProguardConfiguration(HelloWorldMain.class));
     Path mainDexListOutput = temp.getRoot().toPath().resolve("main-dex-output.txt");
-    R8Command command =
-        ToolHelper.prepareR8CommandBuilder(readClasses(HelloWorldMain.class))
-            .setDisableTreeShaking(true)
-            .setDisableMinification(true)
-            .addMainDexRulesFiles(mainDexRules)
-            .setMainDexListOutputPath(mainDexListOutput)
-            .setOutput(temp.getRoot().toPath(), OutputMode.DexIndexed)
-            .build();
-    ToolHelper.runR8(command);
+    testForR8(Backend.DEX)
+        .addProgramClasses(HelloWorldMain.class)
+        .noTreeShaking()
+        .noMinification()
+        .setMinApi(AndroidApiLevel.K)
+        .addMainDexRuleFiles(mainDexRules)
+        .setMainDexListConsumer(new FileConsumer(mainDexListOutput))
+        .compile();
     // Main dex list with the single class.
     assertEquals(
         ImmutableList.of(HelloWorldMain.class.getTypeName().replace('.', '/') + ".class"),
@@ -121,7 +113,7 @@
   }
 
   @Test
-  public void testD8DesugaredLambdasInMainDexList() throws IOException, CompilationFailedException {
+  public void testD8DesugaredLambdasInMainDexList() throws Exception {
     Path mainDexList = writeTextToTempFile(testClassMainDexName);
     TestMainDexListConsumer consumer = new TestMainDexListConsumer();
     testForD8()
@@ -134,17 +126,16 @@
   }
 
   @Test
-  public void testD8DesugaredLambdasInMainDexListMerging()
-      throws IOException, CompilationFailedException {
+  public void testD8DesugaredLambdasInMainDexListMerging() throws Exception {
     Path mainDexList = writeTextToTempFile(testClassMainDexName);
-    Path dexOutput = temp.getRoot().toPath().resolve("classes.zip");
     // Build intermediate dex code first.
-    testForD8()
-        .setMinApi(AndroidApiLevel.K)
-        .addProgramClasses(ImmutableList.of(TestClass.class, MyConsumer.class))
-        .setIntermediate(true)
-        .setProgramConsumer(new ArchiveConsumer(dexOutput))
-        .compile();
+    Path dexOutput =
+        testForD8()
+            .setMinApi(AndroidApiLevel.K)
+            .addProgramClasses(ImmutableList.of(TestClass.class, MyConsumer.class))
+            .setIntermediate(true)
+            .compile()
+            .writeToZip();
     // Now test that when merging with a main dex list it is correctly updated.
     TestMainDexListConsumer consumer = new TestMainDexListConsumer();
     testForD8()
diff --git a/src/test/java/com/android/tools/r8/naming/AbstractMethodRenamingTest.java b/src/test/java/com/android/tools/r8/naming/AbstractMethodRenamingTest.java
index 71b158d..9f44e4b 100644
--- a/src/test/java/com/android/tools/r8/naming/AbstractMethodRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/AbstractMethodRenamingTest.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -81,26 +80,20 @@
 
   private void inspect(CodeInspector inspector) {
     ClassSubject base = inspector.clazz(Base.class);
-    assertThat(base, isPresent());
-    assertThat(base, isRenamed());
+    assertThat(base, isPresentAndRenamed());
     MethodSubject foo = base.uniqueMethodWithName("foo");
-    assertThat(foo, isPresent());
-    assertThat(foo, isRenamed());
+    assertThat(foo, isPresentAndRenamed());
 
     ClassSubject sub1 = inspector.clazz(Sub1.class);
-    assertThat(sub1, isPresent());
-    assertThat(sub1, isRenamed());
+    assertThat(sub1, isPresentAndRenamed());
     MethodSubject fooInSub1 = sub1.uniqueMethodWithName("foo");
-    assertThat(fooInSub1, isPresent());
-    assertThat(fooInSub1, isRenamed());
+    assertThat(fooInSub1, isPresentAndRenamed());
     assertEquals(foo.getFinalName(), fooInSub1.getFinalName());
 
     ClassSubject sub2 = inspector.clazz(Sub1.class);
-    assertThat(sub2, isPresent());
-    assertThat(sub2, isRenamed());
+    assertThat(sub2, isPresentAndRenamed());
     MethodSubject fooInSub2 = sub2.uniqueMethodWithName("foo");
-    assertThat(fooInSub2, isPresent());
-    assertThat(fooInSub2, isRenamed());
+    assertThat(fooInSub2, isPresentAndRenamed());
     assertEquals(foo.getFinalName(), fooInSub2.getFinalName());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java b/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java
index 2815aed..9f2d940 100644
--- a/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/AbstractR8KotlinNamingTestBase.java
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
@@ -29,65 +29,65 @@
 
   protected ClassSubject checkClassIsRenamed(CodeInspector inspector, String className) {
     ClassSubject classSubject = inspector.clazz(className);
-    assertThat(classSubject, isRenamed());
+    assertThat(classSubject, isPresentAndRenamed());
     return classSubject;
   }
 
   protected ClassSubject checkClassIsNotRenamed(CodeInspector inspector, String className) {
     ClassSubject classSubject = inspector.clazz(className);
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     return classSubject;
   }
 
   protected FieldSubject checkFieldIsRenamed(
       ClassSubject classSubject, String fieldType, String fieldName) {
     FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldType, fieldName);
-    assertThat(fieldSubject, isRenamed());
+    assertThat(fieldSubject, isPresentAndRenamed());
     return fieldSubject;
   }
 
   protected FieldSubject checkFieldIsRenamed(ClassSubject classSubject, String fieldName) {
     FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldName);
-    assertThat(fieldSubject, isRenamed());
+    assertThat(fieldSubject, isPresentAndRenamed());
     return fieldSubject;
   }
 
   protected FieldSubject checkFieldIsNotRenamed(
       ClassSubject classSubject, String fieldType, String fieldName) {
     FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldType, fieldName);
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
     return fieldSubject;
   }
 
   protected FieldSubject checkFieldIsNotRenamed(ClassSubject classSubject, String fieldName) {
     FieldSubject fieldSubject = checkFieldIsKept(classSubject, fieldName);
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
     return fieldSubject;
   }
 
   protected MethodSubject checkMethodIsRenamed(
       ClassSubject classSubject, MethodSignature methodSignature) {
     MethodSubject methodSubject = checkMethodIsKept(classSubject, methodSignature);
-    assertThat(methodSubject, isRenamed());
+    assertThat(methodSubject, isPresentAndRenamed());
     return methodSubject;
   }
 
   protected MethodSubject checkMethodIsRenamed(ClassSubject classSubject, String methodName) {
     MethodSubject methodSubject = checkMethodIsKept(classSubject, methodName);
-    assertThat(methodSubject, isRenamed());
+    assertThat(methodSubject, isPresentAndRenamed());
     return methodSubject;
   }
 
   protected MethodSubject checkMethodIsNotRenamed(
       ClassSubject classSubject, MethodSignature methodSignature) {
     MethodSubject methodSubject = checkMethodIsKept(classSubject, methodSignature);
-    assertThat(methodSubject, not(isRenamed()));
+    assertThat(methodSubject, isPresentAndNotRenamed());
     return methodSubject;
   }
 
   protected MethodSubject checkMethodIsNotRenamed(ClassSubject classSubject, String methodName) {
     MethodSubject methodSubject = checkMethodIsKept(classSubject, methodName);
-    assertThat(methodSubject, not(isRenamed()));
+    assertThat(methodSubject, isPresentAndNotRenamed());
     return methodSubject;
   }
 
diff --git a/src/test/java/com/android/tools/r8/naming/AvoidRTest.java b/src/test/java/com/android/tools/r8/naming/AvoidRTest.java
index 5c2d882..8feb257 100644
--- a/src/test/java/com/android/tools/r8/naming/AvoidRTest.java
+++ b/src/test/java/com/android/tools/r8/naming/AvoidRTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.DescriptorUtils.getUnqualifiedClassNameFromDescriptor;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
@@ -60,19 +60,23 @@
     }
     builder.addProgramClassFileData(jasminBuilder.buildClasses());
     Set<String> usedDescriptors = new HashSet<>();
-    builder.noTreeShaking()
+    builder
+        .noTreeShaking()
         .addKeepRules("-classobfuscationdictionary " + dictionary)
         .compile()
-        .inspect(codeInspector -> {
-          codeInspector.forAllClasses(classSubject -> {
-            assertThat(classSubject, isRenamed());
-            String renamedDescriptor = classSubject.getFinalDescriptor();
-            assertTrue(usedDescriptors.add(renamedDescriptor));
-            assertNotEquals("R", getUnqualifiedClassNameFromDescriptor(renamedDescriptor));
-            assertTrue(expectedNames.contains(
-                getUnqualifiedClassNameFromDescriptor(renamedDescriptor)));
-          });
-        });
+        .inspect(
+            codeInspector -> {
+              codeInspector.forAllClasses(
+                  classSubject -> {
+                    assertThat(classSubject, isPresentAndRenamed());
+                    String renamedDescriptor = classSubject.getFinalDescriptor();
+                    assertTrue(usedDescriptors.add(renamedDescriptor));
+                    assertNotEquals("R", getUnqualifiedClassNameFromDescriptor(renamedDescriptor));
+                    assertTrue(
+                        expectedNames.contains(
+                            getUnqualifiedClassNameFromDescriptor(renamedDescriptor)));
+                  });
+            });
   }
 
   @Test
@@ -84,15 +88,18 @@
     }
     builder.addProgramClassFileData(jasminBuilder.buildClasses());
     Set<String> usedNames = new HashSet<>();
-    builder.noTreeShaking()
+    builder
+        .noTreeShaking()
         .compile()
-        .inspect(codeInspector -> {
-          codeInspector.forAllClasses(classSubject -> {
-            assertThat(classSubject, isRenamed());
-            assertTrue(usedNames.add(classSubject.getFinalName()));
-            assertNotEquals("R", classSubject.getFinalName());
-          });
-        });
+        .inspect(
+            codeInspector -> {
+              codeInspector.forAllClasses(
+                  classSubject -> {
+                    assertThat(classSubject, isPresentAndRenamed());
+                    assertTrue(usedNames.add(classSubject.getFinalName()));
+                    assertNotEquals("R", classSubject.getFinalName());
+                  });
+            });
     assertTrue(usedNames.contains("Q"));
     assertTrue(usedNames.contains("S"));
   }
@@ -114,17 +121,20 @@
     }
     builder.addProgramClassFileData(jasminBuilder.buildClasses());
     Set<String> usedDescriptors = new HashSet<>();
-    builder.noTreeShaking()
+    builder
+        .noTreeShaking()
         .addKeepRules(keepRule)
         .compile()
-        .inspect(codeInspector -> {
-          codeInspector.forAllClasses(classSubject -> {
-            assertThat(classSubject, isRenamed());
-            String renamedDescriptor = classSubject.getFinalDescriptor();
-            assertTrue(usedDescriptors.add(renamedDescriptor));
-            assertNotEquals("R", getUnqualifiedClassNameFromDescriptor(renamedDescriptor));
-          });
-        });
+        .inspect(
+            codeInspector -> {
+              codeInspector.forAllClasses(
+                  classSubject -> {
+                    assertThat(classSubject, isPresentAndRenamed());
+                    String renamedDescriptor = classSubject.getFinalDescriptor();
+                    assertTrue(usedDescriptors.add(renamedDescriptor));
+                    assertNotEquals("R", getUnqualifiedClassNameFromDescriptor(renamedDescriptor));
+                  });
+            });
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/naming/ClassNameMinifierOriginalClassNameTest.java b/src/test/java/com/android/tools/r8/naming/ClassNameMinifierOriginalClassNameTest.java
index 553fe0c..779eb8a 100644
--- a/src/test/java/com/android/tools/r8/naming/ClassNameMinifierOriginalClassNameTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ClassNameMinifierOriginalClassNameTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -62,7 +62,7 @@
         .inspect(
             inspector -> {
               assertEquals(1, inspector.allClasses().size());
-              assertThat(inspector.clazz(B.class), isRenamed());
+              assertThat(inspector.clazz(B.class), isPresentAndRenamed());
               assertEquals(A.class.getTypeName(), inspector.clazz(B.class).getFinalName());
             });
   }
diff --git a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeInSubInterfaceTest.java b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeInSubInterfaceTest.java
index 8c50aa7..3eae470 100644
--- a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeInSubInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeInSubInterfaceTest.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -94,13 +94,13 @@
   private void inspect(CodeInspector inspector, boolean overloadAggressively)
       throws NoSuchMethodException {
     ClassSubject superInterface = inspector.clazz(SuperInterface.class);
-    assertThat(superInterface, isRenamed());
+    assertThat(superInterface, isPresentAndRenamed());
     MethodSubject foo1 = superInterface.uniqueMethodWithName("foo");
-    assertThat(foo1, isRenamed());
+    assertThat(foo1, isPresentAndRenamed());
     ClassSubject subInterface = inspector.clazz(SubInterface.class);
-    assertThat(subInterface, isRenamed());
+    assertThat(subInterface, isPresentAndRenamed());
     MethodSubject foo2 = subInterface.method(SubInterface.class.getDeclaredMethod("foo"));
-    assertThat(foo2, isRenamed());
+    assertThat(foo2, isPresentAndRenamed());
     if (overloadAggressively && parameters.isDexRuntime()) {
       assertNotEquals(foo1.getFinalName(), foo2.getFinalName());
     } else {
diff --git a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
index 6cb9837..5d11b24 100644
--- a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -83,7 +83,7 @@
     Set<String> minifiedMethodNames = new HashSet<>();
     for (Set<MethodSubject> methodSubjects : methodSubjectsByName.values()) {
       for (MethodSubject methodSubject : methodSubjects) {
-        assertThat(methodSubject, isRenamed());
+        assertThat(methodSubject, isPresentAndRenamed());
         minifiedMethodNames.add(methodSubject.getFinalName());
       }
     }
diff --git a/src/test/java/com/android/tools/r8/naming/EnumMinification.java b/src/test/java/com/android/tools/r8/naming/EnumMinification.java
index 177a7f0..6a5ff3e 100644
--- a/src/test/java/com/android/tools/r8/naming/EnumMinification.java
+++ b/src/test/java/com/android/tools/r8/naming/EnumMinification.java
@@ -5,7 +5,8 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 
@@ -65,12 +66,14 @@
     ClassSubject clazz = inspector.clazz(enumTypeName);
     // The class and fields - including field $VALUES and method valueOf - can be renamed. Only
     // the values() method needs to be
-    assertThat(clazz, isRenamed());
-    assertThat(clazz.uniqueFieldWithName("VALUE1"), isRenamed());
-    assertThat(clazz.uniqueFieldWithName("VALUE2"), isRenamed());
-    assertThat(clazz.uniqueFieldWithName("$VALUES"), isRenamed());
-    assertThat(clazz.uniqueMethodWithName("valueOf"), valueOfKept ? isRenamed() : not(isPresent()));
-    assertThat(clazz.uniqueMethodWithName("values"), not(isRenamed()));
+    assertThat(clazz, isPresentAndRenamed());
+    assertThat(clazz.uniqueFieldWithName("VALUE1"), isPresentAndRenamed());
+    assertThat(clazz.uniqueFieldWithName("VALUE2"), isPresentAndRenamed());
+    assertThat(clazz.uniqueFieldWithName("$VALUES"), isPresentAndRenamed());
+    assertThat(
+        clazz.uniqueMethodWithName("valueOf"),
+        valueOfKept ? isPresentAndRenamed() : not(isPresent()));
+    assertThat(clazz.uniqueMethodWithName("values"), isPresentAndNotRenamed());
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/naming/ForNameRenamingTest.java b/src/test/java/com/android/tools/r8/naming/ForNameRenamingTest.java
index 1d776b5..c69ecd0 100644
--- a/src/test/java/com/android/tools/r8/naming/ForNameRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ForNameRenamingTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -48,8 +48,7 @@
 
   private void inspect(CodeInspector inspector) {
     ClassSubject boo = inspector.clazz(Boo.class);
-    assertThat(boo, isPresent());
-    assertThat(boo, isRenamed());
+    assertThat(boo, isPresentAndRenamed());
 
     ClassSubject main = inspector.clazz(MAIN);
     assertThat(main, isPresent());
diff --git a/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java b/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
index 5eca4d1..f72abf5 100644
--- a/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
+++ b/src/test/java/com/android/tools/r8/naming/KeepPackageNamesTest.java
@@ -4,8 +4,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.DescriptorUtils.getPackageNameFromDescriptor;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -44,15 +43,13 @@
 
     public void inspect(CodeInspector inspector) {
       ClassSubject top = inspector.clazz(Top.class);
-      assertThat(top, isPresent());
-      assertThat(top, isRenamed());
+      assertThat(top, isPresentAndRenamed());
       assertEquals(
           getPackageNameFromDescriptor(top.getOriginalDescriptor()),
           getPackageNameFromDescriptor(top.getFinalDescriptor()));
 
       ClassSubject sub = inspector.clazz(SubClass.class);
-      assertThat(sub, isPresent());
-      assertThat(sub, isRenamed());
+      assertThat(sub, isPresentAndRenamed());
       switch (this) {
         case SINGLE_ASTERISK:
           assertNotEquals(
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
index bcb02da..07dad43 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -327,13 +327,13 @@
                     .setProguardMapConsumer(StringConsumer.emptyConsumer())
                     .build()));
     // All classes are kept, and renamed.
-    assertThat(inspector.clazz("Simple"), isRenamed());
-    assertThat(inspector.clazz("Base"), isRenamed());
-    assertThat(inspector.clazz("Outer"), isRenamed());
-    assertThat(inspector.clazz("Outer$Inner"), isRenamed());
-    assertThat(inspector.clazz("Outer$ExtendsInner"), isRenamed());
-    assertThat(inspector.clazz("Outer$Inner$InnerInner"), isRenamed());
-    assertThat(inspector.clazz("Outer$Inner$ExtendsInnerInner"), isRenamed());
+    assertThat(inspector.clazz("Simple"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Base"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Outer"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Outer$Inner"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Outer$ExtendsInner"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Outer$Inner$InnerInner"), isPresentAndRenamed());
+    assertThat(inspector.clazz("Outer$Inner$ExtendsInnerInner"), isPresentAndRenamed());
 
     // Test that classes with have their original signature if the default was provided.
     if (!signatures.containsKey("Simple")) {
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
index 5737496..12b18e4 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierFieldSignatureTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -193,8 +193,8 @@
                     .build()));
     // All classes are kept, and renamed.
     ClassSubject clazz = inspector.clazz("Fields");
-    assertThat(clazz, isRenamed());
-    assertThat(inspector.clazz("Fields$Inner"), isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
+    assertThat(inspector.clazz("Fields$Inner"), isPresentAndRenamed());
 
     FieldSubject anX = lookupAnX(inspector);
     FieldSubject anArrayOfX = lookupAnArrayOfX(inspector);
@@ -202,10 +202,10 @@
     FieldSubject aFieldsOfXInner = clazz.field("Fields$Inner", "aFieldsOfXInner");
 
     // Check that all fields have been renamed
-    assertThat(anX, isRenamed());
-    assertThat(anArrayOfX, isRenamed());
-    assertThat(aFieldsOfX, isRenamed());
-    assertThat(aFieldsOfXInner, isRenamed());
+    assertThat(anX, isPresentAndRenamed());
+    assertThat(anArrayOfX, isPresentAndRenamed());
+    assertThat(aFieldsOfX, isPresentAndRenamed());
+    assertThat(aFieldsOfXInner, isPresentAndRenamed());
 
     //System.out.println(generic.getFinalSignatureAttribute());
     //System.out.println(generic.getOriginalSignatureAttribute());
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
index b19ed16..a275bdb 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -215,8 +215,8 @@
                     .build()));
     // All classes are kept, and renamed.
     ClassSubject clazz = inspector.clazz("Methods");
-    assertThat(clazz, isRenamed());
-    assertThat(inspector.clazz("Methods$Inner"), isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
+    assertThat(inspector.clazz("Methods$Inner"), isPresentAndRenamed());
 
     MethodSubject generic = lookupGeneric(inspector);
     MethodSubject parameterizedReturn = lookupParameterizedReturn(inspector);
@@ -225,10 +225,10 @@
         clazz.method("void", "parametrizedThrows", ImmutableList.of());
 
     // Check that all methods have been renamed
-    assertThat(generic, isRenamed());
-    assertThat(parameterizedReturn, isRenamed());
-    assertThat(parameterizedArguments, isRenamed());
-    assertThat(parametrizedThrows, isRenamed());
+    assertThat(generic, isPresentAndRenamed());
+    assertThat(parameterizedReturn, isPresentAndRenamed());
+    assertThat(parameterizedArguments, isPresentAndRenamed());
+    assertThat(parametrizedThrows, isPresentAndRenamed());
 
     // Test that methods have their original signature if the default was provided.
     if (!signatures.containsKey("generic")) {
diff --git a/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java b/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
index 18bc136..11c9154 100644
--- a/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
@@ -5,8 +5,7 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -59,8 +58,7 @@
     assertThat(classSubject, isPresent());
 
     FieldSubject fieldSubject = classSubject.uniqueFieldWithName("a");
-    assertThat(fieldSubject, isPresent());
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
 
     FieldSubject helloFieldSubject = classSubject.uniqueFieldWithName("hello");
     assertThat(helloFieldSubject, isPresent());
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubClassTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubClassTest.java
index 943e4bf..67b86ce 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubClassTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubClassTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -102,40 +102,40 @@
     assertThat(aFieldSubject, isPresent());
 
     if (reserveName) {
-      assertThat(f1FieldSubject, isRenamed());
+      assertThat(f1FieldSubject, isPresentAndRenamed());
       assertEquals("e", f1FieldSubject.getFinalName());
 
-      assertThat(f2FieldSubject, isRenamed());
+      assertThat(f2FieldSubject, isPresentAndRenamed());
       assertEquals("f", f2FieldSubject.getFinalName());
 
-      assertThat(f3FieldSubject, isRenamed());
+      assertThat(f3FieldSubject, isPresentAndRenamed());
       assertEquals("b", f3FieldSubject.getFinalName());
 
-      assertThat(f4FieldSubject, isRenamed());
+      assertThat(f4FieldSubject, isPresentAndRenamed());
       assertEquals("c", f4FieldSubject.getFinalName());
 
-      assertThat(f5FieldSubject, isRenamed());
+      assertThat(f5FieldSubject, isPresentAndRenamed());
       assertEquals("d", f5FieldSubject.getFinalName());
 
       // B.a should not be renamed because it is not allowed to be minified.
-      assertThat(aFieldSubject, not(isRenamed()));
+      assertThat(aFieldSubject, isPresentAndNotRenamed());
     } else {
-      assertThat(f1FieldSubject, isRenamed());
+      assertThat(f1FieldSubject, isPresentAndRenamed());
       assertEquals("d", f1FieldSubject.getFinalName());
 
-      assertThat(f2FieldSubject, isRenamed());
+      assertThat(f2FieldSubject, isPresentAndRenamed());
       assertEquals("e", f2FieldSubject.getFinalName());
 
-      assertThat(f3FieldSubject, isRenamed());
+      assertThat(f3FieldSubject, isPresentAndRenamed());
       assertEquals("a", f3FieldSubject.getFinalName());
 
-      assertThat(f4FieldSubject, isRenamed());
+      assertThat(f4FieldSubject, isPresentAndRenamed());
       assertEquals("b", f4FieldSubject.getFinalName());
 
-      assertThat(f5FieldSubject, isRenamed());
+      assertThat(f5FieldSubject, isPresentAndRenamed());
       assertEquals("c", f5FieldSubject.getFinalName());
 
-      assertThat(aFieldSubject, isRenamed());
+      assertThat(aFieldSubject, isPresentAndRenamed());
       assertEquals("f", aFieldSubject.getFinalName());
     }
   }
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubInterfaceTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubInterfaceTest.java
index 309c156..89804e8 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSubInterfaceTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assume.assumeFalse;
@@ -69,13 +69,13 @@
 
     FieldSubject f1FieldSubject = iClassSubject.uniqueFieldWithName("f1");
     assertThat(f1FieldSubject, isPresent());
-    assertThat(f1FieldSubject, isRenamed());
+    assertThat(f1FieldSubject, isPresentAndRenamed());
 
     FieldSubject aFieldSubject = jClassSubject.uniqueFieldWithName("a");
     assertThat(aFieldSubject, isPresent());
 
     if (reserveName) {
-      assertThat(aFieldSubject, not(isRenamed()));
+      assertThat(aFieldSubject, isPresentAndNotRenamed());
 
       // Interface fields are visited/renamed before fields on classes. Thus, the interface field
       // I.f1 will be visited first and assigned the name b (since the name a is reserved).
@@ -88,7 +88,7 @@
 
       // The interface field J.a will be visited after I.f1, and will therefore be assigned the name
       // b.
-      assertThat(aFieldSubject, isRenamed());
+      assertThat(aFieldSubject, isPresentAndRenamed());
       assertEquals("b", aFieldSubject.getFinalName());
     }
 
@@ -121,7 +121,7 @@
 
     FieldSubject f2FieldSubject = aClassSubject.uniqueFieldWithName("f2");
     assertThat(f2FieldSubject, isPresent());
-    assertThat(f2FieldSubject, isRenamed());
+    assertThat(f2FieldSubject, isPresentAndRenamed());
 
     assertEquals(expectedNameForF2, f2FieldSubject.getFinalName());
   }
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
index c687947..e7f32e3 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -63,7 +63,7 @@
     // Fields are visited/renamed according to the class hierarchy order. Thus, the field A.a will
     // be visited first and assigned the name a. As it ends up receiving the same name as in the
     // original program, it has not technically been renamed.
-    assertThat(aFieldSubject, not(isRenamed()));
+    assertThat(aFieldSubject, isPresentAndNotRenamed());
 
     inspect(inspector);
   }
@@ -90,16 +90,14 @@
     assertThat(aSub1ClassSubject, isPresent());
 
     FieldSubject fooFieldSubject = aSub1ClassSubject.uniqueFieldWithName("foo");
-    assertThat(fooFieldSubject, isPresent());
-    assertThat(fooFieldSubject, isRenamed());
+    assertThat(fooFieldSubject, isPresentAndRenamed());
     assertNotEquals("a", fooFieldSubject.getFinalName());
 
     ClassSubject aSub2ClassSubject = inspector.clazz(ASub2.class);
     assertThat(aSub2ClassSubject, isPresent());
 
     FieldSubject barFieldSubject = aSub2ClassSubject.uniqueFieldWithName("bar");
-    assertThat(barFieldSubject, isPresent());
-    assertThat(barFieldSubject, isRenamed());
+    assertThat(barFieldSubject, isPresentAndRenamed());
     assertNotEquals("a", barFieldSubject.getFinalName());
 
     // Verify that ASub1.foo and ASub2.bar has been renamed to the same name.
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
index 4af8655..599799e 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.naming;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assume.assumeFalse;
@@ -66,7 +66,7 @@
     // Interface fields are visited/renamed before fields on classes. Thus, the interface field I.a
     // will be visited first and assigned the name a. As it ends up receiving the same name as in
     // the input program, it has not technically been renamed.
-    assertThat(aFieldSubject, not(isRenamed()));
+    assertThat(aFieldSubject, isPresentAndNotRenamed());
 
     inspect(inspector);
   }
@@ -95,7 +95,7 @@
 
     FieldSubject f1FieldSubject = jClassSubject.uniqueFieldWithName("f1");
     assertThat(f1FieldSubject, isPresent());
-    assertThat(f1FieldSubject, isRenamed());
+    assertThat(f1FieldSubject, isPresentAndRenamed());
     assertEquals("b", f1FieldSubject.getFinalName());
 
     ClassSubject aClassSubject = inspector.clazz(A.class);
@@ -103,7 +103,7 @@
 
     FieldSubject f2FieldSubject = aClassSubject.uniqueFieldWithName("f2");
     assertThat(f2FieldSubject, isPresent());
-    assertThat(f2FieldSubject, isRenamed());
+    assertThat(f2FieldSubject, isPresentAndRenamed());
     assertEquals("c", f2FieldSubject.getFinalName());
   }
 
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingDesugarLambdaTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingDesugarLambdaTest.java
index e0d117f..0d0af87 100644
--- a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingDesugarLambdaTest.java
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingDesugarLambdaTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming.applymapping;
 
 import static com.android.tools.r8.Collectors.toSingle;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertNotSame;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -58,7 +58,7 @@
             .compile()
             .inspect(
                 inspector -> {
-                  assertThat(inspector.clazz(A.class), isRenamed());
+                  assertThat(inspector.clazz(A.class), isPresentAndRenamed());
                   assertEquals(finalName, inspector.clazz(A.class).getFinalName());
                 });
 
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionAsmTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionAsmTest.java
index 837c7df..1d188fb 100644
--- a/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionAsmTest.java
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionAsmTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming.applymapping.sourcelibrary;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -113,18 +113,15 @@
             .inspector();
 
     ClassSubject base = codeInspector.clazz("HasMapping");
-    assertThat(base, isPresent());
-    assertThat(base, isRenamed());
+    assertThat(base, isPresentAndRenamed());
     assertEquals("X", base.getFinalName());
     MethodSubject x = base.method("void", "foo", ImmutableList.of());
-    assertThat(x, isPresent());
-    assertThat(x, isRenamed());
+    assertThat(x, isPresentAndRenamed());
     assertEquals("a", x.getFinalName());
 
     // To ensure still getting illegal-access error we need to rename consistently.
     ClassSubject sub = codeInspector.clazz("NoMapping");
-    assertThat(sub, isPresent());
-    assertThat(sub, isRenamed());
+    assertThat(sub, isPresentAndRenamed());
     assertEquals("Y", sub.getFinalName());
     MethodSubject y = sub.method("void", "a", ImmutableList.of());
     assertThat(y, isPresent());
@@ -212,17 +209,14 @@
 
     CodeInspector codeInspector = compileResult.inspector();
     ClassSubject base = codeInspector.clazz("A");
-    assertThat(base, isPresent());
-    assertThat(base, isRenamed());
+    assertThat(base, isPresentAndRenamed());
     assertEquals("X", base.getFinalName());
     MethodSubject x = base.method("void", "x", ImmutableList.of());
-    assertThat(x, isPresent());
-    assertThat(x, isRenamed());
+    assertThat(x, isPresentAndRenamed());
     assertEquals("y", x.getFinalName());
 
     ClassSubject sub = codeInspector.clazz("B");
-    assertThat(sub, isPresent());
-    assertThat(sub, isRenamed());
+    assertThat(sub, isPresentAndRenamed());
     assertEquals("Y", sub.getFinalName());
     MethodSubject subX = sub.method("void", "x", ImmutableList.of());
     assertThat(subX, not(isPresent()));
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionTest.java
index 3b683fa..725c5a9 100644
--- a/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionTest.java
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/sourcelibrary/MemberResolutionTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming.applymapping.sourcelibrary;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -133,23 +133,19 @@
     ClassSubject base = inspector.clazz(AbstractChecker.class);
     assertThat(base, isPresent());
     FieldSubject p = base.field("java.lang.String", "tag");
-    assertThat(p, isPresent());
-    assertThat(p, isRenamed());
+    assertThat(p, isPresentAndRenamed());
     assertEquals("p", p.getFinalName());
     MethodSubject x = base.method("void", "check", ImmutableList.of());
-    assertThat(x, isPresent());
-    assertThat(x, isRenamed());
+    assertThat(x, isPresentAndRenamed());
     assertEquals("x", x.getFinalName());
 
     ClassSubject sub = inspector.clazz(ConcreteChecker.class);
     assertThat(sub, isPresent());
     FieldSubject q = sub.field("java.lang.String", "tag");
-    assertThat(q, isPresent());
-    assertThat(q, isRenamed());
+    assertThat(q, isPresentAndRenamed());
     assertEquals("q", q.getFinalName());
     MethodSubject y = sub.method("void", "check", ImmutableList.of());
-    assertThat(y, isPresent());
-    assertThat(y, isRenamed());
+    assertThat(y, isPresentAndRenamed());
     assertEquals("y", y.getFinalName());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/b116840216/ReserveOuterClassNameTest.java b/src/test/java/com/android/tools/r8/naming/b116840216/ReserveOuterClassNameTest.java
index d138e1b..5da3af5 100644
--- a/src/test/java/com/android/tools/r8/naming/b116840216/ReserveOuterClassNameTest.java
+++ b/src/test/java/com/android/tools/r8/naming/b116840216/ReserveOuterClassNameTest.java
@@ -3,9 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming.b116840216;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.CompatProguardCommandBuilder;
@@ -89,25 +88,19 @@
 
     CodeInspector inspector = new CodeInspector(processedApp);
     ClassSubject mainSubject = inspector.clazz(mainClass);
-    assertThat(mainSubject, isPresent());
-    assertThat(mainSubject, not(isRenamed()));
+    assertThat(mainSubject, isPresentAndNotRenamed());
     MethodSubject mainMethod = mainSubject.mainMethod();
-    assertThat(mainMethod, isPresent());
-    assertThat(mainMethod, not(isRenamed()));
+    assertThat(mainMethod, isPresentAndNotRenamed());
 
     ClassSubject outer = inspector.clazz(Outer.class);
-    assertThat(outer, isPresent());
-    assertThat(outer, not(isRenamed()));
+    assertThat(outer, isPresentAndNotRenamed());
     MethodSubject bar = outer.method("void", "bar", ImmutableList.of());
-    assertThat(bar, isPresent());
-    assertThat(bar, isRenamed());
+    assertThat(bar, isPresentAndRenamed());
 
     ClassSubject inner = inspector.clazz(Outer.Inner.class);
-    assertThat(inner, isPresent());
-    assertThat(inner, not(isRenamed()));
+    assertThat(inner, isPresentAndNotRenamed());
     MethodSubject foo = inner.method("void", "foo", ImmutableList.of());
-    assertThat(foo, isPresent());
-    assertThat(foo, isRenamed());
+    assertThat(foo, isPresentAndRenamed());
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
index e1cd05a..18d0719 100644
--- a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
+++ b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.naming.b124357885;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -68,23 +68,25 @@
 
   @Test
   public void test() throws Exception {
-    R8TestCompileResult compileResult = testForR8(Backend.DEX)
-        .addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
-        .addKeepMainRule(Main.class)
-        .addKeepRules("-keepattributes Signature,InnerClasses,EnclosingMethod")
-        .minification(minification)
-        .compile()
-        .inspect(inspector -> {
-          assertThat(inspector.clazz(Main.class), isNotRenamed());
-          assertThat(inspector.clazz(Service.class), isRenamed(minification));
-          assertThat(inspector.clazz(Foo.class), not(isPresent()));
-          assertThat(inspector.clazz(FooImpl.class), isRenamed(minification));
-          // TODO(124477502): Using uniqueMethodWithName("fooList") does not work.
-          assertEquals(1, inspector.clazz(Service.class).allMethods().size());
-          MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
-          AnnotationSubject signature = fooList.annotation("dalvik.annotation.Signature");
-          checkSignatureAnnotation(inspector, signature);
-        });
+    R8TestCompileResult compileResult =
+        testForR8(Backend.DEX)
+            .addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
+            .addKeepMainRule(Main.class)
+            .addKeepRules("-keepattributes Signature,InnerClasses,EnclosingMethod")
+            .minification(minification)
+            .compile()
+            .inspect(
+                inspector -> {
+                  assertThat(inspector.clazz(Main.class), isPresentAndNotRenamed());
+                  assertThat(inspector.clazz(Service.class), isPresentAndRenamed(minification));
+                  assertThat(inspector.clazz(Foo.class), not(isPresent()));
+                  assertThat(inspector.clazz(FooImpl.class), isPresentAndRenamed(minification));
+                  // TODO(124477502): Using uniqueMethodWithName("fooList") does not work.
+                  assertEquals(1, inspector.clazz(Service.class).allMethods().size());
+                  MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
+                  AnnotationSubject signature = fooList.annotation("dalvik.annotation.Signature");
+                  checkSignatureAnnotation(inspector, signature);
+                });
 
         String fooImplFinalName = compileResult.inspector().clazz(FooImpl.class).getFinalName();
 
diff --git a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
index 2f909be..78f0d0c 100644
--- a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
+++ b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming.b126592786;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -55,19 +55,20 @@
             "}",
             "-keepattributes InnerClasses,EnclosingMethod,Signature ")
         .compile()
-        .inspect(inspector -> {
-            String genericTypeDescriptor = "Ljava/lang/Object;";
-            if (genericTypeLive) {
-              ClassSubject genericType = inspector.clazz(GenericType.class);
-              assertThat(genericType, isRenamed(minify));
-              genericTypeDescriptor = genericType.getFinalDescriptor();
-            }
-            String expectedSignature = "Ljava/util/List<" + genericTypeDescriptor + ">;";
-            FieldSubject list = inspector.clazz(A.class).uniqueFieldWithName("list");
-            assertThat(list, isPresent());
-            assertThat(list.getSignatureAnnotation(), isPresent());
-            assertEquals(expectedSignature, list.getSignatureAnnotationValue());
-        })
+        .inspect(
+            inspector -> {
+              String genericTypeDescriptor = "Ljava/lang/Object;";
+              if (genericTypeLive) {
+                ClassSubject genericType = inspector.clazz(GenericType.class);
+                assertThat(genericType, isPresentAndRenamed(minify));
+                genericTypeDescriptor = genericType.getFinalDescriptor();
+              }
+              String expectedSignature = "Ljava/util/List<" + genericTypeDescriptor + ">;";
+              FieldSubject list = inspector.clazz(A.class).uniqueFieldWithName("list");
+              assertThat(list, isPresent());
+              assertThat(list.getSignatureAnnotation(), isPresent());
+              assertEquals(expectedSignature, list.getSignatureAnnotationValue());
+            })
         .run(mainClass)
         .assertSuccess();
   }
diff --git a/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java b/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
index f063f9e..56ed80c 100644
--- a/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
+++ b/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming.b128656974;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNotEquals;
 
@@ -40,8 +40,7 @@
               ClassSubject greetingBase = inspector.clazz(Greeting.getGreetingBase());
               assertThat(greetingBase, isPresent());
               FieldSubject greeting = greetingBase.uniqueFieldWithName("greeting");
-              assertThat(greeting, isPresent());
-              assertThat(greeting, isRenamed());
+              assertThat(greeting, isPresentAndRenamed());
               assertNotEquals("a", greeting.getFinalName());
             });
   }
@@ -88,8 +87,7 @@
               ClassSubject base = inspector.clazz(TestClassBase.class);
               assertThat(base, isPresent());
               MethodSubject foo = base.uniqueMethodWithName("foo");
-              assertThat(foo, isPresent());
-              assertThat(foo, isRenamed());
+              assertThat(foo, isPresentAndRenamed());
               assertNotEquals("a", foo.getFinalName());
             });
   }
diff --git a/src/test/java/com/android/tools/r8/naming/b130791310/B130791310.java b/src/test/java/com/android/tools/r8/naming/b130791310/B130791310.java
index d8f3910..bb27506 100644
--- a/src/test/java/com/android/tools/r8/naming/b130791310/B130791310.java
+++ b/src/test/java/com/android/tools/r8/naming/b130791310/B130791310.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.naming.b130791310;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assume.assumeFalse;
@@ -110,13 +110,11 @@
 
   private void inspect(CodeInspector inspector, boolean isR8) {
     ClassSubject holder = inspector.clazz(SomeLogic.class);
-    assertThat(holder, isPresent());
-    assertThat(holder, not(isRenamed()));
+    assertThat(holder, isPresentAndNotRenamed());
     MethodSubject someMethod = holder.uniqueMethodWithName("someMethod");
     if (isR8) {
       if (onlyForceInlining) {
-        assertThat(someMethod, isPresent());
-        assertThat(someMethod, not(isRenamed()));
+        assertThat(someMethod, isPresentAndNotRenamed());
       } else {
         assertThat(someMethod, not(isPresent()));
       }
@@ -126,8 +124,7 @@
         // method signature modification.
         assertThat(someMethod, not(isPresent()));
       } else {
-        assertThat(someMethod, isPresent());
-        assertThat(someMethod, not(isRenamed()));
+        assertThat(someMethod, isPresentAndNotRenamed());
       }
     }
   }
diff --git a/src/test/java/com/android/tools/r8/naming/b133686361/AlreadyRenamedAbstractMethodRenamingTest.java b/src/test/java/com/android/tools/r8/naming/b133686361/AlreadyRenamedAbstractMethodRenamingTest.java
index d104210..7cda3cd 100644
--- a/src/test/java/com/android/tools/r8/naming/b133686361/AlreadyRenamedAbstractMethodRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/b133686361/AlreadyRenamedAbstractMethodRenamingTest.java
@@ -3,9 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming.b133686361;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -88,26 +87,20 @@
 
   private void inspect(CodeInspector inspector) {
     ClassSubject base = inspector.clazz(Base.class);
-    assertThat(base, isPresent());
-    assertThat(base, isRenamed());
+    assertThat(base, isPresentAndRenamed());
     MethodSubject a = base.uniqueMethodWithName("a");
-    assertThat(a, isPresent());
-    assertThat(a, not(isRenamed()));
+    assertThat(a, isPresentAndNotRenamed());
 
     ClassSubject sub1 = inspector.clazz(Sub1.class);
-    assertThat(sub1, isPresent());
-    assertThat(sub1, isRenamed());
+    assertThat(sub1, isPresentAndRenamed());
     MethodSubject aInSub1 = sub1.uniqueMethodWithName("a");
-    assertThat(aInSub1, isPresent());
-    assertThat(aInSub1, not(isRenamed()));
+    assertThat(aInSub1, isPresentAndNotRenamed());
     assertEquals(a.getFinalName(), aInSub1.getFinalName());
 
     ClassSubject sub2 = inspector.clazz(Sub1.class);
-    assertThat(sub2, isPresent());
-    assertThat(sub2, isRenamed());
+    assertThat(sub2, isPresentAndRenamed());
     MethodSubject aInSub2 = sub2.uniqueMethodWithName("a");
-    assertThat(aInSub2, isPresent());
-    assertThat(aInSub2, not(isRenamed()));
+    assertThat(aInSub2, isPresentAndNotRenamed());
     assertEquals(a.getFinalName(), aInSub2.getFinalName());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/identifiernamestring/ClassNameComparisonSwitchTest.java b/src/test/java/com/android/tools/r8/naming/identifiernamestring/ClassNameComparisonSwitchTest.java
index 97a96cc..81038cf 100644
--- a/src/test/java/com/android/tools/r8/naming/identifiernamestring/ClassNameComparisonSwitchTest.java
+++ b/src/test/java/com/android/tools/r8/naming/identifiernamestring/ClassNameComparisonSwitchTest.java
@@ -4,8 +4,7 @@
 
 package com.android.tools.r8.naming.identifiernamestring;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -51,8 +50,7 @@
   private void verifyClassesHaveBeenMinified(CodeInspector inspector) {
     for (Class<?> clazz : ImmutableList.of(A.class, B.class, C.class)) {
       ClassSubject classSubject = inspector.clazz(clazz);
-      assertThat(classSubject, isPresent());
-      assertThat(classSubject, isRenamed());
+      assertThat(classSubject, isPresentAndRenamed());
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/proguard/NonExistingConfigFileTest.java b/src/test/java/com/android/tools/r8/proguard/NonExistingConfigFileTest.java
index 7d0dc70..b241eff 100644
--- a/src/test/java/com/android/tools/r8/proguard/NonExistingConfigFileTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/NonExistingConfigFileTest.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.proguard;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.fail;
@@ -28,11 +27,11 @@
         .addKeepRuleFiles(pg)
         .compile()
         .assertNoMessages()
-        .inspect(inspector -> {
-          ClassSubject clazz = inspector.clazz(TestClass.class);
-          assertThat(clazz, isPresent());
-          assertThat(clazz, isRenamed());
-        });
+        .inspect(
+            inspector -> {
+              ClassSubject clazz = inspector.clazz(TestClass.class);
+              assertThat(clazz, isPresentAndRenamed());
+            });
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java b/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java
index b7017e7..ddaf47f 100644
--- a/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/AsterisksTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -75,11 +75,9 @@
     );
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
     ClassSubject classSubject = codeInspector.clazz(B111974287.class);
-    assertThat(classSubject, isPresent());
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     FieldSubject fieldSubject = classSubject.field(B111974287.class.getTypeName(), "self");
-    assertThat(fieldSubject, isPresent());
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
     fieldSubject = classSubject.field(B111974287.class.getTypeName() + "[]", "clones");
     // TODO(b/111974287): Proguard6 kept and renamed the field with array type.
     if (shrinker == Shrinker.PROGUARD6) {
@@ -97,16 +95,14 @@
     );
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
     ClassSubject classSubject = codeInspector.clazz(B111974287.class);
-    assertThat(classSubject, isPresent());
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     DexClass clazz = classSubject.getDexProgramClass();
     assertEquals(3, clazz.getMethodCollection().numberOfVirtualMethods());
     for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
       assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
       MethodSubject methodSubject =
           classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
-      assertThat(methodSubject, isPresent());
-      assertThat(methodSubject, not(isRenamed()));
+      assertThat(methodSubject, isPresentAndNotRenamed());
     }
   }
 
@@ -119,14 +115,11 @@
     );
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
     ClassSubject classSubject = codeInspector.clazz(B111974287.class);
-    assertThat(classSubject, isPresent());
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     FieldSubject fieldSubject = classSubject.field(B111974287.class.getTypeName(), "self");
-    assertThat(fieldSubject, isPresent());
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
     fieldSubject = classSubject.field(B111974287.class.getTypeName() + "[]", "clones");
-    assertThat(fieldSubject, isPresent());
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
   }
 
   @Test
@@ -138,16 +131,14 @@
     );
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
     ClassSubject classSubject = codeInspector.clazz(B111974287.class);
-    assertThat(classSubject, isPresent());
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     DexClass clazz = classSubject.getDexProgramClass();
     assertEquals(3, clazz.getMethodCollection().numberOfVirtualMethods());
     for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
       assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
       MethodSubject methodSubject =
           classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
-      assertThat(methodSubject, isPresent());
-      assertThat(methodSubject, not(isRenamed()));
+      assertThat(methodSubject, isPresentAndNotRenamed());
     }
   }
 
@@ -160,16 +151,14 @@
     );
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
     ClassSubject classSubject = codeInspector.clazz(B111974287.class);
-    assertThat(classSubject, isPresent());
-    assertThat(classSubject, not(isRenamed()));
+    assertThat(classSubject, isPresentAndNotRenamed());
     DexClass clazz = classSubject.getDexProgramClass();
     assertEquals(3, clazz.getMethodCollection().numberOfVirtualMethods());
     for (DexEncodedMethod encodedMethod : clazz.virtualMethods()) {
       assertTrue(encodedMethod.method.name.toString().startsWith("foo"));
       MethodSubject methodSubject =
           classSubject.method(MethodSignature.fromDexMethod(encodedMethod.method));
-      assertThat(methodSubject, isPresent());
-      assertThat(methodSubject, not(isRenamed()));
+      assertThat(methodSubject, isPresentAndNotRenamed());
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/shaking/AtomicFieldUpdaterTest.java b/src/test/java/com/android/tools/r8/shaking/AtomicFieldUpdaterTest.java
index f9a6bea..7015177 100644
--- a/src/test/java/com/android/tools/r8/shaking/AtomicFieldUpdaterTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/AtomicFieldUpdaterTest.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.shaking;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
@@ -50,8 +50,8 @@
     // Verify that the field is still there.
     CodeInspector inspector = new CodeInspector(output, proguardMapPath);
     ClassSubject classSubject = inspector.clazz(AtomicFieldUpdaterTestClass.A.class.getName());
-    assertThat(classSubject, isRenamed());
-    assertThat(classSubject.field("int", "field"), isRenamed());
+    assertThat(classSubject, isPresentAndRenamed());
+    assertThat(classSubject.field("int", "field"), isPresentAndRenamed());
     // Check that the code runs.
     assertEquals(
         runOnJava(AtomicFieldUpdaterTestClass.class),
diff --git a/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java b/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java
index ac18813..3c15d88 100644
--- a/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -173,7 +173,7 @@
         .inspect(
             inspector -> {
               FieldSubject fld = inspector.clazz(fieldHolder.name).uniqueFieldWithName(fieldName);
-              assertThat(fld, isRenamed());
+              assertThat(fld, isPresentAndRenamed());
 
               ClassSubject classSubject = inspector.clazz(clazz.name);
               assertThat(classSubject, isPresent());
@@ -370,7 +370,7 @@
       boolean isR8) {
     FieldSubject fld = inspector.clazz(fieldHolder.name).uniqueFieldWithName(fieldName);
     if (isR8) {
-      assertThat(fld, isRenamed());
+      assertThat(fld, isPresentAndRenamed());
     } else {
       assertThat(fld, isPresent());
     }
diff --git a/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
new file mode 100644
index 0000000..d989fbf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
@@ -0,0 +1,297 @@
+// Copyright (c) 2020, 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.shaking;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticException;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.R8;
+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.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.android.tools.r8.utils.graphinspector.GraphInspector;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class KeepAnnotatedMemberTest extends TestBase {
+
+  private static final Path R8_JAR = Paths.get(ToolHelper.THIRD_PARTY_DIR, "r8", "r8.jar");
+  private static final String ABSENT_ANNOTATION = "com.android.tools.r8.MissingAnnotation";
+  private static final String PRESENT_ANNOTATION =
+      "com.android.tools.r8.com.google.common.annotations.VisibleForTesting";
+
+  private static final String CLASS_WITH_ANNOTATED_METHOD =
+      "com.android.tools.r8.com.google.common.math.IntMath";
+
+  private static final String ANNOTATED_METHOD = "lessThanBranchFree";
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public KeepAnnotatedMemberTest(TestParameters parameters) {
+    parameters.assertNoneRuntime();
+  }
+
+  @Test
+  public void testPresence() throws Exception {
+    CodeInspector inspector = new CodeInspector(R8_JAR);
+    assertThat(inspector.clazz(ABSENT_ANNOTATION), not(isPresent()));
+    assertThat(inspector.clazz(PRESENT_ANNOTATION), isPresent());
+    ClassSubject clazz = inspector.clazz(CLASS_WITH_ANNOTATED_METHOD);
+    MethodSubject method = clazz.uniqueMethodWithName(ANNOTATED_METHOD);
+    assertThat(method, isPresent());
+  }
+
+  // TODO(b/159966986): A general keep rule should not cause compiler assertion errors.
+  @Test(expected = CompilationFailedException.class)
+  public void testPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .addKeepRules("-keep class * { @" + PRESENT_ANNOTATION + " *; }")
+        .compileWithExpectedDiagnostics(
+            diagnostics ->
+                diagnostics.assertErrorsMatch(diagnosticException(AssertionError.class)));
+  }
+
+  @Test
+  public void testPresentAnnotationSplit() throws Exception {
+    // These rules should be equivalent to the above.
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .addKeepRules(
+            "-keep class *", "-keepclassmembers class * { @" + PRESENT_ANNOTATION + " *; }")
+        .compile();
+  }
+
+  @Test
+  public void testWithMembersAbsentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .allowUnusedProguardConfigurationRules()
+        .addKeepRules("-keepclasseswithmembers class * { @" + ABSENT_ANNOTATION + " *; }")
+        .compile()
+        .inspect(inspector -> assertEquals(0, inspector.allClasses().size()));
+  }
+
+  @Test
+  public void testWithMembersPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .addKeepRules("-keepclasseswithmembers class * { @" + PRESENT_ANNOTATION + " *** *(...); }")
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject clazz = inspector.clazz(CLASS_WITH_ANNOTATED_METHOD);
+              assertThat(clazz, isPresent());
+              assertThat(clazz.uniqueMethodWithName(ANNOTATED_METHOD), isPresent());
+            });
+  }
+
+  @Test
+  public void testUnsatisfiedClassMembersPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        // TODO(b/159971974): Technically this rule does not hit anything and should fail due to
+        //  missing allowUnusedProguardConfigurationRules()
+        .addKeepRules("-keepclassmembers class * { @" + PRESENT_ANNOTATION + " *** *(...); }")
+        .compile()
+        .inspect(inspector -> assertEquals(0, inspector.allClasses().size()));
+  }
+
+  @Test
+  public void testSatisfiedClassMembersPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+        .addKeepRules("-keepclassmembers class * { @" + PRESENT_ANNOTATION + " *** *(...); }")
+        .compile()
+        .inspect(
+            inspector -> {
+              assertEquals(1, inspector.allClasses().size());
+              List<FoundMethodSubject> methods =
+                  inspector.clazz(CLASS_WITH_ANNOTATED_METHOD).allMethods();
+              assertEquals(
+                  1, methods.stream().filter(m -> m.getOriginalName().equals("<init>")).count());
+              assertEquals(
+                  1,
+                  methods.stream()
+                      .filter(m -> m.getOriginalName().equals(ANNOTATED_METHOD))
+                      .count());
+              assertEquals(2, methods.size());
+            });
+  }
+
+  @Test
+  public void testUnsatisfiedConditionalPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .allowUnusedProguardConfigurationRules()
+        .addKeepRules("-if class * -keep class <1> { @" + PRESENT_ANNOTATION + " *** *(...); }")
+        .compile()
+        .inspect(inspector -> assertEquals(0, inspector.allClasses().size()));
+  }
+
+  @Test
+  public void testSatisfiedConditionalPresentAnnotation() throws Exception {
+    testForR8(Backend.CF)
+        .addProgramFiles(R8_JAR)
+        .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+        .addKeepRules("-if class * -keep class <1> { @" + PRESENT_ANNOTATION + " *** *(...); }")
+        .compile()
+        .inspect(
+            inspector -> {
+              assertEquals(1, inspector.allClasses().size());
+              List<FoundMethodSubject> methods =
+                  inspector.clazz(CLASS_WITH_ANNOTATED_METHOD).allMethods();
+              assertEquals(
+                  1, methods.stream().filter(m -> m.getOriginalName().equals("<init>")).count());
+              // TODO(b/132318609): This should have the annotated method, but does not due to the
+              //  annotation being removed.
+              assertEquals(
+                  0,
+                  methods.stream()
+                      .filter(m -> m.getOriginalName().equals(ANNOTATED_METHOD))
+                      .count());
+              assertEquals(1, methods.size());
+            });
+  }
+
+  @Test
+  public void testConditionalEqualsKeepClassMembers() throws Exception {
+    GraphInspector referenceInspector =
+        testForR8(Backend.CF)
+            .enableGraphInspector()
+            .addProgramFiles(R8_JAR)
+            .addKeepMainRule(R8.class)
+            .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+            // TODO(b/132318609): Remove keep annotation once fixed.
+            .addKeepClassRules(PRESENT_ANNOTATION)
+            .addKeepRules("-keepclassmembers class * { @" + PRESENT_ANNOTATION + " *** *(...); }")
+            .compile()
+            .graphInspector();
+
+    GraphInspector ifThenKeepClassMembersInspector =
+        testForR8(Backend.CF)
+            .enableGraphInspector()
+            .addProgramFiles(R8_JAR)
+            .addKeepMainRule(R8.class)
+            .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+            // TODO(b/132318609): Remove keep annotation once fixed.
+            .addKeepClassRules(PRESENT_ANNOTATION)
+            .addKeepRules(
+                "-if class * "
+                    + "-keepclassmembers class <1> { @"
+                    + PRESENT_ANNOTATION
+                    + " *** *(...); }")
+            .compile()
+            .graphInspector();
+    // TODO(b/159418523): It appears that the insertion in never-inline causes additional retention.
+    assertRetainedClassesEqual(referenceInspector, ifThenKeepClassMembersInspector, false, true);
+
+    GraphInspector ifThenKeepClassesWithMembersInspector =
+        testForR8(Backend.CF)
+            .enableGraphInspector()
+            .addProgramFiles(R8_JAR)
+            .addKeepMainRule(R8.class)
+            .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+            // TODO(b/132318609): Remove keep annotation once fixed.
+            .addKeepClassRules(PRESENT_ANNOTATION)
+            .addKeepRules(
+                "-if class * "
+                    + "-keepclasseswithmembers class <1> { @"
+                    + PRESENT_ANNOTATION
+                    + " *** *(...); }")
+            .compile()
+            .graphInspector();
+    // TODO(b/159418523): It appears that the insertion in never-inline causes additional retention.
+    assertRetainedClassesEqual(
+        referenceInspector, ifThenKeepClassesWithMembersInspector, false, true);
+
+    GraphInspector ifHasMemberThenKeepClassInspector =
+        testForR8(Backend.CF)
+            .enableGraphInspector()
+            .addProgramFiles(R8_JAR)
+            .addKeepMainRule(R8.class)
+            .addKeepClassRules(CLASS_WITH_ANNOTATED_METHOD)
+            // TODO(b/132318609): Remove keep annotation once fixed.
+            .addKeepClassRules(PRESENT_ANNOTATION)
+            .addKeepRules(
+                "-if class * { @"
+                    + PRESENT_ANNOTATION
+                    + " *** *(...); } "
+                    + "-keep class <1> { @"
+                    + PRESENT_ANNOTATION
+                    + " *** <2>(...); }")
+            .compile()
+            .graphInspector();
+    // TODO(b/159418523): It appears that the insertion in never-inline causes additional retention.
+    //  Also, here neither is a subset of the other. That also appears wrong.
+    assertRetainedClassesEqual(referenceInspector, ifHasMemberThenKeepClassInspector, true, true);
+  }
+
+  private void assertRetainedClassesEqual(
+      GraphInspector referenceResult,
+      GraphInspector conditionalResult,
+      boolean expectReferenceIsLarger,
+      boolean expectConditionalIsLarger) {
+    Set<String> referenceClasses =
+        new TreeSet<>(
+            referenceResult.codeInspector().allClasses().stream()
+                .map(c -> c.getOriginalName())
+                .collect(Collectors.toSet()));
+
+    Set<String> conditionalClasses =
+        conditionalResult.codeInspector().allClasses().stream()
+            .map(c -> c.getOriginalName())
+            .collect(Collectors.toSet());
+    {
+      SetView<String> notInReference = Sets.difference(conditionalClasses, referenceClasses);
+      if (expectConditionalIsLarger) {
+        assertFalse("Expected classes in -if rule to retain more.", notInReference.isEmpty());
+      } else {
+        assertEquals(
+            "Classes in -if rule that are not in -keepclassmembers rule",
+            Collections.emptySet(),
+            notInReference);
+      }
+    }
+    {
+      SetView<String> notInConditional = Sets.difference(referenceClasses, conditionalClasses);
+      if (expectReferenceIsLarger) {
+        assertFalse(
+            "Expected classes in -keepclassmembers rule to retain more.",
+            notInConditional.isEmpty());
+      } else {
+        assertEquals(
+            "Classes in -keepclassmembers rule that are not in -if rule",
+            Collections.emptySet(),
+            new TreeSet<>(notInConditional));
+      }
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java b/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
index 8673412..bee167f 100644
--- a/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -183,7 +183,7 @@
     if (!enableClassInlining && !enableVerticalClassMerging) {
       CodeInspector inspector = compiled.inspector();
       ClassSubject classSubject = inspector.clazz(B.class.getName());
-      assertThat(classSubject, isRenamed());
+      assertThat(classSubject, isPresentAndRenamed());
       assertThat(classSubject.method("void", "m1", ImmutableList.of()), isPresent());
       assertThat(classSubject.method("void", "m2", ImmutableList.of()), not(isPresent()));
       assertThat(classSubject.method("void", "m3", ImmutableList.of()), isPresent());
diff --git a/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java
index 5cdbd87..59c649b 100644
--- a/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ParameterTypeTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -136,14 +136,14 @@
             .inspector();
 
     ClassSubject superInterface1 = inspector.clazz(B112452064SuperInterface1.class);
-    assertThat(superInterface1, isRenamed());
+    assertThat(superInterface1, isPresentAndRenamed());
     MethodSubject foo = superInterface1.uniqueMethodWithName("foo");
     assertThat(foo, not(isPresent()));
     ClassSubject superInterface2 = inspector.clazz(B112452064SuperInterface2.class);
     if (enableVerticalClassMerging) {
       assertThat(superInterface2, not(isPresent()));
     } else {
-      assertThat(superInterface2, isRenamed());
+      assertThat(superInterface2, isPresentAndRenamed());
     }
     MethodSubject bar = superInterface2.uniqueMethodWithName("bar");
     assertThat(bar, not(isPresent()));
@@ -152,7 +152,7 @@
       assertThat(subInterface, not(isPresent()));
     } else {
       assertThat(subInterface, isPresent());
-      assertThat(subInterface, isRenamed());
+      assertThat(subInterface, isPresentAndRenamed());
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/shaking/ReturnTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ReturnTypeTest.java
index 4c25b86..98b7f80 100644
--- a/src/test/java/com/android/tools/r8/shaking/ReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ReturnTypeTest.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.shaking;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assume.assumeTrue;
 
@@ -93,7 +93,7 @@
         .inspect(
             inspector -> {
               ClassSubject returnType = inspector.clazz(B112517039ReturnType.class);
-              assertThat(returnType, isRenamed());
+              assertThat(returnType, isPresentAndRenamed());
             });
   }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java
index d24d8c1..edd818e 100644
--- a/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/AnnotationsOnFieldsTest.java
@@ -1,7 +1,7 @@
 package com.android.tools.r8.shaking.annotations;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static java.lang.annotation.ElementType.FIELD;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -59,18 +59,18 @@
             inspector -> {
               ClassSubject clazz = inspector.clazz(TestClass.class);
               assertThat(clazz, isPresent());
-              assertThat(clazz, isRenamed());
+              assertThat(clazz, isPresentAndRenamed());
 
               FieldSubject field = clazz.uniqueFieldWithName("field");
               assertThat(field, isPresent());
               assertThat(field.annotation(FieldAnnotation.class.getTypeName()), isPresent());
-              assertThat(inspector.clazz(FieldAnnotationUse.class), isRenamed());
+              assertThat(inspector.clazz(FieldAnnotationUse.class), isPresentAndRenamed());
 
               FieldSubject staticField = clazz.uniqueFieldWithName("staticField");
               assertThat(staticField, isPresent());
               assertThat(
                   staticField.annotation(StaticFieldAnnotation.class.getTypeName()), isPresent());
-              assertThat(inspector.clazz(StaticFieldAnnotationUse.class), isRenamed());
+              assertThat(inspector.clazz(StaticFieldAnnotationUse.class), isPresentAndRenamed());
             })
         .run(MainClass.class)
         .assertSuccess();
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
index 84ceffa..c975c82 100644
--- a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.shaking.annotations;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.not;
@@ -105,20 +105,15 @@
             .assertSuccessWithOutput(JAVA_OUTPUT)
             .inspector();
     ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
-    assertThat(clazz, isPresent());
-    assertThat(clazz, not(isRenamed()));
+    assertThat(clazz, isPresentAndNotRenamed());
     MethodSubject f1 = clazz.uniqueMethodWithName("f1");
-    assertThat(f1, isPresent());
-    assertThat(f1, not(isRenamed()));
+    assertThat(f1, isPresentAndNotRenamed());
     MethodSubject f2 = clazz.uniqueMethodWithName("f2");
-    assertThat(f2, isPresent());
-    assertThat(f2, not(isRenamed()));
+    assertThat(f2, isPresentAndNotRenamed());
     MethodSubject f3 = clazz.uniqueMethodWithName("f3");
-    assertThat(f3, isPresent());
-    assertThat(f3, not(isRenamed()));
+    assertThat(f3, isPresentAndNotRenamed());
     MethodSubject f4 = clazz.uniqueMethodWithName("f4");
-    assertThat(f4, isPresent());
-    assertThat(f4, not(isRenamed()));
+    assertThat(f4, isPresentAndNotRenamed());
 
     ClassSubject impl = inspector.clazz(IMPL_CLASS_NAME);
     assertThat(impl, isPresent());
@@ -152,11 +147,9 @@
     assertThat(clazz, isPresent());
     assertEquals(minify, clazz.isRenamed());
     MethodSubject f1 = clazz.uniqueMethodWithName("f1");
-    assertThat(f1, isPresent());
-    assertThat(f1, not(isRenamed()));
+    assertThat(f1, isPresentAndNotRenamed());
     MethodSubject f2 = clazz.uniqueMethodWithName("f2");
-    assertThat(f2, isPresent());
-    assertThat(f2, not(isRenamed()));
+    assertThat(f2, isPresentAndNotRenamed());
     MethodSubject f3 = clazz.uniqueMethodWithName("f3");
     assertThat(f3, not(isPresent()));
     MethodSubject f4 = clazz.uniqueMethodWithName("f4");
@@ -190,11 +183,9 @@
     assertThat(clazz, isPresent());
     assertEquals(minify, clazz.isRenamed());
     MethodSubject f1 = clazz.uniqueMethodWithName("f1");
-    assertThat(f1, isPresent());
-    assertThat(f1, not(isRenamed()));
+    assertThat(f1, isPresentAndNotRenamed());
     MethodSubject f2 = clazz.uniqueMethodWithName("f2");
-    assertThat(f2, isPresent());
-    assertThat(f2, not(isRenamed()));
+    assertThat(f2, isPresentAndNotRenamed());
     MethodSubject f3 = clazz.uniqueMethodWithName("f3");
     assertThat(f3, not(isPresent()));
     MethodSubject f4 = clazz.uniqueMethodWithName("f4");
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/KeepInnerClassesEnclosingMethodAnnotationsTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/KeepInnerClassesEnclosingMethodAnnotationsTest.java
index 3b060f0..87c3303 100644
--- a/src/test/java/com/android/tools/r8/shaking/attributes/KeepInnerClassesEnclosingMethodAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/attributes/KeepInnerClassesEnclosingMethodAnnotationsTest.java
@@ -6,7 +6,8 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isMemberClass;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -123,8 +124,8 @@
                 "-keepattributes InnerClasses,EnclosingMethod",
                 "-keep class **Outer*",
                 keepMainProguardConfiguration(Main.class)));
-    assertThat(result.outer, not(isRenamed()));
-    assertThat(result.inner, not(isRenamed()));
+    assertThat(result.outer, isPresentAndNotRenamed());
+    assertThat(result.inner, isPresentAndNotRenamed());
     assertThat(result.inner, isMemberClass());
     fullInnerClassesEnclosingMethodInformation(result);
   }
@@ -134,8 +135,8 @@
     TestResult result =
         runShrinker(
             ImmutableList.of("-keep class **Outer*", keepMainProguardConfiguration(Main.class)));
-    assertThat(result.outer, not(isRenamed()));
-    assertThat(result.inner, not(isRenamed()));
+    assertThat(result.outer, isPresentAndNotRenamed());
+    assertThat(result.inner, isPresentAndNotRenamed());
     assertThat(result.inner, not(isMemberClass()));
     noInnerClassesEnclosingMethodInformation(result);
   }
@@ -148,8 +149,8 @@
                 "-keepattributes InnerClasses,EnclosingMethod",
                 "-keep class **Outer$Inner",
                 keepMainProguardConfiguration(Main.class)));
-    assertThat(result.outer, not(isRenamed()));
-    assertThat(result.inner, not(isRenamed()));
+    assertThat(result.outer, isPresentAndNotRenamed());
+    assertThat(result.inner, isPresentAndNotRenamed());
     assertThat(result.inner, isMemberClass());
     fullInnerClassesEnclosingMethodInformation(result);
   }
@@ -162,8 +163,8 @@
                 "-keepattributes InnerClasses,EnclosingMethod",
                 "-keep class **Outer",
                 keepMainProguardConfiguration(Main.class)));
-    assertThat(result.outer, not(isRenamed()));
-    assertThat(result.inner, isRenamed());
+    assertThat(result.outer, isPresentAndNotRenamed());
+    assertThat(result.inner, isPresentAndRenamed());
     assertThat(result.inner, isMemberClass());
     fullInnerClassesEnclosingMethodInformation(result);
   }
diff --git a/src/test/java/com/android/tools/r8/shaking/b113138046/NativeMethodTest.java b/src/test/java/com/android/tools/r8/shaking/b113138046/NativeMethodTest.java
index 15fba7f..686c35b 100644
--- a/src/test/java/com/android/tools/r8/shaking/b113138046/NativeMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/b113138046/NativeMethodTest.java
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking.b113138046;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -63,7 +62,7 @@
           "void", "foo", ImmutableList.of(Handler.class.getCanonicalName()));
       assertEquals(expectedFooPresence, nativeFoo.isPresent());
       if (expectedFooPresence) {
-        assertThat(nativeFoo, not(isRenamed()));
+        assertThat(nativeFoo, isPresentAndNotRenamed());
         DexEncodedMethod method = nativeFoo.getMethod();
         assertTrue(method.accessFlags.isNative());
         assertNull(method.getCode());
diff --git a/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java b/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
index eebb7d5..32a861a 100644
--- a/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
@@ -4,67 +4,53 @@
 
 package com.android.tools.r8.shaking.defaultmethods;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbstract;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
-import com.android.tools.r8.ClassFileConsumer;
-import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.R8Command;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+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.MethodSubject;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
-import java.util.function.Consumer;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
 public class DefaultMethodsTest extends TestBase {
 
-  private Backend backend;
+  private final TestParameters parameters;
 
-  @Parameterized.Parameters(name = "Backend: {0}")
-  public static Backend[] data() {
-    return ToolHelper.getBackends();
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  public DefaultMethodsTest(Backend backend) {
-    this.backend = backend;
+  public DefaultMethodsTest(TestParameters parameters) {
+    this.parameters = parameters;
   }
 
-  private void runTest(List<String> additionalKeepRules, Consumer<CodeInspector> inspection)
+  private void runTest(
+      List<String> additionalKeepRules,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspection)
       throws Exception {
-    R8Command.Builder builder = R8Command.builder();
-    builder.addProgramFiles(ToolHelper.getClassFileForTestClass(InterfaceWithDefaultMethods.class));
-    builder.addProgramFiles(ToolHelper.getClassFileForTestClass(ClassImplementingInterface.class));
-    builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class));
-    if (backend == Backend.DEX) {
-      builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
-      int apiLevel = AndroidApiLevel.O.getLevel();
-      builder.setMinApiLevel(apiLevel);
-      builder.addLibraryFiles(ToolHelper.getAndroidJar(apiLevel));
-    } else {
-      assert backend == Backend.CF;
-      builder.setProgramConsumer(ClassFileConsumer.emptyConsumer());
-      builder.addLibraryFiles(ToolHelper.getJava8RuntimeJar());
-    }
-    // Always keep main in the test class, so the output never becomes empty.
-    builder.addProguardConfiguration(ImmutableList.of(
-        "-keep class " + TestClass.class.getCanonicalName() + "{",
-        "  public static void main(java.lang.String[]);",
-        "}",
-        "-dontobfuscate"),
-        Origin.unknown());
-    builder.addProguardConfiguration(additionalKeepRules, Origin.unknown());
-    AndroidApp app = ToolHelper.runR8(builder.build(), o -> o.enableClassInlining = false);
-    inspection.accept(new CodeInspector(app));
+    testForR8(parameters.getBackend())
+        .addProgramClasses(
+            InterfaceWithDefaultMethods.class, ClassImplementingInterface.class, TestClass.class)
+        .setMinApi(parameters.getApiLevel())
+        .addKeepMainRule(TestClass.class)
+        .addKeepRules(additionalKeepRules)
+        .noMinification()
+        .compile()
+        .inspect(inspection);
   }
 
   private void interfaceNotKept(CodeInspector inspector) {
@@ -73,53 +59,98 @@
 
   private void defaultMethodNotKept(CodeInspector inspector) {
     ClassSubject clazz = inspector.clazz(InterfaceWithDefaultMethods.class);
-    assertTrue(clazz.isPresent());
-    assertFalse(clazz.method("int", "method", ImmutableList.of()).isPresent());
+    assertThat(clazz, isPresent());
+    assertThat(clazz.method("int", "method", ImmutableList.of()), not(isPresent()));
   }
 
   private void defaultMethodKept(CodeInspector inspector) {
     ClassSubject clazz = inspector.clazz(InterfaceWithDefaultMethods.class);
-    assertTrue(clazz.isPresent());
+    assertThat(clazz, isPresent());
     MethodSubject method = clazz.method("int", "method", ImmutableList.of());
-    assertTrue(method.isPresent());
-    assertFalse(method.isAbstract());
+    assertThat(method, isPresent());
+    ClassSubject companionClass = clazz.toCompanionClass();
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      assertThat(method, not(isAbstract()));
+      assertThat(companionClass, not(isPresent()));
+    } else {
+      assertThat(method, isAbstract());
+      assertThat(companionClass, isPresent());
+      MethodSubject defaultMethod = method.toMethodOnCompanionClass();
+      assertThat(defaultMethod, isPresent());
+    }
+  }
+
+  private void defaultMethodKeptWithoutCompanionClass(CodeInspector inspector) {
+    ClassSubject clazz = inspector.clazz(InterfaceWithDefaultMethods.class);
+    assertThat(clazz, isPresent());
+    MethodSubject method = clazz.method("int", "method", ImmutableList.of());
+    assertThat(method, isPresent());
+    ClassSubject companionClass = clazz.toCompanionClass();
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      assertThat(method, not(isAbstract()));
+    } else {
+      assertThat(method, isAbstract());
+    }
+    assertThat(companionClass, not(isPresent()));
   }
 
   @Test
-  public void test() throws Exception {
+  public void testInterfaceNotKept() throws Exception {
     runTest(ImmutableList.of(), this::interfaceNotKept);
-    runTest(ImmutableList.of(
-        "-keep interface " + InterfaceWithDefaultMethods.class.getCanonicalName() + "{",
-        "}"
-    ), this::defaultMethodNotKept);
-    runTest(ImmutableList.of(
-        "-keep interface " + InterfaceWithDefaultMethods.class.getCanonicalName() + "{",
-        "  <methods>;",
-        "}"
-    ), this::defaultMethodKept);
-    runTest(ImmutableList.of(
-        "-keep interface " + InterfaceWithDefaultMethods.class.getCanonicalName() + "{",
-        "  public int method();",
-        "}"
-    ), this::defaultMethodKept);
+  }
+
+  @Test
+  public void testDefaultMethodNotKept() throws Exception {
     runTest(
         ImmutableList.of(
-            "-keep class " + ClassImplementingInterface.class.getCanonicalName() + "{",
+            "-keep interface " + InterfaceWithDefaultMethods.class.getTypeName() + "{", "}"),
+        this::defaultMethodNotKept);
+  }
+
+  @Test
+  public void testDefaultMethodKeptWithMethods() throws Exception {
+    runTest(
+        ImmutableList.of(
+            "-keep interface " + InterfaceWithDefaultMethods.class.getTypeName() + "{",
+            "  <methods>;",
+            "}"),
+        this::defaultMethodKept);
+  }
+
+  @Test
+  public void testDefaultMethodsKeptExplicitly() throws Exception {
+    runTest(
+        ImmutableList.of(
+            "-keep interface " + InterfaceWithDefaultMethods.class.getTypeName() + "{",
+            "  public int method();",
+            "}"),
+        this::defaultMethodKept);
+  }
+
+  @Test
+  public void testDefaultMethodNotKeptIndirectly() throws Exception {
+    runTest(
+        ImmutableList.of(
+            "-keep class " + ClassImplementingInterface.class.getTypeName() + "{",
             "  <methods>;",
             "}",
             // Prevent InterfaceWithDefaultMethods from being merged into ClassImplementingInterface
-            "-keep class " + InterfaceWithDefaultMethods.class.getCanonicalName()),
+            "-keep class " + InterfaceWithDefaultMethods.class.getTypeName()),
         this::defaultMethodNotKept);
+  }
+
+  @Test
+  public void testDefaultMethodKeptIndirectly() throws Exception {
     runTest(
         ImmutableList.of(
-            "-keep class " + ClassImplementingInterface.class.getCanonicalName() + "{",
+            "-keep class " + ClassImplementingInterface.class.getTypeName() + "{",
             "  <methods>;",
             "}",
             "-keep class " + TestClass.class.getCanonicalName() + "{",
             "  public void useInterfaceMethod();",
             "}",
             // Prevent InterfaceWithDefaultMethods from being merged into ClassImplementingInterface
-            "-keep class " + InterfaceWithDefaultMethods.class.getCanonicalName()),
-        this::defaultMethodKept);
+            "-keep class " + InterfaceWithDefaultMethods.class.getTypeName()),
+        this::defaultMethodKeptWithoutCompanionClass);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/ConditionalKeepIfKeptTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/ConditionalKeepIfKeptTest.java
index 790ea8d..34c9293 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/ConditionalKeepIfKeptTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/ConditionalKeepIfKeptTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.shaking.ifrule;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -160,10 +160,10 @@
               ClassSubject classSubject = inspector.clazz(StaticallyReferenced.class);
               assertThat(classSubject, isPresent());
               assertEquals(3, classSubject.allMethods().size());
-              classSubject.allMethods().forEach(m -> assertThat(m, not(isRenamed())));
+              classSubject.allMethods().forEach(m -> assertThat(m, isPresentAndNotRenamed()));
               // Keeping methods will cause the fields to be kept too (but allow renaming them).
               assertEquals(2, classSubject.allFields().size());
-              classSubject.allFields().forEach(f -> assertThat(f, isRenamed()));
+              classSubject.allFields().forEach(f -> assertThat(f, isPresentAndRenamed()));
             });
   }
 
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java
index 50d64f8..74d2cfb 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking.ifrule;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -108,7 +108,7 @@
     }
 
     ClassSubject clazz = codeInspector.clazz(DependentUser.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     // Members of DependentUser are not used anywhere.
     MethodSubject m = clazz.method("void", "callFoo", ImmutableList.of());
     assertThat(m, not(isPresent()));
@@ -117,7 +117,7 @@
 
     // Although DependentUser#callFoo is shrinked, Dependent is kept via -if.
     clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     // But, its members are gone.
     m = clazz.method("java.lang.String", "foo", ImmutableList.of());
     assertThat(m, not(isPresent()));
@@ -145,7 +145,7 @@
     }
 
     ClassSubject clazz = codeInspector.clazz(DependentUser.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     // Members of DependentUser are not used anywhere.
     MethodSubject m = clazz.method("void", "callFoo", ImmutableList.of());
     assertThat(m, not(isPresent()));
@@ -154,7 +154,7 @@
 
     // Although DependentUser#callFoo is shrinked, Dependent is kept via -if.
     clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     // But, its members are gone.
     m = clazz.method("java.lang.String", "foo", ImmutableList.of());
     assertThat(m, not(isPresent()));
@@ -178,19 +178,19 @@
     }
 
     ClassSubject clazz = codeInspector.clazz(DependentUser.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     MethodSubject m = clazz.method("void", "callFoo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "canBeShrinked");
     assertThat(f, not(isPresent()));
 
     // Dependent is kept due to DependentUser#callFoo, but renamed.
     clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     m = clazz.method("java.lang.String", "foo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 
   @Test
@@ -227,19 +227,19 @@
     }
 
     ClassSubject clazz = codeInspector.clazz(DependentUser.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     MethodSubject m = clazz.method("void", "callFoo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "canBeShrinked");
     assertThat(f, not(isPresent()));
 
     // Dependent is kept due to DependentUser#callFoo, but renamed.
     clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     m = clazz.method("java.lang.String", "foo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 
   @Test
@@ -276,19 +276,19 @@
     }
 
     ClassSubject clazz = codeInspector.clazz(DependentUser.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     MethodSubject m = clazz.method("void", "callFoo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "canBeShrinked");
     assertThat(f, not(isPresent()));
 
     // Dependent is kept due to DependentUser#callFoo, but renamed.
     clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     m = clazz.method("java.lang.String", "foo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 
   @Test
@@ -307,11 +307,11 @@
 
     ClassSubject clazz = codeInspector.clazz(Dependent.class);
     // Only class name is not renamed, if triggered.
-    assertThat(clazz, keepPrecondition ? isNotRenamed() : isRenamed());
+    assertThat(clazz, keepPrecondition ? isPresentAndNotRenamed() : isPresentAndRenamed());
     MethodSubject m = clazz.method("java.lang.String", "foo", ImmutableList.of());
-    assertThat(m, isRenamed());
+    assertThat(m, isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 
   @Test
@@ -332,12 +332,12 @@
 
     ClassSubject clazz = codeInspector.clazz(Dependent.class);
     // Class name is not renamed, if triggered.
-    assertThat(clazz, keepPrecondition ? isNotRenamed() : isRenamed());
+    assertThat(clazz, keepPrecondition ? isPresentAndNotRenamed() : isPresentAndRenamed());
     MethodSubject m = clazz.method("java.lang.String", "foo", ImmutableList.of());
     // Method name is not renamed either, if triggered.
-    assertThat(m, keepPrecondition ? isNotRenamed() : isRenamed());
+    assertThat(m, keepPrecondition ? isPresentAndNotRenamed() : isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 
   @Test
@@ -357,11 +357,11 @@
     CodeInspector codeInspector = inspectAfterShrinking(shrinker, CLASSES, config);
 
     ClassSubject clazz = codeInspector.clazz(Dependent.class);
-    assertThat(clazz, isRenamed());
+    assertThat(clazz, isPresentAndRenamed());
     MethodSubject m = clazz.method("java.lang.String", "foo", ImmutableList.of());
     // Only method name is not renamed, if triggered.
-    assertThat(m, keepPrecondition ? isNotRenamed() : isRenamed());
+    assertThat(m, keepPrecondition ? isPresentAndNotRenamed() : isPresentAndRenamed());
     FieldSubject f = clazz.field("int", "intField");
-    assertThat(f, isRenamed());
+    assertThat(f, isPresentAndRenamed());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnTargetedMethodTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnTargetedMethodTest.java
index 35d802c..153bf38 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnTargetedMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnTargetedMethodTest.java
@@ -4,8 +4,7 @@
 
 package com.android.tools.r8.shaking.ifrule;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.TestBase;
@@ -35,8 +34,7 @@
             .inspector();
 
     ClassSubject interfaceSubject = inspector.clazz(Interface.class);
-    assertThat(interfaceSubject, isPresent());
-    assertThat(interfaceSubject, isRenamed());
+    assertThat(interfaceSubject, isPresentAndRenamed());
   }
 
   static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepClassMembersRuleOnIndirectlyInstantiatedClassTest.java b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepClassMembersRuleOnIndirectlyInstantiatedClassTest.java
index 327f61d..5b47f4f 100644
--- a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepClassMembersRuleOnIndirectlyInstantiatedClassTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepClassMembersRuleOnIndirectlyInstantiatedClassTest.java
@@ -5,8 +5,7 @@
 package com.android.tools.r8.shaking.keepclassmembers;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.not;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.NeverInline;
@@ -59,8 +58,7 @@
     assertThat(classSubject, isPresent());
 
     FieldSubject fieldSubject = classSubject.uniqueFieldWithName("greeting");
-    assertThat(fieldSubject, isPresent());
-    assertThat(fieldSubject, not(isRenamed()));
+    assertThat(fieldSubject, isPresentAndNotRenamed());
   }
 
   static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepInterfaceMethodTest.java b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepInterfaceMethodTest.java
index e6baeae..93309e8 100644
--- a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepInterfaceMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/KeepInterfaceMethodTest.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.shaking.keepclassmembers;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assume.assumeTrue;
 
@@ -96,7 +96,7 @@
     ClassSubject clazzSubject = inspector.clazz(clazz);
     assertThat(clazzSubject, isPresent());
     MethodSubject foo = clazzSubject.uniqueMethodWithName("foo");
-    assertThat(foo, isNotRenamed());
+    assertThat(foo, isPresentAndNotRenamed());
   }
 
   public interface I {
diff --git a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
index f2f6731..45c7a00 100644
--- a/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
+++ b/src/test/java/com/android/tools/r8/shaking/keepclassmembers/b115867670/B115867670.java
@@ -5,7 +5,8 @@
 package com.android.tools.r8.shaking.keepclassmembers.b115867670;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -105,7 +106,7 @@
       assertThat(cls, isPresent());
       assertFalse("Class " + clazz.getSimpleName() + " should not be abstract", cls.isAbstract());
       assertEquals(1, cls.asFoundClassSubject().allFields().size());
-      cls.forAllFields(field -> assertThat(field, not(isRenamed())));
+      cls.forAllFields(field -> assertThat(field, isPresentAndNotRenamed()));
     }
   }
 
@@ -114,10 +115,10 @@
     for (Class clazz : new Class[] {Foo.class, Foo.Interaction.class, Foo.Request.class}) {
       ClassSubject cls = inspector.clazz(clazz);
       assertThat(cls, isPresent());
-      assertThat(cls, isRenamed());
+      assertThat(cls, isPresentAndRenamed());
       assertFalse("Class " + clazz.getSimpleName() + " should not be abstract", cls.isAbstract());
       assertEquals(1, cls.asFoundClassSubject().allFields().size());
-      cls.forAllFields(field -> assertThat(field, isRenamed()));
+      cls.forAllFields(field -> assertThat(field, isPresentAndRenamed()));
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java b/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
index a084679..cea851e 100644
--- a/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
@@ -4,7 +4,7 @@
 package com.android.tools.r8.shaking.proxy;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -86,7 +86,6 @@
     ClassSubject itf = inspector.clazz(M_I);
     assertThat(itf, isPresent());
     MethodSubject mtd = itf.uniqueMethodWithName("onEnterForeground");
-    assertThat(mtd, isPresent());
-    assertThat(mtd, not(isRenamed()));
+    assertThat(mtd, isPresentAndNotRenamed());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/staticinterfacemethods/defaultmethods/StaticInterfaceMethodsTest.java b/src/test/java/com/android/tools/r8/shaking/staticinterfacemethods/defaultmethods/StaticInterfaceMethodsTest.java
new file mode 100644
index 0000000..ca0aaa5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/staticinterfacemethods/defaultmethods/StaticInterfaceMethodsTest.java
@@ -0,0 +1,224 @@
+// 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.shaking.staticinterfacemethods.defaultmethods;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.utils.BooleanUtils;
+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.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class StaticInterfaceMethodsTest extends TestBase {
+
+  private final TestParameters parameters;
+  private final boolean allowObfuscation;
+
+  @Parameterized.Parameters(name = "{0}, allowObfuscation: {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
+  }
+
+  public StaticInterfaceMethodsTest(TestParameters parameters, boolean allowObfuscation) {
+    this.parameters = parameters;
+    this.allowObfuscation = allowObfuscation;
+  }
+
+  private R8TestCompileResult compileTest(
+      List<String> additionalKeepRules,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspection)
+      throws Exception {
+    return testForR8(parameters.getBackend())
+        .addProgramClasses(InterfaceWithStaticMethods.class, TestClass.class)
+        .setMinApi(parameters.getApiLevel())
+        .addKeepMainRule(TestClass.class)
+        .addKeepRules(additionalKeepRules)
+        .enableInliningAnnotations()
+        .compile()
+        .inspect(inspection);
+  }
+
+  private void runTest(
+      List<String> additionalKeepRules,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspection)
+      throws Exception {
+    R8TestCompileResult compileResult = compileTest(additionalKeepRules, inspection);
+    Path app = compileResult.writeToZip();
+
+    TestRunResult<?> result;
+    if (allowObfuscation) {
+      result =
+          testForR8(parameters.getBackend())
+              .addProgramClasses(InstrumentedTestClass.class)
+              .addKeepAllClassesRule()
+              .addApplyMapping(compileResult.getProguardMap())
+              .addClasspathClasses(InterfaceWithStaticMethods.class)
+              .setMinApi(parameters.getApiLevel())
+              .compile()
+              .addRunClasspathFiles(app)
+              .run(parameters.getRuntime(), InstrumentedTestClass.class);
+    } else {
+      result =
+          testForRuntime(parameters)
+              .addProgramClasses(InstrumentedTestClass.class)
+              .addClasspathFiles(app)
+              .addRunClasspathFiles(app)
+              .run(parameters.getRuntime(), InstrumentedTestClass.class);
+    }
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      result.assertSuccessWithOutputLines("42");
+    } else {
+      result.assertFailure();
+    }
+  }
+
+  private void interfaceNotKept(CodeInspector inspector) {
+    assertFalse(inspector.clazz(InterfaceWithStaticMethods.class).isPresent());
+  }
+
+  private void staticMethodNotKept(CodeInspector inspector) {
+    ClassSubject clazz = inspector.clazz(InterfaceWithStaticMethods.class);
+    assertTrue(clazz.isPresent());
+    assertFalse(clazz.method("int", "method", ImmutableList.of()).isPresent());
+  }
+
+  private void staticMethodKeptB159987443(CodeInspector inspector) {
+    ClassSubject clazz = inspector.clazz(InterfaceWithStaticMethods.class);
+    assertThat(clazz, isPresent());
+    MethodSubject method = clazz.method("int", "method", ImmutableList.of());
+    ClassSubject companionClass = clazz.toCompanionClass();
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      assertThat(method, isStatic());
+      assertThat(companionClass, not(isPresent()));
+    } else {
+      assertThat(method, not(isPresent()));
+      // TODO(159987443): The companion class should be present.
+      assertThat(companionClass, not(isPresent()));
+      // Also check that method exists on companion class.
+    }
+  }
+
+  private void staticMethodKept(CodeInspector inspector) {
+    ClassSubject clazz = inspector.clazz(InterfaceWithStaticMethods.class);
+    ClassSubject companionClass = clazz.toCompanionClass();
+    MethodSubject method = clazz.method("int", "method", ImmutableList.of());
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      assertThat(clazz, allowObfuscation ? isPresentAndRenamed() : isPresentAndNotRenamed());
+      assertThat(method, isStatic());
+      assertThat(companionClass, not(isPresent()));
+    } else {
+      // When there is only a static method in the interface nothing is left on the interface itself
+      // after desugaring, only the companion class is left.
+      assertThat(clazz, not(isPresent()));
+      assertThat(method, not(isPresent()));
+      // TODO(159987443): The companion class should be present.
+      assertThat(companionClass, not(isPresent()));
+      // Also check that method exists on companion class.
+    }
+  }
+
+  @Test
+  public void testInterfaceNotKept() throws Exception {
+    assumeTrue(!allowObfuscation); // No use of allowObfuscation.
+
+    compileTest(ImmutableList.of(), this::interfaceNotKept);
+  }
+
+  @Test
+  public void testStaticMethodNotKept() throws Exception {
+    assumeTrue(!allowObfuscation); // No use of allowObfuscation.
+
+    compileTest(
+        ImmutableList.of(
+            "-keep interface " + InterfaceWithStaticMethods.class.getTypeName() + "{", "}"),
+        this::staticMethodNotKept);
+  }
+
+  @Test
+  public void testDefaultMethodKeptWithMethods() throws Exception {
+    assumeTrue(!allowObfuscation); // No use of allowObfuscation.
+
+    compileTest(
+        ImmutableList.of(
+            "-keep interface " + InterfaceWithStaticMethods.class.getTypeName() + "{",
+            "  <methods>;",
+            "}"),
+        this::staticMethodKeptB159987443);
+  }
+
+  @Test
+  public void testDefaultMethodKeptIndirectly() throws Exception {
+    ImmutableList.Builder<String> builder = ImmutableList.builder();
+    builder.add(
+        "-keep class " + TestClass.class.getTypeName() + "{",
+        "  public void useStaticInterfaceMethod();",
+        "}");
+    if (parameters.canUseDefaultAndStaticInterfaceMethods()) {
+      // TODO(160142903): @NeverInline does not seem to work on static interface methods.
+      // TODO(160144053): Using -keepclassmembers for this cause InterfaceWithStaticMethods to
+      // be renamed.
+      if (allowObfuscation) {
+        builder.add(
+            "-if class " + InterfaceWithStaticMethods.class.getTypeName(),
+            "-keep,allowobfuscation class " + InterfaceWithStaticMethods.class.getTypeName() + "{",
+            "  public static int method();",
+            "}");
+      } else {
+        builder.add(
+            "-if class " + InterfaceWithStaticMethods.class.getTypeName(),
+            "-keep class " + InterfaceWithStaticMethods.class.getTypeName() + "{",
+            "  public static int method();",
+            "}");
+      }
+    }
+    runTest(builder.build(), this::staticMethodKept);
+  }
+
+  public static class TestClass {
+
+    public void useStaticInterfaceMethod() {
+      System.out.println(InterfaceWithStaticMethods.method());
+    }
+
+    public static void main(String[] args) {}
+  }
+
+  public interface InterfaceWithStaticMethods {
+    @NeverInline
+    static int method() {
+      return 42;
+    }
+  }
+
+  public static class InstrumentedTestClass {
+
+    public static void main(String[] args) {
+      System.out.println(InterfaceWithStaticMethods.method());
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
index 81b988e..6a04a0a 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentClassSubject.java
@@ -7,12 +7,17 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.references.ClassReference;
 import java.util.List;
 import java.util.function.Consumer;
 import kotlinx.metadata.jvm.KotlinClassMetadata;
 
 public class AbsentClassSubject extends ClassSubject {
 
+  public AbsentClassSubject(CodeInspector codeInspector, ClassReference reference) {
+    super(codeInspector, reference);
+  }
+
   @Override
   public boolean isPresent() {
     return false;
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
index 38dc236..c62f945 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
@@ -142,4 +142,9 @@
   public String getJvmMethodSignatureAsString() {
     return null;
   }
+
+  @Override
+  public MethodSubject toMethodOnCompanionClass() {
+    throw new Unreachable("Cannot determine companion class method");
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
index 97a3b29..84d76a1 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
@@ -4,10 +4,14 @@
 
 package com.android.tools.r8.utils.codeinspector;
 
+import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.COMPANION_CLASS_NAME_SUFFIX;
+
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.references.TypeReference;
 import com.android.tools.r8.smali.SmaliBuilder;
 import com.android.tools.r8.utils.ListUtils;
@@ -23,6 +27,14 @@
 
 public abstract class ClassSubject extends Subject {
 
+  protected final ClassReference reference;
+  protected final CodeInspector codeInspector;
+
+  public ClassSubject(CodeInspector codeInspector, ClassReference reference) {
+    this.codeInspector = codeInspector;
+    this.reference = reference;
+  }
+
   public abstract void forAllMethods(Consumer<FoundMethodSubject> inspection);
 
   public final List<FoundMethodSubject> allMethods() {
@@ -192,4 +204,11 @@
   public abstract KmPackageSubject getKmPackage();
 
   public abstract KotlinClassMetadata getKotlinClassMetadata();
+
+  public ClassSubject toCompanionClass() {
+    String descriptor = reference.getDescriptor();
+    return codeInspector.clazz(
+        Reference.classFromDescriptor(
+            descriptor.substring(0, descriptor.length() - 1) + COMPANION_CLASS_NAME_SUFFIX + ";"));
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 76ed0e2..43ba1fb 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -48,6 +48,7 @@
 import com.android.tools.r8.utils.codeinspector.InstructionSubject.JumboStringMode;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -280,9 +281,9 @@
     }
     DexClass clazz = application.definitionFor(toDexTypeIgnorePrimitives(name));
     if (clazz == null) {
-      return new AbsentClassSubject();
+      return new AbsentClassSubject(this, reference);
     }
-    return new FoundClassSubject(this, clazz, naming);
+    return new FoundClassSubject(this, clazz, naming, reference);
   }
 
   public ClassSubject companionClassFor(Class<?> clazz) {
@@ -308,6 +309,10 @@
     return builder.build();
   }
 
+  public FieldSubject field(Field field) {
+    return field(Reference.fieldFromField(field));
+  }
+
   public FieldSubject field(FieldReference field) {
     ClassSubject clazz = clazz(field.getHolderClass());
     if (!clazz.isPresent()) {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index 2ce3024..bd65812 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.naming.signature.GenericSignatureParser;
+import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.StringUtils;
 import java.util.List;
@@ -32,13 +33,15 @@
 
 public class FoundClassSubject extends ClassSubject {
 
-  private final CodeInspector codeInspector;
   private final DexClass dexClass;
   final ClassNamingForNameMapper naming;
 
   FoundClassSubject(
-      CodeInspector codeInspector, DexClass dexClass, ClassNamingForNameMapper naming) {
-    this.codeInspector = codeInspector;
+      CodeInspector codeInspector,
+      DexClass dexClass,
+      ClassNamingForNameMapper naming,
+      ClassReference reference) {
+    super(codeInspector, reference);
     this.dexClass = dexClass;
     this.naming = naming;
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmDeclarationContainerSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmDeclarationContainerSubject.java
index 6363747..a74c3d8 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmDeclarationContainerSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundKmDeclarationContainerSubject.java
@@ -129,7 +129,7 @@
   default ClassSubject getClassSubjectFromKmType(KmType kmType) {
     String descriptor = getDescriptorFromKmType(kmType);
     if (descriptor == null) {
-      return new AbsentClassSubject();
+      return new AbsentClassSubject(codeInspector(), Reference.classFromDescriptor("Lnot_found;"));
     }
     return getClassSubjectFromDescriptor(descriptor);
   }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 1f1fe84..d4f8b5b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.utils.codeinspector;
 
+import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.DEFAULT_METHOD_PREFIX;
+
 import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.cf.code.CfPosition;
 import com.android.tools.r8.code.Instruction;
@@ -31,6 +33,7 @@
 import com.android.tools.r8.naming.signature.GenericSignatureParser;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.references.TypeReference;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.LocalVariableTable.LocalVariableTableEntry;
 import com.google.common.base.Predicates;
@@ -39,6 +42,7 @@
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.List;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -372,4 +376,19 @@
         + ")"
         + dexMethod.method.proto.returnType.toDescriptorString();
   }
+
+  @Override
+  public MethodSubject toMethodOnCompanionClass() {
+    ClassSubject companionClass = clazz.toCompanionClass();
+    MethodReference reference = asMethodReference();
+    List<String> p =
+        ImmutableList.<String>builder()
+            .add(clazz.getFinalName())
+            .addAll(reference.getFormalTypes().stream().map(TypeReference::getTypeName).iterator())
+            .build();
+    return companionClass.method(
+        reference.getReturnType().getTypeName(),
+        DEFAULT_METHOD_PREFIX + reference.getMethodName(),
+        p);
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
index 949903d..5842c9b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
@@ -123,7 +123,7 @@
     };
   }
 
-  public static Matcher<Subject> isRenamed() {
+  public static Matcher<Subject> isPresentAndRenamed() {
     return new TypeSafeMatcher<Subject>() {
       @Override
       protected boolean matchesSafely(Subject subject) {
@@ -143,7 +143,7 @@
     };
   }
 
-  public static Matcher<Subject> isNotRenamed() {
+  public static Matcher<Subject> isPresentAndNotRenamed() {
     return new TypeSafeMatcher<Subject>() {
       @Override
       protected boolean matchesSafely(Subject subject) {
@@ -163,8 +163,8 @@
     };
   }
 
-  public static Matcher<Subject> isRenamed(boolean isRenamed) {
-    return isRenamed ? isRenamed() : isNotRenamed();
+  public static Matcher<Subject> isPresentAndRenamed(boolean isRenamed) {
+    return isRenamed ? isPresentAndRenamed() : isPresentAndNotRenamed();
   }
 
   public static Matcher<MemberSubject> isStatic() {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
index 8fc439f..690838d 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
@@ -102,4 +102,6 @@
   }
 
   public abstract String getJvmMethodSignatureAsString();
+
+  public abstract MethodSubject toMethodOnCompanionClass();
 }
diff --git a/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java b/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
index fe98a17..8d6dd4b 100644
--- a/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/graphinspector/GraphInspector.java
@@ -661,6 +661,10 @@
     }
   }
 
+  public CodeInspector codeInspector() {
+    return inspector;
+  }
+
   public Set<GraphNode> getRoots() {
     return Collections.unmodifiableSet(roots);
   }
diff --git a/third_party/proguard/README.google b/third_party/proguard/README.google
index abe0568..714899c 100644
--- a/third_party/proguard/README.google
+++ b/third_party/proguard/README.google
@@ -1,8 +1,9 @@
 URL: https://sourceforge.net/projects/proguard/files/proguard/5.2/
 URL: https://sourceforge.net/projects/proguard/files/proguard/6.0/
-Version: 5.2.1, 6.0.1
+URL: https://github.com/Guardsquare/proguard/releases/download/v7.0.0/proguard-7.0.0.tar.gz
+Version: 5.2.1, 6.0.1, 7.0.0
 License: GPL
-License File: proguard5.2.1/docs/license.html, proguard6.0.1/docs/license.html
+License File: proguard5.2.1/docs/license.html, proguard6.0.1/docs/license.html, proguard-7.0.0/docs/license.md
 
 Description:
 ProGuard Java Optimizer and Obfuscator
diff --git a/third_party/proguard/proguard-7.0.0.tar.gz.sha1 b/third_party/proguard/proguard-7.0.0.tar.gz.sha1
new file mode 100644
index 0000000..eb88ebe
--- /dev/null
+++ b/third_party/proguard/proguard-7.0.0.tar.gz.sha1
@@ -0,0 +1 @@
+96b54d82acbf8ccdf53fdc5ea95f65907e526fca
\ No newline at end of file
diff --git a/tools/keeprule_benchmark.py b/tools/keeprule_benchmark.py
new file mode 100755
index 0000000..0a7e063
--- /dev/null
+++ b/tools/keeprule_benchmark.py
@@ -0,0 +1,247 @@
+#!/usr/bin/env python
+# Copyright (c) 2020, 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.
+
+import argparse
+import os
+import subprocess
+import sys
+import time
+
+import jdk
+import proguard
+import toolhelper
+import utils
+
+SHRINKERS = ['r8'] + proguard.getVersions()
+
+INPUT_PROGRAM = utils.PINNED_R8_JAR
+
+ANNO = 'com.android.tools.r8.com.google.common.annotations.VisibleForTesting'
+
+R8_OPTIONS = [
+  'printTimes',
+  'passthroughDexCode',
+  'enableClassMerging',
+  'enableDevirtualization',
+  'enableNonNullTracking',
+  'enableInlining',
+  'enableSwitchMapRemoval',
+  'enableValuePropagation',
+  'useSmaliSyntax',
+  'verbose',
+  'quiet',
+  'invalidDebugInfoFatal',
+  'intermediate',
+  'enableLambdaMerging',
+  'enableDesugaring',
+  'enableMainDexListCheck',
+  'enableTreeShaking',
+  'printCfg',
+  'ignoreMissingClasses',
+  'forceProguardCompatibility',
+  'enableMinification',
+  'disableAssertions',
+  'debugKeepRules',
+  'debug',
+  'minimalMainDex',
+  'skipReadingDexCode',
+]
+
+R8_CLASSES = [
+  'com.android.tools.r8.code.Format11x',
+  'com.android.tools.r8.code.MoveFrom16',
+  'com.android.tools.r8.code.AddLong2Addr',
+  'com.android.tools.r8.code.AgetByte',
+  'com.android.tools.r8.code.SubDouble',
+  'com.android.tools.r8.code.Sput',
+  'com.android.tools.r8.code.Format10x',
+  'com.android.tools.r8.code.RemInt',
+  'com.android.tools.r8.code.ConstWide',
+  'com.android.tools.r8.code.SgetWide',
+  'com.android.tools.r8.code.OrInt2Addr',
+  'com.android.tools.r8.code.Iget',
+  'com.android.tools.r8.code.Instruction',
+  'com.android.tools.r8.code.SubInt2Addr',
+  'com.android.tools.r8.code.SwitchPayload',
+  'com.android.tools.r8.code.Const4',
+  'com.android.tools.r8.code.ShrIntLit8',
+  'com.android.tools.r8.code.ConstWide16',
+  'com.android.tools.r8.code.NegInt',
+  'com.android.tools.r8.code.SgetBoolean',
+  'com.android.tools.r8.code.Format22x',
+  'com.android.tools.r8.code.InvokeVirtualRange',
+  'com.android.tools.r8.code.Format45cc',
+  'com.android.tools.r8.code.DivFloat2Addr',
+  'com.android.tools.r8.code.MulIntLit16',
+  'com.android.tools.r8.code.BytecodeStream',
+]
+
+KEEP_MAIN = \
+  '-keep class com.android.tools.r8.R8 { void main(java.lang.String[]); }'
+
+BENCHMARKS = [
+  # Baseline compile just keeps R8.main (implicitly kept for all benchmarks).
+  ('KeepBaseline', ''),
+
+  # Mirror default keep getters/setters, but independent of hierarchy.
+  ('KeepGetters',
+    '-keepclassmembers class * { *** get*(); }'),
+  ('KeepGettersIf',
+    '-if class * { *** get*(); } -keep class <1> { *** get<2>(); }'),
+
+  # Mirror default keep getters/setters below View (here a class with a B).
+  ('KeepSubGetters',
+    '-keepclassmembers class * extends **.*B* { *** get*(); }'),
+  ('KeepSubGettersIf',
+    '-if class * extends **.*B* -keep class <1> { *** get*(); }'),
+
+  # General keep rule to keep annotated members.
+  ('KeepAnnoMethod',
+    '-keepclasseswithmembers class * { @%s *** *(...); }' % ANNO),
+  ('KeepAnnoMethodCond',
+    '-keepclassmembers class * { @%s *** *(...); }' % ANNO),
+  ('KeepAnnoMethodIf',
+    '-if class * { @%s *** *(...); } -keep class <1> { @%s *** <2>(...); }' \
+        % (ANNO, ANNO)),
+
+  # Large collection of rules mirroring AAPT conditional rules on R fields.
+  ('KeepAaptFieldIf',
+   '\n'.join([
+     '-if class **.InternalOptions { boolean %s; }'
+     ' -keep class %s { <init>(...); }' % (f, c)
+     for (f, c) in zip(R8_OPTIONS, R8_CLASSES) * 1 #100
+   ])),
+
+  # If rules with predicates that will never by true, but will need
+  # consideration. The CodeSize of these should be equal to the baseline run.
+  ('KeepIfNonExistingClass',
+   '-if class **.*A*B*C*D*E*F* -keep class %s' % ANNO),
+  ('KeepIfNonExistingMember',
+   '-if class **.*A* { *** *a*b*c*d*e*f*(...); } -keep class %s' % ANNO)
+]
+
+def parse_arguments(argv):
+  parser = argparse.ArgumentParser(
+                    description = 'Run keep-rule benchmarks.')
+  parser.add_argument('--golem',
+                    help = 'Link in third party dependencies.',
+                    default = False,
+                    action = 'store_true')
+  parser.add_argument('--ignore-java-version',
+                    help='Do not check java version',
+                    default=False,
+                    action='store_true')
+  parser.add_argument('--shrinker',
+                    help='The shrinker to use',
+                    choices=SHRINKERS,
+                    default=SHRINKERS[0])
+  parser.add_argument('--runs',
+                      help='Number of runs to average out time on',
+                      type=int,
+                      default=3)
+  parser.add_argument('--benchmark',
+                      help='Benchmark to run (default all)',
+                      choices=map(lambda (x,y): x, BENCHMARKS),
+                      default=None)
+  options = parser.parse_args(argv)
+  return options
+
+class BenchmarkResult:
+  def __init__(self, name, size, runs):
+    self.name = name
+    self.size = size
+    self.runs = runs
+
+def isPG(shrinker):
+  return proguard.isValidVersion(shrinker)
+
+def shrinker_args(shrinker, keepfile, output):
+  if shrinker == 'r8':
+    return [
+      jdk.GetJavaExecutable(),
+      '-cp', utils.R8LIB_JAR,
+      'com.android.tools.r8.R8',
+      INPUT_PROGRAM,
+      '--lib', utils.RT_JAR,
+      '--output', output,
+      '--min-api', '10000',
+      '--pg-conf', keepfile,
+      ]
+  elif isPG(shrinker):
+    return proguard.getCmd([
+      '-injars', INPUT_PROGRAM,
+      '-libraryjars', utils.RT_JAR,
+      '-outjars', output,
+      '-dontwarn', '**',
+      '-optimizationpasses', '2',
+      '@' + keepfile,
+    ],
+    version=shrinker)
+  else:
+    assert False, "Unexpected shrinker " + shrinker
+
+def dex(input, output):
+  toolhelper.run(
+      'd8',
+      [
+        input,
+        '--lib', utils.RT_JAR,
+        '--min-api', '10000',
+        '--output', output
+      ],
+      build=False,
+      debug=False)
+
+def run_shrinker(options, temp):
+  benchmarks = BENCHMARKS
+  if options.benchmark:
+    for (name, rules) in BENCHMARKS:
+      if name == options.benchmark:
+        benchmarks = [(name, rules)]
+        break
+    assert len(benchmarks) == 1, "Unexpected benchmark " + options.benchmark
+
+  run_count = options.runs
+  benchmark_results = []
+  for (name, rule) in benchmarks:
+    benchmark_keep = os.path.join(temp, '%s-keep.txt' % name)
+    with open(benchmark_keep, 'w') as fp:
+      fp.write(KEEP_MAIN)
+      fp.write('\n')
+      fp.write(rule)
+
+    benchmark_runs = []
+    benchmark_size = 0
+    for i in range(run_count):
+      out = os.path.join(temp, '%s-out%d.jar' % (name, i))
+      cmd = shrinker_args(options.shrinker, benchmark_keep, out)
+      utils.PrintCmd(cmd)
+      t0 = time.time()
+      subprocess.check_output(cmd)
+      t1 = time.time()
+      benchmark_runs.append(t1 - t0)
+      if isPG(options.shrinker):
+        dexout = os.path.join(temp, '%s-out%d-dex.jar' % (name, i))
+        dex(out, dexout)
+        benchmark_size = utils.uncompressed_size(dexout)
+      else:
+        benchmark_size = utils.uncompressed_size(out)
+    benchmark_results.append(
+        BenchmarkResult(name, benchmark_size, benchmark_runs))
+
+  print 'Runs:', options.runs
+  for result in benchmark_results:
+    benchmark_avg = sum(result.runs) / run_count
+    print '%s(CodeSize): %d' % (result.name, result.size)
+    print '%s(RunTimeRaw): %d ms' % (result.name, 1000.0 * benchmark_avg)
+
+if __name__ == '__main__':
+  options = parse_arguments(sys.argv[1:])
+  if options.golem:
+    golem.link_third_party()
+  if not options.ignore_java_version:
+    utils.check_java_version()
+  with utils.TempDir() as temp:
+    run_shrinker(options, temp)
diff --git a/tools/proguard.py b/tools/proguard.py
index b1bde54..5984622 100755
--- a/tools/proguard.py
+++ b/tools/proguard.py
@@ -6,22 +6,65 @@
 # Run ProGuard, Google's internal version
 
 from __future__ import print_function
-import jdk
+
 import os
 import subprocess
 import sys
+from exceptions import ValueError
 
+import jdk
 import utils
 
-PROGUARD_JAR = os.path.join(utils.REPO_ROOT, 'third_party', 'proguard',
-    'proguard_internal_159423826', 'ProGuard_deploy.jar')
+# Internal constants, these should not be used outside this script.
+# Use the friendly utility methods below.
+PG_DIR = os.path.join(utils.THIRD_PARTY, 'proguard')
+DEFAULT = 'pg6'
+DEFAULT_ALIAS = 'pg'
+VERSIONS = {
+  'pg5': os.path.join(PG_DIR, 'proguard5.2.1', 'lib', 'proguard.jar'),
+  'pg6': os.path.join(PG_DIR, 'proguard6.0.1', 'lib', 'proguard.jar'),
+  'pg7': os.path.join(PG_DIR, 'proguard-7.0.0', 'lib', 'proguard.jar'),
+  'pg_internal': os.path.join(
+      PG_DIR, 'proguard_internal_159423826', 'ProGuard_deploy.jar'),
+}
+# Add alias for the default version.
+VERSIONS[DEFAULT_ALIAS] = VERSIONS[DEFAULT]
 
-def run(args, track_memory_file = None, stdout=None, stderr=None):
+# Get versions sorted (nice for argument lists)
+def getVersions():
+  versions = list(VERSIONS.keys())
+  versions.sort()
+  return versions
+
+def isValidVersion(version):
+  return version in VERSIONS
+
+def getValidatedVersion(version):
+  if not isValidVersion(version):
+    raise ValueError("Invalid PG version: '%s'" % version)
+  return version
+
+def getJar(version=DEFAULT):
+  return VERSIONS[getValidatedVersion(version)]
+
+def getRetraceJar(version=DEFAULT):
+  if version == 'pg_internal':
+    raise ValueError("No retrace in internal distribution")
+  return getJar().replace('proguard.jar', 'retrace.jar')
+
+def getCmd(args, version=DEFAULT, jvmArgs=None):
+  cmd = []
+  if jvmArgs:
+    cmd.extend(jvmArgs)
+  cmd.extend([jdk.GetJavaExecutable(), '-jar', getJar(version)])
+  cmd.extend(args)
+  return cmd
+
+def run(args, version=DEFAULT, track_memory_file=None, stdout=None, stderr=None):
   cmd = []
   if track_memory_file:
     cmd.extend(['tools/track_memory.sh', track_memory_file])
-  cmd.extend([jdk.GetJavaExecutable(), '-jar', PROGUARD_JAR])
-  cmd.extend(args)
+  cmd.extend(getCmd(args, version))
   utils.PrintCmd(cmd)
   subprocess.call(cmd, stdout=stdout, stderr=stderr)
 
diff --git a/tools/r8_release.py b/tools/r8_release.py
index 1224b1d..0612c36 100755
--- a/tools/r8_release.py
+++ b/tools/r8_release.py
@@ -385,6 +385,77 @@
   return release_google3
 
 
+def update_desugar_library_in_studio(args):
+  assert os.path.exists(args.studio), ("Could not find STUDIO path %s"
+                                       % args.studio)
+
+  def make_release(args):
+    library_version = args.update_desugar_library_in_studio[0]
+    configuration_version = args.update_desugar_library_in_studio[1]
+    change_name = 'update-desugar-library-dependencies'
+
+    with utils.ChangedWorkingDirectory(args.studio):
+      if not args.use_existing_work_branch:
+        subprocess.call(['repo', 'abandon', change_name])
+      if not args.no_sync:
+        subprocess.check_call(['repo', 'sync', '-cq', '-j', '16'])
+
+      cmd = ['tools/base/bazel/bazel',
+         'run',
+         '//tools/base/bazel:add_dependency',
+         '--',
+         '--repo=https://maven.google.com com.android.tools:desugar_jdk_libs:%s' % library_version]
+      utils.PrintCmd(cmd)
+      subprocess.check_call(" ".join(cmd), shell=True)
+      cmd = ['tools/base/bazel/bazel', 'shutdown']
+      utils.PrintCmd(cmd)
+      subprocess.check_call(cmd)
+
+    prebuilts_tools = os.path.join(args.studio, 'prebuilts', 'tools')
+    with utils.ChangedWorkingDirectory(prebuilts_tools):
+      if not args.use_existing_work_branch:
+        with utils.ChangedWorkingDirectory(prebuilts_tools):
+          subprocess.check_call(['repo', 'start', change_name])
+      m2_dir = os.path.join(
+        'common', 'm2', 'repository', 'com', 'android', 'tools')
+      subprocess.check_call(
+        ['git',
+         'add',
+         os.path.join(m2_dir, DESUGAR_JDK_LIBS, library_version)])
+      subprocess.check_call(
+        ['git',
+         'add',
+         os.path.join(
+           m2_dir, DESUGAR_JDK_LIBS_CONFIGURATION, configuration_version)])
+
+      git_message = ("""Update library desugaring dependencies
+
+  com.android.tools:desugar_jdk_libs:%s
+  com.android.tools:desugar_jdk_libs_configuration:%s
+
+Bug: %s
+Test: L8ToolTest, L8DexDesugarTest"""
+                     % (library_version,
+                        configuration_version,
+                        '\nBug: '.join(args.bug)))
+
+      if not args.use_existing_work_branch:
+        subprocess.check_call(['git', 'commit', '-a', '-m', git_message])
+      else:
+        print ('Not committing when --use-existing-work-branch. '
+            + 'Commit message should be:\n\n'
+            + git_message
+            + '\n')
+      # Don't upload if requested not to, or if changes are not committed due
+      # to --use-existing-work-branch
+      if not args.no_upload and not args.use_existing_work_branch:
+        process = subprocess.Popen(['repo', 'upload', '.', '--verify'],
+                                   stdin=subprocess.PIPE)
+        return process.communicate(input='y\n')[0]
+
+  return make_release
+
+
 def prepare_desugar_library(args):
 
   def make_release(args):
@@ -677,6 +748,10 @@
                       nargs=2,
                       metavar=('<version>', '<configuration hash>'),
                       help='The new version of com.android.tools:desugar_jdk_libs')
+  group.add_argument('--update-desugar-library-in-studio',
+                      nargs=2,
+                      metavar=('<version>', '<configuration version>'),
+                      help='Update studio mirror of com.android.tools:desugar_jdk_libs')
   group.add_argument('--new-dev-branch',
                       nargs=2,
                       metavar=('<version>', '<master hash>'),
@@ -772,7 +847,7 @@
 
   if args.google3:
     targets_to_run.append(prepare_google3(args))
-  if args.studio:
+  if args.studio and not args.update_desugar_library_in_studio:
     targets_to_run.append(prepare_studio(args))
   if args.aosp:
     targets_to_run.append(prepare_aosp(args))
@@ -782,6 +857,16 @@
   if args.desugar_library:
     targets_to_run.append(prepare_desugar_library(args))
 
+  if args.update_desugar_library_in_studio:
+    if not args.studio:
+      print ("--studio required")
+      sys.exit(1)
+    if args.bug == []:
+      print ("Update studio mirror of com.android.tools:desugar_jdk_libs "
+             + "requires at least one bug by using '--bug'")
+      sys.exit(1)
+    targets_to_run.append(update_desugar_library_in_studio(args))
+
   final_results = []
   for target_closure in targets_to_run:
     final_results.append(target_closure(args))
diff --git a/tools/r8lib_size_compare.py b/tools/r8lib_size_compare.py
index 84dd1a2..568f254 100755
--- a/tools/r8lib_size_compare.py
+++ b/tools/r8lib_size_compare.py
@@ -73,13 +73,17 @@
 
   if not is_output_newer(utils.R8_JAR, r8lib_jar):
     r8lib_memory = os.path.join(tmpdir, 'r8lib%s-memory.txt' % inline_suffix)
+    # TODO(b/160420801): The signature of build_r8lib has changed.
     build_r8lib.build_r8lib(
-        output_path=r8lib_jar, output_map=r8lib_map,
-        extra_args=r8lib_args, track_memory_file=r8lib_memory)
+        output_path=r8lib_jar,
+        output_map=r8lib_map,
+        extra_args=r8lib_args,
+        track_memory_file=r8lib_memory)
 
   pg_output = os.path.join(tmpdir, 'r8lib-pg%s.jar' % inline_suffix)
   pg_memory = os.path.join(tmpdir, 'r8lib-pg%s-memory.txt' % inline_suffix)
   pg_map = os.path.join(tmpdir, 'r8lib-pg%s-map.txt' % inline_suffix)
+  # TODO(b/160420801): This must use proguard.* utils once working again.
   pg_args = ['tools/track_memory.sh', pg_memory,
              'third_party/proguard/proguard6.0.2/bin/proguard.sh',
              '@' + pg_config,
diff --git a/tools/retrace_benchmark.py b/tools/retrace_benchmark.py
index 21bb738..a819ea5 100755
--- a/tools/retrace_benchmark.py
+++ b/tools/retrace_benchmark.py
@@ -4,13 +4,14 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import argparse
-import jdk
-import golem
 import os
 import subprocess
 import sys
 import time
-import toolhelper
+
+import golem
+import jdk
+import proguard
 import utils
 
 RETRACERS = ['r8', 'proguard', 'remapper']
@@ -44,13 +45,7 @@
     retracer_args = [
         '-cp', utils.R8LIB_JAR, 'com.android.tools.r8.retrace.Retrace']
   elif options.retracer == 'proguard':
-    retracer_args = ['-jar',
-                     os.path.join(
-                        utils.THIRD_PARTY,
-                        'proguard',
-                        'proguard6.0.1',
-                        'lib',
-                        'retrace.jar')]
+    retracer_args = ['-jar', proguard.getRetraceJar()]
   elif options.retracer == 'remapper':
     retracer_args = ['-jar',
                      os.path.join(
diff --git a/tools/run_proguard_dx_on_app.py b/tools/run_proguard_dx_on_app.py
index 61ac1d7..bb1d72a 100755
--- a/tools/run_proguard_dx_on_app.py
+++ b/tools/run_proguard_dx_on_app.py
@@ -120,6 +120,7 @@
       track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
     proguard.run(
         args,
+        version='pg_internal',
         track_memory_file = track_memory_file,
         stdout=open(os.devnull, 'w'))
     if options.print_memoryuse:
diff --git a/tools/test_helloexample.py b/tools/test_helloexample.py
index abda493..f81e64c 100755
--- a/tools/test_helloexample.py
+++ b/tools/test_helloexample.py
@@ -19,6 +19,7 @@
 
 import golem
 import jdk
+import proguard
 import utils
 
 HELLO_JAR = os.path.join(utils.BUILD, 'test', 'examples', 'hello.jar')
@@ -87,7 +88,7 @@
   parser = argparse.ArgumentParser(
       description = 'Compile a hello world example program')
   parser.add_argument('--tool',
-                      choices = ['d8', 'r8', 'pg'],
+                      choices = ['d8', 'r8'] + proguard.getVersions(),
                       required = True,
                       help = 'Compiler tool to use.')
   parser.add_argument('--output-mode',
@@ -163,19 +164,17 @@
     if output_mode == 'cf':
       cmd.append('--classfile')
     return [cmd]
-  if tool == 'pg':
+  if proguard.isValidVersion(tool):
     # Build PG invokation with additional rules to silence warnings.
     pg_out = output if output_mode == 'cf' \
       else os.path.join(output_dir, 'pgout.zip')
-    cmds = [[
-      jdk.GetJavaExecutable(),
-      '-jar', utils.PROGUARD_JAR,
+    cmds = [proguard.getCmd([
       '-injars', ':'.join([HELLO_JAR] + extra),
       '-libraryjars', lib,
       '-outjars', pg_out,
       '-dontwarn **',
       '@' + rules_file
-    ]]
+    ], version=tool)]
     if output_mode == 'dex':
       cmds.append(
           GetCompilerPrefix('d8', 'dex', output, pg_out, lib, [], noopt))
diff --git a/tools/utils.py b/tools/utils.py
index 16a0696..4a171ad 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -61,12 +61,6 @@
 GENERATED_LICENSE = os.path.join(GENERATED_LICENSE_DIR, 'LICENSE')
 RT_JAR = os.path.join(REPO_ROOT, 'third_party/openjdk/openjdk-rt-1.8/rt.jar')
 R8LIB_KEEP_RULES = os.path.join(REPO_ROOT, 'src/main/keep.txt')
-PROGUARD_JAR = os.path.join(
-    THIRD_PARTY,
-    'proguard',
-    'proguard6.0.1',
-    'lib',
-    'proguard.jar')
 CF_SEGMENTS_TOOL = os.path.join(THIRD_PARTY, 'cf_segments')
 PINNED_R8_JAR = os.path.join(REPO_ROOT, 'third_party/r8/r8.jar')
 PINNED_PGR8_JAR = os.path.join(REPO_ROOT, 'third_party/r8/r8-pg6.0.1.jar')