diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 100b5aa..b843181 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -34,7 +34,7 @@
 import com.android.tools.r8.inspector.internal.InspectorImpl;
 import com.android.tools.r8.ir.analysis.proto.GeneratedExtensionRegistryShrinker;
 import com.android.tools.r8.ir.conversion.IRConverter;
-import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter;
 import com.android.tools.r8.ir.desugar.NestedPrivateMethodLense;
 import com.android.tools.r8.ir.desugar.R8NestBasedAccessDesugaring;
 import com.android.tools.r8.ir.optimize.AssertionsRewriter;
@@ -278,7 +278,7 @@
         MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());
       }
       if (!options.desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
-        BackportedMethodRewriter.checkForAssumedLibraryTypes(appView);
+        DesugaredLibraryRetargeter.checkForAssumedLibraryTypes(appView);
       }
 
       List<ProguardConfigurationRule> synthesizedProguardRules = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index 4b8c6d4..01c5298 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter;
 import com.android.tools.r8.ir.desugar.NestBasedAccessDesugaring;
 import com.android.tools.r8.ir.desugar.TwrCloseResourceRewriter;
 import com.android.tools.r8.ir.optimize.ServiceLoaderRewriter;
@@ -44,8 +45,7 @@
   private String toStringCache = null;
 
   DexType(DexString descriptor) {
-    assert !descriptor.toString().contains(".")
-        : "Malformed descriptor: " + descriptor.toString();
+    assert !descriptor.toString().contains(".") : "Malformed descriptor: " + descriptor.toString();
     this.descriptor = descriptor;
   }
 
@@ -145,11 +145,12 @@
   }
 
   @Override
-  public void collectIndexedItems(IndexedItemCollection collection,
-      DexMethod method, int instructionOffset) {
+  public void collectIndexedItems(
+      IndexedItemCollection collection, DexMethod method, int instructionOffset) {
     if (collection.addType(this)) {
-      collection.getRenamedDescriptor(this).collectIndexedItems(collection, method,
-          instructionOffset);
+      collection
+          .getRenamedDescriptor(this)
+          .collectIndexedItems(collection, method, instructionOffset);
     }
   }
 
@@ -272,6 +273,7 @@
         || name.contains(TwrCloseResourceRewriter.UTILITY_CLASS_NAME)
         || name.contains(NestBasedAccessDesugaring.NEST_CONSTRUCTOR_NAME)
         || name.contains(BackportedMethodRewriter.UTILITY_CLASS_NAME_PREFIX)
+        || name.contains(DesugaredLibraryRetargeter.DESUGAR_LIB_RETARGET_CLASS_NAME_PREFIX)
         || name.contains(ServiceLoaderRewriter.SERVICE_LOADER_CLASS_NAME)
         || oldSynthesizedName(name);
   }
