Merge commit '5f9bf2799edba45cf60bb7bd684f6d19f438a08e' into dev-release

Change-Id: I9604ea001979aeee5ea02c9c7ffeb2483e0b05c5
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index f2dfda6..d6185c6 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -1,5 +1,5 @@
 {
-  "identifier": "com.tools.android:desugar_jdk_libs_configuration:2.1.0",
+  "identifier": "com.tools.android:desugar_jdk_libs_configuration:2.1.1",
   "configuration_format_version": 101,
   "required_compilation_api_level": 30,
   "synthesized_library_classes_package_prefix": "j$.",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json b/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
index 7303240..a576966 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_minimal.json
@@ -1,5 +1,5 @@
 {
-  "identifier": "com.tools.android:desugar_jdk_libs_configuration_minimal:2.1.0",
+  "identifier": "com.tools.android:desugar_jdk_libs_configuration_minimal:2.1.1",
   "configuration_format_version": 101,
   "required_compilation_api_level": 24,
   "synthesized_library_classes_package_prefix": "j$.",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
index 1aff889..19db3fa 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
@@ -1,5 +1,5 @@
 {
-  "identifier": "com.tools.android:desugar_jdk_libs_configuration_nio:2.1.0",
+  "identifier": "com.tools.android:desugar_jdk_libs_configuration_nio:2.1.1",
   "configuration_format_version": 101,
   "required_compilation_api_level": 30,
   "synthesized_library_classes_package_prefix": "j$.",
diff --git a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
index e67c735..ca4321e 100644
--- a/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveProtoAndroidResourceProvider.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.origin.ArchiveEntryOrigin;
 import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.utils.FileUtils;
 import com.google.common.io.ByteStreams;
 import java.io.ByteArrayInputStream;
@@ -49,6 +50,15 @@
     this.origin = origin;
   }
 
+  /**
+   * Creates an android resource provider from an archive.
+   *
+   * @param archive Zip archive to provide resources from.
+   */
+  public ArchiveProtoAndroidResourceProvider(Path archive) {
+    this(archive, new PathOrigin(archive));
+  }
+
   @Override
   public Collection<AndroidResourceInput> getAndroidResources() throws ResourceException {
     try (ZipFile zipFile = FileUtils.createZipFile(archive.toFile(), StandardCharsets.UTF_8)) {
diff --git a/src/main/java/com/android/tools/r8/R8CommandParser.java b/src/main/java/com/android/tools/r8/R8CommandParser.java
index fa0a094..e3d5927 100644
--- a/src/main/java/com/android/tools/r8/R8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/R8CommandParser.java
@@ -308,8 +308,7 @@
       } else if (arg.equals("--android-resources")) {
         Path inputPath = Paths.get(nextArg);
         Path outputPath = Paths.get(nextNextArg);
-        builder.setAndroidResourceProvider(
-            new ArchiveProtoAndroidResourceProvider(inputPath, new PathOrigin(inputPath)));
+        builder.setAndroidResourceProvider(new ArchiveProtoAndroidResourceProvider(inputPath));
         builder.setAndroidResourceConsumer(
             new ArchiveProtoAndroidResourceConsumer(outputPath, inputPath));
       } else if (arg.equals("--feature")) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index fb052fb..fcd5428 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexMethod;
@@ -288,7 +289,7 @@
     public void acceptNestConstructorBridge(
         ProgramMethod target,
         ProgramMethod bridge,
-        DexProgramClass argumentClass,
+        DexClass argumentClass,
         DexClassAndMethod context) {
       // Intentionally empty.
     }
@@ -722,7 +723,7 @@
     public void acceptNestConstructorBridge(
         ProgramMethod target,
         ProgramMethod bridge,
-        DexProgramClass argumentClass,
+        DexClass argumentClass,
         DexClassAndMethod context) {
       // Intentionally empty.
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
index a4465a9..93b2f34 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/D8NestBasedAccessDesugaring.java
@@ -13,7 +13,6 @@
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramField;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.conversion.D8MethodProcessor;
@@ -109,7 +108,7 @@
               public void acceptNestConstructorBridge(
                   ProgramMethod target,
                   ProgramMethod bridge,
-                  DexProgramClass argumentClass,
+                  DexClass argumentClass,
                   DexClassAndMethod context) {
                 methodProcessor.scheduleDesugaredMethodForProcessing(bridge);
               }
@@ -229,8 +228,7 @@
     private void ensureConstructorBridgeFromClasspathAccess(
         ProgramMethod method, NestBasedAccessDesugaringEventConsumer eventConsumer) {
       assert method.getDefinition().isInstanceInitializer();
-      DexProgramClass constructorArgumentClass =
-          ensureConstructorArgumentClass(method).asProgramClass();
+      DexClass constructorArgumentClass = ensureConstructorArgumentClass(method);
       DexMethod bridgeReference = getConstructorBridgeReference(method, constructorArgumentClass);
       synchronized (method.getHolder().getMethodCollection()) {
         if (method.getHolder().lookupMethod(bridgeReference) == null) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
index 10f3501..0550d47 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
@@ -232,7 +232,7 @@
                     : AccessBridgeFactory.createMethodAccessorBridge(
                         bridgeAndTarget.getBridge(), targetMethod, dexItemFactory));
     if (targetMethod.getDefinition().isInstanceInitializer()) {
-      DexProgramClass argumentClass = getConstructorArgumentClass(targetMethod).asProgramClass();
+      DexClass argumentClass = getConstructorArgumentClass(targetMethod);
       eventConsumer.acceptNestConstructorBridge(targetMethod, bridgeMethod, argumentClass, context);
     } else {
       eventConsumer.acceptNestMethodBridge(targetMethod, bridgeMethod, context);
@@ -441,34 +441,70 @@
   }
 
   private DexClass getConstructorArgumentClass(DexClassAndMethod constructor) {
-    return syntheticNestConstructorTypes.get(constructor.getHolderType());
+    if (!appView.options().legacyNestDesugaringIAClasses) {
+      return syntheticNestConstructorTypes.get(constructor.getHolder().getNestHost());
+    } else {
+      return syntheticNestConstructorTypes.get(constructor.getHolderType());
+    }
   }
 
   DexClass ensureConstructorArgumentClass(DexClassAndMethod constructor) {
     assert constructor.getDefinition().isInstanceInitializer();
-    return syntheticNestConstructorTypes.computeIfAbsent(
-        constructor.getHolderType(),
-        holder -> {
-          if (constructor.isProgramMethod()) {
-            return appView
-                .getSyntheticItems()
-                .createFixedClass(
-                    kinds -> kinds.INIT_TYPE_ARGUMENT,
-                    constructor.asProgramMethod().getHolder(),
-                    appView,
-                    builder -> {});
-          } else {
-            assert constructor.isClasspathMethod();
-            return appView
-                .getSyntheticItems()
-                .ensureFixedClasspathClass(
-                    kinds -> kinds.INIT_TYPE_ARGUMENT,
-                    constructor.asClasspathMethod().getHolder(),
-                    appView,
-                    ignored -> {},
-                    ignored -> {});
-          }
-        });
+    assert constructor.isProgramMethod() || constructor.isClasspathMethod();
+    if (!appView.options().legacyNestDesugaringIAClasses) {
+      DexType hostType =
+          constructor.isProgramMethod()
+              ? constructor.asProgramMethod().getHolder().getNestHost()
+              : constructor.asClasspathMethod().getHolder().getNestHost();
+      DexClass host = appView.definitionFor(hostType);
+      return syntheticNestConstructorTypes.computeIfAbsent(
+          hostType,
+          holder -> {
+            if (host.isProgramClass()) {
+              return appView
+                  .getSyntheticItems()
+                  .createFixedClass(
+                      kinds -> kinds.INIT_TYPE_ARGUMENT,
+                      host.asProgramClass(),
+                      appView,
+                      builder -> {});
+            } else {
+              assert host.isClasspathClass();
+              return appView
+                  .getSyntheticItems()
+                  .ensureFixedClasspathClass(
+                      kinds -> kinds.INIT_TYPE_ARGUMENT,
+                      host.asClasspathClass(),
+                      appView,
+                      ignored -> {},
+                      ignored -> {});
+            }
+          });
+    } else {
+      return syntheticNestConstructorTypes.computeIfAbsent(
+          constructor.getHolderType(),
+          holder -> {
+            if (constructor.isProgramMethod()) {
+              return appView
+                  .getSyntheticItems()
+                  .createFixedClass(
+                      kinds -> kinds.INIT_TYPE_ARGUMENT,
+                      constructor.asProgramMethod().getHolder(),
+                      appView,
+                      builder -> {});
+            } else {
+              assert constructor.isClasspathMethod();
+              return appView
+                  .getSyntheticItems()
+                  .ensureFixedClasspathClass(
+                      kinds -> kinds.INIT_TYPE_ARGUMENT,
+                      constructor.asClasspathMethod().getHolder(),
+                      appView,
+                      ignored -> {},
+                      ignored -> {});
+            }
+          });
+    }
   }
 
   DexMethod getConstructorBridgeReference(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaringEventConsumer.java
index afbeedc..8ec49e2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaringEventConsumer.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.ir.desugar.nest;
 
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramField;
 import com.android.tools.r8.graph.ProgramMethod;
 
@@ -14,7 +14,7 @@
   void acceptNestConstructorBridge(
       ProgramMethod target,
       ProgramMethod bridge,
-      DexProgramClass argumentClass,
+      DexClass argumentClass,
       DexClassAndMethod context);
 
   void acceptNestFieldGetBridge(
@@ -46,7 +46,7 @@
     public void acceptNestConstructorBridge(
         ProgramMethod target,
         ProgramMethod bridge,
-        DexProgramClass argumentClass,
+        DexClass argumentClass,
         DexClassAndMethod context) {
       // Intentionally empty.
     }
diff --git a/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java
index b556923..3af5dc4 100644
--- a/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -7,6 +7,7 @@
 import static com.android.tools.r8.profile.rewriting.ProfileRewritingVarHandleDesugaringEventConsumerUtils.handleVarHandleDesugaringClassContext;
 
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexMethod;
@@ -292,7 +293,7 @@
   public void acceptNestConstructorBridge(
       ProgramMethod target,
       ProgramMethod bridge,
-      DexProgramClass argumentClass,
+      DexClass argumentClass,
       DexClassAndMethod context) {
     nestBasedAccessDesugaringEventConsumer.acceptNestConstructorBridge(
         target, bridge, argumentClass, context);
diff --git a/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
index 7d731fb..c44706f 100644
--- a/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingNestBasedAccessDesugaringEventConsumer.java
@@ -4,8 +4,8 @@
 
 package com.android.tools.r8.profile.rewriting;
 
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramField;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaringEventConsumer;
@@ -38,12 +38,13 @@
   public void acceptNestConstructorBridge(
       ProgramMethod target,
       ProgramMethod bridge,
-      DexProgramClass argumentClass,
+      DexClass argumentClass,
       DexClassAndMethod context) {
     if (context.isProgramMethod()) {
       additionsCollection.applyIfContextIsInProfile(
           context.asProgramMethod(),
-          additionsBuilder -> additionsBuilder.addRule(argumentClass).addRule(bridge));
+          additionsBuilder ->
+              additionsBuilder.addRule(argumentClass.getReference()).addRule(bridge));
     } else {
       additionsCollection.accept(
           additions ->
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index 69f6f02..a63cce4 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -402,9 +402,18 @@
               return;
             }
             assert type.isIdenticalTo(newType)
-                || !info.isPinned(options)
-                || info.isMinificationAllowed(options)
-                || info.isRepackagingAllowed(options);
+                    || !info.isPinned(options)
+                    || info.isMinificationAllowed(options)
+                    || info.isRepackagingAllowed(options)
+                : type.toSourceString()
+                    + " -> "
+                    + newType.toSourceString()
+                    + ": isPinned: "
+                    + info.isPinned(options)
+                    + ", isMinificationAllowed: "
+                    + info.isMinificationAllowed(options)
+                    + ", isRepackagingAllowed: "
+                    + info.isRepackagingAllowed(options);
             KeepClassInfo previous = newClassInfo.put(newType, info);
             assert previous == null;
           });
diff --git a/src/main/java/com/android/tools/r8/shaking/rules/MaterializedRules.java b/src/main/java/com/android/tools/r8/shaking/rules/MaterializedRules.java
index c66cdf1..ad3f8f6 100644
--- a/src/main/java/com/android/tools/r8/shaking/rules/MaterializedRules.java
+++ b/src/main/java/com/android/tools/r8/shaking/rules/MaterializedRules.java
@@ -31,11 +31,11 @@
   }
 
   public MaterializedRules rewriteWithLens(NonIdentityGraphLens lens) {
-    // The preconditions of these are not rewritten. We assume witnessing instructions
-    // to cary the original references to deem them effectively live.
+    // The conditional rules are not rewritten. We assume witnessing instructions to carry the
+    // original references to deem them effectively live.
     // TODO(b/323816623): Do we need to rewrite the consequent sets? Or would the constraints
     //  always ensure they remain if the keep info needs to be reapplied?
-    return this;
+    return new MaterializedRules(rootConsequences.rewrittenWithLens(lens), conditionalRules);
   }
 
   public ApplicableRulesEvaluator toApplicableRules() {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index 3340e46..572b8d1 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -26,6 +26,8 @@
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import com.android.tools.r8.utils.ReachabilitySensitiveValue;
+import com.android.tools.r8.utils.structural.HasherWrapper;
+import com.android.tools.r8.utils.structural.StructuralItem;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -186,11 +188,6 @@
         directMethods.add(method);
       }
     }
-    long checksum =
-        7 * (long) directMethods.hashCode()
-            + 11 * (long) virtualMethods.hashCode()
-            + 13 * (long) staticFields.hashCode()
-            + 17 * (long) instanceFields.hashCode();
     C clazz =
         getClassKind()
             .create(
@@ -214,7 +211,7 @@
                 DexEncodedMethod.EMPTY_ARRAY,
                 DexEncodedMethod.EMPTY_ARRAY,
                 factory.getSkipNameValidationForTesting(),
-                c -> checksum,
+                c -> getChecksum(),
                 null,
                 ReachabilitySensitiveValue.DISABLED);
     if (useSortedMethodBacking) {
@@ -224,4 +221,18 @@
     clazz.setVirtualMethods(virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
     return clazz;
   }
+
+  private long getChecksum() {
+    return 7 * hashEntries(virtualMethods, directMethods)
+        + 13 * hashEntries(instanceFields, staticFields);
+  }
+
+  private <S extends StructuralItem<S>> long hashEntries(List<S>... entryLists) {
+    // Use a hasher that is stable across jvm runs.
+    HasherWrapper hasherWrapper = HasherWrapper.murmur3128Hasher();
+    for (List<S> entryList : entryLists) {
+      entryList.stream().sorted().forEach(e -> e.hash(hasherWrapper));
+    }
+    return hasherWrapper.hash().hashCode();
+  }
 }
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 3146c85..dac665d 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -523,6 +523,10 @@
   // Flag to allow force nest desugaring, even if natively supported on the chosen API level.
   public boolean forceNestDesugaring =
       System.getProperty("com.android.tools.r8.forceNestDesugaring") != null;
+  // Flag to use legacy generation of -IA classes for nests (only for Platform until aosp/3241282
+  // lands).
+  public boolean legacyNestDesugaringIAClasses =
+      System.getProperty("com.android.tools.r8.legacyNestDesugaringIAClasses") != null;
 
   // TODO(b/293591931): Remove this flag.
   // Flag to allow permitted subclasses annotations in DEX. See b/231930852 for context.
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
index 5ac9755..875288c 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
@@ -64,6 +64,19 @@
   private final Set<String> seenNoneClassValues = new HashSet<>();
   private final Set<Integer> seenResourceIds = new HashSet<>();
 
+  private static final Set<String> SPECIAL_MANIFEST_ELEMENTS =
+      ImmutableSet.of(
+          "provider",
+          "activity",
+          "service",
+          "receiver",
+          "instrumentation",
+          "process",
+          "application");
+
+  private static final Set<String> SPECIAL_APPLICATION_ATTRIBUTES =
+      ImmutableSet.of("backupAgent", "appComponentFactory", "zygotePreloadName");
+
   @FunctionalInterface
   public interface ClassReferenceCallback {
     boolean tryClass(String possibleClass, Origin xmlFileOrigin);
@@ -226,7 +239,7 @@
   private void traceXml(String xmlFile, InputStream inputStream) {
     try {
       XmlNode xmlNode = XmlNode.parseFrom(inputStream);
-      visitNode(xmlNode, xmlFile);
+      visitNode(xmlNode, xmlFile, null);
       // Ensure that we trace the transitive reachable ids, without us having to iterate all
       // resources for the reachable marker.
       ProtoAndroidManifestUsageRecorderKt.recordUsagesFromNode(xmlNode, r8ResourceShrinkerModel)
@@ -237,7 +250,6 @@
     }
   }
 
-
   private void tryEnqueuerOnString(String possibleClass, String xmlName) {
     // There are a lot of xml tags and attributes that are evaluated over and over, if it is
     // not a class, ignore it.
@@ -249,18 +261,51 @@
     }
   }
 
-  private void visitNode(XmlNode xmlNode, String xmlName) {
+  private void visitNode(XmlNode xmlNode, String xmlName, String manifestPackageName) {
     XmlElement element = xmlNode.getElement();
     tryEnqueuerOnString(element.getName(), xmlName);
+
     for (XmlAttribute xmlAttribute : element.getAttributeList()) {
+      if (xmlAttribute.getName().equals("package") && element.getName().equals("manifest")) {
+        // We are traversing a manifest, record the package name if we see it.
+        manifestPackageName = xmlAttribute.getValue();
+      }
       String value = xmlAttribute.getValue();
       tryEnqueuerOnString(value, xmlName);
       if (value.startsWith(".")) {
         // package specific names, e.g. context
         getPackageNames().forEach(s -> tryEnqueuerOnString(s + value, xmlName));
       }
+      if (manifestPackageName != null) {
+        // Manifest case
+        traceManifestSpecificValues(xmlName, manifestPackageName, xmlAttribute, element);
+      }
     }
-    element.getChildList().forEach(e -> visitNode(e, xmlName));
+    for (XmlNode node : element.getChildList()) {
+      visitNode(node, xmlName, manifestPackageName);
+    }
+  }
+
+  private void traceManifestSpecificValues(
+      String xmlName, String packageName, XmlAttribute xmlAttribute, XmlElement element) {
+    if (!SPECIAL_MANIFEST_ELEMENTS.contains(element.getName())) {
+      return;
+    }
+    // All elements can have package specific name attributes pointing at classes.
+    if (xmlAttribute.getName().equals("name")) {
+      tryEnqueuerOnString(getFullyQualifiedName(packageName, xmlAttribute), xmlName);
+    }
+    // Application elements have multiple special case attributes, where the value is potentially
+    // a class name (unqualified).
+    if (element.getName().equals("application")) {
+      if (SPECIAL_APPLICATION_ATTRIBUTES.contains(xmlAttribute.getName())) {
+        tryEnqueuerOnString(getFullyQualifiedName(packageName, xmlAttribute), xmlName);
+      }
+    }
+  }
+
+  private static String getFullyQualifiedName(String packageName, XmlAttribute xmlAttribute) {
+    return packageName + "." + xmlAttribute.getValue();
   }
 
   public Map<Integer, List<String>> getResourceIdToXmlFiles() {
diff --git a/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java
index 6afaa95..1ba438d 100644
--- a/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java
+++ b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java
@@ -6,6 +6,7 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.DexIndexedConsumer.ArchiveConsumer;
 import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
@@ -51,6 +52,18 @@
     assertTrue(Files.exists(logDirectory.resolve("0.log")));
   }
 
+  @Test
+  public void testD8DeterminismWithChecksums() throws Exception {
+    Path logDirectory = temp.newFolder().toPath();
+    Path ref = compileD8WithChecksums(1, logDirectory);
+    for (int i = 2; i <= ITERATIONS; i++) {
+      Path next = compileD8WithChecksums(i, logDirectory);
+      assertProgramsEqual(ref, next);
+    }
+    // Check that setting the determinism checker wrote a log file.
+    assertTrue(Files.exists(logDirectory.resolve("0.log")));
+  }
+
   private Path compile(int iteration, Path logDirectory) throws Exception {
     System.out.println("= compiling " + iteration + "/" + ITERATIONS + " ======================");
     Path out = temp.newFolder().toPath().resolve("out.jar");
@@ -71,4 +84,25 @@
         .compile();
     return out;
   }
+
+  private Path compileD8WithChecksums(int iteration, Path logDirectory) throws Exception {
+    System.out.println("= compiling d8 " + iteration + "/" + ITERATIONS + " =====================");
+    Path out = temp.newFolder().toPath().resolve("out.jar");
+    testForD8(Backend.DEX)
+        .addProgramFiles(ToolHelper.getR8WithRelocatedDeps())
+        .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
+        .addOptionsModification(
+            options -> {
+              options
+                  .getTestingOptions()
+                  .setDeterminismChecker(DeterminismChecker.createWithFileBacking(logDirectory));
+              // Ensure that we generate the same check sums, see b/359616078
+              options.encodeChecksums = true;
+            })
+        .allowStdoutMessages()
+        .allowStderrMessages()
+        .setProgramConsumer(new ArchiveConsumer(out))
+        .compile();
+    return out;
+  }
 }
diff --git a/src/test/examplesJava11/nesthostexample/NestInitArgumentContextTest.java b/src/test/examplesJava11/nesthostexample/NestInitArgumentContextTest.java
index 0dec846..2de3600 100644
--- a/src/test/examplesJava11/nesthostexample/NestInitArgumentContextTest.java
+++ b/src/test/examplesJava11/nesthostexample/NestInitArgumentContextTest.java
@@ -29,10 +29,15 @@
   @Parameter(1)
   public boolean intermediate;
 
-  @Parameters(name = "{0}, intermediate = {1}")
+  @Parameter(2)
+  public boolean legacyNestDesugaringIAClasses;
+
+  @Parameters(name = "{0}, intermediate = {1}, legacyNestDesugaringIAClasses = {2}")
   public static List<Object[]> data() {
     return buildParameters(
-        getTestParameters().withDexRuntimesAndAllApiLevels().build(), BooleanUtils.values());
+        getTestParameters().withDexRuntimesAndAllApiLevels().build(),
+        BooleanUtils.values(),
+        BooleanUtils.values());
   }
 
   @Test
@@ -41,11 +46,13 @@
         .addProgramClassesAndInnerClasses(NestInitArgumentContextClass.class)
         .setMinApi(parameters)
         .setIntermediate(intermediate)
+        .addOptionsModification(
+            options -> options.legacyNestDesugaringIAClasses = legacyNestDesugaringIAClasses)
         .compile()
         .inspect(
             inspector ->
                 assertEquals(
-                    5,
+                    legacyNestDesugaringIAClasses ? 5 : 1,
                     inspector.allClasses().stream()
                         .map(ClassSubject::getFinalName)
                         .filter(name -> name.endsWith("-IA"))
@@ -69,11 +76,13 @@
               .addClasspathClasses(innerClasses)
               .setMinApi(parameters)
               .setIntermediate(intermediate)
+              .addOptionsModification(
+                  options -> options.legacyNestDesugaringIAClasses = legacyNestDesugaringIAClasses)
               .compile()
               .inspect(
                   inspector ->
                       assertEquals(
-                          1,
+                          legacyNestDesugaringIAClasses ? 1 : 0,
                           inspector.allClasses().stream()
                               .map(ClassSubject::getFinalName)
                               .filter(name -> name.endsWith("-IA"))
@@ -87,6 +96,8 @@
             .addClasspathClasses(innerClasses)
             .setMinApi(parameters)
             .setIntermediate(intermediate)
+            .addOptionsModification(
+                options -> options.legacyNestDesugaringIAClasses = legacyNestDesugaringIAClasses)
             .compile()
             .inspect(
                 inspector ->
@@ -102,11 +113,13 @@
         .addProgramFiles(innerClassesCompiled)
         .addProgramFiles(outerClassCompiled)
         .setMinApi(parameters)
+        .addOptionsModification(
+            options -> options.legacyNestDesugaringIAClasses = legacyNestDesugaringIAClasses)
         .compile()
         .inspect(
             inspector ->
                 assertEquals(
-                    5,
+                    legacyNestDesugaringIAClasses ? 5 : 1,
                     inspector.allClasses().stream()
                         .map(ClassSubject::getFinalName)
                         .filter(name -> name.endsWith("-IA"))
diff --git a/src/test/examplesJava11/nesthostexample/NestOnProgramOnClassPathTest.java b/src/test/examplesJava11/nesthostexample/NestOnProgramOnClassPathTest.java
index d2e3d0c..974683a 100644
--- a/src/test/examplesJava11/nesthostexample/NestOnProgramOnClassPathTest.java
+++ b/src/test/examplesJava11/nesthostexample/NestOnProgramOnClassPathTest.java
@@ -64,13 +64,13 @@
     inner.inspect(
         inspector -> {
           assertThisNumberOfBridges(inspector, 3);
-          assertNestConstructor(inspector);
+          assertNoNestConstructor(inspector);
         });
     D8TestCompileResult host = compileClassesWithD8ProgramClasses(nestHost, nestHost);
     host.inspect(
         inspector -> {
           assertThisNumberOfBridges(inspector, 1);
-          assertNestConstructor(inspector);
+          assertInitArgumentClass(inspector);
         });
   }
 
@@ -100,10 +100,14 @@
         .compile();
   }
 
-  private static void assertNestConstructor(CodeInspector inspector) {
+  private static void assertInitArgumentClass(CodeInspector inspector) {
     assertTrue(inspector.allClasses().stream().anyMatch(FoundClassSubject::isSynthetic));
   }
 
+  private static void assertNoNestConstructor(CodeInspector inspector) {
+    assertTrue(inspector.allClasses().stream().noneMatch(FoundClassSubject::isSynthetic));
+  }
+
   private static void assertThisNumberOfBridges(CodeInspector inspector, int numBridges) {
     for (FoundClassSubject clazz : inspector.allClasses()) {
       if (!clazz.isSynthetic()) {
diff --git a/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationAttributesTest.java b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationAttributesTest.java
new file mode 100644
index 0000000..2770b77
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationAttributesTest.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2024, 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.androidresources;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResource;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResourceBuilder;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class AndroidManifestWithApplicationAttributesTest extends TestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameter(1)
+  public String attributeName;
+
+  @Parameters(name = "{0}, attributeName: {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDefaultDexRuntime().withAllApiLevels().build(),
+        ImmutableList.of("backupAgent", "appComponentFactory", "zygotePreloadName"));
+  }
+
+  private static final String INNER_CLASS_NAME =
+      AndroidManifestWithApplicationAttributesTest.class.getSimpleName()
+          + "$"
+          + Bar.class.getSimpleName();
+
+  public static String MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION =
+      "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+          + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+          + "    xmlns:tools=\"http://schemas.android.com/tools\""
+          + "    package=\""
+          + AndroidManifestWithApplicationAttributesTest.class.getPackage().getName()
+          + "\""
+          + ">\n"
+          + "    <application android:%s=\""
+          + INNER_CLASS_NAME
+          + "\"/>"
+          + "</manifest>";
+
+  public AndroidTestResource getTestResources(TemporaryFolder temp) throws Exception {
+    return new AndroidTestResourceBuilder()
+        .withManifest(
+            String.format(MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION, attributeName))
+        .build(temp);
+  }
+
+  @Test
+  public void testManifestReferences() throws Exception {
+    testForR8(parameters.getBackend())
+        .setMinApi(parameters)
+        .addProgramClasses(Bar.class)
+        .addAndroidResources(getTestResources(temp))
+        .enableOptimizedShrinking()
+        .compile()
+        .inspect(
+            codeInspector -> {
+              ClassSubject barClass = codeInspector.clazz(Bar.class);
+              assertThat(barClass, isPresentAndNotRenamed());
+              // We should have two and only two methods, the two constructors.
+              assertEquals(barClass.allMethods(MethodSubject::isInstanceInitializer).size(), 2);
+              assertEquals(barClass.allMethods().size(), 2);
+            });
+  }
+
+  // Only referenced from Manifest file
+  public static class Bar {
+    // We should keep this since this is a provider
+    public Bar() {
+      System.out.println("init");
+    }
+
+    public Bar(String x) {
+      System.out.println("init with string");
+    }
+
+    public void bar() {
+      System.out.println("never kept");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationElementTest.java b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationElementTest.java
new file mode 100644
index 0000000..5e3ea38
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithApplicationElementTest.java
@@ -0,0 +1,101 @@
+// Copyright (c) 2024, 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.androidresources;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResource;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResourceBuilder;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class AndroidManifestWithApplicationElementTest extends TestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameter(1)
+  public String elementType;
+
+  @Parameters(name = "{0}, elementType: {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDefaultDexRuntime().withAllApiLevels().build(),
+        ImmutableList.of("provider", "activity", "service", "receiver"));
+  }
+
+  private static final String INNER_CLASS_NAME =
+      AndroidManifestWithApplicationElementTest.class.getSimpleName()
+          + "$"
+          + Bar.class.getSimpleName();
+
+  public static String MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION =
+      "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+          + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+          + "    xmlns:tools=\"http://schemas.android.com/tools\""
+          + "    package=\""
+          + AndroidManifestWithApplicationElementTest.class.getPackage().getName()
+          + "\""
+          + ">\n"
+          + "    <application>\n"
+          + "      <%s android:name=\""
+          + INNER_CLASS_NAME
+          + "\"/>"
+          + "    </application>\n"
+          + "</manifest>";
+
+  public AndroidTestResource getTestResources(TemporaryFolder temp) throws Exception {
+    return new AndroidTestResourceBuilder()
+        .withManifest(
+            String.format(MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION, elementType))
+        .build(temp);
+  }
+
+  @Test
+  public void testManifestReferences() throws Exception {
+    testForR8(parameters.getBackend())
+        .setMinApi(parameters)
+        .addProgramClasses(Bar.class)
+        .addAndroidResources(getTestResources(temp))
+        .enableOptimizedShrinking()
+        .compile()
+        .inspect(
+            codeInspector -> {
+              ClassSubject barClass = codeInspector.clazz(Bar.class);
+              assertThat(barClass, isPresentAndNotRenamed());
+              // We should have two and only two methods, the two constructors.
+              assertEquals(barClass.allMethods(MethodSubject::isInstanceInitializer).size(), 2);
+              assertEquals(barClass.allMethods().size(), 2);
+            });
+  }
+
+  // Only referenced from Manifest file
+  public static class Bar {
+    // We should keep this since this is a provider
+    public Bar() {
+      System.out.println("init");
+    }
+
+    public Bar(String x) {
+      System.out.println("init with string");
+    }
+
+    public void bar() {
+      System.out.println("never kept");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithManifestEntriesTest.java b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithManifestEntriesTest.java
new file mode 100644
index 0000000..6037077
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithManifestEntriesTest.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2024, 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.androidresources;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResource;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResourceBuilder;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class AndroidManifestWithManifestEntriesTest extends TestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameter(1)
+  public String elementType;
+
+  @Parameters(name = "{0}, elementType: {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDefaultDexRuntime().withAllApiLevels().build(),
+        ImmutableList.of("application", "instrumentation"));
+  }
+
+  private static final String INNER_CLASS_NAME =
+      AndroidManifestWithManifestEntriesTest.class.getSimpleName()
+          + "$"
+          + Bar.class.getSimpleName();
+
+  public static String MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION =
+      "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+          + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+          + "    xmlns:tools=\"http://schemas.android.com/tools\""
+          + "    package=\""
+          + AndroidManifestWithManifestEntriesTest.class.getPackage().getName()
+          + "\""
+          + ">\n"
+          + "      <%s android:name=\""
+          + INNER_CLASS_NAME
+          + "\"/>\n"
+          + "</manifest>";
+
+  public AndroidTestResource getTestResources(TemporaryFolder temp) throws Exception {
+    return new AndroidTestResourceBuilder()
+        .withManifest(
+            String.format(MANIFEST_WITH_MANIFEST_PACKAGE_USAGE_SUB_APPLICATION, elementType))
+        .build(temp);
+  }
+
+  @Test
+  public void testManifestReferences() throws Exception {
+    testForR8(parameters.getBackend())
+        .setMinApi(parameters)
+        .addProgramClasses(Bar.class)
+        .addAndroidResources(getTestResources(temp))
+        .enableOptimizedShrinking()
+        .compile()
+        .inspect(
+            codeInspector -> {
+              ClassSubject barClass = codeInspector.clazz(Bar.class);
+              assertThat(barClass, isPresentAndNotRenamed());
+              // We should have two and only two methods, the two constructors.
+              assertEquals(barClass.allMethods(MethodSubject::isInstanceInitializer).size(), 2);
+              assertEquals(barClass.allMethods().size(), 2);
+            });
+  }
+
+  // Only referenced from Manifest file
+  public static class Bar {
+    // We should keep this since this is a provider
+    public Bar() {
+      System.out.println("init");
+    }
+
+    public Bar(String x) {
+      System.out.println("init with string");
+    }
+
+    public void bar() {
+      System.out.println("never kept");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithProcessesTest.java b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithProcessesTest.java
new file mode 100644
index 0000000..e4f8583
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/androidresources/AndroidManifestWithProcessesTest.java
@@ -0,0 +1,92 @@
+// Copyright (c) 2024, 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.androidresources;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResource;
+import com.android.tools.r8.androidresources.AndroidResourceTestingUtils.AndroidTestResourceBuilder;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class AndroidManifestWithProcessesTest extends TestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection parameters() {
+    return getTestParameters().withDefaultDexRuntime().withAllApiLevels().build();
+  }
+
+  private static final String INNER_CLASS_NAME =
+      AndroidManifestWithProcessesTest.class.getSimpleName() + "$" + Bar.class.getSimpleName();
+
+  public static String MANIFEST_WITH_PROCESS =
+      "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+          + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+          + "    xmlns:tools=\"http://schemas.android.com/tools\""
+          + "    package=\""
+          + AndroidManifestWithProcessesTest.class.getPackage().getName()
+          + "\""
+          + ">\n"
+          + "    <application>\n"
+          + "        <processes>\n"
+          + "            <process android:process=\":sub\" android:name=\""
+          + INNER_CLASS_NAME
+          + "\"/>\n"
+          + "        </processes>\n"
+          + "    </application>\n"
+          + "</manifest>";
+
+  public AndroidTestResource getTestResources(TemporaryFolder temp) throws Exception {
+    return new AndroidTestResourceBuilder().withManifest(MANIFEST_WITH_PROCESS).build(temp);
+  }
+
+  @Test
+  public void testManifestReferences() throws Exception {
+    testForR8(parameters.getBackend())
+        .setMinApi(parameters)
+        .addProgramClasses(Bar.class)
+        .addAndroidResources(getTestResources(temp))
+        .enableOptimizedShrinking()
+        .compile()
+        .inspect(
+            codeInspector -> {
+              ClassSubject barClass = codeInspector.clazz(Bar.class);
+              assertThat(barClass, isPresentAndNotRenamed());
+              // We should have two and only two methods, the two constructors.
+              assertEquals(barClass.allMethods(MethodSubject::isInstanceInitializer).size(), 2);
+              assertEquals(barClass.allMethods().size(), 2);
+            });
+  }
+
+  // Only referenced from Manifest file
+  public static class Bar {
+    // We should keep this since this is a provider
+    public Bar() {
+      System.out.println("init");
+    }
+
+    public Bar(String x) {
+      System.out.println("init with string");
+    }
+
+    public void bar() {
+      System.out.println("never kept");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DateTimeFormatterStandaloneMonthTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DateTimeFormatterStandaloneMonthTest.java
index 0a83c05..60f5174 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DateTimeFormatterStandaloneMonthTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DateTimeFormatterStandaloneMonthTest.java
@@ -5,12 +5,11 @@
 package com.android.tools.r8.desugar.desugaredlibrary;
 
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
-import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK8_DESCRIPTOR;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_DESCRIPTOR;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 
 import com.android.tools.r8.SingleTestRunResult;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.utils.StringUtils;
@@ -30,21 +29,6 @@
       StringUtils.lines(
           "1 - 1", "2 - 2", "3 - 3", "4 - 4", "5 - 5", "6 - 6", "7 - 7", "8 - 8", "9 - 9",
           "10 - 10", "11 - 11", "12 - 12");
-  private static final String expectedOutputLibJdk11 =
-      StringUtils.lines(
-          "Jan - January",
-          "Feb - February",
-          "Mar - March",
-          "Apr - April",
-          "May - May",
-          "Jun - June",
-          "Jul - July",
-          "Aug - August",
-          "Sep - September",
-          "Oct - October",
-          "Nov - November",
-          // TODO(b/323306225): December is missing.
-          " - ");
   private static final String expectedOutput =
       StringUtils.lines(
           "Jan - January",
@@ -90,15 +74,11 @@
             .addKeepMainRule(TestClass.class)
             .run(parameters.getRuntime(), TestClass.class)
             .assertSuccess();
-    if (apiLevelWithJavaTime(parameters)) {
-      run.assertSuccessWithOutput(expectedOutput);
-    } else if (libraryDesugaringSpecification.getDescriptor() == JDK8_DESCRIPTOR) {
-      run.assertSuccessWithOutput(expectedOutputDesugaredLibJdk8);
-    } else if (parameters.getRuntime().asDex().getVersion().isEqualTo(Version.V4_0_4)) {
-      // Not sure why this works for Dalvik 4.0.4, but not really relevant.
+    if (apiLevelWithJavaTime(parameters)
+        || libraryDesugaringSpecification.getDescriptor() == JDK11_DESCRIPTOR) {
       run.assertSuccessWithOutput(expectedOutput);
     } else {
-      run.assertSuccessWithOutput(expectedOutputLibJdk11);
+      run.assertSuccessWithOutput(expectedOutputDesugaredLibJdk8);
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MethodParametersTest.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MethodParametersTest.java
index 3c7248a..b2ea090 100644
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MethodParametersTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MethodParametersTest.java
@@ -91,9 +91,9 @@
             parameters.isCfRuntime(),
             result ->
                 result.assertSuccessWithOutputLines(
-                    "Outer$Inner-IA, 1",
-                    "int, Outer$Inner-IA, 2",
-                    "int, int, Outer$Inner-IA, 3",
+                    "Outer-IA, 1",
+                    "int, Outer-IA, 2",
+                    "int, int, Outer-IA, 3",
                     "int, int, 2",
                     "int, 1",
                     "0"),
@@ -102,9 +102,9 @@
                     "0",
                     "int, 1",
                     "int, int, 2",
-                    "int, int, Outer$Inner-IA, 3",
-                    "int, Outer$Inner-IA, 2",
-                    "Outer$Inner-IA, 1"));
+                    "int, int, Outer-IA, 3",
+                    "int, Outer-IA, 2",
+                    "Outer-IA, 1"));
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/NestBasedAccessBridgesProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/NestBasedAccessBridgesProfileRewritingTest.java
index 5756f2e..2b2d2f0 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/NestBasedAccessBridgesProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/NestBasedAccessBridgesProfileRewritingTest.java
@@ -107,7 +107,6 @@
     inspect(
         profileInspector,
         inspector,
-        false,
         parameters.canUseNestBasedAccessesWhenDesugaring(),
         false);
   }
@@ -117,7 +116,6 @@
     inspect(
         profileInspector,
         inspector,
-        parameters.canHaveNonReboundConstructorInvoke(),
         parameters.canUseNestBasedAccesses(),
         true);
   }
@@ -125,7 +123,6 @@
   private void inspect(
       ArtProfileInspector profileInspector,
       CodeInspector inspector,
-      boolean canHaveNonReboundConstructorInvoke,
       boolean canUseNestBasedAccesses,
       boolean isR8)
       throws Exception {
@@ -135,7 +132,7 @@
     ClassSubject syntheticConstructorArgumentClassSubject =
         inspector.clazz(
             SyntheticItemsTestUtils.syntheticNestConstructorArgumentClass(
-                Reference.classFromClass(NestMember.class)));
+                Reference.classFromClass(Main.class)));
     assertThat(
         syntheticConstructorArgumentClassSubject, notIf(isPresent(), canUseNestBasedAccesses));
 
diff --git a/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java b/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
index 3412d54..7ef9b00 100644
--- a/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/R8TestBuilder.java
@@ -966,9 +966,7 @@
               Path resourceZip = testResource.getResourceZip();
               featureSplitGenerator
                   .setAndroidResourceConsumer(new ArchiveProtoAndroidResourceConsumer(outputFile))
-                  .setAndroidResourceProvider(
-                      new ArchiveProtoAndroidResourceProvider(
-                          resourceZip, new PathOrigin(resourceZip)))
+                  .setAndroidResourceProvider(new ArchiveProtoAndroidResourceProvider(resourceZip))
                   .setProgramConsumer(DexIndexedConsumer.emptyConsumer());
 
               return featureSplitGenerator.build();
@@ -997,10 +995,10 @@
       AndroidTestResource testResource) {
     Path resources = testResource.getResourceZip();
     if (testResource.getAdditionalKeepRuleFiles().isEmpty()) {
-      return new ArchiveProtoAndroidResourceProvider(resources, new PathOrigin(resources));
+      return new ArchiveProtoAndroidResourceProvider(resources);
     }
     ArchiveProtoAndroidResourceProvider provider =
-        new ArchiveProtoAndroidResourceProvider(resources, new PathOrigin(resources)) {
+        new ArchiveProtoAndroidResourceProvider(resources) {
           @Override
           public Collection<AndroidResourceInput> getAndroidResources() throws ResourceException {
             ArrayList<AndroidResourceInput> resourceInputs =
diff --git a/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1 b/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1
index 8779e19..ac5fd5a 100644
--- a/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1
+++ b/third_party/openjdk/desugar_jdk_libs_11.tar.gz.sha1
@@ -1 +1 @@
-5b02bd53b6df482392dbd41b04c137b0b3c99388
\ No newline at end of file
+f4f486f37cf801466634ffbf584adb80dc839f4d
\ No newline at end of file
diff --git a/tools/r8_release.py b/tools/r8_release.py
index 5e0f695..e524f5c 100755
--- a/tools/r8_release.py
+++ b/tools/r8_release.py
@@ -649,7 +649,8 @@
         # TODO(b/237636871): Cleanup and generalize.
         if (not (library_version.startswith('1.1') or
                  library_version.startswith('1.2') or
-                 library_version.startswith('2.0'))):
+                 library_version.startswith('2.0') or
+                 library_version.startswith('2.1'))):
             print(
                 "Release script does not support desugared library version %s" %
                 library_version)
@@ -658,7 +659,7 @@
         postfixes = ['']
         if library_version.startswith('1.2'):
             postfixes = ['_legacy']
-        if library_version.startswith('2.0'):
+        if library_version.startswith('2.0') or library_version.startswith('2.1'):
             postfixes = ['_minimal', '', '_nio']
 
         with utils.TempDir() as temp: