Merge commit '52a26850e962460800d42788a8c55384dd3c6e55' into dev-release
diff --git a/build.gradle b/build.gradle
index 041431e..c65df58e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2047,6 +2047,12 @@
 def numberOfTestTimesToPrint = 40
 
 test { task ->
+
+    dependsOn buildLibraryDesugarConversions
+    dependsOn getJarsFromSupportLibs
+    // R8.jar is required for running bootstrap tests.
+    dependsOn r8
+
     def newTestingReport = project.hasProperty('testing-report')
     if (newTestingReport) {
         setUpNewTestReporting(task)
@@ -2064,6 +2070,7 @@
         systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
     }
 
+
     if (!newTestingReport) {
         testLogging.exceptionFormat = 'full'
         if (project.hasProperty('print_test_stdout')) {
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 8a4c9cc..d814466 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -8,6 +8,7 @@
 
 import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryKeepRuleGenerator;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.ApplicationWriter;
 import com.android.tools.r8.dex.Marker;
@@ -799,6 +800,9 @@
       new GenericSignatureRewriter(appView, prefixRewritingNamingLens)
           .run(appView.appInfo().classes(), executorService);
 
+      new DesugaredLibraryKeepRuleGenerator(appView, prefixRewritingNamingLens)
+          .runIfNecessary(timing);
+
       // Generate the resulting application resources.
       // TODO(b/165783399): Apply the graph lens to all instructions in the CF and DEX backends.
       writeApplication(
diff --git a/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java b/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java
new file mode 100644
index 0000000..fb4b86e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java
@@ -0,0 +1,304 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.desugar.desugaredlibrary;
+
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
+import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.references.ArrayReference;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.FieldReference;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.PackageReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer;
+import com.android.tools.r8.tracereferences.TraceReferencesKeepRules;
+import com.android.tools.r8.tracereferences.Tracer;
+import com.android.tools.r8.tracereferences.internal.TracedClassImpl;
+import com.android.tools.r8.tracereferences.internal.TracedFieldImpl;
+import com.android.tools.r8.tracereferences.internal.TracedMethodImpl;
+import com.android.tools.r8.utils.ClassReferenceUtils;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.NopDiagnosticsHandler;
+import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.TypeReferenceUtils;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+
+/** Generates keep rules for L8 using trace references. */
+public class DesugaredLibraryKeepRuleGenerator {
+
+  private final AppView<AppInfoWithClassHierarchy> appView;
+  private final NamingLens namingLens;
+  private final InternalOptions options;
+
+  public DesugaredLibraryKeepRuleGenerator(
+      AppView<AppInfoWithClassHierarchy> appView, NamingLens namingLens) {
+    this.appView = appView;
+    this.namingLens = namingLens;
+    this.options = appView.options();
+  }
+
+  public void runIfNecessary(Timing timing) {
+    if (shouldRun()) {
+      timing.begin("Desugared library keep rule generator");
+      run();
+      timing.end();
+    }
+  }
+
+  private boolean shouldRun() {
+    if (options.isDesugaredLibraryCompilation()
+        || options.desugaredLibraryKeepRuleConsumer == null
+        || !options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
+      return false;
+    }
+    return namingLens.hasPrefixRewritingLogic()
+        || options.desugaredLibraryConfiguration.hasEmulatedLibraryInterfaces();
+  }
+
+  private void run() {
+    Tracer tracer = new Tracer(appView, new NopDiagnosticsHandler(), createTargetPredicate());
+    tracer.run(createTraceReferencesConsumer());
+  }
+
+  private Predicate<DexType> createTargetPredicate() {
+    DesugaredLibraryConfiguration desugaredLibraryConfiguration =
+        options.desugaredLibraryConfiguration;
+    Set<DexType> potentialTypesToKeep =
+        SetUtils.newIdentityHashSet(
+            desugaredLibraryConfiguration.getCustomConversions().values(),
+            desugaredLibraryConfiguration.getEmulateLibraryInterface().values());
+    byte[] synthesizedLibraryClassesPackageDescriptorPrefix =
+        DexString.encodeToMutf8(
+            "L" + desugaredLibraryConfiguration.getSynthesizedLibraryClassesPackagePrefix());
+    return type ->
+        namingLens.prefixRewrittenType(type) != null
+            || potentialTypesToKeep.contains(type)
+            || type.getDescriptor().startsWith(synthesizedLibraryClassesPackageDescriptorPrefix);
+  }
+
+  private KeepRuleGenerator createTraceReferencesConsumer() {
+    return new KeepRuleGenerator(appView, namingLens);
+  }
+
+  private static class KeepRuleGenerator extends TraceReferencesConsumer.ForwardingConsumer {
+
+    private final DexItemFactory factory;
+    private final NamingLens namingLens;
+
+    // May receive concurrent callbacks from trace references.
+    private final Map<ClassReference, ClassReference> classRewritingCache =
+        new ConcurrentHashMap<>();
+    private final Map<FieldReference, FieldReference> fieldRewritingCache =
+        new ConcurrentHashMap<>();
+    private final Map<MethodReference, MethodReference> methodRewritingCache =
+        new ConcurrentHashMap<>();
+
+    // We currently cache the conversion from TypeReference to DexType, but not conversions from
+    // ArrayReference to DexType, nor conversions from (formal types, return type) to DexProto.
+    private final Map<TypeReference, DexType> typeConversionCache = new ConcurrentHashMap<>();
+
+    private KeepRuleGenerator(
+        AppView<? extends AppInfoWithClassHierarchy> appView, NamingLens namingLens) {
+      super(
+          TraceReferencesKeepRules.builder()
+              .setOutputConsumer(appView.options().desugaredLibraryKeepRuleConsumer)
+              .build());
+      this.factory = appView.dexItemFactory();
+      this.namingLens = namingLens;
+    }
+
+    @Override
+    public void acceptType(TracedClass tracedClass, DiagnosticsHandler handler) {
+      ClassReference rewrittenReference = rewrittenWithLens(tracedClass.getReference());
+      super.acceptType(
+          rewrittenReference != tracedClass.getReference()
+              ? new TracedClassImpl(rewrittenReference, tracedClass.getAccessFlags())
+              : tracedClass,
+          handler);
+    }
+
+    @Override
+    public void acceptField(TracedField tracedField, DiagnosticsHandler handler) {
+      FieldReference rewrittenReference = rewrittenWithLens(tracedField.getReference());
+      super.acceptField(
+          rewrittenReference != tracedField.getReference()
+              ? new TracedFieldImpl(rewrittenReference, tracedField.getAccessFlags())
+              : tracedField,
+          handler);
+    }
+
+    @Override
+    public void acceptMethod(TracedMethod tracedMethod, DiagnosticsHandler handler) {
+      MethodReference rewrittenReference = rewrittenWithLens(tracedMethod.getReference());
+      super.acceptMethod(
+          rewrittenReference != tracedMethod.getReference()
+              ? new TracedMethodImpl(rewrittenReference, tracedMethod.getAccessFlags())
+              : tracedMethod,
+          handler);
+    }
+
+    @Override
+    public void acceptPackage(PackageReference pkg, DiagnosticsHandler handler) {
+      super.acceptPackage(pkg, handler);
+    }
+
+    private DexType convertClassReference(ClassReference classReference) {
+      return typeConversionCache.computeIfAbsent(
+          classReference, key -> ClassReferenceUtils.toDexType(key.asClass(), factory));
+    }
+
+    private DexProto convertProto(List<TypeReference> formalTypes, TypeReference returnType) {
+      return TypeReferenceUtils.toDexProto(
+          formalTypes, returnType, factory, this::convertClassReference);
+    }
+
+    private DexType convertTypeReference(TypeReference typeReference) {
+      return typeConversionCache.computeIfAbsent(
+          typeReference,
+          key -> TypeReferenceUtils.toDexType(key, factory, this::convertClassReference));
+    }
+
+    private ClassReference rewrittenWithLens(ClassReference classReference) {
+      // First check if we have the result.
+      ClassReference cached = classRewritingCache.get(classReference);
+      if (cached != null) {
+        return cached;
+      }
+      // Otherwise, convert to DexType, apply the naming lens, and cache the result.
+      return internalRewrittenWithLens(classReference, convertClassReference(classReference));
+    }
+
+    private ClassReference rewrittenWithLens(ClassReference classReference, DexType type) {
+      // First check if we have the result.
+      ClassReference cached = classRewritingCache.get(classReference);
+      if (cached != null) {
+        return cached;
+      }
+      // Otherwise, apply the naming lens and cache the result.
+      return internalRewrittenWithLens(classReference, type);
+    }
+
+    private ClassReference internalRewrittenWithLens(ClassReference classReference, DexType type) {
+      DexString rewrittenDescriptor = namingLens.lookupClassDescriptor(type);
+      return addCacheEntry(
+          classReference,
+          rewrittenDescriptor != type.getDescriptor()
+              ? Reference.classFromDescriptor(rewrittenDescriptor.toString())
+              : classReference,
+          classRewritingCache);
+    }
+
+    private FieldReference rewrittenWithLens(FieldReference fieldReference) {
+      // First check if we have the result.
+      FieldReference cached = fieldRewritingCache.get(fieldReference);
+      if (cached != null) {
+        return cached;
+      }
+      // Convert to DexField, using the typeConversionCache.
+      DexField field =
+          factory.createField(
+              convertClassReference(fieldReference.getHolderClass()),
+              convertTypeReference(fieldReference.getFieldType()),
+              fieldReference.getFieldName());
+      // Rewrite the field components, using the classRewritingCache.
+      ClassReference rewrittenFieldHolder =
+          rewrittenWithLens(fieldReference.getHolderClass(), field.getHolderType());
+      String rewrittenFieldName = namingLens.lookupName(field).toString();
+      TypeReference rewrittenFieldType =
+          rewrittenWithLens(fieldReference.getFieldType(), field.getType());
+      // Cache the result.
+      FieldReference rewrittenFieldReference =
+          Reference.field(rewrittenFieldHolder, rewrittenFieldName, rewrittenFieldType);
+      return addCacheEntry(
+          fieldReference,
+          rewrittenFieldReference.equals(fieldReference) ? fieldReference : rewrittenFieldReference,
+          fieldRewritingCache);
+    }
+
+    private MethodReference rewrittenWithLens(MethodReference methodReference) {
+      // First check if we have the result.
+      MethodReference cached = methodRewritingCache.get(methodReference);
+      if (cached != null) {
+        return cached;
+      }
+      // Convert to DexMethod, using the typeConversionCache.
+      DexMethod method =
+          factory.createMethod(
+              convertClassReference(methodReference.getHolderClass()),
+              convertProto(methodReference.getFormalTypes(), methodReference.getReturnType()),
+              methodReference.getMethodName());
+      // Rewrite the method components, using the classRewritingCache.
+      ClassReference rewrittenMethodHolder =
+          rewrittenWithLens(methodReference.getHolderClass(), method.getHolderType());
+      String rewrittenMethodName = namingLens.lookupName(method).toString();
+      Iterator<DexType> parameterIterator = method.getParameters().iterator();
+      List<TypeReference> rewrittenMethodFormalTypes =
+          ListUtils.mapOrElse(
+              methodReference.getFormalTypes(),
+              formalType -> rewrittenWithLens(formalType, parameterIterator.next()),
+              methodReference.getFormalTypes());
+      TypeReference rewrittenMethodReturnType =
+          rewrittenWithLens(methodReference.getReturnType(), method.getReturnType());
+      // Cache the result.
+      MethodReference rewrittenMethodReference =
+          Reference.method(
+              rewrittenMethodHolder,
+              rewrittenMethodName,
+              rewrittenMethodFormalTypes,
+              rewrittenMethodReturnType);
+      return addCacheEntry(
+          methodReference,
+          rewrittenMethodReference.equals(methodReference)
+              ? methodReference
+              : rewrittenMethodReference,
+          methodRewritingCache);
+    }
+
+    private TypeReference rewrittenWithLens(TypeReference typeReference, DexType type) {
+      // The naming lens does not impact 'void' and primitives.
+      if (typeReference == null || typeReference.isPrimitive()) {
+        return typeReference;
+      }
+      // For array types we only cache the result for the base type.
+      if (typeReference.isArray()) {
+        ArrayReference arrayReference = typeReference.asArray();
+        TypeReference baseType = arrayReference.getBaseType();
+        if (baseType.isPrimitive()) {
+          return typeReference;
+        }
+        assert baseType.isClass();
+        ClassReference rewrittenBaseType = rewrittenWithLens(baseType.asClass());
+        return rewrittenBaseType != baseType
+            ? Reference.array(rewrittenBaseType, arrayReference.getDimensions())
+            : typeReference;
+      }
+      // Rewrite the class type using classRewritingCache.
+      assert typeReference.isClass();
+      return rewrittenWithLens(typeReference.asClass(), type);
+    }
+
+    private <T> T addCacheEntry(T reference, T rewrittenReference, Map<T, T> rewritingCache) {
+      rewritingCache.put(reference, rewrittenReference);
+      return rewrittenReference;
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
index 2261228..7595a40 100644
--- a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
+++ b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
@@ -22,8 +22,9 @@
 
   static CodeToKeep createCodeToKeep(InternalOptions options, NamingLens namingLens) {
     if ((!namingLens.hasPrefixRewritingLogic()
-            && options.desugaredLibraryConfiguration.getEmulateLibraryInterface().isEmpty())
-        || options.isDesugaredLibraryCompilation()) {
+            && !options.desugaredLibraryConfiguration.hasEmulatedLibraryInterfaces())
+        || options.isDesugaredLibraryCompilation()
+        || options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
       return new NopCodeToKeep();
     }
     return new DesugaredLibraryCodeToKeep(namingLens, options);
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java
rename to src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
index 1b73b9f..e1530bf 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionClassContext.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.references.ClassReference;
 
 @Keep
-public interface MissingDefinitionClassContext extends MissingDefinitionContext {
+public interface DefinitionClassContext extends DefinitionContext {
 
   /** Returns the reference of the class context. */
   ClassReference getClassReference();
@@ -19,7 +19,7 @@
   }
 
   @Override
-  default MissingDefinitionClassContext asClassContext() {
+  default DefinitionClassContext asClassContext() {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java
new file mode 100644
index 0000000..d05e123
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionContext.java
@@ -0,0 +1,61 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.origin.Origin;
+
+/** A context that references a missing definition in the program, classpath, or library. */
+@Keep
+public interface DefinitionContext {
+
+  /** The origin of the context. */
+  Origin getOrigin();
+
+  /** Predicate that is true iff this is an instance of {@link DefinitionClassContext}. */
+  default boolean isClassContext() {
+    return false;
+  }
+
+  /** Predicate that is true iff this is an instance of {@link DefinitionFieldContext}. */
+  default boolean isFieldContext() {
+    return false;
+  }
+
+  /** Predicate that is true iff this is an instance of {@link DefinitionMethodContext}. */
+  default boolean isMethodContext() {
+    return false;
+  }
+
+  /**
+   * Return a non-null {@link DefinitionClassContext} if this type is {@link
+   * DefinitionClassContext}.
+   *
+   * @return this with static type of {@link DefinitionClassContext}.
+   */
+  default DefinitionClassContext asClassContext() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link DefinitionFieldContext} if this type is {@link
+   * DefinitionFieldContext}.
+   *
+   * @return this with static type of {@link DefinitionFieldContext}.
+   */
+  default DefinitionFieldContext asFieldContext() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link DefinitionMethodContext} if this type is {@link
+   * DefinitionMethodContext}.
+   *
+   * @return this with static type of {@link DefinitionMethodContext}.
+   */
+  default DefinitionMethodContext asMethodContext() {
+    return null;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java
rename to src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
index 7564f5a..b3c4981 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionFieldContext.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.references.FieldReference;
 
 @Keep
-public interface MissingDefinitionFieldContext extends MissingDefinitionContext {
+public interface DefinitionFieldContext extends DefinitionContext {
 
   /** Returns the reference of the field context. */
   FieldReference getFieldReference();
@@ -19,7 +19,7 @@
   }
 
   @Override
-  default MissingDefinitionFieldContext asFieldContext() {
+  default DefinitionFieldContext asFieldContext() {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java b/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java
rename to src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
index 315a29c..86742db 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/DefinitionMethodContext.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.references.MethodReference;
 
 @Keep
-public interface MissingDefinitionMethodContext extends MissingDefinitionContext {
+public interface DefinitionMethodContext extends DefinitionContext {
 
   /** Returns the reference of the method context. */
   MethodReference getMethodReference();
@@ -19,7 +19,7 @@
   }
 
   @Override
-  default MissingDefinitionMethodContext asMethodContext() {
+  default DefinitionMethodContext asMethodContext() {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java
deleted file mode 100644
index cb5d3b4..0000000
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.diagnostic;
-
-import com.android.tools.r8.Keep;
-import com.android.tools.r8.origin.Origin;
-
-/** A context that references a missing definition in the program, classpath, or library. */
-@Keep
-public interface MissingDefinitionContext {
-
-  /** The origin of the context. */
-  Origin getOrigin();
-
-  /** Predicate that is true iff this is an instance of {@link MissingDefinitionClassContext}. */
-  default boolean isClassContext() {
-    return false;
-  }
-
-  /** Predicate that is true iff this is an instance of {@link MissingDefinitionFieldContext}. */
-  default boolean isFieldContext() {
-    return false;
-  }
-
-  /** Predicate that is true iff this is an instance of {@link MissingDefinitionMethodContext}. */
-  default boolean isMethodContext() {
-    return false;
-  }
-
-  /**
-   * Return a non-null {@link MissingDefinitionClassContext} if this type is {@link
-   * MissingDefinitionClassContext}.
-   *
-   * @return this with static type of {@link MissingDefinitionClassContext}.
-   */
-  default MissingDefinitionClassContext asClassContext() {
-    return null;
-  }
-
-  /**
-   * Return a non-null {@link MissingDefinitionFieldContext} if this type is {@link
-   * MissingDefinitionFieldContext}.
-   *
-   * @return this with static type of {@link MissingDefinitionFieldContext}.
-   */
-  default MissingDefinitionFieldContext asFieldContext() {
-    return null;
-  }
-
-  /**
-   * Return a non-null {@link MissingDefinitionMethodContext} if this type is {@link
-   * MissingDefinitionMethodContext}.
-   *
-   * @return this with static type of {@link MissingDefinitionMethodContext}.
-   */
-  default MissingDefinitionMethodContext asMethodContext() {
-    return null;
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
index ec486de..03fe322 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
@@ -68,5 +68,5 @@
   String getDiagnosticMessage();
 
   /** The contexts from which this missing definition was referenced. */
-  Collection<MissingDefinitionContext> getReferencedFromContexts();
+  Collection<DefinitionContext> getReferencedFromContexts();
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionClassContextImpl.java
similarity index 68%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionClassContextImpl.java
index 7944a1e..b632519 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionClassContextImpl.java
@@ -4,16 +4,16 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.DefinitionClassContext;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 
-public class MissingDefinitionClassContextImpl extends MissingDefinitionContextBase
-    implements MissingDefinitionClassContext {
+public class DefinitionClassContextImpl extends DefinitionContextBase
+    implements DefinitionClassContext {
 
   private final ClassReference classReference;
 
-  private MissingDefinitionClassContextImpl(ClassReference classReference, Origin origin) {
+  private DefinitionClassContextImpl(ClassReference classReference, Origin origin) {
     super(origin);
     this.classReference = classReference;
   }
@@ -27,7 +27,7 @@
     return classReference;
   }
 
-  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
+  public static class Builder extends DefinitionContextBase.Builder<Builder> {
 
     private ClassReference classReference;
 
@@ -44,9 +44,9 @@
     }
 
     @Override
-    public MissingDefinitionClassContextImpl build() {
+    public DefinitionClassContextImpl build() {
       assert validate();
-      return new MissingDefinitionClassContextImpl(classReference, origin);
+      return new DefinitionClassContextImpl(classReference, origin);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextBase.java b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextBase.java
similarity index 74%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextBase.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextBase.java
index cf6a0d1..44bd042 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextBase.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextBase.java
@@ -4,14 +4,14 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.origin.Origin;
 
-public abstract class MissingDefinitionContextBase implements MissingDefinitionContext {
+public abstract class DefinitionContextBase implements DefinitionContext {
 
   private final Origin origin;
 
-  MissingDefinitionContextBase(Origin origin) {
+  DefinitionContextBase(Origin origin) {
     this.origin = origin;
   }
 
@@ -31,7 +31,7 @@
 
     abstract B self();
 
-    public abstract MissingDefinitionContext build();
+    public abstract DefinitionContext build();
 
     public boolean validate() {
       assert origin != null;
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextUtils.java b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextUtils.java
new file mode 100644
index 0000000..1703738
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionContextUtils.java
@@ -0,0 +1,79 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.diagnostic.internal;
+
+import com.android.tools.r8.diagnostic.DefinitionClassContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionFieldContext;
+import com.android.tools.r8.diagnostic.DefinitionMethodContext;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.Definition;
+import com.android.tools.r8.graph.ProgramDerivedContext;
+import com.android.tools.r8.utils.FieldReferenceUtils;
+import com.android.tools.r8.utils.MethodReferenceUtils;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class DefinitionContextUtils {
+
+  public static void accept(
+      DefinitionContext definitionContext,
+      Consumer<DefinitionClassContext> definitionClassContextConsumer,
+      Consumer<DefinitionFieldContext> definitionFieldContextConsumer,
+      Consumer<DefinitionMethodContext> definitionMethodContextConsumer) {
+    if (definitionContext.isClassContext()) {
+      definitionClassContextConsumer.accept(definitionContext.asClassContext());
+    } else if (definitionContext.isFieldContext()) {
+      definitionFieldContextConsumer.accept(definitionContext.asFieldContext());
+    } else {
+      assert definitionContext.isMethodContext();
+      definitionMethodContextConsumer.accept(definitionContext.asMethodContext());
+    }
+  }
+
+  public static <T> T apply(
+      DefinitionContext definitionContext,
+      Function<DefinitionClassContext, T> definitionClassContextFn,
+      Function<DefinitionFieldContext, T> definitionFieldContextFn,
+      Function<DefinitionMethodContext, T> definitionMethodContextFn) {
+    if (definitionContext.isClassContext()) {
+      return definitionClassContextFn.apply(definitionContext.asClassContext());
+    } else if (definitionContext.isFieldContext()) {
+      return definitionFieldContextFn.apply(definitionContext.asFieldContext());
+    } else {
+      assert definitionContext.isMethodContext();
+      return definitionMethodContextFn.apply(definitionContext.asMethodContext());
+    }
+  }
+
+  public static DefinitionContext create(ProgramDerivedContext programDerivedContext) {
+    Definition context = programDerivedContext.getContext();
+    DefinitionContextBase.Builder<?> builder;
+    if (context.isClass()) {
+      builder =
+          DefinitionClassContextImpl.builder()
+              .setClassContext(context.asClass().getClassReference());
+    } else if (context.isField()) {
+      builder =
+          DefinitionFieldContextImpl.builder()
+              .setFieldContext(context.asField().getFieldReference());
+    } else if (context.isMethod()) {
+      builder =
+          DefinitionMethodContextImpl.builder()
+              .setMethodContext(context.asMethod().getMethodReference());
+    } else {
+      throw new Unreachable();
+    }
+    return builder.setOrigin(context.getOrigin()).build();
+  }
+
+  public static String toSourceString(DefinitionContext definitionContext) {
+    return DefinitionContextUtils.apply(
+        definitionContext,
+        classContext -> classContext.getClassReference().getTypeName(),
+        fieldContext -> FieldReferenceUtils.toSourceString(fieldContext.getFieldReference()),
+        methodContext -> MethodReferenceUtils.toSourceString(methodContext.getMethodReference()));
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionFieldContextImpl.java
similarity index 68%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionFieldContextImpl.java
index b9ecf41..888f401 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionFieldContextImpl.java
@@ -4,16 +4,16 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.DefinitionFieldContext;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.FieldReference;
 
-public class MissingDefinitionFieldContextImpl extends MissingDefinitionContextBase
-    implements MissingDefinitionFieldContext {
+public class DefinitionFieldContextImpl extends DefinitionContextBase
+    implements DefinitionFieldContext {
 
   private final FieldReference fieldReference;
 
-  private MissingDefinitionFieldContextImpl(FieldReference fieldReference, Origin origin) {
+  private DefinitionFieldContextImpl(FieldReference fieldReference, Origin origin) {
     super(origin);
     this.fieldReference = fieldReference;
   }
@@ -27,7 +27,7 @@
     return fieldReference;
   }
 
-  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
+  public static class Builder extends DefinitionContextBase.Builder<Builder> {
 
     private FieldReference fieldReference;
 
@@ -44,9 +44,9 @@
     }
 
     @Override
-    public MissingDefinitionFieldContextImpl build() {
+    public DefinitionFieldContextImpl build() {
       assert validate();
-      return new MissingDefinitionFieldContextImpl(fieldReference, origin);
+      return new DefinitionFieldContextImpl(fieldReference, origin);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionMethodContextImpl.java
similarity index 68%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionMethodContextImpl.java
index eba8719..5c35d3b 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/DefinitionMethodContextImpl.java
@@ -4,16 +4,16 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.DefinitionMethodContext;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.MethodReference;
 
-public class MissingDefinitionMethodContextImpl extends MissingDefinitionContextBase
-    implements MissingDefinitionMethodContext {
+public class DefinitionMethodContextImpl extends DefinitionContextBase
+    implements DefinitionMethodContext {
 
   private final MethodReference methodReference;
 
-  private MissingDefinitionMethodContextImpl(MethodReference methodReference, Origin origin) {
+  private DefinitionMethodContextImpl(MethodReference methodReference, Origin origin) {
     super(origin);
     this.methodReference = methodReference;
   }
@@ -27,7 +27,7 @@
     return methodReference;
   }
 
-  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
+  public static class Builder extends DefinitionContextBase.Builder<Builder> {
 
     private MethodReference methodReference;
 
@@ -44,9 +44,9 @@
     }
 
     @Override
-    public MissingDefinitionMethodContextImpl build() {
+    public DefinitionMethodContextImpl build() {
       assert validate();
-      return new MissingDefinitionMethodContextImpl(methodReference, origin);
+      return new DefinitionMethodContextImpl(methodReference, origin);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
index b240279..82d5a35 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingClassInfo;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.references.ClassReference;
 import java.util.Collection;
@@ -15,7 +15,7 @@
   private final ClassReference classReference;
 
   private MissingClassInfoImpl(
-      ClassReference classReference, Collection<MissingDefinitionContext> referencedFromContexts) {
+      ClassReference classReference, Collection<DefinitionContext> referencedFromContexts) {
     super(referencedFromContexts);
     this.classReference = classReference;
   }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java
deleted file mode 100644
index 74b48c5..0000000
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.diagnostic.internal;
-
-import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.Definition;
-import com.android.tools.r8.graph.ProgramDerivedContext;
-import com.android.tools.r8.utils.FieldReferenceUtils;
-import com.android.tools.r8.utils.MethodReferenceUtils;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public class MissingDefinitionContextUtils {
-
-  public static void accept(
-      MissingDefinitionContext missingDefinitionContext,
-      Consumer<MissingDefinitionClassContext> missingDefinitionClassContextConsumer,
-      Consumer<MissingDefinitionFieldContext> missingDefinitionFieldContextConsumer,
-      Consumer<MissingDefinitionMethodContext> missingDefinitionMethodContextConsumer) {
-    if (missingDefinitionContext.isClassContext()) {
-      missingDefinitionClassContextConsumer.accept(missingDefinitionContext.asClassContext());
-    } else if (missingDefinitionContext.isFieldContext()) {
-      missingDefinitionFieldContextConsumer.accept(missingDefinitionContext.asFieldContext());
-    } else {
-      assert missingDefinitionContext.isMethodContext();
-      missingDefinitionMethodContextConsumer.accept(missingDefinitionContext.asMethodContext());
-    }
-  }
-
-  public static <T> T apply(
-      MissingDefinitionContext missingDefinitionContext,
-      Function<MissingDefinitionClassContext, T> missingDefinitionClassContextFn,
-      Function<MissingDefinitionFieldContext, T> missingDefinitionFieldContextFn,
-      Function<MissingDefinitionMethodContext, T> missingDefinitionMethodContextFn) {
-    if (missingDefinitionContext.isClassContext()) {
-      return missingDefinitionClassContextFn.apply(missingDefinitionContext.asClassContext());
-    } else if (missingDefinitionContext.isFieldContext()) {
-      return missingDefinitionFieldContextFn.apply(missingDefinitionContext.asFieldContext());
-    } else {
-      assert missingDefinitionContext.isMethodContext();
-      return missingDefinitionMethodContextFn.apply(missingDefinitionContext.asMethodContext());
-    }
-  }
-
-  public static MissingDefinitionContext create(ProgramDerivedContext programDerivedContext) {
-    Definition context = programDerivedContext.getContext();
-    MissingDefinitionContextBase.Builder<?> builder;
-    if (context.isClass()) {
-      builder =
-          MissingDefinitionClassContextImpl.builder()
-              .setClassContext(context.asClass().getClassReference());
-    } else if (context.isField()) {
-      builder =
-          MissingDefinitionFieldContextImpl.builder()
-              .setFieldContext(context.asField().getFieldReference());
-    } else if (context.isMethod()) {
-      builder =
-          MissingDefinitionMethodContextImpl.builder()
-              .setMethodContext(context.asMethod().getMethodReference());
-    } else {
-      throw new Unreachable();
-    }
-    return builder.setOrigin(context.getOrigin()).build();
-  }
-
-  public static String toSourceString(MissingDefinitionContext missingDefinitionContext) {
-    return MissingDefinitionContextUtils.apply(
-        missingDefinitionContext,
-        classContext -> classContext.getClassReference().getTypeName(),
-        fieldContext -> FieldReferenceUtils.toSourceString(fieldContext.getFieldReference()),
-        methodContext -> MethodReferenceUtils.toSourceString(methodContext.getMethodReference()));
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoBase.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoBase.java
index b3d2872..8d90a92 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoBase.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoBase.java
@@ -4,16 +4,16 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 
 public abstract class MissingDefinitionInfoBase implements MissingDefinitionInfo {
 
-  final Collection<MissingDefinitionContext> referencedFromContexts;
+  final Collection<DefinitionContext> referencedFromContexts;
 
-  MissingDefinitionInfoBase(Collection<MissingDefinitionContext> referencedFromContexts) {
+  MissingDefinitionInfoBase(Collection<DefinitionContext> referencedFromContexts) {
     this.referencedFromContexts = referencedFromContexts;
   }
 
@@ -25,18 +25,18 @@
   }
 
   @Override
-  public final Collection<MissingDefinitionContext> getReferencedFromContexts() {
+  public final Collection<DefinitionContext> getReferencedFromContexts() {
     return referencedFromContexts;
   }
 
   public abstract static class Builder {
 
-    final ImmutableList.Builder<MissingDefinitionContext> referencedFromContextsBuilder =
+    final ImmutableList.Builder<DefinitionContext> referencedFromContextsBuilder =
         ImmutableList.builder();
 
     Builder() {}
 
-    public Builder addReferencedFromContext(MissingDefinitionContext missingDefinitionContext) {
+    public Builder addReferencedFromContext(DefinitionContext missingDefinitionContext) {
       referencedFromContextsBuilder.add(missingDefinitionContext);
       return this;
     }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
index 224b2a4..a744297 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
@@ -8,8 +8,8 @@
 import static com.android.tools.r8.utils.FieldReferenceUtils.getFieldReferenceComparator;
 import static com.android.tools.r8.utils.MethodReferenceUtils.getMethodReferenceComparator;
 
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingClassInfo;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.diagnostic.MissingFieldInfo;
 import com.android.tools.r8.diagnostic.MissingMethodInfo;
@@ -110,9 +110,9 @@
     Box<ClassReference> classContext = new Box<>();
     Box<FieldReference> fieldContext = new Box<>();
     Box<MethodReference> methodContext = new Box<>();
-    for (MissingDefinitionContext missingDefinitionContext :
+    for (DefinitionContext missingDefinitionContext :
         missingDefinitionInfo.getReferencedFromContexts()) {
-      MissingDefinitionContextUtils.accept(
+      DefinitionContextUtils.accept(
           missingDefinitionContext,
           missingDefinitionClassContext ->
               classContext.setMin(
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingFieldInfoImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingFieldInfoImpl.java
index 216080d..d7acc21 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingFieldInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingFieldInfoImpl.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.diagnostic.MissingFieldInfo;
 import com.android.tools.r8.references.FieldReference;
@@ -15,7 +15,7 @@
   private final FieldReference fieldReference;
 
   private MissingFieldInfoImpl(
-      FieldReference fieldReference, Collection<MissingDefinitionContext> referencedFromContexts) {
+      FieldReference fieldReference, Collection<DefinitionContext> referencedFromContexts) {
     super(referencedFromContexts);
     this.fieldReference = fieldReference;
   }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingMethodInfoImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingMethodInfoImpl.java
index 5be14dc..8ab85d9 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingMethodInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingMethodInfoImpl.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.diagnostic.MissingMethodInfo;
 import com.android.tools.r8.references.MethodReference;
@@ -15,8 +15,7 @@
   private final MethodReference methodReference;
 
   private MissingMethodInfoImpl(
-      MethodReference methodReference,
-      Collection<MissingDefinitionContext> referencedFromContexts) {
+      MethodReference methodReference, Collection<DefinitionContext> referencedFromContexts) {
     super(referencedFromContexts);
     this.methodReference = methodReference;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 646fca7..acd8b41 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -555,6 +555,7 @@
   public final RecordMembers recordMembers = new RecordMembers();
   public final ShortMembers shortMembers = new ShortMembers();
   public final StringMembers stringMembers = new StringMembers();
+  public final SupplierMembers supplierMembers = new SupplierMembers();
   public final DoubleMembers doubleMembers = new DoubleMembers();
   public final ThrowableMethods throwableMethods = new ThrowableMethods();
   public final AssertionErrorMethods assertionErrorMethods = new AssertionErrorMethods();
@@ -1340,11 +1341,29 @@
 
   public class ObjectsMethods {
 
+    public final DexMethod equals =
+        createMethod(objectsType, createProto(booleanType, objectType, objectType), "equals");
+    public final DexMethod hashCode =
+        createMethod(objectsType, createProto(intType, objectType), "hashCode");
+    public final DexMethod isNull =
+        createMethod(objectsType, createProto(booleanType, objectType), "isNull");
+    public final DexMethod nonNull =
+        createMethod(objectsType, createProto(booleanType, objectType), "nonNull");
     public final DexMethod requireNonNull;
     public final DexMethod requireNonNullWithMessage;
     public final DexMethod requireNonNullWithMessageSupplier;
+    public final DexMethod requireNonNullElse =
+        createMethod(
+            objectsType, createProto(objectType, objectType, objectType), "requireNonNullElse");
+    public final DexMethod requireNonNullElseGet =
+        createMethod(
+            objectsType,
+            createProto(objectType, objectType, supplierType),
+            "requireNonNullElseGet");
     public final DexMethod toStringWithObject =
         createMethod(objectsType, createProto(stringType, objectType), "toString");
+    public final DexMethod toStringWithObjectAndNullDefault =
+        createMethod(objectsType, createProto(stringType, objectType, stringType), "toString");
 
     private ObjectsMethods() {
       DexString requireNonNullMethodName = createString("requireNonNull");
@@ -1365,7 +1384,13 @@
     public boolean isRequireNonNullMethod(DexMethod method) {
       return method == requireNonNull
           || method == requireNonNullWithMessage
-          || method == requireNonNullWithMessageSupplier;
+          || method == requireNonNullWithMessageSupplier
+          || method == requireNonNullElse
+          || method == requireNonNullElseGet;
+    }
+
+    public boolean isToStringMethod(DexMethod method) {
+      return method == toStringWithObject || method == toStringWithObjectAndNullDefault;
     }
 
     public Iterable<DexMethod> requireNonNullMethods() {
@@ -1883,6 +1908,13 @@
     }
   }
 
+  public class SupplierMembers extends LibraryMembers {
+
+    public final DexMethod get = createMethod(supplierType, createProto(objectType), "get");
+
+    private SupplierMembers() {}
+  }
+
   public class PolymorphicMethods {
 
     private final DexProto signature = createProto(objectType, objectArrayType);
diff --git a/src/main/java/com/android/tools/r8/graph/DexString.java b/src/main/java/com/android/tools/r8/graph/DexString.java
index af2ad74..ba4d653 100644
--- a/src/main/java/com/android/tools/r8/graph/DexString.java
+++ b/src/main/java/com/android/tools/r8/graph/DexString.java
@@ -50,6 +50,10 @@
     throw new Unreachable();
   }
 
+  public byte byteAt(int index) {
+    return content[index];
+  }
+
   /** DexString is a leaf item so we directly define its compareTo which avoids overhead. */
   @Override
   public int compareTo(DexString other) {
@@ -437,11 +441,19 @@
   }
 
   public boolean startsWith(DexString prefix) {
-    if (content.length < prefix.content.length) {
+    return startsWith(prefix.content);
+  }
+
+  public boolean startsWith(String prefix) {
+    return startsWith(encodeToMutf8(prefix));
+  }
+
+  public boolean startsWith(byte[] prefixContent) {
+    if (content.length < prefixContent.length) {
       return false;
     }
-    for (int i = 0; i < prefix.content.length - 1; i++) {
-      if (content[i] != prefix.content[i]) {
+    for (int i = 0; i < prefixContent.length - 1; i++) {
+      if (content[i] != prefixContent[i]) {
         return false;
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
index d0e0027..7bd9cf9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
@@ -304,7 +304,7 @@
       return true;
     }
     InvokeMethod replacement;
-    if (appView.options().canUseRequireNonNull()) {
+    if (appView.options().canUseJavaUtilObjectsRequireNonNull()) {
       DexMethod requireNonNullMethod = appView.dexItemFactory().objectsMethods.requireNonNull;
       replacement = new InvokeStatic(requireNonNullMethod, null, ImmutableList.of(receiver));
     } else {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
index 32b1f29..14a7d45 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
@@ -107,10 +107,18 @@
   void replaceCurrentInstructionWithConstClass(
       AppView<?> appView, IRCode code, DexType type, DebugLocalInfo localInfo);
 
+  default void replaceCurrentInstructionWithConstFalse(IRCode code) {
+    replaceCurrentInstructionWithConstInt(code, 0);
+  }
+
   void replaceCurrentInstructionWithConstInt(IRCode code, int value);
 
   void replaceCurrentInstructionWithConstString(AppView<?> appView, IRCode code, DexString value);
 
+  default void replaceCurrentInstructionWithConstTrue(IRCode code) {
+    replaceCurrentInstructionWithConstInt(code, 1);
+  }
+
   default void replaceCurrentInstructionWithConstString(
       AppView<?> appView, IRCode code, String value) {
     replaceCurrentInstructionWithConstString(
diff --git a/src/main/java/com/android/tools/r8/ir/code/Invoke.java b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
index d076960..02c1ad0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Invoke.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
@@ -190,6 +190,10 @@
     return getArgument(0);
   }
 
+  public Value getLastArgument() {
+    return getArgument(arguments().size() - 1);
+  }
+
   public int requiredArgumentRegisters() {
     int registers = 0;
     for (Value inValue : inValues) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 85d90e6..d582fdb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -578,14 +578,24 @@
   }
 
   public void replaceUsers(Value newValue) {
+    replaceUsers(newValue, null);
+  }
+
+  public void replaceUsers(Value newValue, Set<Value> affectedValues) {
     if (this == newValue) {
       return;
     }
     for (Instruction user : uniqueUsers()) {
       user.replaceValue(this, newValue);
+      if (affectedValues != null && user.hasOutValue()) {
+        affectedValues.add(user.outValue);
+      }
     }
     for (Phi user : uniquePhiUsers()) {
       user.replaceOperand(this, newValue);
+      if (affectedValues != null) {
+        affectedValues.add(user);
+      }
     }
     if (debugData != null) {
       for (Instruction user : debugData.users) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
index d19fd84..9ec7242 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
@@ -161,6 +161,10 @@
     return rewritePrefix;
   }
 
+  public boolean hasEmulatedLibraryInterfaces() {
+    return !getEmulateLibraryInterface().isEmpty();
+  }
+
   public Map<DexType, DexType> getEmulateLibraryInterface() {
     return emulateLibraryInterface;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 32ec969..36d70df 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -305,7 +305,7 @@
             if (invokedMethod == dexItemFactory.npeMethods.init) {
               message = null;
             } else if (invokedMethod == dexItemFactory.npeMethods.initWithMessage) {
-              if (!appView.options().canUseRequireNonNull()) {
+              if (!appView.options().canUseJavaUtilObjectsRequireNonNull()) {
                 continue;
               }
               message = constructorCall.getArgument(1);
@@ -3348,7 +3348,7 @@
     assert theIf == block.exit();
     iterator.previous();
     Instruction instruction;
-    if (appView.options().canUseRequireNonNull()) {
+    if (appView.options().canUseJavaUtilObjectsRequireNonNull()) {
       if (message != null) {
         DexMethod requireNonNullMethod =
             appView.dexItemFactory().objectsMethods.requireNonNullWithMessage;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index e034587..41a298a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -776,7 +776,7 @@
 
         InstructionListIterator iterator = throwBlock.listIterator(code);
         iterator.setInsertionPosition(invoke.getPosition());
-        if (appView.options().canUseRequireNonNull()) {
+        if (appView.options().canUseJavaUtilObjectsRequireNonNull()) {
           DexMethod requireNonNullMethod = appView.dexItemFactory().objectsMethods.requireNonNull;
           iterator.add(new InvokeStatic(requireNonNullMethod, null, ImmutableList.of(receiver)));
         } else {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
index 831236b..08199da 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/ObjectsMethodOptimizer.java
@@ -8,12 +8,17 @@
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexItemFactory.ObjectsMethods;
+import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.InstructionListIterator;
 import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.ir.code.InvokeStatic;
+import com.android.tools.r8.ir.code.InvokeVirtual;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.utils.InternalOptions;
+import com.google.common.collect.ImmutableList;
 import java.util.Set;
 
 public class ObjectsMethodOptimizer extends StatelessLibraryMethodModelCollection {
@@ -21,12 +26,14 @@
   private final AppView<?> appView;
   private final DexItemFactory dexItemFactory;
   private final ObjectsMethods objectsMethods;
+  private final InternalOptions options;
 
   ObjectsMethodOptimizer(AppView<?> appView) {
     DexItemFactory dexItemFactory = appView.dexItemFactory();
     this.appView = appView;
     this.dexItemFactory = dexItemFactory;
     this.objectsMethods = dexItemFactory.objectsMethods;
+    this.options = appView.options();
   }
 
   @Override
@@ -41,24 +48,152 @@
       InvokeMethod invoke,
       DexClassAndMethod singleTarget,
       Set<Value> affectedValues) {
-    if (objectsMethods.isRequireNonNullMethod(singleTarget.getReference())) {
-      optimizeRequireNonNull(instructionIterator, invoke, affectedValues);
-    } else if (singleTarget.getReference() == objectsMethods.toStringWithObject) {
-      optimizeToStringWithObject(code, instructionIterator, invoke, affectedValues);
+    DexMethod singleTargetReference = singleTarget.getReference();
+    switch (singleTargetReference.getName().byteAt(0)) {
+      case 'e':
+        if (singleTargetReference == objectsMethods.equals) {
+          optimizeEquals(code, instructionIterator, invoke);
+        }
+        break;
+      case 'h':
+        if (singleTargetReference == objectsMethods.hashCode) {
+          optimizeHashCode(code, instructionIterator, invoke);
+        }
+        break;
+      case 'i':
+        if (singleTargetReference == objectsMethods.isNull) {
+          optimizeIsNull(code, instructionIterator, invoke);
+        }
+        break;
+      case 'n':
+        if (singleTargetReference == objectsMethods.nonNull) {
+          optimizeNonNull(code, instructionIterator, invoke);
+        }
+        break;
+      case 'r':
+        if (objectsMethods.isRequireNonNullMethod(singleTargetReference)) {
+          optimizeRequireNonNull(instructionIterator, invoke, affectedValues, singleTarget);
+        }
+        break;
+      case 't':
+        if (objectsMethods.isToStringMethod(singleTargetReference)) {
+          optimizeToStringWithObject(
+              code, instructionIterator, invoke, affectedValues, singleTarget);
+        }
+        break;
+      default:
+        // Intentionally empty.
+        break;
+    }
+  }
+
+  private void optimizeEquals(
+      IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke) {
+    Value aValue = invoke.getFirstArgument();
+    Value bValue = invoke.getLastArgument();
+    if (aValue.isAlwaysNull(appView)) {
+      // Optimize Objects.equals(null, b) into true if b is null, false if b is never null, and
+      // Objects.isNull(b) otherwise.
+      if (bValue.isAlwaysNull(appView)) {
+        instructionIterator.replaceCurrentInstructionWithConstTrue(code);
+      } else if (bValue.isNeverNull()) {
+        instructionIterator.replaceCurrentInstructionWithConstFalse(code);
+      } else if (options.canUseJavaUtilObjectsIsNull()) {
+        instructionIterator.replaceCurrentInstruction(
+            InvokeStatic.builder()
+                .setMethod(objectsMethods.isNull)
+                .setOutValue(invoke.outValue())
+                .setSingleArgument(bValue)
+                .build());
+      }
+    } else if (aValue.isNeverNull()) {
+      // Optimize Objects.equals(nonNull, b) into nonNull.equals(b).
+      instructionIterator.replaceCurrentInstruction(
+          InvokeVirtual.builder()
+              .setMethod(dexItemFactory.objectMembers.equals)
+              .setOutValue(invoke.outValue())
+              .setArguments(ImmutableList.of(aValue, bValue))
+              .build());
+    }
+  }
+
+  private void optimizeHashCode(
+      IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke) {
+    Value inValue = invoke.getFirstArgument();
+    if (inValue.isAlwaysNull(appView)) {
+      // Optimize Objects.hashCode(null) into 0.
+      instructionIterator.replaceCurrentInstructionWithConstInt(code, 0);
+    } else if (inValue.isNeverNull()) {
+      // Optimize Objects.hashCode(nonNull) into nonNull.hashCode().
+      instructionIterator.replaceCurrentInstruction(
+          InvokeVirtual.builder()
+              .setMethod(dexItemFactory.objectMembers.hashCode)
+              .setOutValue(invoke.outValue())
+              .setSingleArgument(inValue)
+              .build());
+    }
+  }
+
+  private void optimizeIsNull(
+      IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke) {
+    Value inValue = invoke.getFirstArgument();
+    if (inValue.isAlwaysNull(appView)) {
+      // Optimize Objects.isNull(null) into true.
+      instructionIterator.replaceCurrentInstructionWithConstTrue(code);
+    } else if (inValue.isNeverNull()) {
+      // Optimize Objects.isNull(nonNull) into false.
+      instructionIterator.replaceCurrentInstructionWithConstFalse(code);
+    }
+  }
+
+  private void optimizeNonNull(
+      IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke) {
+    Value inValue = invoke.getFirstArgument();
+    if (inValue.isAlwaysNull(appView)) {
+      // Optimize Objects.nonNull(null) into false.
+      instructionIterator.replaceCurrentInstructionWithConstFalse(code);
+    } else if (inValue.isNeverNull()) {
+      // Optimize Objects.nonNull(nonNull) into true.
+      instructionIterator.replaceCurrentInstructionWithConstTrue(code);
     }
   }
 
   private void optimizeRequireNonNull(
-      InstructionListIterator instructionIterator, InvokeMethod invoke, Set<Value> affectedValues) {
+      InstructionListIterator instructionIterator,
+      InvokeMethod invoke,
+      Set<Value> affectedValues,
+      DexClassAndMethod singleTarget) {
+    if (invoke.hasOutValue() && invoke.outValue().hasLocalInfo()) {
+      // Replacing the out-value with an in-value would change debug info.
+      return;
+    }
+
     Value inValue = invoke.getFirstArgument();
-    if (inValue.getType().isDefinitelyNotNull()) {
-      Value outValue = invoke.outValue();
-      if (outValue != null) {
-        affectedValues.addAll(outValue.affectedValues());
-        outValue.replaceUsers(inValue);
+    if (inValue.isNeverNull()) {
+      // Optimize Objects.requireNonNull*(nonNull, ...) into nonNull.
+      if (invoke.hasOutValue()) {
+        invoke.outValue().replaceUsers(inValue, affectedValues);
       }
-      // TODO(b/152853271): Debugging information is lost here (DebugLocalWrite may be required).
       instructionIterator.removeOrReplaceByDebugLocalRead();
+    } else if (inValue.isAlwaysNull(appView)) {
+      if (singleTarget.getReference() == objectsMethods.requireNonNullElse) {
+        // Optimize Objects.requireNonNullElse(null, defaultObj) into defaultObj.
+        if (invoke.hasOutValue()) {
+          invoke.outValue().replaceUsers(invoke.getLastArgument(), affectedValues);
+        }
+        instructionIterator.removeOrReplaceByDebugLocalRead();
+      } else if (singleTarget.getReference() == objectsMethods.requireNonNullElseGet) {
+        // Optimize Objects.requireNonNullElseGet(null, supplier) into supplier.get().
+        if (invoke.hasOutValue()) {
+          invoke.outValue().replaceUsers(invoke.getLastArgument(), affectedValues);
+        }
+        instructionIterator.replaceCurrentInstruction(
+            InvokeVirtual.builder()
+                .setMethod(dexItemFactory.supplierMembers.get)
+                .setOutValue(invoke.outValue())
+                .setSingleArgument(invoke.getLastArgument())
+                .build());
+      }
     }
   }
 
@@ -66,15 +201,24 @@
       IRCode code,
       InstructionListIterator instructionIterator,
       InvokeMethod invoke,
-      Set<Value> affectedValues) {
+      Set<Value> affectedValues,
+      DexClassAndMethod singleTarget) {
     Value object = invoke.getFirstArgument();
     TypeElement type = object.getType();
 
     // Optimize Objects.toString(null) into "null".
     if (type.isDefinitelyNull()) {
-      instructionIterator.replaceCurrentInstructionWithConstString(appView, code, "null");
-      if (invoke.hasOutValue()) {
-        affectedValues.addAll(invoke.outValue().affectedValues());
+      if (singleTarget.getReference() == objectsMethods.toStringWithObject) {
+        if (invoke.hasOutValue()) {
+          affectedValues.addAll(invoke.outValue().affectedValues());
+        }
+        instructionIterator.replaceCurrentInstructionWithConstString(appView, code, "null");
+      } else {
+        assert singleTarget.getReference() == objectsMethods.toStringWithObjectAndNullDefault;
+        if (invoke.hasOutValue()) {
+          invoke.outValue().replaceUsers(invoke.getLastArgument(), affectedValues);
+        }
+        instructionIterator.removeOrReplaceByDebugLocalRead();
       }
       return;
     }
diff --git a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
index 3e8ad60..0ec8c27 100644
--- a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
+++ b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
@@ -9,8 +9,8 @@
 import static com.android.tools.r8.utils.collections.IdentityHashSetFromMap.newProgramDerivedContextSet;
 
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
+import com.android.tools.r8.diagnostic.internal.DefinitionContextUtils;
 import com.android.tools.r8.diagnostic.internal.MissingClassInfoImpl;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
 import com.android.tools.r8.diagnostic.internal.MissingDefinitionsDiagnosticImpl;
 import com.android.tools.r8.errors.dontwarn.DontWarnConfiguration;
 import com.android.tools.r8.graph.AppView;
@@ -147,7 +147,7 @@
                 MissingClassInfoImpl.builder().setClass(missingClass.asClassReference());
             for (ProgramDerivedContext programDerivedContext : programDerivedContexts) {
               missingClassInfoBuilder.addReferencedFromContext(
-                  MissingDefinitionContextUtils.create(programDerivedContext));
+                  DefinitionContextUtils.create(programDerivedContext));
             }
             diagnosticBuilder.addMissingDefinitionInfo(missingClassInfoBuilder.build());
           });
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 2871b74..ff71812 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -81,6 +81,8 @@
   private static final List<String> IGNORED_CLASS_DESCRIPTOR_OPTIONS =
       ImmutableList.of("isclassnamestring", "whyarenotsimple", "convertchecknotnull");
 
+  private static final List<String> IGNORED_RETURN_VALUE_ATTRIBUTES = ImmutableList.of("_NONNULL_");
+
   private static final List<String> WARNED_SINGLE_ARG_OPTIONS = ImmutableList.of(
       // TODO(b/37137994): -outjars should be reported as errors, not just as warnings!
       "outjars");
@@ -588,6 +590,19 @@
           || parseOptimizationOption(optionStart);
     }
 
+    private boolean parseIgnoredReturnValueAttribute() {
+      return Iterables.any(IGNORED_RETURN_VALUE_ATTRIBUTES, this::skipReturnValueAttribute);
+    }
+
+    private boolean parseIgnoredReturnValueAttributes() {
+      boolean anySkipped = false;
+      while (parseIgnoredReturnValueAttribute()) {
+        anySkipped = true;
+        skipWhitespace();
+      }
+      return anySkipped;
+    }
+
     private void parseInclude() throws ProguardRuleParserException {
       TextPosition start = getPosition();
       Path included = parseFileName(false);
@@ -673,6 +688,10 @@
       return false;
     }
 
+    private boolean skipReturnValueAttribute(String name) {
+      return acceptString(name);
+    }
+
     private boolean parseOptimizationOption(TextPosition optionStart)
         throws ProguardRuleParserException {
       if (!acceptString("optimizations")) {
@@ -1317,49 +1336,52 @@
                   // Parse "return ..." if present.
                   if (acceptString("return")) {
                     skipWhitespace();
-                    if (acceptString("true")) {
-                      ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(true));
-                    } else if (acceptString("false")) {
-                      ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(false));
-                    } else if (acceptString("null")) {
-                      ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue());
-                    } else {
-                      TextPosition fieldOrValueStart = getPosition();
-                      String qualifiedFieldNameOrInteger = acceptFieldNameOrIntegerForReturn();
-                      if (qualifiedFieldNameOrInteger != null) {
-                        if (isInteger(qualifiedFieldNameOrInteger)) {
-                          Integer min = Integer.parseInt(qualifiedFieldNameOrInteger);
-                          Integer max = min;
-                          skipWhitespace();
-                          if (acceptString("..")) {
+                    boolean anyReturnValueAttributesSkipped = parseIgnoredReturnValueAttributes();
+                    if (!anyReturnValueAttributesSkipped || !hasNextChar(';')) {
+                      if (acceptString("true")) {
+                        ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(true));
+                      } else if (acceptString("false")) {
+                        ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(false));
+                      } else if (acceptString("null")) {
+                        ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue());
+                      } else {
+                        TextPosition fieldOrValueStart = getPosition();
+                        String qualifiedFieldNameOrInteger = acceptFieldNameOrIntegerForReturn();
+                        if (qualifiedFieldNameOrInteger != null) {
+                          if (isInteger(qualifiedFieldNameOrInteger)) {
+                            Integer min = Integer.parseInt(qualifiedFieldNameOrInteger);
+                            Integer max = min;
                             skipWhitespace();
-                            max = acceptInteger();
-                            if (max == null) {
-                              throw parseError("Expected integer value");
+                            if (acceptString("..")) {
+                              skipWhitespace();
+                              max = acceptInteger();
+                              if (max == null) {
+                                throw parseError("Expected integer value");
+                              }
                             }
-                          }
-                          if (!allowValueSpecification) {
-                            throw parseError("Unexpected value specification", fieldOrValueStart);
-                          }
-                          ruleBuilder.setReturnValue(
-                              new ProguardMemberRuleReturnValue(new LongInterval(min, max)));
-                        } else {
-                          if (ruleBuilder.getTypeMatcher() instanceof MatchSpecificType) {
-                            int lastDotIndex = qualifiedFieldNameOrInteger.lastIndexOf(".");
-                            DexType fieldType = ((MatchSpecificType) ruleBuilder
-                                .getTypeMatcher()).type;
-                            DexType fieldClass =
-                                dexItemFactory.createType(
-                                    javaTypeToDescriptor(
-                                        qualifiedFieldNameOrInteger.substring(0, lastDotIndex)));
-                            DexString fieldName =
-                                dexItemFactory.createString(
-                                    qualifiedFieldNameOrInteger.substring(lastDotIndex + 1));
-                            DexField field = dexItemFactory
-                                .createField(fieldClass, fieldType, fieldName);
-                            ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(field));
+                            if (!allowValueSpecification) {
+                              throw parseError("Unexpected value specification", fieldOrValueStart);
+                            }
+                            ruleBuilder.setReturnValue(
+                                new ProguardMemberRuleReturnValue(new LongInterval(min, max)));
                           } else {
-                            throw parseError("Expected specific type", fieldOrValueStart);
+                            if (ruleBuilder.getTypeMatcher() instanceof MatchSpecificType) {
+                              int lastDotIndex = qualifiedFieldNameOrInteger.lastIndexOf(".");
+                              DexType fieldType =
+                                  ((MatchSpecificType) ruleBuilder.getTypeMatcher()).type;
+                              DexType fieldClass =
+                                  dexItemFactory.createType(
+                                      javaTypeToDescriptor(
+                                          qualifiedFieldNameOrInteger.substring(0, lastDotIndex)));
+                              DexString fieldName =
+                                  dexItemFactory.createString(
+                                      qualifiedFieldNameOrInteger.substring(lastDotIndex + 1));
+                              DexField field =
+                                  dexItemFactory.createField(fieldClass, fieldType, fieldName);
+                              ruleBuilder.setReturnValue(new ProguardMemberRuleReturnValue(field));
+                            } else {
+                              throw parseError("Expected specific type", fieldOrValueStart);
+                            }
                           }
                         }
                       }
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
index 6940f63..d1926db 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesKeepRules.java
@@ -50,7 +50,7 @@
     private boolean allowObfuscation;
 
     /**
-     * Indicate if the generated keep rules should have the <code>allobobfuscation</code> modifier.
+     * Indicate if the generated keep rules should have the <code>allowobfuscation</code> modifier.
      */
     public Builder setAllowObfuscation(boolean value) {
       allowObfuscation = value;
diff --git a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesResult.java b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesResult.java
index e0ce86a..1b16d54 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesResult.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/TraceReferencesResult.java
@@ -34,7 +34,7 @@
     this.keepPackageNames = keepPackageNames;
   }
 
-  static Builder builder() {
+  public static Builder builder() {
     return new Builder();
   }
 
diff --git a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
index 1dc8da6..3e8de35 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
@@ -12,12 +12,12 @@
 import com.android.tools.r8.diagnostic.internal.MissingMethodInfoImpl;
 import com.android.tools.r8.features.ClassToFeatureSplitMap;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndField;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
@@ -38,14 +38,10 @@
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.shaking.MainDexInfo;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.AccessFlags;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.ClassAccessFlags;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.FieldAccessFlags;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.MethodAccessFlags;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedClass;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedField;
-import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedMethod;
 import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedReference;
+import com.android.tools.r8.tracereferences.internal.TracedClassImpl;
+import com.android.tools.r8.tracereferences.internal.TracedFieldImpl;
+import com.android.tools.r8.tracereferences.internal.TracedMethodImpl;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
@@ -54,199 +50,7 @@
 import java.util.Set;
 import java.util.function.Predicate;
 
-class Tracer {
-
-  static class AccessFlagsImpl<T extends com.android.tools.r8.graph.AccessFlags<T>>
-      implements AccessFlags {
-    T accessFlags;
-
-    AccessFlagsImpl(T accessFlags) {
-      this.accessFlags = accessFlags;
-    }
-
-    @Override
-    public boolean isStatic() {
-      return accessFlags.isStatic();
-    }
-
-    @Override
-    public boolean isPublic() {
-      return accessFlags.isPublic();
-    }
-
-    @Override
-    public boolean isProtected() {
-      return accessFlags.isProtected();
-    }
-
-    @Override
-    public boolean isPrivate() {
-      return accessFlags.isPrivate();
-    }
-  }
-
-  static class ClassAccessFlagsImpl
-      extends AccessFlagsImpl<com.android.tools.r8.graph.ClassAccessFlags>
-      implements ClassAccessFlags {
-    ClassAccessFlagsImpl(com.android.tools.r8.graph.ClassAccessFlags accessFlags) {
-      super(accessFlags);
-    }
-
-    @Override
-    public boolean isInterface() {
-      return accessFlags.isInterface();
-    }
-
-    @Override
-    public boolean isEnum() {
-      return accessFlags.isEnum();
-    }
-  }
-
-  static class FieldAccessFlagsImpl
-      extends AccessFlagsImpl<com.android.tools.r8.graph.FieldAccessFlags>
-      implements FieldAccessFlags {
-    FieldAccessFlagsImpl(com.android.tools.r8.graph.FieldAccessFlags accessFlags) {
-      super(accessFlags);
-    }
-  }
-
-  static class MethodAccessFlagsImpl
-      extends AccessFlagsImpl<com.android.tools.r8.graph.MethodAccessFlags>
-      implements MethodAccessFlags {
-    MethodAccessFlagsImpl(com.android.tools.r8.graph.MethodAccessFlags accessFlags) {
-      super(accessFlags);
-    }
-  }
-
-  abstract static class TracedReferenceBase<T, F> implements TracedReference<T, F> {
-    private final T reference;
-    private final F accessFlags;
-    private final boolean missingDefinition;
-
-    private TracedReferenceBase(T reference, F accessFlags, boolean missingDefinition) {
-      assert accessFlags != null || missingDefinition;
-      this.reference = reference;
-      this.accessFlags = accessFlags;
-      this.missingDefinition = missingDefinition;
-    }
-
-    @Override
-    public T getReference() {
-      return reference;
-    }
-
-    @Override
-    public boolean isMissingDefinition() {
-      return missingDefinition;
-    }
-
-    @Override
-    public F getAccessFlags() {
-      return accessFlags;
-    }
-
-    @Override
-    public int hashCode() {
-      // Equality is only based on the reference.
-      return reference.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-      // Equality is only based on the reference.
-      if (!(other instanceof TracedReferenceBase)) {
-        return false;
-      }
-      return reference.equals(((TracedReferenceBase<?, ?>) other).reference);
-    }
-
-    public abstract String getKindName();
-  }
-
-  static class TracedClassImpl extends TracedReferenceBase<ClassReference, ClassAccessFlags>
-      implements TracedClass {
-    private TracedClassImpl(DexType type) {
-      this(type, null);
-    }
-
-    private TracedClassImpl(DexType reference, DexClass definition) {
-      super(
-          reference.asClassReference(),
-          definition != null ? new ClassAccessFlagsImpl(definition.getAccessFlags()) : null,
-          definition == null);
-    }
-
-    private TracedClassImpl(DexClass clazz) {
-      this(clazz.getType(), clazz);
-    }
-
-    @Override
-    public String getKindName() {
-      return "type";
-    }
-
-    @Override
-    public String toString() {
-      return getReference().getTypeName();
-    }
-  }
-
-  static class TracedFieldImpl extends TracedReferenceBase<FieldReference, FieldAccessFlags>
-      implements TracedField {
-    private TracedFieldImpl(DexField field) {
-      this(field, null);
-    }
-
-    private TracedFieldImpl(DexField reference, DexEncodedField definition) {
-      super(
-          reference.asFieldReference(),
-          definition != null ? new FieldAccessFlagsImpl(definition.getAccessFlags()) : null,
-          definition == null);
-    }
-
-    private TracedFieldImpl(DexClassAndField field) {
-      this(field.getReference(), field.getDefinition());
-    }
-
-    @Override
-    public String getKindName() {
-      return "field";
-    }
-
-    @Override
-    public String toString() {
-      return getReference().toString();
-    }
-  }
-
-  static class TracedMethodImpl extends TracedReferenceBase<MethodReference, MethodAccessFlags>
-      implements TracedMethod {
-    private TracedMethodImpl(DexMethod reference) {
-      this(reference, null);
-    }
-
-    private TracedMethodImpl(DexMethod reference, DexEncodedMethod definition) {
-      super(
-          reference.asMethodReference(),
-          definition != null ? new MethodAccessFlagsImpl(definition.getAccessFlags()) : null,
-          definition == null);
-    }
-
-    private TracedMethodImpl(DexClassAndMethod method) {
-      this(method.getReference(), method.getDefinition());
-    }
-
-    @Override
-    public String getKindName() {
-      return "method";
-    }
-
-    @Override
-    public String toString() {
-      return getReference().toString();
-    }
-  }
+public class Tracer {
 
   private final AppInfoWithClassHierarchy appInfo;
   private final DiagnosticsHandler diagnostics;
@@ -269,6 +73,18 @@
         type -> targetDescriptors.contains(type.toDescriptorString()));
   }
 
+  public Tracer(
+      AppView<? extends AppInfoWithClassHierarchy> appView,
+      DiagnosticsHandler diagnostics,
+      Predicate<DexType> targetPredicate) {
+    this(
+        appView.appInfo(),
+        diagnostics,
+        appView.graphLens(),
+        appView.initClassLens(),
+        targetPredicate);
+  }
+
   private Tracer(
       AppInfoWithClassHierarchy appInfo,
       DiagnosticsHandler diagnostics,
@@ -282,7 +98,7 @@
     this.targetPredicate = targetPredicate;
   }
 
-  void run(TraceReferencesConsumer consumer) {
+  public void run(TraceReferencesConsumer consumer) {
     UseCollector useCollector = new UseCollector(appInfo, consumer, diagnostics, targetPredicate);
     for (DexProgramClass clazz : appInfo.classes()) {
       useCollector.registerSuperType(clazz, clazz.superType);
@@ -389,7 +205,7 @@
       }
     }
 
-    private <R, T extends TracedReferenceBase<R, ?>> void collectMissing(
+    private <R, T extends TracedReference<R, ?>> void collectMissing(
         T tracedReference, Set<R> missingCollection) {
       if (tracedReference.isMissingDefinition()) {
         missingCollection.add(tracedReference.getReference());
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/AccessFlagsImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/AccessFlagsImpl.java
new file mode 100644
index 0000000..978e1c2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/AccessFlagsImpl.java
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.AccessFlags;
+
+public class AccessFlagsImpl<T extends com.android.tools.r8.graph.AccessFlags<T>>
+    implements AccessFlags {
+  T accessFlags;
+
+  AccessFlagsImpl(T accessFlags) {
+    this.accessFlags = accessFlags;
+  }
+
+  @Override
+  public boolean isStatic() {
+    return accessFlags.isStatic();
+  }
+
+  @Override
+  public boolean isPublic() {
+    return accessFlags.isPublic();
+  }
+
+  @Override
+  public boolean isProtected() {
+    return accessFlags.isProtected();
+  }
+
+  @Override
+  public boolean isPrivate() {
+    return accessFlags.isPrivate();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/ClassAccessFlagsImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/ClassAccessFlagsImpl.java
new file mode 100644
index 0000000..a5753d2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/ClassAccessFlagsImpl.java
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.ClassAccessFlags;
+
+public class ClassAccessFlagsImpl
+    extends AccessFlagsImpl<com.android.tools.r8.graph.ClassAccessFlags>
+    implements ClassAccessFlags {
+  ClassAccessFlagsImpl(com.android.tools.r8.graph.ClassAccessFlags accessFlags) {
+    super(accessFlags);
+  }
+
+  @Override
+  public boolean isInterface() {
+    return accessFlags.isInterface();
+  }
+
+  @Override
+  public boolean isEnum() {
+    return accessFlags.isEnum();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/FieldAccessFlagsImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/FieldAccessFlagsImpl.java
new file mode 100644
index 0000000..012f3c0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/FieldAccessFlagsImpl.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.FieldAccessFlags;
+
+public class FieldAccessFlagsImpl
+    extends AccessFlagsImpl<com.android.tools.r8.graph.FieldAccessFlags>
+    implements FieldAccessFlags {
+  FieldAccessFlagsImpl(com.android.tools.r8.graph.FieldAccessFlags accessFlags) {
+    super(accessFlags);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/MethodAccessFlagsImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/MethodAccessFlagsImpl.java
new file mode 100644
index 0000000..2f0fa66
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/MethodAccessFlagsImpl.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.MethodAccessFlags;
+
+public class MethodAccessFlagsImpl
+    extends AccessFlagsImpl<com.android.tools.r8.graph.MethodAccessFlags>
+    implements MethodAccessFlags {
+  MethodAccessFlagsImpl(com.android.tools.r8.graph.MethodAccessFlags accessFlags) {
+    super(accessFlags);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedClassImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedClassImpl.java
new file mode 100644
index 0000000..fd9a353
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedClassImpl.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.ClassAccessFlags;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedClass;
+
+public class TracedClassImpl extends TracedReferenceBase<ClassReference, ClassAccessFlags>
+    implements TracedClass {
+  public TracedClassImpl(DexType type) {
+    this(type.asClassReference(), null);
+  }
+
+  public TracedClassImpl(DexClass clazz) {
+    this(clazz.getClassReference(), new ClassAccessFlagsImpl(clazz.getAccessFlags()));
+  }
+
+  public TracedClassImpl(ClassReference classReference, ClassAccessFlags accessFlags) {
+    super(classReference, accessFlags, accessFlags == null);
+  }
+
+  @Override
+  public String toString() {
+    return getReference().getTypeName();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedFieldImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedFieldImpl.java
new file mode 100644
index 0000000..9c6ac2d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedFieldImpl.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.graph.DexClassAndField;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.references.FieldReference;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.FieldAccessFlags;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedField;
+
+public class TracedFieldImpl extends TracedReferenceBase<FieldReference, FieldAccessFlags>
+    implements TracedField {
+  public TracedFieldImpl(DexField field) {
+    this(field.asFieldReference(), null);
+  }
+
+  public TracedFieldImpl(DexClassAndField field) {
+    this(field.getFieldReference(), new FieldAccessFlagsImpl(field.getAccessFlags()));
+  }
+
+  public TracedFieldImpl(FieldReference fieldReference, FieldAccessFlags accessFlags) {
+    super(fieldReference, accessFlags, accessFlags == null);
+  }
+
+  @Override
+  public String toString() {
+    return getReference().toString();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java
new file mode 100644
index 0000000..c12cbd4
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedMethodImpl.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.MethodAccessFlags;
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedMethod;
+
+public class TracedMethodImpl extends TracedReferenceBase<MethodReference, MethodAccessFlags>
+    implements TracedMethod {
+  public TracedMethodImpl(DexMethod method) {
+    this(method.asMethodReference(), null);
+  }
+
+  public TracedMethodImpl(DexClassAndMethod method) {
+    this(method.getMethodReference(), new MethodAccessFlagsImpl(method.getAccessFlags()));
+  }
+
+  public TracedMethodImpl(MethodReference methodReference, MethodAccessFlags accessFlags) {
+    super(methodReference, accessFlags, accessFlags == null);
+  }
+
+  @Override
+  public String toString() {
+    return getReference().toString();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/internal/TracedReferenceBase.java b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedReferenceBase.java
new file mode 100644
index 0000000..254048b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/tracereferences/internal/TracedReferenceBase.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.tracereferences.internal;
+
+import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedReference;
+
+abstract class TracedReferenceBase<T, F> implements TracedReference<T, F> {
+  private final T reference;
+  private final F accessFlags;
+  private final boolean missingDefinition;
+
+  TracedReferenceBase(T reference, F accessFlags, boolean missingDefinition) {
+    assert accessFlags != null || missingDefinition;
+    this.reference = reference;
+    this.accessFlags = accessFlags;
+    this.missingDefinition = missingDefinition;
+  }
+
+  @Override
+  public T getReference() {
+    return reference;
+  }
+
+  @Override
+  public boolean isMissingDefinition() {
+    return missingDefinition;
+  }
+
+  @Override
+  public F getAccessFlags() {
+    return accessFlags;
+  }
+
+  @Override
+  public int hashCode() {
+    // Equality is only based on the reference.
+    return reference.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    // Equality is only based on the reference.
+    if (!(other instanceof TracedReferenceBase)) {
+      return false;
+    }
+    return reference.equals(((TracedReferenceBase<?, ?>) other).reference);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/ClassReferenceUtils.java b/src/main/java/com/android/tools/r8/utils/ClassReferenceUtils.java
index fa2a18c..30754f0 100644
--- a/src/main/java/com/android/tools/r8/utils/ClassReferenceUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ClassReferenceUtils.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.utils;
 
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
@@ -33,4 +35,8 @@
   public static Comparator<ClassReference> getClassReferenceComparator() {
     return COMPARATOR;
   }
+
+  public static DexType toDexType(ClassReference classReference, DexItemFactory dexItemFactory) {
+    return dexItemFactory.createType(classReference.getDescriptor());
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index d868ed1..ff812b6 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1325,6 +1325,7 @@
     public boolean enableSwitchToIfRewriting = true;
     public boolean enableEnumUnboxingDebugLogs = false;
     public boolean forceRedundantConstNumberRemoval = false;
+    public boolean enableExperimentalDesugaredLibraryKeepRuleGenerator = false;
     public boolean enableExperimentalRecordDesugaring = false;
     public boolean invertConditionals = false;
     public boolean placeExceptionalBlocksLast = false;
@@ -1560,7 +1561,11 @@
     return !isDesugaring() || hasMinApi(AndroidApiLevel.K);
   }
 
-  public boolean canUseRequireNonNull() {
+  public boolean canUseJavaUtilObjectsIsNull() {
+    return isGeneratingDex() && hasMinApi(AndroidApiLevel.N);
+  }
+
+  public boolean canUseJavaUtilObjectsRequireNonNull() {
     return isGeneratingDex() && hasMinApi(AndroidApiLevel.K);
   }
 
diff --git a/src/main/java/com/android/tools/r8/utils/NopDiagnosticsHandler.java b/src/main/java/com/android/tools/r8/utils/NopDiagnosticsHandler.java
new file mode 100644
index 0000000..1487bd3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/NopDiagnosticsHandler.java
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.DiagnosticsLevel;
+
+public class NopDiagnosticsHandler implements DiagnosticsHandler {
+
+  @Override
+  public void error(Diagnostic error) {
+    // Intentionally empty.
+  }
+
+  @Override
+  public void warning(Diagnostic warning) {
+    // Intentionally empty.
+  }
+
+  @Override
+  public void info(Diagnostic info) {
+    // Intentionally empty.
+  }
+
+  @Override
+  public DiagnosticsLevel modifyDiagnosticsLevel(DiagnosticsLevel level, Diagnostic diagnostic) {
+    return level;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java b/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
index 15344f9..20f1e99 100644
--- a/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/TypeReferenceUtils.java
@@ -4,8 +4,17 @@
 
 package com.android.tools.r8.utils;
 
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.references.ArrayReference;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.PrimitiveReference;
 import com.android.tools.r8.references.TypeReference;
 import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
 
 public class TypeReferenceUtils {
 
@@ -27,4 +36,70 @@
   public static Comparator<TypeReference> getTypeReferenceComparator() {
     return COMPARATOR;
   }
+
+  /**
+   * Converts the given {@param formalTypes} and {@param returnType} to a {@link DexProto}.
+   *
+   * @param classReferenceConverter is used to convert {@link ClassReference} instances into {@link
+   *     DexType}, to allow caching of intermediate results at the call site.
+   */
+  public static DexProto toDexProto(
+      List<TypeReference> formalTypes,
+      TypeReference returnType,
+      DexItemFactory dexItemFactory,
+      Function<ClassReference, DexType> classReferenceConverter) {
+    return dexItemFactory.createProto(
+        toDexType(returnType, dexItemFactory, classReferenceConverter),
+        ListUtils.map(
+            formalTypes,
+            formalType -> toDexType(formalType, dexItemFactory, classReferenceConverter)));
+  }
+
+  /**
+   * Converts the given {@param typeReference} to a {@link DexType}.
+   *
+   * @param classReferenceConverter is used to convert {@link ClassReference} instances into {@link
+   *     DexType}, to allow caching of intermediate results at the call site.
+   */
+  public static DexType toDexType(
+      TypeReference typeReference,
+      DexItemFactory dexItemFactory,
+      Function<ClassReference, DexType> classReferenceConverter) {
+    if (typeReference == null) {
+      return null;
+    }
+    if (typeReference.isPrimitive()) {
+      PrimitiveReference primitiveReference = typeReference.asPrimitive();
+      switch (primitiveReference.getDescriptor().charAt(0)) {
+        case 'Z':
+          return dexItemFactory.booleanType;
+        case 'B':
+          return dexItemFactory.byteType;
+        case 'C':
+          return dexItemFactory.charType;
+        case 'S':
+          return dexItemFactory.shortType;
+        case 'I':
+          return dexItemFactory.intType;
+        case 'F':
+          return dexItemFactory.floatType;
+        case 'J':
+          return dexItemFactory.longType;
+        case 'D':
+          return dexItemFactory.doubleType;
+        default:
+          throw new Unreachable(
+              "Invalid primitive descriptor: " + primitiveReference.getDescriptor());
+      }
+    }
+    if (typeReference.isArray()) {
+      ArrayReference arrayReference = typeReference.asArray();
+      TypeReference baseType = arrayReference.getBaseType();
+      return dexItemFactory.createArrayType(
+          arrayReference.getDimensions(),
+          toDexType(baseType, dexItemFactory, classReferenceConverter));
+    }
+    assert typeReference.isClass();
+    return classReferenceConverter.apply(typeReference.asClass());
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 0577d2f..79bfbde 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -1754,7 +1754,12 @@
         || parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.K);
   }
 
-  public static boolean canUseRequireNonNull(TestParameters parameters) {
+  public static boolean canUseJavaUtilObjectsIsNull(TestParameters parameters) {
+    return parameters.isDexRuntime()
+        && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N);
+  }
+
+  public static boolean canUseJavaUtilObjectsRequireNonNull(TestParameters parameters) {
     return parameters.isDexRuntime()
         && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.K);
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
index efddc67..3e89a4f 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ObjectsTest.java
@@ -526,22 +526,22 @@
       // Android K methods.
       objectsCompare("b", "a");
       objectsDeepEquals(args, new Object());
-      objectsEquals(args, new Object());
+      objectsEquals(makeNullable(args), new Object());
       objectsHash(1, 2);
       objectsHashCode(4);
-      objectsRequireNonNull(System.currentTimeMillis() >= 0 ? null : new Object());
+      objectsRequireNonNull(getNonNullableNull());
       objectsRequireNonNullWithMessage(null, "Was null");
       if (objectsRequireNonNullWithSupplierSupported) {
         objectsRequireNonNullWithSupplier(null, () -> "Supplier said was null");
       } else {
         System.out.println("Not supported (b/174840626)");
       }
-      objectsToString("5");
-      objectsToStringWithNullDefault(null, "6");
+      objectsToString(makeNullable("5"));
+      objectsToStringWithNullDefault(getNonNullableNull(), "6");
 
       // Android N methods.
-      objectsIsNull(null);
-      objectsNonNull(null);
+      objectsIsNull(getNonNullableNull());
+      objectsNonNull(getNonNullableNull());
 
       // Android R methods.
       Class<?> c = Class.forName("AndroidRUtilsObjectsMethods");
@@ -553,6 +553,14 @@
       c.getDeclaredMethod("requireNonNullElse", Object.class, Object.class).invoke(null, null, 4);
       // TODO(b/174840626) Also support requireNonNullElseGet.
     }
+
+    private static Object makeNullable(Object obj) {
+      return System.currentTimeMillis() > 0 ? obj : null;
+    }
+
+    private static Object getNonNullableNull() {
+      return System.currentTimeMillis() > 0 ? null : new Object();
+    }
   }
 
   /*
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
index 4178db4..f058329 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
@@ -7,35 +7,35 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
-import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.DefinitionClassContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionFieldContext;
+import com.android.tools.r8.diagnostic.DefinitionMethodContext;
 
 public class FoundMissingDefinitionContextSubject {
 
-  private final MissingDefinitionContext context;
+  private final DefinitionContext context;
 
-  public FoundMissingDefinitionContextSubject(MissingDefinitionContext context) {
+  public FoundMissingDefinitionContextSubject(DefinitionContext context) {
     this.context = context;
   }
 
   public FoundMissingDefinitionContextSubject assertEqualTo(
-      MissingDefinitionClassContext expectedContext) {
+      DefinitionClassContext expectedContext) {
     assertTrue(context.isClassContext());
     assertEquals(expectedContext.getClassReference(), context.asClassContext().getClassReference());
     return this;
   }
 
   public FoundMissingDefinitionContextSubject assertEqualTo(
-      MissingDefinitionFieldContext expectedContext) {
+      DefinitionFieldContext expectedContext) {
     assertTrue(context.isFieldContext());
     assertEquals(expectedContext.getFieldReference(), context.asFieldContext().getFieldReference());
     return this;
   }
 
   public FoundMissingDefinitionContextSubject assertEqualTo(
-      MissingDefinitionMethodContext expectedContext) {
+      DefinitionMethodContext expectedContext) {
     assertTrue(context.isMethodContext());
     assertEquals(
         expectedContext.getMethodReference(), context.asMethodContext().getMethodReference());
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
index 89a5db5..2fc9bfa 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
@@ -7,9 +7,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
+import com.android.tools.r8.diagnostic.internal.DefinitionContextUtils;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
@@ -34,7 +34,7 @@
         .getReferencedFromContexts()
         .forEach(
             context ->
-                MissingDefinitionContextUtils.accept(
+                DefinitionContextUtils.accept(
                     context,
                     classContext ->
                         classContexts.put(
@@ -51,11 +51,11 @@
   }
 
   public FoundMissingDefinitionInfoSubject assertExactContexts(
-      List<MissingDefinitionContext> expectedContexts) {
+      List<DefinitionContext> expectedContexts) {
     assertEquals(expectedContexts.size(), missingDefinitionInfo.getReferencedFromContexts().size());
     expectedContexts.forEach(
         expectedContext ->
-            MissingDefinitionContextUtils.accept(
+            DefinitionContextUtils.accept(
                 expectedContext,
                 expectedClassContext -> {
                   FoundMissingDefinitionContextSubject subject =
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
index 28c8fbd..990d480 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
@@ -9,8 +9,8 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ThrowableConsumer;
+import com.android.tools.r8.diagnostic.DefinitionContext;
 import com.android.tools.r8.diagnostic.MissingClassInfo;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
 import com.android.tools.r8.diagnostic.MissingFieldInfo;
@@ -66,12 +66,12 @@
   }
 
   public FoundMissingDefinitionsDiagnosticSubject assertIsMissingClassWithExactContexts(
-      ClassReference classReference, MissingDefinitionContext... expectedContexts) {
+      ClassReference classReference, DefinitionContext... expectedContexts) {
     return assertIsMissingClassWithExactContexts(classReference, Arrays.asList(expectedContexts));
   }
 
   public FoundMissingDefinitionsDiagnosticSubject assertIsMissingClassWithExactContexts(
-      ClassReference classReference, List<MissingDefinitionContext> expectedContexts) {
+      ClassReference classReference, List<DefinitionContext> expectedContexts) {
     return inspectMissingClassInfo(
         classReference,
         missingClassInfoSubject -> missingClassInfoSubject.assertExactContexts(expectedContexts));
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/SyntheticInlineNullCheckPositionTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/SyntheticInlineNullCheckPositionTest.java
index 4eadc56..b5588bd 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/SyntheticInlineNullCheckPositionTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/SyntheticInlineNullCheckPositionTest.java
@@ -71,7 +71,7 @@
         .assertFailureWithErrorThatThrows(NullPointerException.class)
         .inspectStackTrace(
             stackTrace -> {
-              if (canUseRequireNonNull(parameters)) {
+              if (canUseJavaUtilObjectsIsNull(parameters)) {
                 assertThat(
                     stackTrace,
                     isSameExceptForSpecificLineNumber(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsEqualsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsEqualsTest.java
new file mode 100644
index 0000000..109c991
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsEqualsTest.java
@@ -0,0 +1,123 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithHolderAndName;
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.notIf;
+import static com.android.tools.r8.utils.codeinspector.Matchers.onlyIf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+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.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsEqualsTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withDexRuntimes()
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.K)
+        .build();
+  }
+
+  public ObjectsEqualsTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentsMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArguments");
+              assertThat(testNonNullArgumentsMethodSubject, isPresent());
+              assertThat(
+                  testNonNullArgumentsMethodSubject,
+                  not(invokesMethodWithHolderAndName("java.util.Objects", "equals")));
+              assertThat(
+                  testNonNullArgumentsMethodSubject,
+                  invokesMethodWithHolderAndName("java.lang.Object", "equals"));
+
+              MethodSubject testNullAndNullArgumentsMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullAndNullArguments");
+              assertThat(testNullAndNullArgumentsMethodSubject, isPresent());
+              assertThat(
+                  testNullAndNullArgumentsMethodSubject, not(invokesMethodWithName("equals")));
+
+              MethodSubject testNullAndNonNullArgumentsMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullAndNonNullArguments");
+              assertThat(testNullAndNonNullArgumentsMethodSubject, isPresent());
+              assertThat(
+                  testNullAndNonNullArgumentsMethodSubject, not(invokesMethodWithName("equals")));
+
+              MethodSubject testNullAndMaybeNullArgumentsMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullAndMaybeNullArguments");
+              assertThat(testNullAndMaybeNullArgumentsMethodSubject, isPresent());
+              assertThat(
+                  testNullAndMaybeNullArgumentsMethodSubject,
+                  notIf(invokesMethodWithName("equals"), canUseJavaUtilObjectsIsNull(parameters)));
+              assertThat(
+                  testNullAndMaybeNullArgumentsMethodSubject,
+                  onlyIf(canUseJavaUtilObjectsIsNull(parameters), invokesMethodWithName("isNull")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("false", "true", "false", "false");
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArguments();
+      testNullAndNullArguments();
+      testNullAndNonNullArguments();
+      testNullAndMaybeNullArguments();
+    }
+
+    @NeverInline
+    static void testNonNullArguments() {
+      System.out.println(Objects.equals(new Object(), new Object()));
+    }
+
+    @NeverInline
+    static void testNullAndNullArguments() {
+      System.out.println(Objects.equals(null, null));
+    }
+
+    @NeverInline
+    static void testNullAndNonNullArguments() {
+      System.out.println(Objects.equals(null, new Object()));
+    }
+
+    @NeverInline
+    static void testNullAndMaybeNullArguments() {
+      System.out.println(
+          Objects.equals(null, System.currentTimeMillis() > 0 ? new Object() : null));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsHashCodeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsHashCodeTest.java
new file mode 100644
index 0000000..8ed1eac
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsHashCodeTest.java
@@ -0,0 +1,95 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithHolderAndName;
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsHashCodeTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public ObjectsHashCodeTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableNeverClassInliningAnnotations()
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(
+                  testNonNullArgumentMethodSubject,
+                  not(invokesMethodWithHolderAndName("java.util.Objects", "hashCode")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(testNullArgumentMethodSubject, not(invokesMethodWithName("hashCode")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("42", "0");
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Objects.hashCode(new A()));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Objects.hashCode(null));
+    }
+  }
+
+  @NeverClassInline
+  static class A {
+
+    @Override
+    public int hashCode() {
+      return System.currentTimeMillis() > 0 ? 42 : -1;
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsIsNullTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsIsNullTest.java
new file mode 100644
index 0000000..6064fec
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsIsNullTest.java
@@ -0,0 +1,81 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsIsNullTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public ObjectsIsNullTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(testNonNullArgumentMethodSubject, not(invokesMethodWithName("isNull")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(testNullArgumentMethodSubject, not(invokesMethodWithName("isNull")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("false", "true");
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Objects.isNull(new Object()));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Objects.isNull(null));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsNonNullTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsNonNullTest.java
new file mode 100644
index 0000000..d4b4d35
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsNonNullTest.java
@@ -0,0 +1,81 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsNonNullTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public ObjectsNonNullTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(testNonNullArgumentMethodSubject, not(invokesMethodWithName("nonNull")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(testNullArgumentMethodSubject, not(invokesMethodWithName("nonNull")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("true", "false");
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Objects.nonNull(new Object()));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Objects.nonNull(null));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseGetTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseGetTest.java
new file mode 100644
index 0000000..e0a4c6d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseGetTest.java
@@ -0,0 +1,106 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+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.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.function.Supplier;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsRequireNonNullElseGetTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withDexRuntimes()
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.N)
+        .build();
+  }
+
+  public ObjectsRequireNonNullElseGetTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(getProgramClassFileData())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(
+                  testNonNullArgumentMethodSubject,
+                  not(invokesMethodWithName("requireNonNullElseGet")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(
+                  testNullArgumentMethodSubject,
+                  not(invokesMethodWithName("requireNonNullElseGet")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("Foo", "Bar");
+  }
+
+  private byte[] getProgramClassFileData() throws IOException {
+    return transformer(Main.class)
+        .replaceClassDescriptorInMethodInstructions(
+            descriptor(Mock.class), descriptor(Objects.class))
+        .transform();
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Mock.requireNonNullElseGet("Foo", null));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Mock.requireNonNullElseGet(null, () -> "Bar"));
+    }
+  }
+
+  // References to this class are rewritten to java.util.Objects by transformation.
+  static class Mock {
+
+    public static Object requireNonNullElseGet(Object obj, Supplier<?> supplier) {
+      throw new RuntimeException();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseTest.java
new file mode 100644
index 0000000..39acb1e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsRequireNonNullElseTest.java
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.io.IOException;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsRequireNonNullElseTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
+  }
+
+  public ObjectsRequireNonNullElseTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(getProgramClassFileData())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(
+                  testNonNullArgumentMethodSubject,
+                  not(invokesMethodWithName("requireNonNullElse")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(
+                  testNullArgumentMethodSubject, not(invokesMethodWithName("requireNonNullElse")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("Foo", "Bar");
+  }
+
+  private byte[] getProgramClassFileData() throws IOException {
+    return transformer(Main.class)
+        .replaceClassDescriptorInMethodInstructions(
+            descriptor(Mock.class), descriptor(Objects.class))
+        .transform();
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Mock.requireNonNullElse("Foo", ":-("));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Mock.requireNonNullElse(null, "Bar"));
+    }
+  }
+
+  // References to this class are rewritten to java.util.Objects by transformation.
+  static class Mock {
+
+    public static Object requireNonNullElse(Object obj, Object defaultObj) {
+      throw new RuntimeException();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsToStringWithNullDefaultTest.java b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsToStringWithNullDefaultTest.java
new file mode 100644
index 0000000..fe974a5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/library/ObjectsToStringWithNullDefaultTest.java
@@ -0,0 +1,86 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.library;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+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.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ObjectsToStringWithNullDefaultTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withCfRuntimes()
+        .withDexRuntimes()
+        .withApiLevelsStartingAtIncluding(AndroidApiLevel.K)
+        .build();
+  }
+
+  public ObjectsToStringWithNullDefaultTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject testNonNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNonNullArgument");
+              assertThat(testNonNullArgumentMethodSubject, isPresent());
+              assertThat(testNonNullArgumentMethodSubject, not(invokesMethodWithName("toString")));
+
+              MethodSubject testNullArgumentMethodSubject =
+                  mainClassSubject.uniqueMethodWithName("testNullArgument");
+              assertThat(testNullArgumentMethodSubject, isPresent());
+              assertThat(testNullArgumentMethodSubject, not(invokesMethodWithName("toString")));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("Foo", "Bar");
+  }
+
+  static class Main {
+
+    public static void main(String[] args) {
+      testNonNullArgument();
+      testNullArgument();
+    }
+
+    @NeverInline
+    static void testNonNullArgument() {
+      System.out.println(Objects.toString("Foo", ":-("));
+    }
+
+    @NeverInline
+    static void testNullArgument() {
+      System.out.println(Objects.toString(null, "Bar"));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/AssumeInstanceFieldValueTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/AssumeInstanceFieldValueTest.java
index f975e36..18618ca 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/AssumeInstanceFieldValueTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/AssumeInstanceFieldValueTest.java
@@ -70,7 +70,7 @@
 
     MethodSubject mainMethodSubject = testClassSubject.mainMethod();
     assertThat(mainMethodSubject, isPresent());
-    if (canUseRequireNonNull(parameters)) {
+    if (canUseJavaUtilObjectsIsNull(parameters)) {
       assertThat(mainMethodSubject, invokesMethodWithName("requireNonNull"));
     } else {
       assertThat(mainMethodSubject, invokesMethodWithName("getClass"));
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
index f45220d..11bc862 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromCatchHandlerTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
index 37df585..773261d 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromCheckCastTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
index d114dc02..cfb378f 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
@@ -17,8 +17,8 @@
 //  we retain missing annotations even if there is no -keepattributes *Annotations*.
 public class MissingClassReferencedFromClassAnnotationTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
index 10663fa..3499bdb 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.Reference;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -18,8 +18,8 @@
 
 public class MissingClassReferencedFromClassAnnotationWithDataTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
index 94550b8..3cdf187 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromConstClassTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
index 40408ee..da337fd 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.R8TestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -22,8 +22,8 @@
 
 public class MissingClassReferencedFromEnclosingMethodAttributeTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(getMainClass()))
           .setOrigin(getOrigin(getMainClass()))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
index 7638885..71e9638 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.FieldReferenceUtils;
@@ -18,8 +18,8 @@
 //  we retain missing annotations even if there is no -keepattributes *Annotations*.
 public class MissingClassReferencedFromFieldAnnotationTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
index 51da805..e221fbe 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
@@ -8,16 +8,16 @@
 import com.android.tools.r8.TestCompilerBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
 
 public class MissingClassReferencedFromImplementsClauseTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
index f421eb1..ce77469 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.R8TestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -22,8 +22,8 @@
 
 public class MissingClassReferencedFromInnerClassAttributeTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
index 1ce5f9f..f2803fc 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInstanceGetToExistingFieldTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "field"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
index f367fed..49105ae 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInstanceGetToMissingFieldTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
index 7ec1e09..7059a7d 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromInstanceOfTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
index 1f0e5a7..21e65c8 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInstancePutToExistingFieldTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "field"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
index b4dd5a1..687aa72 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInstancePutToMissingFieldTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
index 31e1942..1d7d4ca 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -24,8 +24,8 @@
 public class MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
index 4c62ad2..b997418 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -24,8 +24,8 @@
 public class MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
index 28c1a79..9930828 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Main.class, "get", MissingClass.class))
           .setOrigin(getOrigin(Main.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
index 396117f..49f5b94 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,8 +19,8 @@
 public class MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Main.class, "get"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
index c212d86..9c82922 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
@@ -8,16 +8,16 @@
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
 /** If a field definition refers to a missing class, then the field definition is to be blamed. */
 public class MissingClassReferencedFromKeptFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
index fc2d8d3..ba2d1eb 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
@@ -8,16 +8,16 @@
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 /** If a method definition refers to a missing class, then the method definition is to be blamed. */
 public class MissingClassReferencedFromKeptMethodParameterTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Main.class, "get", MissingClass.class))
           .setOrigin(getOrigin(Main.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
index 6dc3edb..dc940b2 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
@@ -8,16 +8,16 @@
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 /** If a method definition refers to a missing class, then the method definition is to be blamed. */
 public class MissingClassReferencedFromKeptMethodReturnTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Main.class, "get"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
index 860bce2..e3e4d0f 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
@@ -11,15 +11,15 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryInstanceFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Library.class, "field"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
index c5c7950..87ccb41 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
@@ -11,15 +11,15 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryStaticFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Library.class, "field"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
index 4a56add..654ae54 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
@@ -11,16 +11,16 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryVirtualMethodParameterTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Library.class, "method", MissingClass.class))
           .setOrigin(getOrigin(Library.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
index 5c627ef..1e659de 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
@@ -11,16 +11,16 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryVirtualMethodReturnTest
     extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Library.class, "method"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
index 5130304..b4c5a43 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
@@ -18,8 +18,8 @@
 //  we retain missing annotations even if there is no -keepattributes *Annotations*.
 public class MissingClassReferencedFromMethodAnnotationTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
index 194e12d..da8c6cb 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.missingclasses.MissingClassReferencedFromNestHostAttributeTest.MissingClass.Main;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
@@ -21,8 +21,8 @@
 
 public class MissingClassReferencedFromNestHostAttributeTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
index 540620e..ae99dbc 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.google.common.collect.ImmutableList;
@@ -20,8 +20,8 @@
 
 public class MissingClassReferencedFromNestMemberAttributeTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
index 003b28e..2e047e5 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromNewArrayTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
index ee919b2..274e3d0 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
@@ -7,15 +7,15 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromNewInstanceTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
index 21d5683..38b464d 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.R8TestBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.missingclasses.MissingClassReferencedFromOuterClassAttributeTest.MissingClass.Main;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
@@ -23,8 +23,8 @@
 
 public class MissingClassReferencedFromOuterClassAttributeTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
index a5b5432..021991f 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
@@ -18,8 +18,8 @@
 //  we retain missing annotations even if there is no -keepattributes *Annotations*.
 public class MissingClassReferencedFromParameterAnnotationTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
index 332da9c..d870671 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -18,8 +18,8 @@
  */
 public class MissingClassReferencedFromStaticGetToExistingFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
index 9028167..52944a8 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -18,8 +18,8 @@
  */
 public class MissingClassReferencedFromStaticGetToMissingFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
index cbbd217..3b0f099 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -18,8 +18,8 @@
  */
 public class MissingClassReferencedFromStaticPutToExistingFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
index e1ba4c6..b8488cc 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -18,8 +18,8 @@
  */
 public class MissingClassReferencedFromStaticPutToMissingFieldTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
index 79cff47..651b6dd 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
@@ -8,15 +8,15 @@
 import com.android.tools.r8.TestCompilerBuilder;
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionClassContextImpl;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
 
 public class MissingClassReferencedFromSuperClassTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
index 275e6f2..f5fd22e 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
@@ -8,15 +8,15 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestShrinkerBuilder;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromThrowsClauseTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseWithNoShrinkingTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseWithNoShrinkingTest.java
index b9d0ef6..7542952 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseWithNoShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseWithNoShrinkingTest.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.NeverInline;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -21,8 +21,8 @@
   private static final String NEW_A_DESCRIPTOR = "Lfoo/a;";
   private static final String NEW_B_DESCRIPTOR = "Lfoo/b;";
 
-  private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext referencedFrom =
+      DefinitionMethodContextImpl.builder()
           .setMethodContext(
               Reference.method(
                   Reference.classFromDescriptor("Lfoo/a;"), "foo", ImmutableList.of(), null))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
index 31ca7d1..59dea00 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
@@ -20,9 +20,9 @@
 
 public class MissingClassReferencedFromUnusedLambdaParameterTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext[] referencedFrom =
-      new MissingDefinitionContext[] {
-        MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext[] referencedFrom =
+      new DefinitionContext[] {
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -31,7 +31,7 @@
                     null))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build(),
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
index 8859780..c1da466 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.util.Collections;
@@ -20,9 +20,9 @@
 
 public class MissingClassReferencedFromUnusedLambdaReturnTest extends MissingClassesTestBase {
 
-  private static final MissingDefinitionContext[] referencedFrom =
-      new MissingDefinitionContext[] {
-        MissingDefinitionMethodContextImpl.builder()
+  private static final DefinitionContext[] referencedFrom =
+      new DefinitionContext[] {
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -31,7 +31,7 @@
                     Reference.classFromClass(MissingClass.class)))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build(),
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
index a9ece97..eddc508 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
@@ -18,14 +18,14 @@
 
 public class MissingClassReferencedFromUsedLambdaParameterTest extends MissingClassesTestBase {
 
-  private final MissingDefinitionContext[] referencedFrom =
-      new MissingDefinitionContext[] {
-        MissingDefinitionMethodContextImpl.builder()
+  private final DefinitionContext[] referencedFrom =
+      new DefinitionContext[] {
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(
                 MethodReferenceUtils.methodFromMethod(I.class, "m", MissingClass.class))
             .setOrigin(getOrigin(I.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -34,7 +34,7 @@
                     null))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build()
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
index ba46bfc..1d46283 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
@@ -9,8 +9,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.util.Collections;
@@ -18,13 +18,13 @@
 
 public class MissingClassReferencedFromUsedLambdaReturnTest extends MissingClassesTestBase {
 
-  private final MissingDefinitionContext[] referencedFrom =
-      new MissingDefinitionContext[] {
-        MissingDefinitionMethodContextImpl.builder()
+  private final DefinitionContext[] referencedFrom =
+      new DefinitionContext[] {
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.methodFromMethod(I.class, "m"))
             .setOrigin(getOrigin(I.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -33,7 +33,7 @@
                     Reference.classFromClass(MissingClass.class)))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContextImpl.builder()
+        DefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build()
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
index 3022ea4..4dfeca1 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
@@ -13,8 +13,8 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
+import com.android.tools.r8.diagnostic.DefinitionContext;
+import com.android.tools.r8.diagnostic.internal.DefinitionContextUtils;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import java.lang.annotation.Retention;
@@ -101,19 +101,18 @@
   }
 
   void inspectDiagnosticsWithIgnoreWarnings(
-      TestDiagnosticMessages diagnostics, MissingDefinitionContext... referencedFrom) {
+      TestDiagnosticMessages diagnostics, DefinitionContext... referencedFrom) {
     assertTrue(referencedFrom.length > 0);
     inspectDiagnosticsWithIgnoreWarnings(
         diagnostics,
         referencedFrom,
         getExpectedDiagnosticMessage(
-            MissingDefinitionContextUtils.toSourceString(referencedFrom[0]),
-            referencedFrom.length));
+            DefinitionContextUtils.toSourceString(referencedFrom[0]), referencedFrom.length));
   }
 
   void inspectDiagnosticsWithIgnoreWarnings(
       TestDiagnosticMessages diagnostics,
-      MissingDefinitionContext[] referencedFrom,
+      DefinitionContext[] referencedFrom,
       String expectedDiagnosticMessage) {
     diagnostics
         .assertOnlyWarnings()
@@ -132,19 +131,18 @@
   }
 
   void inspectDiagnosticsWithNoRules(
-      TestDiagnosticMessages diagnostics, MissingDefinitionContext... referencedFrom) {
+      TestDiagnosticMessages diagnostics, DefinitionContext... referencedFrom) {
     assertTrue(referencedFrom.length > 0);
     inspectDiagnosticsWithNoRules(
         diagnostics,
         referencedFrom,
         getExpectedDiagnosticMessage(
-            MissingDefinitionContextUtils.toSourceString(referencedFrom[0]),
-            referencedFrom.length));
+            DefinitionContextUtils.toSourceString(referencedFrom[0]), referencedFrom.length));
   }
 
   void inspectDiagnosticsWithNoRules(
       TestDiagnosticMessages diagnostics,
-      MissingDefinitionContext[] referencedFrom,
+      DefinitionContext[] referencedFrom,
       String expectedDiagnosticMessage) {
     diagnostics
         .assertOnlyErrors()
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index f49dc97..c93200c 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -442,8 +442,8 @@
     assertEquals(1, assumeNoSideEffects.size());
     int matches = 0;
     for (ProguardMemberRule rule : assumeNoSideEffects.get(0).getMemberRules()) {
-      assertTrue(rule.hasReturnValue());
       if (rule.getName().matches("returnsTrue") || rule.getName().matches("returnsFalse")) {
+        assertTrue(rule.hasReturnValue());
         assertTrue(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -451,6 +451,7 @@
         assertEquals(rule.getName().matches("returnsTrue"), rule.getReturnValue().getBoolean());
         matches |= 1 << 0;
       } else if (rule.getName().matches("returns1")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -461,6 +462,7 @@
         assertEquals(1, rule.getReturnValue().getSingleValue());
         matches |= 1 << 1;
       } else if (rule.getName().matches("returns2To4")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -470,6 +472,7 @@
         assertEquals(4, rule.getReturnValue().getValueRange().getMax());
         matches |= 1 << 2;
       } else if (rule.getName().matches("returns234To567")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -479,6 +482,7 @@
         assertEquals(567, rule.getReturnValue().getValueRange().getMax());
         matches |= 1 << 3;
       } else if (rule.getName().matches("returnsField")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertTrue(rule.getReturnValue().isField());
@@ -488,17 +492,31 @@
         assertEquals("X", rule.getReturnValue().getField().name.toString());
         matches |= 1 << 4;
       } else if (rule.getName().matches("returnsNull")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
         assertTrue(rule.getReturnValue().isNull());
         assertTrue(rule.getReturnValue().isSingleValue());
         matches |= 1 << 5;
+      } else if (rule.getName().matches("returnsNonNull")) {
+        assertFalse(rule.hasReturnValue());
+        matches |= 1 << 6;
+      } else if (rule.getName().matches("returnsNonNullField")) {
+        assertTrue(rule.hasReturnValue());
+        assertFalse(rule.getReturnValue().isBoolean());
+        assertFalse(rule.getReturnValue().isValueRange());
+        assertTrue(rule.getReturnValue().isField());
+        assertFalse(rule.getReturnValue().isNull());
+        assertEquals("com.google.C", rule.getReturnValue().getField().holder.toString());
+        assertEquals("Object", rule.getReturnValue().getField().type.toString());
+        assertEquals("X", rule.getReturnValue().getField().name.toString());
+        matches |= 1 << 7;
       } else {
         fail("Unexpected");
       }
     }
-    assertEquals((1 << 6) - 1, matches);
+    assertEquals((1 << 8) - 1, matches);
   }
 
   @Test
@@ -511,8 +529,8 @@
     assertEquals(1, assumeValues.size());
     int matches = 0;
     for (ProguardMemberRule rule : assumeValues.get(0).getMemberRules()) {
-      assertTrue(rule.hasReturnValue());
       if (rule.getName().matches("isTrue") || rule.getName().matches("isFalse")) {
+        assertTrue(rule.hasReturnValue());
         assertTrue(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -520,6 +538,7 @@
         assertEquals(rule.getName().matches("isTrue"), rule.getReturnValue().getBoolean());
         matches |= 1 << 0;
       } else if (rule.getName().matches("is1")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -530,6 +549,7 @@
         assertEquals(1, rule.getReturnValue().getSingleValue());
         matches |= 1 << 1;
       } else if (rule.getName().matches("is2To4")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -539,6 +559,7 @@
         assertEquals(4, rule.getReturnValue().getValueRange().getMax());
         matches |= 1 << 2;
       } else if (rule.getName().matches("is234To567")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertTrue(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
@@ -548,6 +569,7 @@
         assertEquals(567, rule.getReturnValue().getValueRange().getMax());
         matches |= 1 << 3;
       } else if (rule.getName().matches("isField")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertTrue(rule.getReturnValue().isField());
@@ -557,17 +579,31 @@
         assertEquals("X", rule.getReturnValue().getField().name.toString());
         matches |= 1 << 4;
       } else if (rule.getName().matches("isNull")) {
+        assertTrue(rule.hasReturnValue());
         assertFalse(rule.getReturnValue().isBoolean());
         assertFalse(rule.getReturnValue().isValueRange());
         assertFalse(rule.getReturnValue().isField());
         assertTrue(rule.getReturnValue().isNull());
         assertTrue(rule.getReturnValue().isSingleValue());
         matches |= 1 << 5;
+      } else if (rule.getName().matches("returnsNonNull")) {
+        assertFalse(rule.hasReturnValue());
+        matches |= 1 << 6;
+      } else if (rule.getName().matches("returnsNonNullField")) {
+        assertTrue(rule.hasReturnValue());
+        assertFalse(rule.getReturnValue().isBoolean());
+        assertFalse(rule.getReturnValue().isValueRange());
+        assertTrue(rule.getReturnValue().isField());
+        assertFalse(rule.getReturnValue().isNull());
+        assertEquals("com.google.C", rule.getReturnValue().getField().holder.toString());
+        assertEquals("Object", rule.getReturnValue().getField().type.toString());
+        assertEquals("X", rule.getReturnValue().getField().name.toString());
+        matches |= 1 << 7;
       } else {
         fail("Unexpected");
       }
     }
-    assertEquals((1 << 6) - 1, matches);
+    assertEquals((1 << 8) - 1, matches);
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeMatchers.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeMatchers.java
index 2b57e91..10a68c1 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeMatchers.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeMatchers.java
@@ -149,6 +149,11 @@
     };
   }
 
+  public static Matcher<MethodSubject> invokesMethodWithHolderAndName(
+      String holderType, String name) {
+    return invokesMethod(null, holderType, name, null);
+  }
+
   public static Matcher<MethodSubject> invokesMethodWithName(String name) {
     return invokesMethod(null, null, name, null);
   }
diff --git a/src/test/proguard/valid/assume-no-side-effects-with-return-value.flags b/src/test/proguard/valid/assume-no-side-effects-with-return-value.flags
index b233ea3..d63e2e1 100644
--- a/src/test/proguard/valid/assume-no-side-effects-with-return-value.flags
+++ b/src/test/proguard/valid/assume-no-side-effects-with-return-value.flags
@@ -10,4 +10,6 @@
     public static int returns234To567() return 234..567;
     public static int returnsField() return com.google.C.X;
     public static Object returnsNull() return null;
+    public static Object returnsNonNull() return _NONNULL_;
+    public static Object returnsNonNullField() return _NONNULL_ com.google.C.X;
 }
diff --git a/src/test/proguard/valid/assume-values-with-return-value.flags b/src/test/proguard/valid/assume-values-with-return-value.flags
index 90cefbe..fdb6a25 100644
--- a/src/test/proguard/valid/assume-values-with-return-value.flags
+++ b/src/test/proguard/valid/assume-values-with-return-value.flags
@@ -10,4 +10,6 @@
     public static final int is234To567() return 234..567;
     public static final int isField() return com.google.C.X;
     public static final Object isNull() return null;
+    public static Object returnsNonNull() return _NONNULL_;
+    public static Object returnsNonNullField() return _NONNULL_ com.google.C.X;
 }
\ No newline at end of file