@@ -298,17 +300,17 @@
   public int elementSizeForPrimitiveArrayType() {
     assert isPrimitiveArrayType();
     switch (descriptor.content[1]) {
-      case 'Z':  // boolean
-      case 'B':  // byte
+      case 'Z': // boolean
+      case 'B': // byte
         return 1;
-      case 'S':  // short
-      case 'C':  // char
+      case 'S': // short
+      case 'C': // char
         return 2;
-      case 'I':  // int
-      case 'F':  // float
+      case 'I': // int
+      case 'F': // float
         return 4;
-      case 'J':  // long
-      case 'D':  // double
+      case 'J': // long
+      case 'D': // double
         return 8;
       default:
         throw new Unreachable("Not array of primitives '" + descriptor + "'");
@@ -328,8 +330,11 @@
     if (leadingSquareBrackets == 0) {
       return this;
     }
-    DexString newDesc = dexItemFactory.createString(descriptor.size - leadingSquareBrackets,
-        Arrays.copyOfRange(descriptor.content, leadingSquareBrackets, descriptor.content.length));
+    DexString newDesc =
+        dexItemFactory.createString(
+            descriptor.size - leadingSquareBrackets,
+            Arrays.copyOfRange(
+                descriptor.content, leadingSquareBrackets, descriptor.content.length));
     return dexItemFactory.createType(newDesc);
   }
 
@@ -364,8 +369,10 @@
 
   public DexType toArrayElementType(DexItemFactory dexItemFactory) {
     assert this.isArrayType();
-    DexString newDesc = dexItemFactory.createString(descriptor.size - 1,
-        Arrays.copyOfRange(descriptor.content, 1, descriptor.content.length));
+    DexString newDesc =
+        dexItemFactory.createString(
+            descriptor.size - 1,
+            Arrays.copyOfRange(descriptor.content, 1, descriptor.content.length));
     return dexItemFactory.createType(newDesc);
   }
 
@@ -376,7 +383,8 @@
     if (lastSeparator == -1) {
       return packagePart ? "" : descriptor.substring(1, descriptor.length() - 1);
     } else {
-      return packagePart ? descriptor.substring(1, lastSeparator)
+      return packagePart
+          ? descriptor.substring(1, lastSeparator)
           : descriptor.substring(lastSeparator + 1, descriptor.length() - 1);
     }
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 4ac8995..4c820ff 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -45,6 +45,7 @@
 import com.android.tools.r8.ir.desugar.D8NestBasedAccessDesugaring;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryAPIConverter;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryAPIConverter.Mode;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.Flavor;
 import com.android.tools.r8.ir.desugar.LambdaRewriter;
@@ -143,6 +144,7 @@
   private final InterfaceMethodRewriter interfaceMethodRewriter;
   private final TwrCloseResourceRewriter twrCloseResourceRewriter;
   private final BackportedMethodRewriter backportedMethodRewriter;
+  private final DesugaredLibraryRetargeter desugaredLibraryRetargeter;
   private final LambdaMerger lambdaMerger;
   private final ClassInliner classInliner;
   private final ClassStaticizer classStaticizer;
@@ -217,13 +219,16 @@
             .collect(Collectors.toList());
     if (options.isDesugaredLibraryCompilation()) {
       // Specific L8 Settings.
-      // BackportedMethodRewriter is needed for retarget core library members and backports.
+      // DesugaredLibraryRetargeter is needed for retarget core library members and backports.
       // InterfaceMethodRewriter is needed for emulated interfaces.
       // LambdaRewriter is needed because if it is missing there are invoke custom on
       // default/static interface methods, and this is not supported by the compiler.
       // DesugaredLibraryAPIConverter is here to duplicate APIs.
       // The rest is nulled out. In addition the rewriting logic fails without lambda rewriting.
-      this.backportedMethodRewriter = new BackportedMethodRewriter(appView, this);
+      this.desugaredLibraryRetargeter =
+          options.desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()
+              ? null
+              : new DesugaredLibraryRetargeter(appView);
       this.interfaceMethodRewriter =
           options.desugaredLibraryConfiguration.getEmulateLibraryInterface().isEmpty()
               ? null
@@ -231,6 +236,7 @@
       this.lambdaRewriter = new LambdaRewriter(appView);
       this.desugaredLibraryAPIConverter =
           new DesugaredLibraryAPIConverter(appView, Mode.GENERATE_CALLBACKS_AND_WRAPPERS);
+      this.backportedMethodRewriter = null;
       this.twrCloseResourceRewriter = null;
       this.lambdaMerger = null;
       this.covariantReturnTypeAnnotationTransformer = null;
@@ -268,6 +274,10 @@
             ? new TwrCloseResourceRewriter(appView, this)
             : null;
     this.backportedMethodRewriter = new BackportedMethodRewriter(appView, this);
+    this.desugaredLibraryRetargeter =
+        options.desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()
+            ? null
+            : new DesugaredLibraryRetargeter(appView);
     this.covariantReturnTypeAnnotationTransformer =
         options.processCovariantReturnTypeAnnotations
             ? new CovariantReturnTypeAnnotationTransformer(this, appView.dexItemFactory())
@@ -450,7 +460,16 @@
 
   private void synthesizeJava8UtilityClass(
       Builder<?> builder, ExecutorService executorService) throws ExecutionException {
-    backportedMethodRewriter.synthesizeUtilityClasses(builder, executorService);
+    if (backportedMethodRewriter != null) {
+      backportedMethodRewriter.synthesizeUtilityClasses(builder, executorService);
+    }
+  }
+
+  private void synthesizeRetargetClass(Builder<?> builder, ExecutorService executorService)
+      throws ExecutionException {
+    if (desugaredLibraryRetargeter != null) {
+      desugaredLibraryRetargeter.synthesizeRetargetClasses(builder, executorService, this);
+    }
   }
 
   private void synthesizeEnumUnboxingUtilityClass(
@@ -482,6 +501,8 @@
     desugarInterfaceMethods(builder, ExcludeDexResources, executor);
     synthesizeTwrCloseResourceUtilityClass(builder, executor);
     synthesizeJava8UtilityClass(builder, executor);
+    synthesizeRetargetClass(builder, executor);
+
     processCovariantReturnTypeAnnotations(builder);
     generateDesugaredLibraryAPIWrappers(builder, executor);
 
@@ -747,6 +768,7 @@
     printPhase("Utility classes synthesis");
     synthesizeTwrCloseResourceUtilityClass(builder, executorService);
     synthesizeJava8UtilityClass(builder, executorService);
+    synthesizeRetargetClass(builder, executorService);
     handleSynthesizedClassMapping(builder);
     synthesizeEnumUnboxingUtilityClass(builder, executorService);
 
@@ -1370,9 +1392,20 @@
       codeRewriter.rewriteThrowableAddAndGetSuppressed(code);
       timing.end();
     }
-    timing.begin("Rewrite backport methods");
-    backportedMethodRewriter.desugar(code);
-    timing.end();
+
+    if (desugaredLibraryRetargeter != null) {
+      // The desugaredLibraryRetargeter should run before backportedMethodRewriter to be able to
+      // perform backport rewriting before the methods can be retargeted.
+      timing.begin("Retarget library methods");
+      desugaredLibraryRetargeter.desugar(code);
+      timing.end();
+    }
+
+    if (backportedMethodRewriter != null) {
+      timing.begin("Rewrite backport methods");
+      backportedMethodRewriter.desugar(code);
+      timing.end();
+    }
 
     timing.begin("Desugar string concat");
     stringConcatRewriter.desugarStringConcats(method.method, code);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 50b068c..c56524e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -21,7 +21,6 @@
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
@@ -31,7 +30,6 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
-import com.android.tools.r8.graph.ResolutionResult;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
@@ -54,13 +52,10 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalOptions.DesugarState;
-import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.IdentityHashMap;
@@ -122,6 +117,9 @@
       BackportedMethodRewriter.RewritableMethods rewritableMethods =
           new BackportedMethodRewriter.RewritableMethods(options, appView);
       rewritableMethods.visit(methods::add);
+      DesugaredLibraryRetargeter desugaredLibraryRetargeter =
+          new DesugaredLibraryRetargeter(appView);
+      desugaredLibraryRetargeter.visit(methods::add);
       return methods;
     } catch (ExecutionException e) {
       throw unwrapExecutionException(e);
@@ -146,49 +144,10 @@
           && !invoke.isInvokeStatic()) {
         continue;
       }
+
       MethodProvider provider = getMethodProviderOrNull(invoke.getInvokedMethod());
       if (provider == null) {
-        if (!rewritableMethods.matchesVirtualRewrite(invoke.getInvokedMethod())) {
-          continue;
-        }
-        // We need to force resolution, even on d8, to know if the invoke has to be rewritten.
-        ResolutionResult resolutionResult =
-            appView
-                .appInfo()
-                .resolveMethod(invoke.getInvokedMethod().holder, invoke.getInvokedMethod());
-        if (resolutionResult.isFailedResolution()) {
-          continue;
-        }
-        DexEncodedMethod singleTarget = resolutionResult.getSingleTarget();
-        assert singleTarget != null;
-        provider = getMethodProviderOrNull(singleTarget.method);
-        if (provider == null) {
-          continue;
-        }
-      }
-
-      // Due to emulated dispatch, we have to rewrite invoke-super differently or we end up in
-      // infinite loops. We do direct resolution. This is a very uncommon case.
-      if (invoke.isInvokeSuper()
-          && rewritableMethods.matchesVirtualRewrite(invoke.getInvokedMethod())) {
-        DexEncodedMethod dexEncodedMethod =
-            appView
-                .appInfo()
-                .withClassHierarchy()
-                .lookupSuperTarget(invoke.getInvokedMethod(), code.method.method.holder);
-        // Final methods can be rewritten as a normal invoke.
-        if (dexEncodedMethod != null && !dexEncodedMethod.isFinal()) {
-          DexMethod retargetMethod =
-              appView
-                  .options()
-                  .desugaredLibraryConfiguration
-                  .retargetMethod(dexEncodedMethod.method, appView);
-          if (retargetMethod != null) {
-            iterator.replaceCurrentInstruction(
-                new InvokeStatic(retargetMethod, invoke.outValue(), invoke.arguments()));
-          }
-          continue;
-        }
+        continue;
       }
 
       provider.rewriteInvoke(invoke, iterator, code, appView, affectedValues);
@@ -222,11 +181,6 @@
     if (!enabled) {
       return;
     }
-    if (appView.options().isDesugaredLibraryCompilation()) {
-      synthesizeEmulatedDispatchMethods(builder);
-    } else {
-      addInterfacesAndForwardingMethods(executorService);
-    }
     if (holders.isEmpty()) {
       return;
     }
@@ -243,8 +197,9 @@
       }
     }
 
-    MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(
-        Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false);
+    MethodAccessFlags flags =
+        MethodAccessFlags.fromSharedAccessFlags(
+            Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false);
     ClassAccessFlags classAccessFlags =
         ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
     // Generate the utility classes in a loop since utility classes can require the
@@ -262,7 +217,12 @@
       Code code = provider.generateTemplateMethod(appView.options(), method);
       DexEncodedMethod dexEncodedMethod =
           new DexEncodedMethod(
-              method, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code, true);
+              method,
+              flags,
+              DexAnnotationSet.empty(),
+              ParameterAnnotationsList.empty(),
+              code,
+              true);
       boolean addToMainDexList =
           referencingClasses.stream()
               .anyMatch(clazz -> appView.appInfo().isInMainDexList(clazz.type));
@@ -273,140 +233,27 @@
               method.holder,
               dexEncodedMethod,
               "java8 methods utility class",
-              addToMainDexList);
+              addToMainDexList,
+              appView);
       // The following may add elements to methodsProviders.
       converter.optimizeSynthesizedClass(utilityClass, executorService);
     }
   }
 
-  private void addInterfacesAndForwardingMethods(ExecutorService executorService)
-      throws ExecutionException {
-    assert !appView.options().isDesugaredLibraryCompilation();
-    Map<DexType, List<DexMethod>> map = Maps.newIdentityHashMap();
-    for (DexMethod emulatedDispatchMethod : rewritableMethods.getEmulatedDispatchMethods()) {
-      map.putIfAbsent(emulatedDispatchMethod.holder, new ArrayList<>(1));
-      map.get(emulatedDispatchMethod.holder).add(emulatedDispatchMethod);
-    }
-    List<DexEncodedMethod> addedMethods = new ArrayList<>();
-    for (DexProgramClass clazz : appView.appInfo().classes()) {
-      if (clazz.superType == null) {
-        assert clazz.type == appView.dexItemFactory().objectType : clazz.type.toSourceString();
-        continue;
-      }
-      DexClass dexClass = appView.definitionFor(clazz.superType);
-      // Only performs computation if superclass is a library class, but not object to filter out
-      // the most common case.
-      if (dexClass != null
-          && dexClass.isLibraryClass()
-          && dexClass.type != appView.dexItemFactory().objectType) {
-        for (DexType dexType : map.keySet()) {
-          if (inherit(dexClass.asLibraryClass(), dexType)) {
-            addedMethods.addAll(addInterfacesAndForwardingMethods(clazz, map.get(dexType)));
-          }
-        }
-      }
-    }
-    if (addedMethods.isEmpty()) {
-      return;
-    }
-    converter.processMethodsConcurrently(addedMethods, executorService);
-  }
-
-  private boolean inherit(DexLibraryClass clazz, DexType typeToInherit) {
-    DexLibraryClass current = clazz;
-    while (current.type != appView.dexItemFactory().objectType) {
-      if (current.type == typeToInherit) {
-        return true;
-      }
-      current = appView.definitionFor(current.superType).asLibraryClass();
-    }
-    return false;
-  }
-
-  private List<DexEncodedMethod> addInterfacesAndForwardingMethods(
-      DexProgramClass clazz, List<DexMethod> dexMethods) {
-    // BackportedMethodRewriter emulate dispatch: insertion of a marker interface & forwarding
-    // methods.
-    // We cannot use the ClassProcessor since this applies up to 26, while the ClassProcessor
-    // applies up to 24.
-    List<DexEncodedMethod> newForwardingMethods = new ArrayList<>();
-    for (DexMethod dexMethod : dexMethods) {
-      DexType[] newInterfaces = Arrays.copyOf(clazz.interfaces.values, clazz.interfaces.size() + 1);
-      newInterfaces[newInterfaces.length - 1] =
-          BackportedMethodRewriter.dispatchInterfaceTypeFor(appView, dexMethod);
-      clazz.interfaces = new DexTypeList(newInterfaces);
-      DexEncodedMethod dexEncodedMethod = clazz.lookupVirtualMethod(dexMethod);
-      if (dexEncodedMethod == null) {
-        DexEncodedMethod newMethod = createForwardingMethod(dexMethod, clazz);
-        clazz.addVirtualMethod(newMethod);
-        newForwardingMethods.add(newMethod);
-      }
-    }
-    return newForwardingMethods;
-  }
-
-  private DexEncodedMethod createForwardingMethod(DexMethod target, DexClass clazz) {
-    // NOTE: Never add a forwarding method to methods of classes unknown or coming from android.jar
-    // even if this results in invalid code, these classes are never desugared.
-    // In desugared library, emulated interface methods can be overridden by retarget lib members.
-    DexMethod forwardMethod =
-        appView.options().desugaredLibraryConfiguration.retargetMethod(target, appView);
-    assert forwardMethod != null && forwardMethod != target;
-    return DexEncodedMethod.createDesugaringForwardingMethod(
-        appView.definitionFor(target), clazz, forwardMethod, appView.dexItemFactory());
-  }
-
-  private void synthesizeEmulatedDispatchMethods(Builder<?> builder) {
-    assert appView.options().isDesugaredLibraryCompilation();
-    if (rewritableMethods.getEmulatedDispatchMethods().isEmpty()) {
-      return;
-    }
-    ClassAccessFlags itfAccessFlags =
-        ClassAccessFlags.fromSharedAccessFlags(
-            Constants.ACC_PUBLIC
-                | Constants.ACC_SYNTHETIC
-                | Constants.ACC_ABSTRACT
-                | Constants.ACC_INTERFACE);
-    ClassAccessFlags holderAccessFlags =
-        ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
-    for (DexMethod emulatedDispatchMethod : rewritableMethods.getEmulatedDispatchMethods()) {
-      // Dispatch interface.
-      DexType interfaceType = dispatchInterfaceTypeFor(appView, emulatedDispatchMethod);
-      DexEncodedMethod itfMethod =
-          generateInterfaceDispatchMethod(emulatedDispatchMethod, interfaceType);
-      synthesizeClassWithUniqueMethod(
-          builder,
-          itfAccessFlags,
-          interfaceType,
-          itfMethod,
-          "desugared library dispatch interface",
-          false);
-      // Dispatch holder.
-      DexType holderType = dispatchHolderTypeFor(appView, emulatedDispatchMethod);
-      DexEncodedMethod dispatchMethod =
-          generateHolderDispatchMethod(emulatedDispatchMethod, holderType, itfMethod.method);
-      synthesizeClassWithUniqueMethod(
-          builder,
-          holderAccessFlags,
-          holderType,
-          dispatchMethod,
-          "desugared library dispatch class",
-          false);
-    }
-  }
-
-  private DexProgramClass synthesizeClassWithUniqueMethod(
+  static DexProgramClass synthesizeClassWithUniqueMethod(
       Builder<?> builder,
       ClassAccessFlags accessFlags,
       DexType type,
       DexEncodedMethod uniqueMethod,
       String origin,
-      boolean addToMainDexList) {
+      boolean addToMainDexList,
+      AppView<?> appView) {
+    DexItemFactory factory = appView.dexItemFactory();
     DexProgramClass newClass =
         new DexProgramClass(
             type,
             null,
-            new SynthesizedOrigin(origin, getClass()),
+            new SynthesizedOrigin(origin, BackportedMethodRewriter.class),
             accessFlags,
             factory.objectType,
             DexTypeList.empty(),
@@ -425,186 +272,64 @@
                 ? DexEncodedMethod.EMPTY_ARRAY
                 : new DexEncodedMethod[] {uniqueMethod},
             factory.getSkipNameValidationForTesting(),
-            getChecksumSupplier(uniqueMethod));
+            getChecksumSupplier(uniqueMethod, appView));
     appView.appInfo().addSynthesizedClass(newClass);
     builder.addSynthesizedClass(newClass, addToMainDexList);
     return newClass;
   }
 
