diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 18d0352..891beb3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -4,6 +4,13 @@
 
 package com.android.tools.r8.ir.desugar;
 
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_CUSTOM;
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_DIRECT;
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_INTERFACE;
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_STATIC;
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_SUPER;
+import static com.android.tools.r8.ir.code.Opcodes.INVOKE_VIRTUAL;
+
 import com.android.tools.r8.DesugarGraphConsumer;
 import com.android.tools.r8.cf.CfVersion;
 import com.android.tools.r8.dex.Constants;
@@ -36,8 +43,10 @@
 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.InvokeCustom;
 import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.InvokeMethod;
+import com.android.tools.r8.ir.code.InvokeMethodWithReceiver;
 import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.InvokeSuper;
 import com.android.tools.r8.ir.conversion.IRConverter;
@@ -241,271 +250,295 @@
     }
 
     ListIterator<BasicBlock> blocks = code.listIterator();
-    AppInfo appInfo = appView.appInfo();
     while (blocks.hasNext()) {
       BasicBlock block = blocks.next();
       InstructionListIterator instructions = block.listIterator(code);
       while (instructions.hasNext()) {
         Instruction instruction = instructions.next();
-
-        if (instruction.isInvokeCustom()) {
-          // Check that static interface methods are not referenced
-          // from invoke-custom instructions via method handles.
-          DexCallSite callSite = instruction.asInvokeCustom().getCallSite();
-          reportStaticInterfaceMethodHandle(context, callSite.bootstrapMethod);
-          for (DexValue arg : callSite.bootstrapArgs) {
-            if (arg.isDexValueMethodHandle()) {
-              reportStaticInterfaceMethodHandle(context, arg.asDexValueMethodHandle().value);
-            }
-          }
-          continue;
+        switch (instruction.opcode()) {
+          case INVOKE_CUSTOM:
+            rewriteInvokeCustom(instruction.asInvokeCustom(), context);
+            break;
+          case INVOKE_DIRECT:
+            rewriteInvokeDirect(instruction.asInvokeDirect(), instructions, context);
+            break;
+          case INVOKE_STATIC:
+            rewriteInvokeStatic(instruction.asInvokeStatic(), instructions, context);
+            break;
+          case INVOKE_SUPER:
+            rewriteInvokeSuper(instruction.asInvokeSuper(), instructions, context);
+            break;
+          case INVOKE_INTERFACE:
+          case INVOKE_VIRTUAL:
+            rewriteInvokeInterfaceOrInvokeVirtual(
+                instruction.asInvokeMethodWithReceiver(), instructions);
+            break;
+          default:
+            // Intentionally empty.
+            break;
         }
+      }
+    }
+  }
 