-  private DexEncodedMethod generateInterfaceDispatchMethod(
-      DexMethod emulatedDispatchMethod, DexType interfaceType) {
-    MethodAccessFlags flags =
-        MethodAccessFlags.fromSharedAccessFlags(
-            Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT | Constants.ACC_SYNTHETIC, false);
-    DexMethod newMethod =
-        factory.createMethod(
-            interfaceType, emulatedDispatchMethod.proto, emulatedDispatchMethod.name);
-    return new DexEncodedMethod(
-        newMethod, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null, true);
-  }
-
-  private DexEncodedMethod generateHolderDispatchMethod(
-      DexMethod emulatedDispatchMethod, DexType dispatchHolder, DexMethod itfMethod) {
-    // The method should look like:
-    // static foo(rcvr, arg0, arg1) {
-    //    if (rcvr instanceof interfaceType) {
-    //      return invoke-interface receiver.foo(arg0, arg1);
-    //    } else {
-    //      return DesugarX.foo(rcvr, arg0, arg1)
-    //    }
-    // We do not deal with complex cases (multiple retargeting of the same signature in the
-    // same inheritance tree, etc., since they do not happen in the most common desugared library.
-    DexMethod desugarMethod =
-        appView
-            .options()
-            .desugaredLibraryConfiguration
-            .retargetMethod(emulatedDispatchMethod, appView);
-    assert desugarMethod != null; // This method is reached only for retarget core lib members.
-    DexMethod newMethod =
-        appView
-            .dexItemFactory()
-            .createMethod(dispatchHolder, desugarMethod.proto, emulatedDispatchMethod.name);
-    return DexEncodedMethod.toEmulateDispatchLibraryMethod(
-        emulatedDispatchMethod.holder,
-        newMethod,
-        desugarMethod,
-        itfMethod,
-        Collections.emptyList(),
-        appView);
-  }
-
-  private ChecksumSupplier getChecksumSupplier(DexEncodedMethod method) {
+  private static ChecksumSupplier getChecksumSupplier(DexEncodedMethod method, AppView<?> appView) {
     if (!appView.options().encodeChecksums) {
       return DexProgramClass::invalidChecksumRequest;
     }
     return c -> method.method.hashCode();
   }
-
-  public static DexType dispatchInterfaceTypeFor(AppView<?> appView, DexMethod method) {
-    return dispatchTypeFor(appView, method, "dispatchInterface");
-  }
-
-  static DexType dispatchHolderTypeFor(AppView<?> appView, DexMethod method) {
-    return dispatchTypeFor(appView, method, "dispatchHolder");
-  }
-
-  private static DexType dispatchTypeFor(AppView<?> appView, DexMethod method, String suffix) {
-    String prefix =
-        appView.options().desugaredLibraryConfiguration.getSynthesizedLibraryClassesPackagePrefix();
-    String descriptor =
-        "L"
-            + prefix
-            + UTILITY_CLASS_NAME_PREFIX
-            + '$'
-            + method.holder.getName()
-            + '$'
-            + method.name
-            + '$'
-            + suffix
-            + ';';
-    return appView.dexItemFactory().createType(descriptor);
-  }
-
+  
   private MethodProvider getMethodProviderOrNull(DexMethod method) {
     DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
     assert original != null;
-    Map<DexType, DexType> backportCoreLibraryMembers =
-        appView.options().desugaredLibraryConfiguration.getBackportCoreLibraryMember();
-    if (backportCoreLibraryMembers.containsKey(original.holder)) {
-      DexType newHolder = backportCoreLibraryMembers.get(original.holder);
-      DexMethod newMethod =
-          appView.dexItemFactory().createMethod(newHolder, original.proto, original.name);
-      MethodProvider provider = rewritableMethods.getProvider(newMethod);
-      if (provider != null) {
-        return provider;
-      }
-      RetargetCoreLibraryMethodProvider extraProvider =
-          new RetargetCoreLibraryMethodProvider(newHolder, original, true);
-      // TODO(b/139788786): cache this entry, but without writing into a lock free structure.
-      // rewritableMethods.addProvider(extraProvider);
-      return extraProvider;
-    }
     return rewritableMethods.getProvider(original);
   }
 
-  public static void checkForAssumedLibraryTypes(AppView<?> appView) {
-    Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
-        appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
-    for (DexString methodName : retargetCoreLibMember.keySet()) {
-      for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
-        DexClass typeClass = appView.definitionFor(inType);
-        if (typeClass == null) {
-          RewritableMethods.warnMissingRetargetCoreLibraryMember(inType, appView);
-        }
-      }
-    }
-  }
-
   private static final class RewritableMethods {
 
     // Map backported method to a provider for creating the actual target method (with code).
     private final Map<DexMethod, MethodProvider> rewritable = new IdentityHashMap<>();
-    // Map virtualRewrites hold a methodName->method mapping for virtual methods which are
-    // rewritten while the holder is non final but no superclass implement the method. In this case
-    // d8 needs to force resolution of given methods to see if the invoke needs to be rewritten.
-    private final Map<DexString, List<DexMethod>> virtualRewrites = new IdentityHashMap<>();
-    // non final virtual library methods requiring generation of emulated dispatch.
-    private final Set<DexMethod> emulatedDispatchMethods = Sets.newHashSet();
 
     RewritableMethods(InternalOptions options, AppView<?> appView) {
-      if (options.shouldBackportMethods()) {
-        DexItemFactory factory = options.itemFactory;
-        if (options.minApiLevel < AndroidApiLevel.K.getLevel()) {
-          initializeAndroidKMethodProviders(factory);
-        }
-        if (options.minApiLevel < AndroidApiLevel.N.getLevel()) {
-          initializeAndroidNMethodProviders(factory);
-        }
-        if (options.minApiLevel < AndroidApiLevel.O.getLevel()) {
-          initializeAndroidOMethodProviders(factory);
-        }
-
-        // The following providers are currently not implemented at any API level in Android.
-        // They however require the Optional/Stream class to be present, either through desugared
-        // libraries or natively. If Optional/Stream class is not present, we do not desugar to
-        // avoid confusion in error messages.
-        if (appView.rewritePrefix.hasRewrittenType(factory.optionalType, appView)
-            || options.minApiLevel >= AndroidApiLevel.N.getLevel()) {
-          initializeJava9OptionalMethodProviders(factory);
-          initializeJava10OptionalMethodProviders(factory);
-          initializeJava11OptionalMethodProviders(factory);
-        }
-        if (appView.rewritePrefix.hasRewrittenType(factory.streamType, appView)
-            || options.minApiLevel >= AndroidApiLevel.N.getLevel()) {
-          initializeStreamMethodProviders(factory);
-        }
-
-        // These are currently not implemented at any API level in Android.
-        initializeJava9MethodProviders(factory);
-        initializeJava10MethodProviders(factory);
-        initializeJava11MethodProviders(factory);
+      if (!options.shouldBackportMethods()) {
+        return;
+      }
+      DexItemFactory factory = options.itemFactory;
+      if (options.minApiLevel < AndroidApiLevel.K.getLevel()) {
+        initializeAndroidKMethodProviders(factory);
+      }
+      if (options.minApiLevel < AndroidApiLevel.N.getLevel()) {
+        initializeAndroidNMethodProviders(factory);
+      }
+      if (options.minApiLevel < AndroidApiLevel.O.getLevel()) {
+        initializeAndroidOMethodProviders(factory);
       }
 
-      if (!options.desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
-        initializeRetargetCoreLibraryMembers(appView);
+      // The following providers are currently not implemented at any API level in Android.
+      // They however require the Optional/Stream class to be present, either through desugared
+      // libraries or natively. If Optional/Stream class is not present, we do not desugar to
+      // avoid confusion in error messages.
+      if (appView.rewritePrefix.hasRewrittenType(factory.optionalType, appView)
+          || options.minApiLevel >= AndroidApiLevel.N.getLevel()) {
+        initializeJava9OptionalMethodProviders(factory);
+        initializeJava10OptionalMethodProviders(factory);
+        initializeJava11OptionalMethodProviders(factory);
       }
-    }
+      if (appView.rewritePrefix.hasRewrittenType(factory.streamType, appView)
+          || options.minApiLevel >= AndroidApiLevel.N.getLevel()) {
+        initializeStreamMethodProviders(factory);
+      }
 
-    boolean matchesVirtualRewrite(DexMethod method) {
-      List<DexMethod> dexMethods = virtualRewrites.get(method.name);
-      if (dexMethods == null) {
-        return false;
-      }
-      for (DexMethod dexMethod : dexMethods) {
-        if (method.match(dexMethod)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    public Set<DexMethod> getEmulatedDispatchMethods() {
-      return emulatedDispatchMethods;
+      // These are currently not implemented at any API level in Android.
+      initializeJava9MethodProviders(factory);
+      initializeJava10MethodProviders(factory);
+      initializeJava11MethodProviders(factory);
     }
 
     boolean isEmpty() {
@@ -669,8 +394,9 @@
 
       // int Objects.compare(T a, T b, Comparator<? super T> c)
       name = factory.createString("compare");
-      proto = factory.createProto(factory.intType, factory.objectType, factory.objectType,
-          factory.comparatorType);
+      proto =
+          factory.createProto(
+              factory.intType, factory.objectType, factory.objectType, factory.comparatorType);
       method = factory.createMethod(type, proto, name);
       addProvider(new MethodGenerator(method, BackportedMethods::ObjectsMethods_compare));
 
@@ -1243,8 +969,9 @@
 
       // String String.join(CharSequence, CharSequence...)
       name = factory.createString("join");
-      proto = factory.createProto(factory.stringType, factory.charSequenceType,
-          factory.charSequenceArrayType);
+      proto =
+          factory.createProto(
+              factory.stringType, factory.charSequenceType, factory.charSequenceArrayType);
       method = factory.createMethod(type, proto, name);
       addProvider(
           new MethodGenerator(method, BackportedMethods::StringMethods_joinArray, "joinArray"));
@@ -1279,19 +1006,13 @@
         name = factory.createString("multiplyFull");
         proto = factory.createProto(factory.longType, factory.intType, factory.intType);
         method = factory.createMethod(type, proto, name);
-        addProvider(
-            new MethodGenerator(
-                method,
-                BackportedMethods::MathMethods_multiplyFull));
+        addProvider(new MethodGenerator(method, BackportedMethods::MathMethods_multiplyFull));
 
         // long {Math,StrictMath}.multiplyHigh(long, long)
         name = factory.createString("multiplyHigh");
         proto = factory.createProto(factory.longType, factory.longType, factory.longType);
         method = factory.createMethod(type, proto, name);
-        addProvider(
-            new MethodGenerator(
-                method,
-                BackportedMethods::MathMethods_multiplyHigh));
+        addProvider(new MethodGenerator(method, BackportedMethods::MathMethods_multiplyHigh));
 
         // long {Math,StrictMath}.floorDiv(long, int)
         name = factory.createString("floorDiv");
@@ -1385,8 +1106,7 @@
       proto = factory.createProto(type, factory.objectArrayType);
       method = factory.createMethod(type, proto, name);
       addProvider(
-          new MethodGenerator(
-              method, BackportedMethods::CollectionMethods_listOfArray, "ofArray"));
+          new MethodGenerator(method, BackportedMethods::CollectionMethods_listOfArray, "ofArray"));
 
       // Set<E> Set.of(<args>) for 0 to 10 arguments and Set.of(E[])
       type = factory.setType;
@@ -1406,8 +1126,7 @@
       proto = factory.createProto(type, factory.objectArrayType);
       method = factory.createMethod(type, proto, name);
       addProvider(
-          new MethodGenerator(
-              method, BackportedMethods::CollectionMethods_setOfArray, "ofArray"));
+          new MethodGenerator(method, BackportedMethods::CollectionMethods_setOfArray, "ofArray"));
 
       // Map<K, V> Map.of(<K, V args>) for 0 to 10 pairs and Map.ofEntries(Map.Entry<K, V>[])
       type = factory.mapType;
@@ -1554,24 +1273,24 @@
       // Optional{void,Int,Long,Double}.stream()
       DexType[] optionalTypes =
           new DexType[] {
-              optionalType,
-              factory.optionalDoubleType,
-              factory.optionalLongType,
-              factory.optionalIntType,
+            optionalType,
+            factory.optionalDoubleType,
+            factory.optionalLongType,
+            factory.optionalIntType,
           };
       DexType[] streamReturnTypes =
           new DexType[] {
-              factory.streamType,
-              factory.createType(factory.createString("Ljava/util/stream/DoubleStream;")),
-              factory.createType(factory.createString("Ljava/util/stream/LongStream;")),
-              factory.createType(factory.createString("Ljava/util/stream/IntStream;")),
+            factory.streamType,
+            factory.createType(factory.createString("Ljava/util/stream/DoubleStream;")),
+            factory.createType(factory.createString("Ljava/util/stream/LongStream;")),
+            factory.createType(factory.createString("Ljava/util/stream/IntStream;")),
           };
       TemplateMethodFactory[] streamMethodFactories =
           new TemplateMethodFactory[] {
-              BackportedMethods::OptionalMethods_stream,
-              BackportedMethods::OptionalMethods_streamDouble,
-              BackportedMethods::OptionalMethods_streamLong,
-              BackportedMethods::OptionalMethods_streamInt,
+            BackportedMethods::OptionalMethods_stream,
+            BackportedMethods::OptionalMethods_streamDouble,
+            BackportedMethods::OptionalMethods_streamLong,
+            BackportedMethods::OptionalMethods_streamInt,
           };
       name = factory.createString("stream");
       for (int i = 0; i < optionalTypes.length; i++) {
@@ -1580,24 +1299,20 @@
         proto = factory.createProto(streamReturnType);
         method = factory.createMethod(optional, proto, name);
         addProvider(
-            new StatifyingMethodGenerator(
-                method, streamMethodFactories[i], "stream", optional));
+            new StatifyingMethodGenerator(method, streamMethodFactories[i], "stream", optional));
       }
 
       // Optional{void,Int,Long,Double}.ifPresentOrElse(consumer,runnable)
       DexType[] consumerTypes =
-          new DexType[]{
-              factory.consumerType,
-              factory.doubleConsumer,
-              factory.longConsumer,
-              factory.intConsumer
+          new DexType[] {
+            factory.consumerType, factory.doubleConsumer, factory.longConsumer, factory.intConsumer
           };
       TemplateMethodFactory[] methodFactories =
-          new TemplateMethodFactory[]{
-              BackportedMethods::OptionalMethods_ifPresentOrElse,
-              BackportedMethods::OptionalMethods_ifPresentOrElseDouble,
-              BackportedMethods::OptionalMethods_ifPresentOrElseLong,
-              BackportedMethods::OptionalMethods_ifPresentOrElseInt
+          new TemplateMethodFactory[] {
+            BackportedMethods::OptionalMethods_ifPresentOrElse,
+            BackportedMethods::OptionalMethods_ifPresentOrElseDouble,
+            BackportedMethods::OptionalMethods_ifPresentOrElseLong,
+            BackportedMethods::OptionalMethods_ifPresentOrElseInt
           };
       for (int i = 0; i < optionalTypes.length; i++) {
         DexType optional = optionalTypes[i];
@@ -1614,17 +1329,14 @@
       // Optional{void,Int,Long,Double}.orElseThrow()
       DexType[] optionalTypes =
           new DexType[] {
-              factory.optionalType,
-              factory.optionalDoubleType,
-              factory.optionalLongType,
-              factory.optionalIntType,
+            factory.optionalType,
+            factory.optionalDoubleType,
+            factory.optionalLongType,
+            factory.optionalIntType,
           };
       DexType[] returnTypes =
           new DexType[] {
-              factory.objectType,
-              factory.doubleType,
-              factory.longType,
-              factory.intType,
+            factory.objectType, factory.doubleType, factory.longType, factory.intType,
           };
       MethodInvokeRewriter[] rewriters =
           new MethodInvokeRewriter[] {
@@ -1645,17 +1357,17 @@
       // Optional{void,Int,Long,Double}.isEmpty()
       DexType[] optionalTypes =
           new DexType[] {
-              factory.optionalType,
-              factory.optionalDoubleType,
-              factory.optionalLongType,
-              factory.optionalIntType,
+            factory.optionalType,
+            factory.optionalDoubleType,
+            factory.optionalLongType,
+            factory.optionalIntType,
           };
       TemplateMethodFactory[] methodFactories =
-          new TemplateMethodFactory[]{
-              BackportedMethods::OptionalMethods_isEmpty,
-              BackportedMethods::OptionalMethods_isEmptyDouble,
-              BackportedMethods::OptionalMethods_isEmptyLong,
-              BackportedMethods::OptionalMethods_isEmptyInt
+          new TemplateMethodFactory[] {
+            BackportedMethods::OptionalMethods_isEmpty,
+            BackportedMethods::OptionalMethods_isEmptyDouble,
+            BackportedMethods::OptionalMethods_isEmptyLong,
+            BackportedMethods::OptionalMethods_isEmptyInt
           };
       DexString name = factory.createString("isEmpty");
       for (int i = 0; i < optionalTypes.length; i++) {
@@ -1676,76 +1388,7 @@
       DexProto proto = factory.createProto(factory.streamType, factory.objectType);
       DexMethod method = factory.createMethod(streamType, proto, name);
       addProvider(
-          new MethodGenerator(
-              method, BackportedMethods::StreamMethods_ofNullable, "ofNullable"));
-    }
-
-    private static void warnMissingRetargetCoreLibraryMember(DexType type, AppView<?> appView) {
-      StringDiagnostic warning =
-          new StringDiagnostic(
-              "Cannot retarget core library member "
-                  + type.getName()
-                  + " because the class is missing.");
-      appView.options().reporter.warning(warning);
-    }
-
-    private void initializeRetargetCoreLibraryMembers(AppView<?> appView) {
-      assert appView.appInfo().hasClassHierarchy()
-          : "Class hierarchy required for desugared library.";
-      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
-          appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
-      for (DexString methodName : retargetCoreLibMember.keySet()) {
-        for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
-          DexClass typeClass = appView.definitionFor(inType);
-          if (typeClass != null) {
-            DexType newHolder = retargetCoreLibMember.get(methodName).get(inType);
-            List<DexEncodedMethod> found = findDexEncodedMethodsWithName(methodName, typeClass);
-            for (DexEncodedMethod encodedMethod : found) {
-              if (!encodedMethod.isStatic()) {
-                virtualRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
-                virtualRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
-                if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
-                  // In this case interface method rewriter takes care of it.
-                  continue;
-                } else if (!encodedMethod.isFinal()) {
-                  // Virtual rewrites require emulated dispatch for inheritance.
-                  // The call is rewritten to the dispatch holder class instead.
-                  handleEmulateDispatch(appView, encodedMethod.method);
-                  newHolder = dispatchHolderTypeFor(appView, encodedMethod.method);
-                }
-              }
-              DexProto proto = encodedMethod.method.proto;
-              DexMethod method = appView.dexItemFactory().createMethod(inType, proto, methodName);
-              addProvider(
-                  new RetargetCoreLibraryMethodProvider(
-                      newHolder, method, encodedMethod.isStatic()));
-            }
-          }
-        }
-      }
-    }
-
-    private List<DexEncodedMethod> findDexEncodedMethodsWithName(
-        DexString methodName, DexClass clazz) {
-      List<DexEncodedMethod> found = new ArrayList<>();
-      for (DexEncodedMethod encodedMethod : clazz.methods()) {
-        if (encodedMethod.method.name == methodName) {
-          found.add(encodedMethod);
-        }
-      }
-      assert found.size() > 0 : "Should have found a method (library specifications).";
-      return found;
-    }
-
-    private void handleEmulateDispatch(AppView<?> appView, DexMethod method) {
-      emulatedDispatchMethods.add(method);
-      if (!appView.options().isDesugaredLibraryCompilation()) {
-        // Add rewrite rules so keeps rules are correctly generated in the program.
-        DexType dispatchInterfaceType = dispatchInterfaceTypeFor(appView, method);
-        appView.rewritePrefix.rewriteType(dispatchInterfaceType, dispatchInterfaceType);
-        DexType dispatchHolderType = dispatchHolderTypeFor(appView, method);
-        appView.rewritePrefix.rewriteType(dispatchHolderType, dispatchHolderType);
-      }
+          new MethodGenerator(method, BackportedMethods::StreamMethods_ofNullable, "ofNullable"));
     }
 
     private void addProvider(MethodProvider generator) {
@@ -1780,52 +1423,6 @@
     public abstract boolean requiresGenerationOfCode();
   }
 
-  private static class RetargetCoreLibraryMethodProvider extends MethodProvider {
-
-    private final DexType newHolder;
-    private DexMethod targetMethod;
-    private boolean isStatic;
-
-    RetargetCoreLibraryMethodProvider(DexType newHolder, DexMethod method, boolean isStatic) {
-      super(method);
-      this.newHolder = newHolder;
-      this.isStatic = isStatic;
-    }
-
-    @Override
-    public void rewriteInvoke(
-        InvokeMethod invoke,
-        InstructionListIterator iterator,
-        IRCode code,
-        AppView<?> appView,
-        Set<Value> affectedValues) {
-      iterator.replaceCurrentInstruction(
-          new InvokeStatic(provideMethod(appView), invoke.outValue(), invoke.inValues()));
-    }
-
-    @Override
-    public DexMethod provideMethod(AppView<?> appView) {
-      if (targetMethod != null) {
-        return targetMethod;
-      }
-      DexItemFactory factory = appView.dexItemFactory();
-      DexProto newProto =
-          isStatic ? method.proto : factory.prependTypeToProto(method.holder, method.proto);
-      targetMethod = factory.createMethod(newHolder, newProto, method.name);
-      return targetMethod;
-    }
-
-    @Override
-    public Code generateTemplateMethod(InternalOptions options, DexMethod method) {
-      throw new Unreachable("Does not generate any method.");
-    }
-
-    @Override
-    public boolean requiresGenerationOfCode() {
-      return false;
-    }
-  }
-
   private static final class InvokeRewriter extends MethodProvider {
 
     private final MethodInvokeRewriter rewriter;
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 bdb4cd9..baa6317 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
@@ -110,12 +110,6 @@
     return libraryCompilation;
   }
 
-  public String getSynthesizedLibraryClassesPackagePrefix(AppView<?> appView) {
-    return appView.options().isDesugaredLibraryCompilation()
-        ? synthesizedLibraryClassesPackagePrefix
-        : "";
-  }
-
   public String getSynthesizedLibraryClassesPackagePrefix() {
     return synthesizedLibraryClassesPackagePrefix;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
new file mode 100644
index 0000000..3949767
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -0,0 +1,441 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+//  for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.desugar;
+
+import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.graph.*;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+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.conversion.IRConverter;
+import com.android.tools.r8.utils.StringDiagnostic;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+
+public class DesugaredLibraryRetargeter {
+
+  public static final String DESUGAR_LIB_RETARGET_CLASS_NAME_PREFIX =
+      "$r8$retargetLibraryMember$virtualDispatch";
+
+  private final AppView<AppInfoWithClassHierarchy> appView;
+  private final Map<DexMethod, DexMethod> retargetLibraryMember = new IdentityHashMap<>();
+  // Map virtualRewrites hold a methodName->method mapping for virtual methods which are
+  // rewritten while the holder is non final but no superclass implement the method. In this case
+  // d8 needs to force resolution of given methods to see if the invoke needs to be rewritten.
+  private final Map<DexString, List<DexMethod>> virtualRewrites = new IdentityHashMap<>();
+  // Non final virtual library methods requiring generation of emulated dispatch.
+  private final Set<DexMethod> emulatedDispatchMethods = Sets.newHashSet();
+
+  public DesugaredLibraryRetargeter(AppView<?> appView) {
+    assert appView.appInfo().hasClassHierarchy()
+        : "Class hierarchy required for desugared library.";
+    this.appView = appView.withClassHierarchy();
+    if (appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
+      return;
+    }
+    new RetargetingSetup().setUpRetargeting();
+  }
+
+  public static void checkForAssumedLibraryTypes(AppView<?> appView) {
+    Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+        appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
+    for (DexString methodName : retargetCoreLibMember.keySet()) {
+      for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
+        DexClass typeClass = appView.definitionFor(inType);
+        if (typeClass == null) {
+          warnMissingRetargetCoreLibraryMember(inType, appView);
+        }
+      }
+    }
+  }
+
+  private static void warnMissingRetargetCoreLibraryMember(DexType type, AppView<?> appView) {
+    StringDiagnostic warning =
+        new StringDiagnostic(
+            "Cannot retarget core library member "
+                + type.getName()
+                + " because the class is missing.");
+    appView.options().reporter.warning(warning);
+  }
+
+  // Used by the ListOfBackportedMethods utility.
+  void visit(Consumer<DexMethod> consumer) {
+    retargetLibraryMember.keySet().forEach(consumer);
+  }
+
+  public void desugar(IRCode code) {
+    if (retargetLibraryMember.isEmpty()) {
+      return;
+    }
+
+    InstructionListIterator iterator = code.instructionListIterator();
+    while (iterator.hasNext()) {
+      Instruction instruction = iterator.next();
+      if (!instruction.isInvokeMethod()) {
+        continue;
+      }
+
+      InvokeMethod invoke = instruction.asInvokeMethod();
+      DexMethod retarget = getRetargetLibraryMember(invoke.getInvokedMethod());
+      if (retarget == null) {
+        if (!matchesVirtualRewrite(invoke.getInvokedMethod())) {
+          continue;
+        }
+        // We need to force resolution, even on d8, to know if the invoke has to be rewritten.
+        ResolutionResult resolutionResult =
+            appView
+                .appInfo()
+                .resolveMethod(invoke.getInvokedMethod().holder, invoke.getInvokedMethod());
+        if (resolutionResult.isFailedResolution()) {
+          continue;
+        }
+        DexEncodedMethod singleTarget = resolutionResult.getSingleTarget();
+        assert singleTarget != null;
+        retarget = getRetargetLibraryMember(singleTarget.method);
+        if (retarget == null) {
+          continue;
+        }
+      }
+
+      // Due to emulated dispatch, we have to rewrite invoke-super differently or we end up in
+      // infinite loops. We do direct resolution. This is a very uncommon case.
+      if (invoke.isInvokeSuper() && matchesVirtualRewrite(invoke.getInvokedMethod())) {
+        DexEncodedMethod dexEncodedMethod =
+            appView
+                .appInfo()
+                .withClassHierarchy()
+                .lookupSuperTarget(invoke.getInvokedMethod(), code.method.method.holder);
+        // Final methods can be rewritten as a normal invoke.
+        if (dexEncodedMethod != null && !dexEncodedMethod.isFinal()) {
+          DexMethod retargetMethod =
+              appView
+                  .options()
+                  .desugaredLibraryConfiguration
+                  .retargetMethod(dexEncodedMethod.method, appView);
+          if (retargetMethod != null) {
+            iterator.replaceCurrentInstruction(
+                new InvokeStatic(retargetMethod, invoke.outValue(), invoke.arguments()));
+          }
+          continue;
+        }
+      }
+
+      iterator.replaceCurrentInstruction(
+          new InvokeStatic(retarget, invoke.outValue(), invoke.inValues()));
+    }
+  }
+
+  private DexMethod getRetargetLibraryMember(DexMethod method) {
+    Map<DexType, DexType> backportCoreLibraryMembers =
+        appView.options().desugaredLibraryConfiguration.getBackportCoreLibraryMember();
+    if (backportCoreLibraryMembers.containsKey(method.holder)) {
+      DexType newHolder = backportCoreLibraryMembers.get(method.holder);
+      return appView.dexItemFactory().createMethod(newHolder, method.proto, method.name);
+    }
+    return retargetLibraryMember.get(method);
+  }
+
+  private boolean matchesVirtualRewrite(DexMethod method) {
+    List<DexMethod> dexMethods = virtualRewrites.get(method.name);
+    if (dexMethods == null) {
+      return false;
+    }
+    for (DexMethod dexMethod : dexMethods) {
+      if (method.match(dexMethod)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private class RetargetingSetup {
+
+    private void setUpRetargeting() {
+      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+          appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
+      for (DexString methodName : retargetCoreLibMember.keySet()) {
+        for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
+          DexClass typeClass = appView.definitionFor(inType);
+          if (typeClass != null) {
+            DexType newHolder = retargetCoreLibMember.get(methodName).get(inType);
+            List<DexEncodedMethod> found = findDexEncodedMethodsWithName(methodName, typeClass);
+            for (DexEncodedMethod encodedMethod : found) {
+              if (!encodedMethod.isStatic()) {
+                virtualRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
+                virtualRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
+                if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
+                  // In this case interface method rewriter takes care of it.
+                  continue;
+                } else if (!encodedMethod.isFinal()) {
+                  // Virtual rewrites require emulated dispatch for inheritance.
+                  // The call is rewritten to the dispatch holder class instead.
+                  handleEmulateDispatch(appView, encodedMethod.method);
+                  newHolder = dispatchHolderTypeFor(encodedMethod.method);
+                }
+              }
+              DexProto proto = encodedMethod.method.proto;
+              DexMethod method = appView.dexItemFactory().createMethod(inType, proto, methodName);
+              retargetLibraryMember.put(
+                  method, computeRetargetMethod(method, encodedMethod.isStatic(), newHolder));
+            }
+          }
+        }
+      }
+    }
+
+    private DexMethod computeRetargetMethod(DexMethod method, boolean isStatic, DexType newHolder) {
+      DexItemFactory factory = appView.dexItemFactory();
+      DexProto newProto =
+          isStatic ? method.proto : factory.prependTypeToProto(method.holder, method.proto);
+      return factory.createMethod(newHolder, newProto, method.name);
+    }
+
+    private List<DexEncodedMethod> findDexEncodedMethodsWithName(
+        DexString methodName, DexClass clazz) {
+      List<DexEncodedMethod> found = new ArrayList<>();
+      for (DexEncodedMethod encodedMethod : clazz.methods()) {
+        if (encodedMethod.method.name == methodName) {
+          found.add(encodedMethod);
+        }
+      }
+      assert found.size() > 0 : "Should have found a method (library specifications).";
+      return found;
+    }
+
+    private void handleEmulateDispatch(AppView<?> appView, DexMethod method) {
+      emulatedDispatchMethods.add(method);
+      if (!appView.options().isDesugaredLibraryCompilation()) {
+        // Add rewrite rules so keeps rules are correctly generated in the program.
+        DexType dispatchInterfaceType = dispatchInterfaceTypeFor(method);
+        appView.rewritePrefix.rewriteType(dispatchInterfaceType, dispatchInterfaceType);
+        DexType dispatchHolderType = dispatchHolderTypeFor(method);
+        appView.rewritePrefix.rewriteType(dispatchHolderType, dispatchHolderType);
+      }
+    }
+  }
+
+  public void synthesizeRetargetClasses(
+      DexApplication.Builder<?> builder, ExecutorService executorService, IRConverter converter)
+      throws ExecutionException {
+    new EmulatedDispatchTreeFixer().fixApp(builder, executorService, converter);
+  }
+
+  // The rewrite of virtual calls requires to go through emulate dispatch. This class is responsible
+  // for inserting interfaces on library boundaries and forwarding methods in the program, and to
+  // synthesize the interfaces and emulated dispatch classes in the desugared library.
+  class EmulatedDispatchTreeFixer {
+
+    void fixApp(
+        DexApplication.Builder<?> builder, ExecutorService executorService, IRConverter converter)
+        throws ExecutionException {
+      if (appView.options().isDesugaredLibraryCompilation()) {
+        synthesizeEmulatedDispatchMethods(builder);
+      } else {
+        addInterfacesAndForwardingMethods(executorService, converter);
+      }
+    }
+
+    private void addInterfacesAndForwardingMethods(
+        ExecutorService executorService, IRConverter converter) throws ExecutionException {
+      assert !appView.options().isDesugaredLibraryCompilation();
+      Map<DexType, List<DexMethod>> map = Maps.newIdentityHashMap();
+      for (DexMethod emulatedDispatchMethod : emulatedDispatchMethods) {
+        map.putIfAbsent(emulatedDispatchMethod.holder, new ArrayList<>(1));
+        map.get(emulatedDispatchMethod.holder).add(emulatedDispatchMethod);
+      }
+      List<DexEncodedMethod> addedMethods = new ArrayList<>();
+      for (DexProgramClass clazz : appView.appInfo().classes()) {
+        if (clazz.superType == null) {
+          assert clazz.type == appView.dexItemFactory().objectType : clazz.type.toSourceString();
+          continue;
+        }
+        DexClass dexClass = appView.definitionFor(clazz.superType);
+        // Only performs computation if superclass is a library class, but not object to filter out
+        // the most common case.
+        if (dexClass != null
+            && dexClass.isLibraryClass()
+            && dexClass.type != appView.dexItemFactory().objectType) {
+          for (DexType dexType : map.keySet()) {
+            if (inherit(dexClass.asLibraryClass(), dexType)) {
+              addedMethods.addAll(addInterfacesAndForwardingMethods(clazz, map.get(dexType)));
+            }
+          }
+        }
+      }
+      if (addedMethods.isEmpty()) {
+        return;
+      }
+      converter.processMethodsConcurrently(addedMethods, executorService);
+    }
+
+    private boolean inherit(DexLibraryClass clazz, DexType typeToInherit) {
+      DexLibraryClass current = clazz;
+      while (current.type != appView.dexItemFactory().objectType) {
+        if (current.type == typeToInherit) {
+          return true;
+        }
+        current = appView.definitionFor(current.superType).asLibraryClass();
+      }
+      return false;
+    }
+
+    private List<DexEncodedMethod> addInterfacesAndForwardingMethods(
+        DexProgramClass clazz, List<DexMethod> dexMethods) {
+      // DesugaredLibraryRetargeter emulate dispatch: insertion of a marker interface & forwarding
+      // methods.
+      // We cannot use the ClassProcessor since this applies up to 26, while the ClassProcessor
+      // applies up to 24.
+      List<DexEncodedMethod> newForwardingMethods = new ArrayList<>();
+      for (DexMethod dexMethod : dexMethods) {
+        DexType[] newInterfaces =
+            Arrays.copyOf(clazz.interfaces.values, clazz.interfaces.size() + 1);
+        newInterfaces[newInterfaces.length - 1] = dispatchInterfaceTypeFor(dexMethod);
+        clazz.interfaces = new DexTypeList(newInterfaces);
+        DexEncodedMethod dexEncodedMethod = clazz.lookupVirtualMethod(dexMethod);
+        if (dexEncodedMethod == null) {
+          DexEncodedMethod newMethod = createForwardingMethod(dexMethod, clazz);
+          clazz.addVirtualMethod(newMethod);
+          newForwardingMethods.add(newMethod);
+        }
+      }
+      return newForwardingMethods;
+    }
+
+    private DexEncodedMethod createForwardingMethod(DexMethod target, DexClass clazz) {
+      // NOTE: Never add a forwarding method to methods of classes unknown or coming from
+      // android.jar
+      // even if this results in invalid code, these classes are never desugared.
+      // In desugared library, emulated interface methods can be overridden by retarget lib members.
+      DexMethod forwardMethod =
+          appView.options().desugaredLibraryConfiguration.retargetMethod(target, appView);
+      assert forwardMethod != null && forwardMethod != target;
+      return DexEncodedMethod.createDesugaringForwardingMethod(
+          appView.definitionFor(target), clazz, forwardMethod, appView.dexItemFactory());
+    }
+
+    private void synthesizeEmulatedDispatchMethods(DexApplication.Builder<?> builder) {
+      assert appView.options().isDesugaredLibraryCompilation();
+      if (emulatedDispatchMethods.isEmpty()) {
+        return;
+      }
+      ClassAccessFlags itfAccessFlags =
+          ClassAccessFlags.fromSharedAccessFlags(
+              Constants.ACC_PUBLIC
+                  | Constants.ACC_SYNTHETIC
+                  | Constants.ACC_ABSTRACT
+                  | Constants.ACC_INTERFACE);
+      ClassAccessFlags holderAccessFlags =
+          ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
+      for (DexMethod emulatedDispatchMethod : emulatedDispatchMethods) {
+        // Dispatch interface.
+        DexType interfaceType = dispatchInterfaceTypeFor(emulatedDispatchMethod);
+        DexEncodedMethod itfMethod =
+            generateInterfaceDispatchMethod(emulatedDispatchMethod, interfaceType);
+        BackportedMethodRewriter.synthesizeClassWithUniqueMethod(
+            builder,
+            itfAccessFlags,
+            interfaceType,
+            itfMethod,
+            "desugared library dispatch interface",
+            false,
+            appView);
+        // Dispatch holder.
+        DexType holderType = dispatchHolderTypeFor(emulatedDispatchMethod);
+        DexEncodedMethod dispatchMethod =
+            generateHolderDispatchMethod(emulatedDispatchMethod, holderType, itfMethod.method);
+        BackportedMethodRewriter.synthesizeClassWithUniqueMethod(
+            builder,
+            holderAccessFlags,
+            holderType,
+            dispatchMethod,
+            "desugared library dispatch class",
+            false,
+            appView);
+      }
+    }
+
+    private DexEncodedMethod generateInterfaceDispatchMethod(
+        DexMethod emulatedDispatchMethod, DexType interfaceType) {
+      MethodAccessFlags flags =
+          MethodAccessFlags.fromSharedAccessFlags(
+              Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT | Constants.ACC_SYNTHETIC, false);
+      DexMethod newMethod =
+          appView
+              .dexItemFactory()
+              .createMethod(
+                  interfaceType, emulatedDispatchMethod.proto, emulatedDispatchMethod.name);
+      return new DexEncodedMethod(
+          newMethod, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null, true);
+    }
+
+    private DexEncodedMethod generateHolderDispatchMethod(
+        DexMethod emulatedDispatchMethod, DexType dispatchHolder, DexMethod itfMethod) {
+      // The method should look like:
+      // static foo(rcvr, arg0, arg1) {
+      //    if (rcvr instanceof interfaceType) {
+      //      return invoke-interface receiver.foo(arg0, arg1);
+      //    } else {
+      //      return DesugarX.foo(rcvr, arg0, arg1)
+      //    }
+      // We do not deal with complex cases (multiple retargeting of the same signature in the
+      // same inheritance tree, etc., since they do not happen in the most common desugared library.
+      DexMethod desugarMethod =
+          appView
+              .options()
+              .desugaredLibraryConfiguration
+              .retargetMethod(emulatedDispatchMethod, appView);
+      assert desugarMethod != null; // This method is reached only for retarget core lib members.
+      DexMethod newMethod =
+          appView
+              .dexItemFactory()
+              .createMethod(dispatchHolder, desugarMethod.proto, emulatedDispatchMethod.name);
+      return DexEncodedMethod.toEmulateDispatchLibraryMethod(
+          emulatedDispatchMethod.holder,
+          newMethod,
+          desugarMethod,
+          itfMethod,
+          Collections.emptyList(),
+          appView);
+    }
+  }
+
+  private DexType dispatchInterfaceTypeFor(DexMethod method) {
+    return dispatchTypeFor(method, "dispatchInterface");
+  }
+
+  private DexType dispatchHolderTypeFor(DexMethod method) {
+    return dispatchTypeFor(method, "dispatchHolder");
+  }
+
+  private DexType dispatchTypeFor(DexMethod method, String suffix) {
+    String descriptor =
+        "L"
+            + appView
+                .options()
+                .desugaredLibraryConfiguration
+                .getSynthesizedLibraryClassesPackagePrefix()
+            + DESUGAR_LIB_RETARGET_CLASS_NAME_PREFIX
+            + '$'
+            + method.holder.getName()
+            + '$'
+            + method.name
+            + '$'
+            + suffix
+            + ';';
+    return appView.dexItemFactory().createType(descriptor);
+  }
+}