-        if (instruction.isInvokeStatic()) {
-          InvokeStatic invokeStatic = instruction.asInvokeStatic();
-          DexMethod method = invokeStatic.getInvokedMethod();
-          if (appView.getSyntheticItems().isPendingSynthetic(method.holder)) {
-            // We did not create this code yet, but it will not require rewriting.
-            continue;
-          }
-          DexClass clazz = appInfo.definitionFor(method.holder);
-          if (clazz == null) {
-            // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
-            // exception but we can not report it as error since it can also be the intended
-            // behavior.
-            if (invokeStatic.getInterfaceBit()) {
-              leavingStaticInvokeToInterface(context);
-            }
-            warnMissingType(context, method.holder);
-          } else if (clazz.isInterface()) {
-            if (isNonDesugaredLibraryClass(clazz)) {
-              // NOTE: we intentionally don't desugar static calls into static interface
-              // methods coming from android.jar since it is only possible in case v24+
-              // version of android.jar is provided.
-              //
-              // We assume such calls are properly guarded by if-checks like
-              //    'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XYZ) { ... }'
-              //
-              // WARNING: This may result in incorrect code on older platforms!
-              // Retarget call to an appropriate method of companion class.
+  private void rewriteInvokeCustom(InvokeCustom invoke, ProgramMethod context) {
+    // Check that static interface methods are not referenced from invoke-custom instructions via
+    // method handles.
+    DexCallSite callSite = invoke.getCallSite();
+    reportStaticInterfaceMethodHandle(context, callSite.bootstrapMethod);
+    for (DexValue arg : callSite.bootstrapArgs) {
+      if (arg.isDexValueMethodHandle()) {
+        reportStaticInterfaceMethodHandle(context, arg.asDexValueMethodHandle().value);
+      }
+    }
+  }
 
-              if (!options.canLeaveStaticInterfaceMethodInvokes()) {
-                // On pre-L devices static calls to interface methods result in verifier
-                // rejecting the whole class. We have to create special dispatch classes,
-                // so the user class is not rejected because it make this call directly.
-                // TODO(b/166247515): If this an incorrect invoke-static without the interface bit
-                //  we end up "fixing" the code and remove and ICCE error.
-                ProgramMethod newProgramMethod =
-                    appView
-                        .getSyntheticItems()
-                        .createMethod(
-                            context.getHolder(),
-                            factory,
-                            syntheticMethodBuilder ->
-                                syntheticMethodBuilder
-                                    .setProto(method.proto)
-                                    .setAccessFlags(
-                                        MethodAccessFlags.fromSharedAccessFlags(
-                                            Constants.ACC_PUBLIC
-                                                | Constants.ACC_STATIC
-                                                | Constants.ACC_SYNTHETIC,
-                                            false))
-                                    .setCode(
-                                        m ->
-                                            ForwardMethodBuilder.builder(factory)
-                                                .setStaticTarget(method, true)
-                                                .setStaticSource(m)
-                                                .build()));
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        newProgramMethod.getReference(),
-                        invokeStatic.outValue(),
-                        invokeStatic.arguments()));
-                synchronized (synthesizedMethods) {
-                  // The synthetic dispatch class has static interface method invokes, so set
-                  // the class file version accordingly.
-                  newProgramMethod.getDefinition().upgradeClassFileVersion(CfVersion.V1_8);
-                  synthesizedMethods.add(newProgramMethod);
-                }
-              } else {
-                // When leaving static interface method invokes upgrade the class file version.
-                context.getDefinition().upgradeClassFileVersion(CfVersion.V1_8);
-              }
-            } else {
+  private void rewriteInvokeDirect(
+      InvokeDirect invoke, InstructionListIterator instructions, ProgramMethod context) {
+    DexMethod method = invoke.getInvokedMethod();
+    if (factory.isConstructor(method)) {
+      return;
+    }
+
+    DexClass clazz = appView.definitionForHolder(method, context);
+    if (clazz == null) {
+      // Report missing class since we don't know if it is an interface.
+      warnMissingType(context, method.holder);
+      return;
+    }
+
+    if (!clazz.isInterface()) {
+      return;
+    }
+
+    if (clazz.isLibraryClass()) {
+      throw new CompilationError(
+          "Unexpected call to a private method "
+              + "defined in library class "
+              + clazz.toSourceString(),
+          getMethodOrigin(context.getReference()));
+    }
+
+    DexEncodedMethod directTarget = clazz.lookupMethod(method);
+    if (directTarget != null) {
+      // This can be a private instance method call. Note that the referenced
+      // method is expected to be in the current class since it is private, but desugaring
+      // may move some methods or their code into other classes.
+      instructions.replaceCurrentInstruction(
+          new InvokeStatic(
+              directTarget.isPrivateMethod()
+                  ? privateAsMethodOfCompanionClass(method)
+                  : defaultAsMethodOfCompanionClass(method),
+              invoke.outValue(),
+              invoke.arguments()));
+    } else {
+      // The method can be a default method in the interface hierarchy.
+      DexClassAndMethod virtualTarget =
+          appView.appInfoForDesugaring().lookupMaximallySpecificMethod(clazz, method);
+      if (virtualTarget != null) {
+        // This is a invoke-direct call to a virtual method.
+        instructions.replaceCurrentInstruction(
+            new InvokeStatic(
+                defaultAsMethodOfCompanionClass(virtualTarget.getDefinition().method),
+                invoke.outValue(),
+                invoke.arguments()));
+      } else {
+        // The below assert is here because a well-type program should have a target, but we
+        // cannot throw a compilation error, since we have no knowledge about the input.
+        assert false;
+      }
+    }
+  }
+
+  private void rewriteInvokeStatic(
+      InvokeStatic invoke, InstructionListIterator instructions, ProgramMethod context) {
+    DexMethod invokedMethod = invoke.getInvokedMethod();
+    if (appView.getSyntheticItems().isPendingSynthetic(invokedMethod.holder)) {
+      // We did not create this code yet, but it will not require rewriting.
+      return;
+    }
+
+    DexClass clazz = appView.definitionFor(invokedMethod.holder, context);
+    if (clazz == null) {
+      // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
+      // exception but we can not report it as error since it can also be the intended
+      // behavior.
+      if (invoke.getInterfaceBit()) {
+        leavingStaticInvokeToInterface(context);
+      }
+      warnMissingType(context, invokedMethod.holder);
+      return;
+    }
+
+    if (!clazz.isInterface()) {
+      if (invoke.getInterfaceBit()) {
+        leavingStaticInvokeToInterface(context);
+      }
+      return;
+    }
+
+    if (isNonDesugaredLibraryClass(clazz)) {
+      // NOTE: we intentionally don't desugar static calls into static interface
+      // methods coming from android.jar since it is only possible in case v24+
+      // version of android.jar is provided.
+      //
+      // We assume such calls are properly guarded by if-checks like
+      //    'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XYZ) { ... }'
+      //
+      // WARNING: This may result in incorrect code on older platforms!
+      // Retarget call to an appropriate method of companion class.
+
+      if (!options.canLeaveStaticInterfaceMethodInvokes()) {
+        // On pre-L devices static calls to interface methods result in verifier
+        // rejecting the whole class. We have to create special dispatch classes,
+        // so the user class is not rejected because it make this call directly.
+        // TODO(b/166247515): If this an incorrect invoke-static without the interface bit
+        //  we end up "fixing" the code and remove and ICCE error.
+        ProgramMethod newProgramMethod =
+            appView
+                .getSyntheticItems()
+                .createMethod(
+                    context.getHolder(),
+                    factory,
+                    syntheticMethodBuilder ->
+                        syntheticMethodBuilder
+                            .setProto(invokedMethod.proto)
+                            .setAccessFlags(
+                                MethodAccessFlags.fromSharedAccessFlags(
+                                    Constants.ACC_PUBLIC
+                                        | Constants.ACC_STATIC
+                                        | Constants.ACC_SYNTHETIC,
+                                    false))
+                            .setCode(
+                                m ->
+                                    ForwardMethodBuilder.builder(factory)
+                                        .setStaticTarget(invokedMethod, true)
+                                        .setStaticSource(m)
+                                        .build()));
+        instructions.replaceCurrentInstruction(
+            new InvokeStatic(
+                newProgramMethod.getReference(), invoke.outValue(), invoke.arguments()));
+        synchronized (synthesizedMethods) {
+          // The synthetic dispatch class has static interface method invokes, so set
+          // the class file version accordingly.
+          newProgramMethod.getDefinition().upgradeClassFileVersion(CfVersion.V1_8);
+          synthesizedMethods.add(newProgramMethod);
+        }
+      } else {
+        // When leaving static interface method invokes upgrade the class file version.
+        context.getDefinition().upgradeClassFileVersion(CfVersion.V1_8);
+      }
+    } else {
+      instructions.replaceCurrentInstruction(
+          new InvokeStatic(
+              staticAsMethodOfCompanionClass(invokedMethod),
+              invoke.outValue(),
+              invoke.arguments()));
+    }
+  }
+
+  private void rewriteInvokeSuper(
+      InvokeSuper invoke, InstructionListIterator instructions, ProgramMethod context) {
+    DexMethod invokedMethod = invoke.getInvokedMethod();
+    DexClass clazz = appView.definitionFor(invokedMethod.holder, context);
+    if (clazz == null) {
+      // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
+      // exception but we can not report it as error since it can also be the intended
+      // behavior.
+      warnMissingType(context, invokedMethod.holder);
+      return;
+    }
+
+    if (clazz.isInterface() && !clazz.isLibraryClass()) {
+      // NOTE: we intentionally don't desugar super calls into interface methods
+      // coming from android.jar since it is only possible in case v24+ version
+      // of android.jar is provided.
+      //
+      // We assume such calls are properly guarded by if-checks like
+      //    'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XYZ) { ... }'
+      //
+      // WARNING: This may result in incorrect code on older platforms!
+      // Retarget call to an appropriate method of companion class.
+      DexMethod amendedMethod = amendDefaultMethod(context.getHolder(), invokedMethod);
+      instructions.replaceCurrentInstruction(
+          new InvokeStatic(
+              defaultAsMethodOfCompanionClass(amendedMethod),
+              invoke.outValue(),
+              invoke.arguments()));
+    } else {
+      DexType emulatedItf = maximallySpecificEmulatedInterfaceOrNull(invokedMethod);
+      if (emulatedItf == null) {
+        if (clazz.isInterface() && appView.rewritePrefix.hasRewrittenType(clazz.type, appView)) {
+          DexClassAndMethod target =
+              appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context);
+          if (target != null && target.getDefinition().isDefaultMethod()) {
+            DexClass holder = target.getHolder();
+            if (holder.isLibraryClass() && holder.isInterface()) {
               instructions.replaceCurrentInstruction(
-                  new InvokeStatic(staticAsMethodOfCompanionClass(method),
-                      invokeStatic.outValue(), invokeStatic.arguments()));
-            }
-          } else {
-            assert !clazz.isInterface();
-            if (invokeStatic.getInterfaceBit()) {
-              leavingStaticInvokeToInterface(context);
+                  new InvokeStatic(
+                      defaultAsMethodOfCompanionClass(target.getReference(), factory),
+                      invoke.outValue(),
+                      invoke.arguments()));
             }
           }
-          continue;
         }
-
-        if (instruction.isInvokeSuper()) {
-          InvokeSuper invokeSuper = instruction.asInvokeSuper();
-          DexMethod invokedMethod = invokeSuper.getInvokedMethod();
-          DexClass clazz = appInfo.definitionFor(invokedMethod.holder);
-          if (clazz == null) {
-            // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
-            // exception but we can not report it as error since it can also be the intended
-            // behavior.
-            warnMissingType(context, invokedMethod.holder);
-          } else if (clazz.isInterface() && !clazz.isLibraryClass()) {
-            // NOTE: we intentionally don't desugar super calls into interface methods
-            // coming from android.jar since it is only possible in case v24+ version
-            // of android.jar is provided.
-            //
-            // We assume such calls are properly guarded by if-checks like
-            //    'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XYZ) { ... }'
-            //
-            // WARNING: This may result in incorrect code on older platforms!
-            // Retarget call to an appropriate method of companion class.
-            DexMethod amendedMethod = amendDefaultMethod(context.getHolder(), invokedMethod);
+      } else {
+        // That invoke super may not resolve since the super method may not be present
+        // since it's in the emulated interface. We need to force resolution. If it resolves
+        // to a library method, then it needs to be rewritten.
+        // If it resolves to a program overrides, the invoke-super can remain.
+        DexClassAndMethod superTarget =
+            appView.appInfoForDesugaring().lookupSuperTarget(invoke.getInvokedMethod(), context);
+        if (superTarget != null && superTarget.isLibraryMethod()) {
+          // Rewriting is required because the super invoke resolves into a missing
+          // method (method is on desugared library). Find out if it needs to be
+          // retarget or if it just calls a companion class method and rewrite.
+          DexMethod retargetMethod =
+              options.desugaredLibraryConfiguration.retargetMethod(superTarget, appView);
+          if (retargetMethod == null) {
+            DexMethod originalCompanionMethod =
+                instanceAsMethodOfCompanionClass(
+                    superTarget.getReference(), DEFAULT_METHOD_PREFIX, factory);
+            DexMethod companionMethod =
+                factory.createMethod(
+                    getCompanionClassType(emulatedItf),
+                    factory.protoWithDifferentFirstParameter(
+                        originalCompanionMethod.proto, emulatedItf),
+                    originalCompanionMethod.name);
             instructions.replaceCurrentInstruction(
-                new InvokeStatic(defaultAsMethodOfCompanionClass(amendedMethod),
-                    invokeSuper.outValue(), invokeSuper.arguments()));
+                new InvokeStatic(companionMethod, invoke.outValue(), invoke.arguments()));
           } else {
-            DexType emulatedItf = maximallySpecificEmulatedInterfaceOrNull(invokedMethod);
-            if (emulatedItf == null) {
-              if (clazz.isInterface()
-                  && appView.rewritePrefix.hasRewrittenType(clazz.type, appView)) {
-                DexClassAndMethod target =
-                    appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, code.context());
-                if (target != null && target.getDefinition().isDefaultMethod()) {
-                  DexClass holder = target.getHolder();
-                  if (holder.isLibraryClass() && holder.isInterface()) {
-                    instructions.replaceCurrentInstruction(
-                        new InvokeStatic(
-                            defaultAsMethodOfCompanionClass(target.getReference(), factory),
-                            invokeSuper.outValue(),
-                            invokeSuper.arguments()));
-                  }
-                }
-              }
-            } else {
-              // That invoke super may not resolve since the super method may not be present
-              // since it's in the emulated interface. We need to force resolution. If it resolves
-              // to a library method, then it needs to be rewritten.
-              // If it resolves to a program overrides, the invoke-super can remain.
-              DexClassAndMethod superTarget =
-                  appView
-                      .appInfoForDesugaring()
-                      .lookupSuperTarget(invokeSuper.getInvokedMethod(), code.context());
-              if (superTarget != null && superTarget.isLibraryMethod()) {
-                // Rewriting is required because the super invoke resolves into a missing
-                // method (method is on desugared library). Find out if it needs to be
-                // retarget or if it just calls a companion class method and rewrite.
-                DexMethod retargetMethod =
-                    options.desugaredLibraryConfiguration.retargetMethod(superTarget, appView);
-                if (retargetMethod == null) {
-                  DexMethod originalCompanionMethod =
-                      instanceAsMethodOfCompanionClass(
-                          superTarget.getReference(), DEFAULT_METHOD_PREFIX, factory);
-                  DexMethod companionMethod =
-                      factory.createMethod(
-                          getCompanionClassType(emulatedItf),
-                          factory.protoWithDifferentFirstParameter(
-                              originalCompanionMethod.proto, emulatedItf),
-                          originalCompanionMethod.name);
-                  instructions.replaceCurrentInstruction(
-                      new InvokeStatic(
-                          companionMethod, invokeSuper.outValue(), invokeSuper.arguments()));
-                } else {
-                  instructions.replaceCurrentInstruction(
-                      new InvokeStatic(
-                          retargetMethod, invokeSuper.outValue(), invokeSuper.arguments()));
-                }
-              }
-            }
-          }
-          continue;
-        }
-
-        if (instruction.isInvokeDirect()) {
-          InvokeDirect invokeDirect = instruction.asInvokeDirect();
-          DexMethod method = invokeDirect.getInvokedMethod();
-          if (factory.isConstructor(method)) {
-            continue;
-          }
-
-          DexClass clazz = appInfo.definitionForHolder(method, context);
-          if (clazz == null) {
-            // Report missing class since we don't know if it is an interface.
-            warnMissingType(context, method.holder);
-          } else if (clazz.isInterface()) {
-            if (clazz.isLibraryClass()) {
-              throw new CompilationError(
-                  "Unexpected call to a private method "
-                      + "defined in library class "
-                      + clazz.toSourceString(),
-                  getMethodOrigin(context.getReference()));
-            }
-            DexEncodedMethod directTarget = clazz.lookupMethod(method);
-            if (directTarget != null) {
-              // This can be a private instance method call. Note that the referenced
-              // method is expected to be in the current class since it is private, but desugaring
-              // may move some methods or their code into other classes.
-              if (directTarget.isPrivateMethod()) {
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        privateAsMethodOfCompanionClass(method),
-                        invokeDirect.outValue(),
-                        invokeDirect.arguments()));
-              } else {
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        defaultAsMethodOfCompanionClass(method),
-                        invokeDirect.outValue(),
-                        invokeDirect.arguments()));
-              }
-            } else {
-              // The method can be a default method in the interface hierarchy.
-              DexClassAndMethod virtualTarget =
-                  appView.appInfoForDesugaring().lookupMaximallySpecificMethod(clazz, method);
-              if (virtualTarget != null) {
-                // This is a invoke-direct call to a virtual method.
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        defaultAsMethodOfCompanionClass(virtualTarget.getDefinition().method),
-                        invokeDirect.outValue(),
-                        invokeDirect.arguments()));
-              } else {
-                // The below assert is here because a well-type program should have a target, but we
-                // cannot throw a compilation error, since we have no knowledge about the input.
-                assert false;
-              }
-            }
-          }
-        }
-
-        if (instruction.isInvokeVirtual() || instruction.isInvokeInterface()) {
-          InvokeMethod invokeMethod = instruction.asInvokeMethod();
-          DexMethod invokedMethod = invokeMethod.getInvokedMethod();
-          DexType emulatedItf = maximallySpecificEmulatedInterfaceOrNull(invokedMethod);
-          if (emulatedItf != null) {
-            // The call potentially ends up in a library class, in which case we need to rewrite,
-            // since the code may be in the desugared library.
-            SingleResolutionResult resolution =
-                appView
-                    .appInfoForDesugaring()
-                    .resolveMethod(invokedMethod, invokeMethod.getInterfaceBit())
-                    .asSingleResolution();
-            if (resolution != null
-                && (resolution.getResolvedHolder().isLibraryClass()
-                    || appView.options().isDesugaredLibraryCompilation())) {
-              rewriteCurrentInstructionToEmulatedInterfaceCall(
-                  emulatedItf, invokedMethod, invokeMethod, instructions);
-            }
+            instructions.replaceCurrentInstruction(
+                new InvokeStatic(retargetMethod, invoke.outValue(), invoke.arguments()));
           }
         }
       }
     }
   }
 
+  private void rewriteInvokeInterfaceOrInvokeVirtual(
+      InvokeMethodWithReceiver invoke, InstructionListIterator instructions) {
+    DexMethod invokedMethod = invoke.getInvokedMethod();
+    DexType emulatedItf = maximallySpecificEmulatedInterfaceOrNull(invokedMethod);
+    if (emulatedItf == null) {
+      return;
+    }
+
+    // The call potentially ends up in a library class, in which case we need to rewrite, since the
+    // code may be in the desugared library.
+    SingleResolutionResult resolution =
+        appView
+            .appInfoForDesugaring()
+            .resolveMethod(invokedMethod, invoke.getInterfaceBit())
+            .asSingleResolution();
+    if (resolution != null
+        && (resolution.getResolvedHolder().isLibraryClass()
+            || appView.options().isDesugaredLibraryCompilation())) {
+      rewriteCurrentInstructionToEmulatedInterfaceCall(
+          emulatedItf, invokedMethod, invoke, instructions);
+    }
+  }
+
   private DexType maximallySpecificEmulatedInterfaceOrNull(DexMethod invokedMethod) {
     // Here we try to avoid doing the expensive look-up on all invokes.
     if (!emulatedMethods.contains(invokedMethod.name)) {
