Merge commit '34bf016d7e1728395f5e791faa2a1c0cdfb3dcdb' into dev-release
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
index f7f3305..eb725d9 100644
--- a/infra/config/global/luci-scheduler.cfg
+++ b/infra/config/global/luci-scheduler.cfg
@@ -59,7 +59,7 @@
   gitiles: {
     repo: "https://r8.googlesource.com/r8"
     # Version branches are named d8-x.y (up until d8-1.5) or just x.y (from 1.6)
-    refs: "regexp:refs/heads/(?:d8-)?[0-9]+\\.[0-9]+"
+    refs: "regexp:refs/heads/(?:d8-)?[0-9]+\\.[0-9]+(\\.[0-9]+)?"
     path_regexps: "src/main/java/com/android/tools/r8/Version.java"
   }
   triggers: "archive_release"
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index b456ecb..e502f2f 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -14,7 +14,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.analysis.ClassInitializerAssertionEnablingAnalysis;
@@ -244,7 +244,7 @@
                 appView,
                 options,
                 marker,
-                GraphLense.getIdentityLense(),
+                GraphLens.getIdentityLens(),
                 NamingLens.getIdentityLens(),
                 null)
             .write(options.getClassFileConsumer());
@@ -272,7 +272,7 @@
                 appView,
                 options,
                 marker == null ? null : ImmutableList.copyOf(markers),
-                GraphLense.getIdentityLense(),
+                GraphLens.getIdentityLens(),
                 InitClassLens.getDefault(),
                 namingLens,
                 null)
@@ -327,7 +327,7 @@
             null,
             options,
             null,
-            GraphLense.getIdentityLense(),
+            GraphLens.getIdentityLens(),
             InitClassLens.getDefault(),
             prefixRewritingNamingLens,
             null,
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index 94ea634..1171440 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.AndroidApp;
@@ -102,7 +102,7 @@
                 null,
                 options,
                 markers,
-                GraphLense.getIdentityLense(),
+                GraphLens.getIdentityLens(),
                 InitClassLens.getDefault(),
                 NamingLens.getIdentityLens(),
                 null);
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index a9d4644..8d2d47d 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.naming.ClassNameMapper;
@@ -101,7 +101,7 @@
                   null,
                   options,
                   markers,
-                  GraphLense.getIdentityLense(),
+                  GraphLens.getIdentityLens(),
                   InitClassLens.getDefault(),
                   NamingLens.getIdentityLens(),
                   null,
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index bbee24d..7913783 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -24,7 +24,7 @@
 import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryConfigurationParser;
@@ -319,7 +319,7 @@
             appView,
             options,
             options.getMarker(Tool.L8),
-            GraphLense.getIdentityLense(),
+            GraphLens.getIdentityLens(),
             NamingLens.getIdentityLens(),
             null);
     ClassFileConsumer consumer =
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index f5059e4..8049508 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
@@ -145,7 +145,7 @@
               appView,
               options,
               options.getMarker(Tool.L8),
-              GraphLense.getIdentityLense(),
+              GraphLens.getIdentityLens(),
               namingLens,
               null)
           .write(options.getClassFileConsumer());
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 17ee9af..93f229c 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -32,8 +32,8 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.EnumValueInfoMapCollection;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.SubtypingInfo;
 import com.android.tools.r8.graph.analysis.ClassInitializerAssertionEnablingAnalysis;
@@ -43,16 +43,16 @@
 import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
-import com.android.tools.r8.ir.desugar.NestedPrivateMethodLense;
+import com.android.tools.r8.ir.desugar.NestedPrivateMethodLens;
 import com.android.tools.r8.ir.desugar.R8NestBasedAccessDesugaring;
 import com.android.tools.r8.ir.optimize.AssertionsRewriter;
 import com.android.tools.r8.ir.optimize.MethodPoolCollection;
 import com.android.tools.r8.ir.optimize.NestReducer;
 import com.android.tools.r8.ir.optimize.SwitchMapCollector;
 import com.android.tools.r8.ir.optimize.UninstantiatedTypeOptimization;
-import com.android.tools.r8.ir.optimize.UninstantiatedTypeOptimization.UninstantiatedTypeOptimizationGraphLense;
+import com.android.tools.r8.ir.optimize.UninstantiatedTypeOptimization.UninstantiatedTypeOptimizationGraphLens;
 import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector;
-import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector.UnusedArgumentsGraphLense;
+import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector.UnusedArgumentsGraphLens;
 import com.android.tools.r8.ir.optimize.enums.EnumUnboxingCfMethods;
 import com.android.tools.r8.ir.optimize.enums.EnumUnboxingRewriter;
 import com.android.tools.r8.ir.optimize.enums.EnumValueInfoMapCollector;
@@ -94,7 +94,7 @@
 import com.android.tools.r8.shaking.TreePruner;
 import com.android.tools.r8.shaking.TreePrunerConfiguration;
 import com.android.tools.r8.shaking.VerticalClassMerger;
-import com.android.tools.r8.shaking.VerticalClassMergerGraphLense;
+import com.android.tools.r8.shaking.VerticalClassMergerGraphLens;
 import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -206,7 +206,7 @@
       ExecutorService executorService,
       DexApplication application,
       AppView<?> appView,
-      GraphLense graphLense,
+      GraphLens graphLens,
       InitClassLens initClassLens,
       NamingLens namingLens,
       InternalOptions options,
@@ -222,7 +222,7 @@
       markers.remove(marker);
       if (options.isGeneratingClassFiles()) {
         new CfApplicationWriter(
-                application, appView, options, marker, graphLense, namingLens, proguardMapSupplier)
+                application, appView, options, marker, graphLens, namingLens, proguardMapSupplier)
             .write(options.getClassFileConsumer());
       } else {
         new ApplicationWriter(
@@ -231,7 +231,7 @@
                 options,
                 // Ensure that the marker for this compilation is the first in the list.
                 ImmutableList.<Marker>builder().add(marker).addAll(markers).build(),
-                graphLense,
+                graphLens,
                 initClassLens,
                 namingLens,
                 proguardMapSupplier)
@@ -438,7 +438,7 @@
       RootSet mainDexRootSet = null;
       MainDexClasses mainDexClasses = MainDexClasses.NONE;
       if (!options.mainDexKeepRules.isEmpty()) {
-        assert appView.graphLense().isIdentityLense();
+        assert appView.graphLens().isIdentityLens();
         // Find classes which may have code executed before secondary dex files installation.
         SubtypingInfo subtypingInfo =
             new SubtypingInfo(appView.appInfo().app().asDirect().allClasses(), appView);
@@ -462,10 +462,10 @@
       if (options.getProguardConfiguration().isAccessModificationAllowed()) {
         AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
         SubtypingInfo subtypingInfo = appViewWithLiveness.appInfo().computeSubtypingInfo();
-        GraphLense publicizedLense =
+        GraphLens publicizedLens =
             ClassAndMemberPublicizer.run(
                 executorService, timing, application, appViewWithLiveness, subtypingInfo);
-        boolean changed = appView.setGraphLense(publicizedLense);
+        boolean changed = appView.setGraphLens(publicizedLens);
         if (changed) {
           // We can now remove visibility bridges. Note that we do not need to update the
           // invoke-targets here, as the existing invokes will simply dispatch to the now
@@ -475,15 +475,15 @@
       }
 
       AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
-      appView.setGraphLense(new MemberRebindingAnalysis(appViewWithLiveness).run());
+      appView.setGraphLens(new MemberRebindingAnalysis(appViewWithLiveness).run());
       appView.appInfo().withLiveness().getFieldAccessInfoCollection().restrictToProgram(appView);
 
       if (options.shouldDesugarNests()) {
         timing.begin("NestBasedAccessDesugaring");
         R8NestBasedAccessDesugaring analyzer = new R8NestBasedAccessDesugaring(appViewWithLiveness);
-        NestedPrivateMethodLense lens = analyzer.run(executorService, application.builder());
+        NestedPrivateMethodLens lens = analyzer.run(executorService, application.builder());
         if (lens != null) {
-          boolean changed = appView.setGraphLense(lens);
+          boolean changed = appView.setGraphLens(lens);
           assert changed;
           appViewWithLiveness.setAppInfo(
               appViewWithLiveness.appInfo().rewrittenWithLens(application.asDirect(), lens));
@@ -508,9 +508,9 @@
           timing.begin("HorizontalStaticClassMerger");
           StaticClassMerger staticClassMerger =
               new StaticClassMerger(appViewWithLiveness, options, mainDexClasses);
-          NestedGraphLense lens = staticClassMerger.run();
+          NestedGraphLens lens = staticClassMerger.run();
           if (lens != null) {
-            boolean changed = appView.setGraphLense(lens);
+            boolean changed = appView.setGraphLens(lens);
             assert changed;
             appViewWithLiveness.setAppInfo(
                 appViewWithLiveness.appInfo().rewrittenWithLens(application.asDirect(), lens));
@@ -522,9 +522,9 @@
           VerticalClassMerger verticalClassMerger =
               new VerticalClassMerger(
                   application, appViewWithLiveness, executorService, timing, mainDexClasses);
-          VerticalClassMergerGraphLense lens = verticalClassMerger.run();
+          VerticalClassMergerGraphLens lens = verticalClassMerger.run();
           if (lens != null) {
-            boolean changed = appView.setGraphLense(lens);
+            boolean changed = appView.setGraphLens(lens);
             assert changed;
             appView.setVerticallyMergedClasses(verticalClassMerger.getMergedClasses());
             application = application.asDirect().rewrittenWithLens(lens);
@@ -537,13 +537,13 @@
           SubtypingInfo subtypingInfo = appViewWithLiveness.appInfo().computeSubtypingInfo();
           {
             timing.begin("UnusedArgumentRemoval");
-            UnusedArgumentsGraphLense lens =
+            UnusedArgumentsGraphLens lens =
                 new UnusedArgumentsCollector(
                         appViewWithLiveness,
                         new MethodPoolCollection(appViewWithLiveness, subtypingInfo))
                     .run(executorService, timing);
             if (lens != null) {
-              boolean changed = appView.setGraphLense(lens);
+              boolean changed = appView.setGraphLens(lens);
               assert changed;
               assert application.asDirect().verifyNothingToRewrite(appView, lens);
               appViewWithLiveness.setAppInfo(
@@ -553,7 +553,7 @@
           }
           if (options.enableUninstantiatedTypeOptimization) {
             timing.begin("UninstantiatedTypeOptimization");
-            UninstantiatedTypeOptimizationGraphLense lens =
+            UninstantiatedTypeOptimizationGraphLens lens =
                 new UninstantiatedTypeOptimization(appViewWithLiveness)
                     .strenghtenOptimizationInfo()
                     .run(
@@ -561,7 +561,7 @@
                         executorService,
                         timing);
             if (lens != null) {
-              boolean changed = appView.setGraphLense(lens);
+              boolean changed = appView.setGraphLens(lens);
               assert changed;
               assert application.asDirect().verifyNothingToRewrite(appView, lens);
               appViewWithLiveness.setAppInfo(
@@ -583,7 +583,7 @@
         appViewWithLiveness.setAppInfo(new EnumValueInfoMapCollector(appViewWithLiveness).run());
       }
 
-      appView.setAppServices(appView.appServices().rewrittenWithLens(appView.graphLense()));
+      appView.setAppServices(appView.appServices().rewrittenWithLens(appView.graphLens()));
 
       timing.begin("Create IR");
       CfgPrinter printer = options.printCfg ? new CfgPrinter() : null;
@@ -601,7 +601,7 @@
       // graph lens entirely, though, since it is needed for mapping all field and method signatures
       // back to the original program.
       timing.begin("AppliedGraphLens construction");
-      appView.setGraphLense(new AppliedGraphLens(appView, application.classes()));
+      appView.setGraphLens(new AppliedGraphLens(appView, application.classes()));
       timing.end();
 
       if (options.printCfg) {
@@ -702,7 +702,7 @@
                       timing)
                   .withEnumValueInfoMaps(enumValueInfoMapCollection));
           // Rerunning the enqueuer should not give rise to any method rewritings.
-          assert enqueuer.buildGraphLense(appView) == appView.graphLense();
+          assert enqueuer.buildGraphLens(appView) == appView.graphLens();
           appView.withGeneratedMessageLiteBuilderShrinker(
               shrinker ->
                   shrinker.rewriteDeadBuilderReferencesFromDynamicMethods(
@@ -861,7 +861,7 @@
         assert appView.rootSet().verifyKeptItemsAreKept(application, appView.appInfo());
       }
       assert appView
-          .graphLense()
+          .graphLens()
           .verifyMappingToOriginalProgram(
               application.classesWithDeterministicOrder(),
               new ApplicationReader(inputApp.withoutMainDexList(), options, timing)
@@ -885,7 +885,7 @@
           executorService,
           application,
           appView,
-          appView.graphLense(),
+          appView.graphLens(),
           appView.initClassLens(),
           prefixRewritingNamingLens,
           options,
@@ -912,11 +912,11 @@
               clazz.forEachProgramMethod(
                   method -> {
                     DexMethod originalMethod =
-                        appView.graphLense().getOriginalMethodSignature(method.getReference());
+                        appView.graphLens().getOriginalMethodSignature(method.getReference());
                     if (originalMethod != method.getReference()) {
                       DexMethod originalMethod2 =
-                          appView.graphLense().getOriginalMethodSignature(method.getReference());
-                      appView.graphLense().getOriginalMethodSignature(method.getReference());
+                          appView.graphLens().getOriginalMethodSignature(method.getReference());
+                      appView.graphLens().getOriginalMethodSignature(method.getReference());
                       DexEncodedMethod definition = method.getDefinition();
                       Code code = definition.getCode();
                       if (code == null) {
@@ -979,7 +979,7 @@
                 options.getProguardConfiguration().getDontWarnPatterns(),
                 executorService,
                 timing));
-    appView.setGraphLense(enqueuer.buildGraphLense(appView));
+    appView.setGraphLens(enqueuer.buildGraphLens(appView));
     if (InternalOptions.assertionsEnabled()) {
       // Register the dead proto types. These are needed to verify that no new missing types are
       // reported and that no dead proto types are referenced in the generated application.
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 8889e81..a7949db 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -15,8 +15,8 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.GraphLenseLookupResult;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.GraphLensLookupResult;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.UseRegistry;
 import com.android.tools.r8.ir.code.Invoke;
@@ -202,7 +202,7 @@
   @Override
   public ConstraintWithTarget inliningConstraint(
       InliningConstraints inliningConstraints, DexProgramClass context) {
-    GraphLense graphLense = inliningConstraints.getGraphLense();
+    GraphLens graphLens = inliningConstraints.getGraphLens();
     AppView<?> appView = inliningConstraints.getAppView();
     DexMethod target = method;
     // Find the DEX invocation type.
@@ -211,17 +211,17 @@
       case Opcodes.INVOKEINTERFACE:
         // Could have changed to an invoke-virtual instruction due to vertical class merging
         // (if an interface is merged into a class).
-        type = graphLense.lookupMethod(target, null, Type.INTERFACE).getType();
+        type = graphLens.lookupMethod(target, null, Type.INTERFACE).getType();
         assert type == Type.INTERFACE || type == Type.VIRTUAL;
         break;
 
       case Opcodes.INVOKESPECIAL:
         if (appView.dexItemFactory().isConstructor(target)) {
           type = Type.DIRECT;
-          assert noNeedToUseGraphLense(target, type, graphLense);
+          assert noNeedToUseGraphLens(target, type, graphLens);
         } else if (target.holder == context.type) {
           // The method could have been publicized.
-          type = graphLense.lookupMethod(target, null, Type.DIRECT).getType();
+          type = graphLens.lookupMethod(target, null, Type.DIRECT).getType();
           assert type == Type.DIRECT || type == Type.VIRTUAL;
         } else {
           // This is a super call. Note that the vertical class merger translates some invoke-super
@@ -229,17 +229,17 @@
           // the target method end up being in the same class, and therefore, we will allow inlining
           // it. The result of using type=SUPER below will be the same, since it leads to the
           // inlining constraint SAMECLASS.
-          // TODO(christofferqa): Consider using graphLense.lookupMethod (to do this, we need the
-          // context for the graph lense, though).
+          // TODO(christofferqa): Consider using graphLens.lookupMethod (to do this, we need the
+          // context for the graph lens, though).
           type = Type.SUPER;
-          assert noNeedToUseGraphLense(target, type, graphLense);
+          assert noNeedToUseGraphLens(target, type, graphLens);
         }
         break;
 
       case Opcodes.INVOKESTATIC:
         {
           // Static invokes may have changed as a result of horizontal class merging.
-          GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, Type.STATIC);
+          GraphLensLookupResult lookup = graphLens.lookupMethod(target, null, Type.STATIC);
           target = lookup.getMethod();
           type = lookup.getType();
         }
@@ -258,7 +258,7 @@
           }
 
           // Virtual invokes may have changed to interface invokes as a result of member rebinding.
-          GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, type);
+          GraphLensLookupResult lookup = graphLens.lookupMethod(target, null, type);
           target = lookup.getMethod();
           type = lookup.getType();
         }
@@ -271,9 +271,9 @@
     return inliningConstraints.forInvoke(target, type, context);
   }
 
-  private static boolean noNeedToUseGraphLense(
-      DexMethod method, Invoke.Type type, GraphLense graphLense) {
-    assert graphLense.lookupMethod(method, null, type).getType() == type;
+  private static boolean noNeedToUseGraphLens(
+      DexMethod method, Invoke.Type type, GraphLens graphLens) {
+    assert graphLens.lookupMethod(method, null, type).getType() == type;
     return true;
   }
 
@@ -304,8 +304,8 @@
   }
 
   private DexEncodedMethod lookupMethod(AppView<?> appView, DexMethod method) {
-    GraphLenseLookupResult lookupResult =
-        appView.graphLense().lookupMethod(method, method, Type.DIRECT);
+    GraphLensLookupResult lookupResult =
+        appView.graphLens().lookupMethod(method, method, Type.DIRECT);
     DexMethod rewrittenMethod = lookupResult.getMethod();
     DexProgramClass clazz = appView.definitionForProgramType(rewrittenMethod.holder);
     assert clazz != null;
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 8986801..f0e8da6 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -33,7 +33,7 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.EnclosingMethodAttribute;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -69,7 +69,7 @@
 
   public final DexApplication application;
   public final AppView<?> appView;
-  public final GraphLense graphLense;
+  public final GraphLens graphLens;
   public final InitClassLens initClassLens;
   public final NamingLens namingLens;
   public final InternalOptions options;
@@ -148,7 +148,7 @@
       AppView<?> appView,
       InternalOptions options,
       List<Marker> markers,
-      GraphLense graphLense,
+      GraphLens graphLens,
       InitClassLens initClassLens,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier) {
@@ -157,7 +157,7 @@
         appView,
         options,
         markers,
-        graphLense,
+        graphLens,
         initClassLens,
         namingLens,
         proguardMapSupplier,
@@ -169,7 +169,7 @@
       AppView<?> appView,
       InternalOptions options,
       List<Marker> markers,
-      GraphLense graphLense,
+      GraphLens graphLens,
       InitClassLens initClassLens,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier,
@@ -181,7 +181,7 @@
     this.options = options;
     this.desugaredLibraryCodeToKeep = CodeToKeep.createCodeToKeep(options, namingLens);
     this.markers = markers;
-    this.graphLense = graphLense;
+    this.graphLens = graphLens;
     this.initClassLens = initClassLens;
     this.namingLens = namingLens;
     this.proguardMapSupplier = proguardMapSupplier;
@@ -338,7 +338,7 @@
       // Fail if there are pending errors, e.g., the program consumers may have reported errors.
       options.reporter.failIfPendingErrors();
       // Supply info to all additional resource consumers.
-      supplyAdditionalConsumers(application, appView, graphLense, namingLens, options);
+      supplyAdditionalConsumers(application, appView, graphLens, namingLens, options);
     } finally {
       application.timing.end();
     }
@@ -347,7 +347,7 @@
   public static void supplyAdditionalConsumers(
       DexApplication application,
       AppView<?> appView,
-      GraphLense graphLense,
+      GraphLens graphLens,
       NamingLens namingLens,
       InternalOptions options) {
     if (options.configurationConsumer != null) {
@@ -366,7 +366,7 @@
     if (dataResourceConsumer != null) {
       ImmutableList<DataResourceProvider> dataResourceProviders = application.dataResourceProviders;
       ResourceAdapter resourceAdapter =
-          new ResourceAdapter(appView, application.dexItemFactory, graphLense, namingLens, options);
+          new ResourceAdapter(appView, application.dexItemFactory, graphLens, namingLens, options);
 
       adaptAndPassDataResources(
           options, dataResourceConsumer, dataResourceProviders, resourceAdapter);
@@ -402,7 +402,7 @@
           options.featureSplitConfiguration.getDataResourceProvidersAndConsumers()) {
         ResourceAdapter resourceAdapter =
             new ResourceAdapter(
-                appView, application.dexItemFactory, graphLense, namingLens, options);
+                appView, application.dexItemFactory, graphLens, namingLens, options);
         adaptAndPassDataResources(
             options, entry.getConsumer(), entry.getProviders(), resourceAdapter);
       }
diff --git a/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java b/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
index 14a8261..536515d 100644
--- a/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
+++ b/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.ProguardPathFilter;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -31,20 +31,20 @@
 
   private final AppView<?> appView;
   private final DexItemFactory dexItemFactory;
-  private final GraphLense graphLense;
-  private final NamingLens namingLense;
+  private final GraphLens graphLens;
+  private final NamingLens namingLens;
   private final InternalOptions options;
 
   public ResourceAdapter(
       AppView<?> appView,
       DexItemFactory dexItemFactory,
-      GraphLense graphLense,
-      NamingLens namingLense,
+      GraphLens graphLens,
+      NamingLens namingLens,
       InternalOptions options) {
     this.appView = appView;
     this.dexItemFactory = dexItemFactory;
-    this.graphLense = graphLense;
-    this.namingLense = namingLense;
+    this.graphLens = graphLens;
+    this.namingLens = namingLens;
     this.options = options;
   }
 
@@ -268,7 +268,7 @@
               DescriptorUtils.javaTypeToDescriptorIgnorePrimitives(javaType));
       DexType dexType = descriptor != null ? dexItemFactory.lookupType(descriptor) : null;
       if (dexType != null) {
-        DexString renamedDescriptor = namingLense.lookupDescriptor(graphLense.lookupType(dexType));
+        DexString renamedDescriptor = namingLens.lookupDescriptor(graphLens.lookupType(dexType));
         if (!descriptor.equals(renamedDescriptor)) {
           String renamedJavaType =
               DescriptorUtils.descriptorToJavaType(renamedDescriptor.toSourceString());
@@ -293,7 +293,7 @@
       if (getClassNameSeparator() != '/') {
         javaPackage = javaPackage.replace(getClassNameSeparator(), '/');
       }
-      String minifiedJavaPackage = namingLense.lookupPackageName(javaPackage);
+      String minifiedJavaPackage = namingLens.lookupPackageName(javaPackage);
       if (!javaPackage.equals(minifiedJavaPackage)) {
         outputRangeFromInput(outputFrom, from);
         outputJavaType(
diff --git a/src/main/java/com/android/tools/r8/graph/AppServices.java b/src/main/java/com/android/tools/r8/graph/AppServices.java
index 0dbaa30..f853b30 100644
--- a/src/main/java/com/android/tools/r8/graph/AppServices.java
+++ b/src/main/java/com/android/tools/r8/graph/AppServices.java
@@ -101,7 +101,7 @@
     return false;
   }
 
-  public AppServices rewrittenWithLens(GraphLense graphLens) {
+  public AppServices rewrittenWithLens(GraphLens graphLens) {
     ImmutableMap.Builder<DexType, Map<FeatureSplit, List<DexType>>> rewrittenFeatureMappings =
         ImmutableMap.builder();
     for (Entry<DexType, Map<FeatureSplit, List<DexType>>> entry : services.entrySet()) {
@@ -157,10 +157,10 @@
 
   private boolean verifyRewrittenWithLens() {
     for (Entry<DexType, Map<FeatureSplit, List<DexType>>> entry : services.entrySet()) {
-      assert entry.getKey() == appView.graphLense().lookupType(entry.getKey());
+      assert entry.getKey() == appView.graphLens().lookupType(entry.getKey());
       for (Entry<FeatureSplit, List<DexType>> featureEntry : entry.getValue().entrySet()) {
         for (DexType type : featureEntry.getValue()) {
-          assert type == appView.graphLense().lookupType(type);
+          assert type == appView.graphLens().lookupType(type);
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 245a9ab..7b0c80f 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -45,7 +45,7 @@
   private AppInfoWithClassHierarchy appInfoForDesugaring;
   private AppServices appServices;
   private final WholeProgramOptimizations wholeProgramOptimizations;
-  private GraphLense graphLense;
+  private GraphLens graphLens;
   private InitClassLens initClassLens;
   private RootSet rootSet;
   // This should perferably always be obtained via AppInfoWithLiveness.
@@ -82,7 +82,7 @@
     assert appInfo != null;
     this.appInfo = appInfo;
     this.wholeProgramOptimizations = wholeProgramOptimizations;
-    this.graphLense = GraphLense.getIdentityLense();
+    this.graphLens = GraphLens.getIdentityLens();
     this.initClassLens = InitClassLens.getDefault();
     this.methodProcessingIdFactory =
         new MethodProcessingId.Factory(options().testing.methodProcessingIdConsumer);
@@ -196,8 +196,8 @@
     allCodeProcessed = true;
   }
 
-  public GraphLense clearCodeRewritings() {
-    return graphLense = graphLense.withCodeRewritingsApplied();
+  public GraphLens clearCodeRewritings() {
+    return graphLens = graphLens.withCodeRewritingsApplied();
   }
 
   public AppServices appServices() {
@@ -329,14 +329,14 @@
     return defaultValue;
   }
 
-  public GraphLense graphLense() {
-    return graphLense;
+  public GraphLens graphLens() {
+    return graphLens;
   }
 
   /** @return true if the graph lens changed, otherwise false. */
-  public boolean setGraphLense(GraphLense graphLense) {
-    if (graphLense != this.graphLense) {
-      this.graphLense = graphLense;
+  public boolean setGraphLens(GraphLens graphLens) {
+    if (graphLens != this.graphLens) {
+      this.graphLens = graphLens;
       return true;
     }
     return false;
diff --git a/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java b/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
index 7e46aad..b602135 100644
--- a/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
@@ -17,7 +17,7 @@
  *
  * <p>The mappings from the original program to the generated program are kept, though.
  */
-public class AppliedGraphLens extends GraphLense {
+public class AppliedGraphLens extends GraphLens {
 
   private final AppView<?> appView;
 
@@ -37,7 +37,7 @@
         DexType type = clazz.type;
         if (appView.verticallyMergedClasses() != null
             && !appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(type)) {
-          DexType original = appView.graphLense().getOriginalType(type);
+          DexType original = appView.graphLens().getOriginalType(type);
           if (original != type) {
             DexType existing = originalTypeNames.forcePut(type, original);
             assert existing == null;
@@ -48,7 +48,7 @@
       // Record original field signatures.
       for (DexEncodedField encodedField : clazz.fields()) {
         DexField field = encodedField.field;
-        DexField original = appView.graphLense().getOriginalFieldSignature(field);
+        DexField original = appView.graphLens().getOriginalFieldSignature(field);
         if (original != field) {
           DexField existing = originalFieldSignatures.forcePut(field, original);
           assert existing == null;
@@ -58,7 +58,7 @@
       // Record original method signatures.
       for (DexEncodedMethod encodedMethod : clazz.methods()) {
         DexMethod method = encodedMethod.method;
-        DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
+        DexMethod original = appView.graphLens().getOriginalMethodSignature(method);
         if (original != method) {
           DexMethod existing = originalMethodSignatures.inverse().get(original);
           if (existing == null) {
@@ -101,7 +101,7 @@
   }
 
   @Override
-  public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied) {
+  public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
     return this != applied
         ? originalMethodSignatures.inverse().getOrDefault(originalMethod, originalMethod)
         : originalMethod;
@@ -117,9 +117,8 @@
   }
 
   @Override
-  public GraphLenseLookupResult lookupMethod(
-      DexMethod method, DexMethod context, Invoke.Type type) {
-    return new GraphLenseLookupResult(method, type);
+  public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Invoke.Type type) {
+    return new GraphLensLookupResult(method, type);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 0b9b084..24237bb 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -94,7 +94,7 @@
   // The original holder is a reference to the holder type that the method was in from input and
   // for which the invokes still refer to. The holder is needed to determine if an invoke-special
   // maps to an invoke-direct or invoke-super.
-  // TODO(b/135969130): Make IR building lense aware and avoid caching the holder type.
+  // TODO(b/135969130): Make IR building lens aware and avoid caching the holder type.
   private final DexType originalHolder;
 
   private final int maxStack;
@@ -381,7 +381,7 @@
             this,
             localVariables,
             method,
-            appView.graphLense().getOriginalMethodSignature(method.getReference()),
+            appView.graphLens().getOriginalMethodSignature(method.getReference()),
             callerPosition,
             origin,
             appView);
@@ -507,9 +507,9 @@
   public ConstraintWithTarget computeInliningConstraint(
       ProgramMethod method,
       AppView<AppInfoWithLiveness> appView,
-      GraphLense graphLense,
+      GraphLens graphLens,
       DexProgramClass context) {
-    InliningConstraints inliningConstraints = new InliningConstraints(appView, graphLense);
+    InliningConstraints inliningConstraints = new InliningConstraints(appView, graphLens);
     if (appView.options().isInterfaceMethodDesugaringEnabled()) {
       // TODO(b/120130831): Conservatively need to say "no" at this point if there are invocations
       // to static interface methods. This should be fixed by making sure that the desugared
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index b4eeb9e..76bead8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -219,7 +219,7 @@
         new DexSourceCode(
             this,
             method,
-            appView.graphLense().getOriginalMethodSignature(method.getReference()),
+            appView.graphLens().getOriginalMethodSignature(method.getReference()),
             null);
     return IRBuilder.create(method, appView, source, origin).build(method);
   }
@@ -237,7 +237,7 @@
         new DexSourceCode(
             this,
             method,
-            appView.graphLense().getOriginalMethodSignature(method.getReference()),
+            appView.graphLens().getOriginalMethodSignature(method.getReference()),
             callerPosition);
     return IRBuilder.createForInlining(
             method, appView, source, origin, methodProcessor, valueNumberGenerator)
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 4c0c7c5..019d295 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -170,7 +170,7 @@
 
   public boolean isObsolete() {
     // Do not be cheating. This util can be used only if you're going to do appropriate action,
-    // e.g., using GraphLense#mapDexEncodedMethod to look up the correct, up-to-date instance.
+    // e.g., using GraphLens#mapDexEncodedMethod to look up the correct, up-to-date instance.
     return obsolete;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index ab9be40..3a78118 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -120,7 +120,7 @@
     return "DexApplication (direct)";
   }
 
-  public DirectMappedDexApplication rewrittenWithLens(GraphLense lens) {
+  public DirectMappedDexApplication rewrittenWithLens(GraphLens lens) {
     // As a side effect, this will rebuild the program classes and library classes maps.
     DirectMappedDexApplication rewrittenApplication = builder().build().asDirect();
     assert rewrittenApplication.mappingIsValid(lens, allClasses.keySet());
@@ -128,7 +128,7 @@
     return rewrittenApplication;
   }
 
-  public boolean verifyNothingToRewrite(AppView<?> appView, GraphLense lens) {
+  public boolean verifyNothingToRewrite(AppView<?> appView, GraphLens lens) {
     assert allClasses.keySet().stream()
         .allMatch(
             type ->
@@ -138,12 +138,12 @@
     return true;
   }
 
-  private boolean mappingIsValid(GraphLense graphLense, Iterable<DexType> types) {
+  private boolean mappingIsValid(GraphLens graphLens, Iterable<DexType> types) {
     // The lens might either map to a different type that is already present in the application
     // (e.g. relinking a type) or it might encode a type that was renamed, in which case the
     // original type will point to a definition that was renamed.
     for (DexType type : types) {
-      DexType renamed = graphLense.lookupType(type);
+      DexType renamed = graphLens.lookupType(type);
       if (renamed != type) {
         if (definitionFor(type) == null && definitionFor(renamed) != null) {
           continue;
diff --git a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
index e5f7c51..4ee6be1 100644
--- a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
@@ -38,7 +38,7 @@
     return maps.keySet();
   }
 
-  public EnumValueInfoMapCollection rewrittenWithLens(GraphLense lens) {
+  public EnumValueInfoMapCollection rewrittenWithLens(GraphLens lens) {
     Builder builder = builder();
     maps.forEach(
         (type, map) -> {
@@ -100,7 +100,7 @@
       map.forEach(consumer);
     }
 
-    EnumValueInfoMap rewrittenWithLens(GraphLense lens) {
+    EnumValueInfoMap rewrittenWithLens(GraphLens lens) {
       LinkedHashMap<DexField, EnumValueInfo> rewritten = new LinkedHashMap<>();
       map.forEach(
           (field, valueInfo) ->
@@ -124,7 +124,7 @@
       return ordinal + 1;
     }
 
-    EnumValueInfo rewrittenWithLens(GraphLense lens) {
+    EnumValueInfo rewrittenWithLens(GraphLens lens) {
       DexType newType = lens.lookupType(type);
       if (type == newType) {
         return this;
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
index 9dd6c41..6224914 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
@@ -54,7 +54,7 @@
   }
 
   public FieldAccessInfoCollectionImpl rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLense lens) {
+      DexDefinitionSupplier definitions, GraphLens lens) {
     FieldAccessInfoCollectionImpl collection = new FieldAccessInfoCollectionImpl();
     infos.forEach(
         (field, info) ->
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
index 383c6e2..ae8a212 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
@@ -313,7 +313,7 @@
     writesWithContexts = null;
   }
 
-  public FieldAccessInfoImpl rewrittenWithLens(DexDefinitionSupplier definitions, GraphLense lens) {
+  public FieldAccessInfoImpl rewrittenWithLens(DexDefinitionSupplier definitions, GraphLens lens) {
     FieldAccessInfoImpl rewritten = new FieldAccessInfoImpl(lens.lookupField(field));
     rewritten.flags = flags;
     if (readsWithContexts != null) {
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignature.java b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
index 3b4d284..beb391d 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -750,7 +750,7 @@
       }
       String originalDescriptor = getDescriptorFromClassBinaryName(name);
       DexType type =
-          appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
+          appView.graphLens().lookupType(appView.dexItemFactory().createType(originalDescriptor));
       if (appView.appInfo().wasPruned(type)) {
         type = appView.dexItemFactory().objectType;
       }
@@ -783,7 +783,7 @@
                       getClassBinaryNameFromDescriptor(enclosingDescriptor)
                           + DescriptorUtils.INNER_CLASS_SEPARATOR
                           + name));
-      return appView.graphLense().lookupType(type);
+      return appView.graphLens().lookupType(type);
     }
 
     //
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLens.java
similarity index 84%
rename from src/main/java/com/android/tools/r8/graph/GraphLense.java
rename to src/main/java/com/android/tools/r8/graph/GraphLens.java
index 0bcbc76..bf6c5c8 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLens.java
@@ -22,32 +22,34 @@
 import java.util.function.Supplier;
 
 /**
- * A GraphLense implements a virtual view on top of the graph, used to delay global rewrites until
+ * A GraphLens implements a virtual view on top of the graph, used to delay global rewrites until
  * later IR processing stages.
- * <p>
- * Valid remappings are limited to the following operations:
+ *
+ * <p>Valid remappings are limited to the following operations:
+ *
  * <ul>
- * <li>Mapping a classes type to one of the super/subtypes.</li>
- * <li>Renaming private methods/fields.</li>
- * <li>Moving methods/fields to a super/subclass.</li>
- * <li>Replacing method/field references by the same method/field on a super/subtype</li>
- * <li>Moved methods might require changed invocation type at the call site</li>
+ *   <li>Mapping a classes type to one of the super/subtypes.
+ *   <li>Renaming private methods/fields.
+ *   <li>Moving methods/fields to a super/subclass.
+ *   <li>Replacing method/field references by the same method/field on a super/subtype
+ *   <li>Moved methods might require changed invocation type at the call site
  * </ul>
+ *
  * Note that the latter two have to take visibility into account.
  */
-public abstract class GraphLense {
+public abstract class GraphLens {
 
   /**
-   * Result of a method lookup in a GraphLense.
+   * Result of a method lookup in a GraphLens.
    *
-   * This provide the new target and the invoke type to use.
+   * <p>This provide the new target and the invoke type to use.
    */
-  public static class GraphLenseLookupResult {
+  public static class GraphLensLookupResult {
 
     private final DexMethod method;
     private final Type type;
 
-    public GraphLenseLookupResult(DexMethod method, Type type) {
+    public GraphLensLookupResult(DexMethod method, Type type) {
       this.method = method;
       this.type = type;
     }
@@ -109,21 +111,21 @@
       originalFieldSignatures.put(to, from);
     }
 
-    public GraphLense build(DexItemFactory dexItemFactory) {
-      return build(dexItemFactory, getIdentityLense());
+    public GraphLens build(DexItemFactory dexItemFactory) {
+      return build(dexItemFactory, getIdentityLens());
     }
 
-    public GraphLense build(DexItemFactory dexItemFactory, GraphLense previousLense) {
+    public GraphLens build(DexItemFactory dexItemFactory, GraphLens previousLens) {
       if (typeMap.isEmpty() && methodMap.isEmpty() && fieldMap.isEmpty()) {
-        return previousLense;
+        return previousLens;
       }
-      return new NestedGraphLense(
+      return new NestedGraphLens(
           typeMap,
           methodMap,
           fieldMap,
           originalFieldSignatures,
           originalMethodSignatures,
-          previousLense,
+          previousLens,
           dexItemFactory);
     }
   }
@@ -144,7 +146,7 @@
     return getRenamedMethodSignature(originalMethod, null);
   }
 
-  public abstract DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied);
+  public abstract DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied);
 
   public DexEncodedMethod mapDexEncodedMethod(
       DexEncodedMethod originalEncodedMethod, DexDefinitionSupplier definitions) {
@@ -154,7 +156,7 @@
   public DexEncodedMethod mapDexEncodedMethod(
       DexEncodedMethod originalEncodedMethod,
       DexDefinitionSupplier definitions,
-      GraphLense applied) {
+      GraphLens applied) {
     assert originalEncodedMethod != DexEncodedMethod.SENTINEL;
     DexMethod newMethod = getRenamedMethodSignature(originalEncodedMethod.method, applied);
     // Note that:
@@ -178,13 +180,13 @@
 
   public abstract DexType lookupType(DexType type);
 
-  // This overload can be used when the graph lense is known to be context insensitive.
+  // This overload can be used when the graph lens is known to be context insensitive.
   public DexMethod lookupMethod(DexMethod method) {
     assert verifyIsContextFreeForMethod(method);
     return lookupMethod(method, null, null).getMethod();
   }
 
-  public abstract GraphLenseLookupResult lookupMethod(
+  public abstract GraphLensLookupResult lookupMethod(
       DexMethod method, DexMethod context, Type type);
 
   public abstract RewrittenPrototypeDescription lookupPrototypeChanges(DexMethod method);
@@ -216,9 +218,9 @@
   // example, used by the vertical class merger to translate invoke-super instructions that hit
   // a method in the direct super class to invoke-direct instructions after class merging.
   //
-  // This method can be used to determine if a graph lense is context sensitive. If a graph lense
+  // This method can be used to determine if a graph lens is context sensitive. If a graph lens
   // is context insensitive, it is safe to invoke lookupMethod() without a context (or to pass null
-  // as context). Trying to invoke a context sensitive graph lense without a context will lead to
+  // as context). Trying to invoke a context sensitive graph lens without a context will lead to
   // an assertion error.
   public abstract boolean isContextFreeForMethods();
 
@@ -226,19 +228,19 @@
     return isContextFreeForMethods();
   }
 
-  public static GraphLense getIdentityLense() {
-    return IdentityGraphLense.getInstance();
+  public static GraphLens getIdentityLens() {
+    return IdentityGraphLens.getInstance();
   }
 
   public boolean hasCodeRewritings() {
     return true;
   }
 
-  public final boolean isIdentityLense() {
-    return this == getIdentityLense();
+  public final boolean isIdentityLens() {
+    return this == getIdentityLens();
   }
 
-  public GraphLense withCodeRewritingsApplied() {
+  public GraphLens withCodeRewritingsApplied() {
     if (hasCodeRewritings()) {
       return new ClearCodeRewritingGraphLens(this);
     }
@@ -390,13 +392,13 @@
     return true;
   }
 
-  private static class IdentityGraphLense extends GraphLense {
+  private static class IdentityGraphLens extends GraphLens {
 
-    private static IdentityGraphLense INSTANCE = new IdentityGraphLense();
+    private static IdentityGraphLens INSTANCE = new IdentityGraphLens();
 
-    private IdentityGraphLense() {}
+    private IdentityGraphLens() {}
 
-    private static IdentityGraphLense getInstance() {
+    private static IdentityGraphLens getInstance() {
       return INSTANCE;
     }
 
@@ -421,7 +423,7 @@
     }
 
     @Override
-    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied) {
+    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
       return originalMethod;
     }
 
@@ -431,8 +433,8 @@
     }
 
     @Override
-    public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
-      return new GraphLenseLookupResult(method, type);
+    public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+      return new GraphLensLookupResult(method, type);
     }
 
     @Override
@@ -458,11 +460,11 @@
 
   // This lens clears all code rewriting (lookup methods mimics identity lens behavior) but still
   // relies on the previous lens for names (getRenamed/Original methods).
-  public static class ClearCodeRewritingGraphLens extends IdentityGraphLense {
+  public static class ClearCodeRewritingGraphLens extends IdentityGraphLens {
 
-    private final GraphLense previous;
+    private final GraphLens previous;
 
-    public ClearCodeRewritingGraphLens(GraphLense previous) {
+    public ClearCodeRewritingGraphLens(GraphLens previous) {
       this.previous = previous;
     }
 
@@ -487,7 +489,7 @@
     }
 
     @Override
-    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied) {
+    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
       return this != applied
           ? previous.getRenamedMethodSignature(originalMethod, applied)
           : originalMethod;
@@ -500,7 +502,7 @@
   }
 
   /**
-   * GraphLense implementation with a parent lense using a simple mapping for type, method and field
+   * GraphLens implementation with a parent lens using a simple mapping for type, method and field
    * mapping.
    *
    * <p>Subclasses can override the lookup methods.
@@ -509,9 +511,9 @@
    * #mapInvocationType(DexMethod, DexMethod, Type)} if the default name mapping applies, and only
    * invocation type might need to change.
    */
-  public static class NestedGraphLense extends GraphLense {
+  public static class NestedGraphLens extends GraphLens {
 
-    protected GraphLense previousLense;
+    protected GraphLens previousLens;
     protected final DexItemFactory dexItemFactory;
 
     protected final Map<DexType, DexType> typeMap;
@@ -524,42 +526,44 @@
     protected final BiMap<DexField, DexField> originalFieldSignatures;
     protected final BiMap<DexMethod, DexMethod> originalMethodSignatures;
 
-    // Overrides this if the sub type needs to be a nested lense while it doesn't have any mappings
-    // at all, e.g., publicizer lense that changes invocation type only.
+    // Overrides this if the sub type needs to be a nested lens while it doesn't have any mappings
+    // at all, e.g., publicizer lens that changes invocation type only.
     protected boolean isLegitimateToHaveEmptyMappings() {
       return false;
     }
 
-    public NestedGraphLense(
+    public NestedGraphLens(
         Map<DexType, DexType> typeMap,
         Map<DexMethod, DexMethod> methodMap,
         Map<DexField, DexField> fieldMap,
         BiMap<DexField, DexField> originalFieldSignatures,
         BiMap<DexMethod, DexMethod> originalMethodSignatures,
-        GraphLense previousLense,
+        GraphLens previousLens,
         DexItemFactory dexItemFactory) {
-      assert !typeMap.isEmpty() || !methodMap.isEmpty() || !fieldMap.isEmpty()
+      assert !typeMap.isEmpty()
+          || !methodMap.isEmpty()
+          || !fieldMap.isEmpty()
           || isLegitimateToHaveEmptyMappings();
       this.typeMap = typeMap.isEmpty() ? null : typeMap;
       this.methodMap = methodMap;
       this.fieldMap = fieldMap;
       this.originalFieldSignatures = originalFieldSignatures;
       this.originalMethodSignatures = originalMethodSignatures;
-      this.previousLense = previousLense;
+      this.previousLens = previousLens;
       this.dexItemFactory = dexItemFactory;
     }
 
-    public <T> T withAlternativeParentLens(GraphLense lens, Supplier<T> action) {
-      GraphLense oldParent = previousLense;
-      previousLense = lens;
+    public <T> T withAlternativeParentLens(GraphLens lens, Supplier<T> action) {
+      GraphLens oldParent = previousLens;
+      previousLens = lens;
       T result = action.get();
-      previousLense = oldParent;
+      previousLens = oldParent;
       return result;
     }
 
     @Override
     public DexType getOriginalType(DexType type) {
-      return previousLense.getOriginalType(type);
+      return previousLens.getOriginalType(type);
     }
 
     @Override
@@ -568,7 +572,7 @@
           originalFieldSignatures != null
               ? originalFieldSignatures.getOrDefault(field, field)
               : field;
-      return previousLense.getOriginalFieldSignature(originalField);
+      return previousLens.getOriginalFieldSignature(originalField);
     }
 
     @Override
@@ -577,23 +581,23 @@
           originalMethodSignatures != null
               ? originalMethodSignatures.getOrDefault(method, method)
               : method;
-      return previousLense.getOriginalMethodSignature(originalMethod);
+      return previousLens.getOriginalMethodSignature(originalMethod);
     }
 
     @Override
     public DexField getRenamedFieldSignature(DexField originalField) {
-      DexField renamedField = previousLense.getRenamedFieldSignature(originalField);
+      DexField renamedField = previousLens.getRenamedFieldSignature(originalField);
       return originalFieldSignatures != null
           ? originalFieldSignatures.inverse().getOrDefault(renamedField, renamedField)
           : renamedField;
     }
 
     @Override
-    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied) {
+    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
       if (this == applied) {
         return originalMethod;
       }
-      DexMethod renamedMethod = previousLense.getRenamedMethodSignature(originalMethod, applied);
+      DexMethod renamedMethod = previousLens.getRenamedMethodSignature(originalMethod, applied);
       return originalMethodSignatures != null
           ? originalMethodSignatures.inverse().getOrDefault(renamedMethod, renamedMethod)
           : renamedMethod;
@@ -618,40 +622,40 @@
           return result;
         }
       }
-      DexType previous = previousLense.lookupType(type);
+      DexType previous = previousLens.lookupType(type);
       return typeMap != null ? typeMap.getOrDefault(previous, previous) : previous;
     }
 
     @Override
-    public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+    public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
       DexMethod previousContext =
           originalMethodSignatures != null
               ? originalMethodSignatures.getOrDefault(context, context)
               : context;
-      GraphLenseLookupResult previous = previousLense.lookupMethod(method, previousContext, type);
+      GraphLensLookupResult previous = previousLens.lookupMethod(method, previousContext, type);
       DexMethod newMethod = methodMap.get(previous.getMethod());
       if (newMethod == null) {
         return previous;
       }
       // TODO(sgjesse): Should we always do interface to virtual mapping? Is it a performance win
       // that only subclasses which are known to need it actually do it?
-      return new GraphLenseLookupResult(
+      return new GraphLensLookupResult(
           newMethod, mapInvocationType(newMethod, method, previous.getType()));
     }
 
     @Override
     public RewrittenPrototypeDescription lookupPrototypeChanges(DexMethod method) {
-      return previousLense.lookupPrototypeChanges(method);
+      return previousLens.lookupPrototypeChanges(method);
     }
 
     @Override
     public DexMethod lookupGetFieldForMethod(DexField field, DexMethod context) {
-      return previousLense.lookupGetFieldForMethod(field, context);
+      return previousLens.lookupGetFieldForMethod(field, context);
     }
 
     @Override
     public DexMethod lookupPutFieldForMethod(DexField field, DexMethod context) {
-      return previousLense.lookupPutFieldForMethod(field, context);
+      return previousLens.lookupPutFieldForMethod(field, context);
     }
 
     /**
@@ -694,18 +698,18 @@
 
     @Override
     public DexField lookupField(DexField field) {
-      DexField previous = previousLense.lookupField(field);
+      DexField previous = previousLens.lookupField(field);
       return fieldMap.getOrDefault(previous, previous);
     }
 
     @Override
     public boolean isContextFreeForMethods() {
-      return previousLense.isContextFreeForMethods();
+      return previousLens.isContextFreeForMethods();
     }
 
     @Override
     public boolean verifyIsContextFreeForMethod(DexMethod method) {
-      assert previousLense.verifyIsContextFreeForMethod(method);
+      assert previousLens.verifyIsContextFreeForMethod(method);
       return true;
     }
 
@@ -726,7 +730,7 @@
         builder.append(entry.getKey().toSourceString()).append(" -> ");
         builder.append(entry.getValue().toSourceString()).append(System.lineSeparator());
       }
-      builder.append(previousLense.toString());
+      builder.append(previousLens.toString());
       return builder.toString();
     }
   }
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
index 546bf90..60c06cc 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
@@ -27,5 +27,5 @@
   boolean isImmediateInterfaceOfInstantiatedLambda(DexProgramClass clazz);
 
   ObjectAllocationInfoCollection rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLense lens);
+      DexDefinitionSupplier definitions, GraphLens lens);
 }
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
index 1245da9..0997dc4 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
@@ -133,7 +133,7 @@
 
   @Override
   public ObjectAllocationInfoCollectionImpl rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLense lens) {
+      DexDefinitionSupplier definitions, GraphLens lens) {
     return builder(true, null).rewrittenWithLens(this, definitions, lens).build(definitions);
   }
 
@@ -368,7 +368,7 @@
     Builder rewrittenWithLens(
         ObjectAllocationInfoCollectionImpl objectAllocationInfos,
         DexDefinitionSupplier definitions,
-        GraphLense lens) {
+        GraphLens lens) {
       instantiatedHierarchy = null;
       objectAllocationInfos.classesWithAllocationSiteTracking.forEach(
           (clazz, allocationSitesForClass) -> {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
index 54d5160..cf531ff 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
@@ -38,16 +38,16 @@
   private final Map<Value, LatticeElement> mapping = new HashMap<>();
   private final Deque<Value> ssaEdges = new LinkedList<>();
   private final Deque<BasicBlock> flowEdges = new LinkedList<>();
-  private final int nextBlockNumber;
+  private final int maxBlockNumber;
   private final BitSet[] executableFlowEdges;
   private final BitSet visitedBlocks;
 
   public SparseConditionalConstantPropagation(AppView<?> appView, IRCode code) {
     this.appView = appView;
     this.code = code;
-    nextBlockNumber = code.getHighestBlockNumber() + 1;
-    executableFlowEdges = new BitSet[nextBlockNumber];
-    visitedBlocks = new BitSet(nextBlockNumber);
+    maxBlockNumber = code.getCurrentBlockNumber() + 1;
+    executableFlowEdges = new BitSet[maxBlockNumber];
+    visitedBlocks = new BitSet(maxBlockNumber);
   }
 
   public void run() {
@@ -252,7 +252,7 @@
   private void setExecutableEdge(int from, int to) {
     BitSet previousExecutable = executableFlowEdges[to];
     if (previousExecutable == null) {
-      previousExecutable = new BitSet(nextBlockNumber);
+      previousExecutable = new BitSet(maxBlockNumber);
       executableFlowEdges[to] = previousExecutable;
     }
     previousExecutable.set(from);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
index c6e42b6..7d13544 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 
 /**
  * Implements a lifted subset lattice for fields.
@@ -70,5 +70,5 @@
     return lessThanOrEqual(other) && !equals(other);
   }
 
-  public abstract AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens);
+  public abstract AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLens lens);
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
index 9fe885d..5bf0c61 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.SetUtils;
 import com.google.common.collect.Sets;
@@ -69,7 +69,7 @@
   }
 
   @Override
-  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLens lens) {
     assert !isEmpty();
     ConcreteMutableFieldSet rewrittenSet = new ConcreteMutableFieldSet();
     for (DexEncodedField field : fields) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
index 73559f3..9a7c7aa 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 
 public class EmptyFieldSet extends AbstractFieldSet implements KnownFieldSet {
 
@@ -39,7 +39,7 @@
   }
 
   @Override
-  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLens lens) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
index f083438..75a1bab 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 
 public class UnknownFieldSet extends AbstractFieldSet {
 
@@ -34,7 +34,7 @@
   }
 
   @Override
-  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+  public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java b/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
index 29ca247..a89c486 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
@@ -24,7 +24,7 @@
   private final Function<DexType, DexType> mapping;
 
   public DestructivePhiTypeUpdater(AppView<? extends AppInfoWithClassHierarchy> appView) {
-    this(appView, appView.graphLense()::lookupType);
+    this(appView, appView.graphLens()::lookupType);
   }
 
   public DestructivePhiTypeUpdater(
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 9939980..c2ffda0 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.analysis.value;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 public abstract class AbstractValue {
@@ -86,7 +86,7 @@
   }
 
   public abstract AbstractValue rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 
   @Override
   public abstract boolean equals(Object o);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
index f5b27f7..c1afe58 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.analysis.value;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 public class BottomValue extends AbstractValue {
@@ -24,7 +24,7 @@
   }
 
   @Override
-  public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/EmptyObjectState.java b/src/main/java/com/android/tools/r8/ir/analysis/value/EmptyObjectState.java
index 48b1d9c..db6be42 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/EmptyObjectState.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/EmptyObjectState.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 public class EmptyObjectState extends ObjectState {
@@ -30,7 +30,7 @@
   }
 
   @Override
-  public ObjectState rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public ObjectState rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/NonEmptyObjectState.java b/src/main/java/com/android/tools/r8/ir/analysis/value/NonEmptyObjectState.java
index 0732b83..fad7303 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/NonEmptyObjectState.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/NonEmptyObjectState.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.IdentityHashMap;
 import java.util.Map;
@@ -34,7 +34,7 @@
   }
 
   @Override
-  public ObjectState rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public ObjectState rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     Map<DexField, AbstractValue> rewrittenState = new IdentityHashMap<>();
     state.forEach(
         (field, value) ->
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/ObjectState.java b/src/main/java/com/android/tools/r8/ir/analysis/value/ObjectState.java
index 066b305..b724858 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/ObjectState.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/ObjectState.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.IdentityHashMap;
 import java.util.Map;
@@ -27,7 +27,7 @@
   public abstract boolean isEmpty();
 
   public abstract ObjectState rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 
   @Override
   public abstract boolean equals(Object o);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
index bcb5c0b..7240424 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.ConstClass;
@@ -107,7 +107,7 @@
   }
 
   @Override
-  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     assert lens.lookupType(type) == type;
     return this;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
index 7bdcc84..b7e359e 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
@@ -14,7 +14,7 @@
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -107,7 +107,7 @@
   }
 
   @Override
-  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     AbstractValueFactory factory = appView.abstractValueFactory();
     if (field.holder == field.type) {
       EnumValueInfoMap unboxedEnumInfo = appView.unboxedEnums().getEnumValueInfoMap(field.type);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
index e6b1ee6..0cb75c3 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.ConstNumber;
@@ -91,7 +91,7 @@
   }
 
   @Override
-  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
index ab7c218..e494c43 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
@@ -92,7 +92,7 @@
   }
 
   @Override
-  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
index 3ce27a0..4a3a11c 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
@@ -47,5 +47,5 @@
 
   @Override
   public abstract SingleValue rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
index 2b4f841..8d4001f 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.analysis.value;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 public class UnknownValue extends AbstractValue {
@@ -29,7 +29,7 @@
   }
 
   @Override
-  public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index b0ef472..fa3c34c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.graph.DebugLocalInfo.PrintLevel;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.type.Nullability;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.Phi.RegisterReadType;
@@ -998,17 +998,17 @@
 
   /**
    * Due to class merging, it is possible that two exception classes have been merged into one. This
-   * function renames the guards according to the given graph lense.
+   * function renames the guards according to the given graph lens.
    *
    * @return true if any guards were renamed.
    */
-  public boolean renameGuardsInCatchHandlers(GraphLense graphLense) {
+  public boolean renameGuardsInCatchHandlers(GraphLens graphLens) {
     assert hasCatchHandlers();
     boolean anyGuardsRenamed = false;
     List<DexType> newGuards = new ArrayList<>(catchHandlers.getGuards().size());
     for (DexType guard : catchHandlers.getGuards()) {
       // The type may have changed due to class merging.
-      DexType renamed = graphLense.lookupType(guard);
+      DexType renamed = graphLens.lookupType(guard);
       newGuards.add(renamed);
       anyGuardsRenamed |= renamed != guard;
     }
@@ -1483,7 +1483,7 @@
     block.add(moveException, code);
     block.add(throwInstruction, code);
     block.close(null);
-    block.setNumber(code.getHighestBlockNumber() + 1);
+    block.setNumber(code.getNextBlockNumber());
     return block;
   }
 
@@ -1762,9 +1762,8 @@
    * method does not affect incoming edges in any way, and just adds new blocks with MoveException
    * and Goto.
    */
-  public int splitCriticalExceptionEdges(
+  public void splitCriticalExceptionEdges(
       IRCode code, Consumer<BasicBlock> onNewBlock, InternalOptions options) {
-    int nextBlockNumber = code.getHighestBlockNumber() + 1;
     List<BasicBlock> predecessors = getMutablePredecessors();
     boolean hasMoveException = entry().isMoveException();
     TypeElement exceptionTypeLattice = null;
@@ -1788,7 +1787,7 @@
             "Invalid block structure: catch block reachable via non-exceptional flow.");
       }
       BasicBlock newBlock = new BasicBlock();
-      newBlock.setNumber(nextBlockNumber++);
+      newBlock.setNumber(code.getNextBlockNumber());
       newPredecessors.add(newBlock);
       if (hasMoveException) {
         Value value =
@@ -1823,7 +1822,6 @@
       phi.addOperands(values);
       move.outValue().replaceUsers(phi);
     }
-    return nextBlockNumber;
   }
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
index 57d52df..68447db 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
@@ -383,9 +383,6 @@
     List<BasicBlock> blocks = code.blocks;
     assert blocksIterator == null || IteratorUtils.peekPrevious(blocksIterator) == block;
 
-    int blockNumber = code.getHighestBlockNumber() + 1;
-    BasicBlock newBlock;
-
     // Don't allow splitting after the last instruction.
     assert hasNext();
 
@@ -394,7 +391,7 @@
 
     // Prepare the new block, placing the exception handlers on the block with the throwing
     // instruction.
-    newBlock = block.createSplitBlock(blockNumber, keepCatchHandlers);
+    BasicBlock newBlock = block.createSplitBlock(code.getNextBlockNumber(), keepCatchHandlers);
 
     // Add a goto instruction.
     Goto newGoto = new Goto(block);
@@ -699,9 +696,8 @@
     assert IteratorUtils.peekNext(blocksIterator) == invokeBlock;
 
     // Insert inlinee blocks into the IR code of the callee, before the invoke block.
-    int blockNumber = code.getHighestBlockNumber() + 1;
     for (BasicBlock bb : inlinee.blocks) {
-      bb.setNumber(blockNumber++);
+      bb.setNumber(code.getNextBlockNumber());
       blocksIterator.add(bb);
     }
 
@@ -745,7 +741,7 @@
       return it;
     }
     BasicBlock newExitBlock = new BasicBlock();
-    newExitBlock.setNumber(code.getHighestBlockNumber() + 1);
+    newExitBlock.setNumber(code.getNextBlockNumber());
     Return newReturn;
     if (normalExits.get(0).exit().asReturn().isReturnVoid()) {
       newReturn = new Return();
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index f177619..77988b8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -38,7 +38,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.Deque;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
@@ -109,6 +108,7 @@
 
   public LinkedList<BasicBlock> blocks;
   public final ValueNumberGenerator valueNumberGenerator;
+  public final ValueNumberGenerator basicBlockNumberGenerator;
   private int usedMarkingColors = 0;
 
   private boolean numbered = false;
@@ -128,14 +128,17 @@
       ProgramMethod method,
       LinkedList<BasicBlock> blocks,
       ValueNumberGenerator valueNumberGenerator,
+      ValueNumberGenerator basicBlockNumberGenerator,
       IRMetadata metadata,
       Origin origin) {
     assert metadata != null;
     assert options != null;
+    assert blocks.size() == basicBlockNumberGenerator.peek();
     this.options = options;
     this.method = method;
     this.blocks = blocks;
     this.valueNumberGenerator = valueNumberGenerator;
+    this.basicBlockNumberGenerator = basicBlockNumberGenerator;
     this.metadata = metadata;
     this.origin = origin;
     // TODO(zerny): Remove or update this property now that all instructions have positions.
@@ -348,7 +351,7 @@
       if (hasSeenThrowingInstruction) {
         List<BasicBlock> successors = block.getSuccessors();
         if (successors.size() == 1 && ListUtils.first(successors).getPredecessors().size() > 1) {
-          BasicBlock splitBlock = block.createSplitBlock(getHighestBlockNumber() + 1, true);
+          BasicBlock splitBlock = block.createSplitBlock(getNextBlockNumber(), true);
           Goto newGoto = new Goto(block);
           newGoto.setPosition(Position.none());
           splitBlock.listIterator(this).add(newGoto);
@@ -361,7 +364,6 @@
 
   public void splitCriticalEdges() {
     List<BasicBlock> newBlocks = new ArrayList<>();
-    int nextBlockNumber = getHighestBlockNumber() + 1;
     for (BasicBlock block : blocks) {
       // We are using a spilling register allocator that might need to insert moves at
       // all critical edges, so we always split them all.
@@ -383,7 +385,7 @@
           // structure.
           BasicBlock newBlock =
               BasicBlock.createGotoBlock(
-                  nextBlockNumber++, pred.exit().getPosition(), metadata, block);
+                  getNextBlockNumber(), pred.exit().getPosition(), metadata, block);
           newBlocks.add(newBlock);
           pred.replaceSuccessor(block, newBlock);
           newBlock.getMutablePredecessors().add(pred);
@@ -424,7 +426,6 @@
     // Get the blocks first, as calling topologicallySortedBlocks also sets marks.
     ImmutableList<BasicBlock> sorted = topologicallySortedBlocks();
     int color = reserveMarkingColor();
-    int nextBlockNumber = blocks.size();
     LinkedList<BasicBlock> tracedBlocks = new LinkedList<>();
     for (BasicBlock block : sorted) {
       if (!block.isMarked(color)) {
@@ -441,7 +442,7 @@
         if (fallthrough != null) {
           BasicBlock newFallthrough =
               BasicBlock.createGotoBlock(
-                  nextBlockNumber++, current.exit().getPosition(), metadata, fallthrough);
+                  getNextBlockNumber(), current.exit().getPosition(), metadata, fallthrough);
           current.exit().setFallthroughBlock(newFallthrough);
           newFallthrough.getMutablePredecessors().add(current);
           fallthrough.replacePredecessor(current, newFallthrough);
@@ -786,12 +787,12 @@
   }
 
   public boolean consistentBlockNumbering() {
-    blocks
-        .stream()
+    blocks.stream()
         .collect(Collectors.groupingBy(BasicBlock::getNumber, Collectors.counting()))
         .forEach(
             (key, value) -> {
               assert value == 1;
+              assert value <= basicBlockNumberGenerator.peek();
             });
     return true;
   }
@@ -1144,8 +1145,12 @@
     return new Phi(valueNumberGenerator.next(), block, type, null, RegisterReadType.NORMAL);
   }
 
-  public final int getHighestBlockNumber() {
-    return blocks.stream().max(Comparator.comparingInt(BasicBlock::getNumber)).get().getNumber();
+  public final int getNextBlockNumber() {
+    return basicBlockNumberGenerator.next();
+  }
+
+  public final int getCurrentBlockNumber() {
+    return basicBlockNumberGenerator.peek();
   }
 
   public ConstClass createConstClass(AppView<?> appView, DexType type) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index be64578..b287f84 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -1397,10 +1397,10 @@
                 .asArrayType()
                 .toDexType(appView.dexItemFactory())
                 .toBaseType(appView.dexItemFactory());
-        assert appView.graphLense().lookupType(outBaseType) == outBaseType;
+        assert appView.graphLens().lookupType(outBaseType) == outBaseType;
       } else if (outTypeElement.isClassType()) {
         DexType outType = outTypeElement.asClassType().getClassType();
-        assert appView.graphLense().lookupType(outType) == outType;
+        assert appView.graphLens().lookupType(outType) == outType;
       }
     }
     return true;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Position.java b/src/main/java/com/android/tools/r8/ir/code/Position.java
index d11bf38..183d352 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Position.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Position.java
@@ -86,7 +86,7 @@
       position = Position.noneWithMethod(context.getReference(), null);
     }
     assert position.getOutermostCaller().method
-        == appView.graphLense().getOriginalMethodSignature(context.getReference());
+        == appView.graphLens().getOriginalMethodSignature(context.getReference());
     return position;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/ValueNumberGenerator.java b/src/main/java/com/android/tools/r8/ir/code/ValueNumberGenerator.java
index ac07f11..722f30e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ValueNumberGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ValueNumberGenerator.java
@@ -9,4 +9,8 @@
   public int next() {
     return nextValueNumber++;
   }
+
+  public int peek() {
+    return nextValueNumber;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
index 9f57ac1..8119a9c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
@@ -18,7 +18,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.FieldAccessInfo;
 import com.android.tools.r8.graph.FieldAccessInfoCollection;
-import com.android.tools.r8.graph.GraphLense.GraphLenseLookupResult;
+import com.android.tools.r8.graph.GraphLens.GraphLensLookupResult;
 import com.android.tools.r8.graph.LookupResult;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.ResolutionResult;
@@ -166,8 +166,8 @@
 
     private void processInvoke(Invoke.Type originalType, DexMethod originalMethod) {
       ProgramMethod context = currentMethod.getProgramMethod();
-      GraphLenseLookupResult result =
-          appView.graphLense().lookupMethod(originalMethod, context.getReference(), originalType);
+      GraphLensLookupResult result =
+          appView.graphLens().lookupMethod(originalMethod, context.getReference(), originalType);
       DexMethod method = result.getMethod();
       Invoke.Type type = result.getType();
       if (type == Invoke.Type.INTERFACE || type == Invoke.Type.VIRTUAL) {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 60fcec2..c36eb8e 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -392,6 +392,7 @@
   private int currentInstructionOffset = -1;
 
   final private ValueNumberGenerator valueNumberGenerator;
+  private final ValueNumberGenerator basicBlockNumberGenerator;
   private final ProgramMethod method;
   private ProgramMethod context;
   public final AppView<?> appView;
@@ -456,7 +457,7 @@
   private static RewrittenPrototypeDescription lookupPrototypeChanges(
       AppView<?> appView, ProgramMethod method) {
     RewrittenPrototypeDescription prototypeChanges =
-        appView.graphLense().lookupPrototypeChanges(method.getReference());
+        appView.graphLens().lookupPrototypeChanges(method.getReference());
     if (Log.ENABLED && prototypeChanges.getArgumentInfoCollection().hasRemovedArguments()) {
       Log.info(
           IRBuilder.class,
@@ -483,6 +484,7 @@
     this.origin = origin;
     this.prototypeChanges = prototypeChanges;
     this.valueNumberGenerator = valueNumberGenerator;
+    this.basicBlockNumberGenerator = new ValueNumberGenerator();
   }
 
   public DexEncodedMethod getMethod() {
@@ -679,7 +681,14 @@
 
     // Package up the IR code.
     IRCode ir =
-        new IRCode(appView.options(), method, blocks, valueNumberGenerator, metadata, origin);
+        new IRCode(
+            appView.options(),
+            method,
+            blocks,
+            valueNumberGenerator,
+            basicBlockNumberGenerator,
+            metadata,
+            origin);
 
     // Verify critical edges are split so we have a place to insert phi moves if necessary.
     assert ir.verifySplitCriticalEdges();
@@ -834,7 +843,7 @@
       assert debugLocalEnds.isEmpty();
       setCurrentBlock(item.block);
       blocks.add(currentBlock);
-      currentBlock.setNumber(nextBlockNumber++);
+      currentBlock.setNumber(basicBlockNumberGenerator.next());
       // Process synthesized move-exception block specially.
       if (item instanceof MoveExceptionWorklistItem) {
         processMoveExceptionItem((MoveExceptionWorklistItem) item);
@@ -2286,7 +2295,7 @@
 
     BlockInfo info = new BlockInfo();
     BasicBlock block = info.block;
-    block.setNumber(nextBlockNumber++);
+    block.setNumber(basicBlockNumberGenerator.next());
     blocks.add(block);
 
     // Compute some unused offset for the new block and link it in the CFG.
@@ -2631,7 +2640,7 @@
             if (joinBlock == null) {
               joinBlock =
                   BasicBlock.createGotoBlock(
-                      blocks.size() + blocksToAdd.size(), block.getPosition(), metadata, block);
+                      basicBlockNumberGenerator.next(), block.getPosition(), metadata, block);
               joinBlocks.put(otherPredecessorIndex, joinBlock);
               blocksToAdd.add(joinBlock);
               BasicBlock otherPredecessor = block.getPredecessors().get(otherPredecessorIndex);
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 0809d00..3f74b74 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
@@ -22,7 +22,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.TypeChecker;
 import com.android.tools.r8.ir.analysis.constant.SparseConditionalConstantPropagation;
@@ -191,7 +191,7 @@
    */
   public IRConverter(
       AppView<?> appView, Timing timing, CfgPrinter printer, MainDexClasses mainDexClasses) {
-    assert appView.appInfo().hasLiveness() || appView.graphLense().isIdentityLense();
+    assert appView.appInfo().hasLiveness() || appView.graphLens().isIdentityLens();
     assert appView.options() != null;
     assert appView.options().programConsumer != null;
     assert timing != null;
@@ -690,7 +690,7 @@
     }
 
     // Process the application identifying outlining candidates.
-    GraphLense graphLenseForIR = appView.graphLense();
+    GraphLens graphLensForIR = appView.graphLens();
     OptimizationFeedbackDelayed feedback = delayedOptimizationFeedback;
     PostMethodProcessor.Builder postMethodProcessorBuilder =
         new PostMethodProcessor.Builder(getOptimizationsForPostIRProcessing());
@@ -712,7 +712,7 @@
           timing,
           executorService);
       timing.end();
-      assert graphLenseForIR == appView.graphLense();
+      assert graphLensForIR == appView.graphLens();
     }
 
     // Assure that no more optimization feedback left after primary processing.
@@ -747,14 +747,14 @@
     }
 
     timing.begin("IR conversion phase 2");
-    graphLenseForIR = appView.graphLense();
+    graphLensForIR = appView.graphLens();
     PostMethodProcessor postMethodProcessor =
         postMethodProcessorBuilder.build(appView.withLiveness(), executorService, timing);
     if (postMethodProcessor != null) {
       assert !options.debug;
       postMethodProcessor.forEachWave(feedback, executorService);
       feedback.updateVisibleOptimizationInfo();
-      assert graphLenseForIR == appView.graphLense();
+      assert graphLensForIR == appView.graphLens();
     }
     timing.end();
 
@@ -1188,7 +1188,7 @@
       codeRewriter.simplifyDebugLocals(code);
     }
 
-    if (appView.graphLense().hasCodeRewritings()) {
+    if (appView.graphLens().hasCodeRewritings()) {
       assert lensCodeRewriter != null;
       timing.begin("Lens rewrite");
       lensCodeRewriter.rewrite(code, context);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index f83952c..6c9877c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -47,8 +47,8 @@
 import com.android.tools.r8.graph.DexValue.DexValueMethodHandle;
 import com.android.tools.r8.graph.DexValue.DexValueMethodType;
 import com.android.tools.r8.graph.DexValue.DexValueType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.GraphLenseLookupResult;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.GraphLensLookupResult;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
@@ -115,7 +115,7 @@
     if (insn.outValue() != null) {
       TypeElement oldType = insn.getOutType();
       TypeElement newType =
-          oldType.fixupClassTypeReferences(appView.graphLense()::lookupType, appView);
+          oldType.fixupClassTypeReferences(appView.graphLens()::lookupType, appView);
       return code.createValue(newType, insn.getLocalInfo());
     }
     return null;
@@ -125,7 +125,7 @@
   public void rewrite(IRCode code, ProgramMethod method) {
     Set<Phi> affectedPhis =
         enumUnboxer != null ? enumUnboxer.rewriteCode(code) : Sets.newIdentityHashSet();
-    GraphLense graphLense = appView.graphLense();
+    GraphLens graphLens = appView.graphLens();
     DexItemFactory factory = appView.dexItemFactory();
     // Rewriting types that affects phi can cause us to compute TOP for cyclic phi's. To solve this
     // we track all phi's that needs to be re-computed.
@@ -134,7 +134,7 @@
     while (blocks.hasNext()) {
       BasicBlock block = blocks.next();
       if (block.hasCatchHandlers() && appView.options().enableVerticalClassMerging) {
-        boolean anyGuardsRenamed = block.renameGuardsInCatchHandlers(graphLense);
+        boolean anyGuardsRenamed = block.renameGuardsInCatchHandlers(graphLens);
         if (anyGuardsRenamed) {
           mayHaveUnreachableBlocks |= unlinkDeadCatchHandlers(block);
         }
@@ -217,13 +217,13 @@
               if (invoke.isInvokeDirect()) {
                 checkInvokeDirect(method.getReference(), invoke.asInvokeDirect());
               }
-              GraphLenseLookupResult lenseLookup =
-                  graphLense.lookupMethod(invokedMethod, method.getReference(), invoke.getType());
-              DexMethod actualTarget = lenseLookup.getMethod();
-              Invoke.Type actualInvokeType = lenseLookup.getType();
+              GraphLensLookupResult lensLookup =
+                  graphLens.lookupMethod(invokedMethod, method.getReference(), invoke.getType());
+              DexMethod actualTarget = lensLookup.getMethod();
+              Invoke.Type actualInvokeType = lensLookup.getType();
               if (actualTarget != invokedMethod || invoke.getType() != actualInvokeType) {
                 RewrittenPrototypeDescription prototypeChanges =
-                    graphLense.lookupPrototypeChanges(actualTarget);
+                    graphLens.lookupPrototypeChanges(actualTarget);
 
                 List<Value> newInValues;
                 ArgumentInfoCollection argumentInfoCollection =
@@ -272,7 +272,7 @@
                         .setLocalInfo(invoke.outValue().getLocalInfo());
                   }
                   invoke.outValue().replaceUsers(constantReturnMaterializingInstruction.outValue());
-                  if (graphLense.lookupType(invoke.getReturnType()) != invoke.getReturnType()) {
+                  if (graphLens.lookupType(invoke.getReturnType()) != invoke.getReturnType()) {
                     affectedPhis.addAll(
                         constantReturnMaterializingInstruction.outValue().uniquePhiUsers());
                   }
@@ -324,7 +324,7 @@
                 }
 
                 DexType actualReturnType = actualTarget.proto.returnType;
-                DexType expectedReturnType = graphLense.lookupType(invokedMethod.proto.returnType);
+                DexType expectedReturnType = graphLens.lookupType(invokedMethod.proto.returnType);
                 if (newInvoke.outValue() != null && actualReturnType != expectedReturnType) {
                   throw new Unreachable(
                       "Unexpected need to insert a cast. Possibly related to resolving"
@@ -343,9 +343,9 @@
             {
               InstanceGet instanceGet = current.asInstanceGet();
               DexField field = instanceGet.getField();
-              DexField actualField = graphLense.lookupField(field);
+              DexField actualField = graphLens.lookupField(field);
               DexMethod replacementMethod =
-                  graphLense.lookupGetFieldForMethod(actualField, method.getReference());
+                  graphLens.lookupGetFieldForMethod(actualField, method.getReference());
               if (replacementMethod != null) {
                 Value newOutValue = makeOutValue(current, code);
                 iterator.replaceCurrentInstruction(
@@ -368,9 +368,9 @@
             {
               InstancePut instancePut = current.asInstancePut();
               DexField field = instancePut.getField();
-              DexField actualField = graphLense.lookupField(field);
+              DexField actualField = graphLens.lookupField(field);
               DexMethod replacementMethod =
-                  graphLense.lookupPutFieldForMethod(actualField, method.getReference());
+                  graphLens.lookupPutFieldForMethod(actualField, method.getReference());
               if (replacementMethod != null) {
                 iterator.replaceCurrentInstruction(
                     new InvokeStatic(replacementMethod, null, current.inValues()));
@@ -390,9 +390,9 @@
             {
               StaticGet staticGet = current.asStaticGet();
               DexField field = staticGet.getField();
-              DexField actualField = graphLense.lookupField(field);
+              DexField actualField = graphLens.lookupField(field);
               DexMethod replacementMethod =
-                  graphLense.lookupGetFieldForMethod(actualField, method.getReference());
+                  graphLens.lookupGetFieldForMethod(actualField, method.getReference());
               if (replacementMethod != null) {
                 Value newOutValue = makeOutValue(current, code);
                 iterator.replaceCurrentInstruction(
@@ -414,9 +414,9 @@
             {
               StaticPut staticPut = current.asStaticPut();
               DexField field = staticPut.getField();
-              DexField actualField = graphLense.lookupField(field);
+              DexField actualField = graphLens.lookupField(field);
               DexMethod replacementMethod =
-                  graphLense.lookupPutFieldForMethod(actualField, method.getReference());
+                  graphLens.lookupPutFieldForMethod(actualField, method.getReference());
               if (replacementMethod != null) {
                 iterator.replaceCurrentInstruction(
                     new InvokeStatic(replacementMethod, current.outValue(), current.inValues()));
@@ -530,7 +530,7 @@
               // For all other instructions, substitute any changed type.
               TypeElement type = current.getOutType();
               TypeElement substituted =
-                  type.fixupClassTypeReferences(graphLense::lookupType, appView);
+                  type.fixupClassTypeReferences(graphLens::lookupType, appView);
               if (substituted != type) {
                 current.outValue().setType(substituted);
                 affectedPhis.addAll(current.outValue().uniquePhiUsers());
@@ -597,7 +597,7 @@
     DexItemFactory dexItemFactory = appView.dexItemFactory();
     DexProto newMethodProto =
         dexItemFactory.applyClassMappingToProto(
-            callSite.methodProto, appView.graphLense()::lookupType, protoFixupCache);
+            callSite.methodProto, appView.graphLens()::lookupType, protoFixupCache);
     DexMethodHandle newBootstrapMethod =
         rewriteDexMethodHandle(
             callSite.bootstrapMethod, context, NOT_ARGUMENT_TO_LAMBDA_METAFACTORY);
@@ -678,7 +678,7 @@
     List<BasicBlock> deadCatchHandlers = new ArrayList<>();
     for (int i = 0; i < guards.size(); i++) {
       // The type may have changed due to class merging.
-      DexType guard = appView.graphLense().lookupType(guards.get(i));
+      DexType guard = appView.graphLens().lookupType(guards.get(i));
       boolean guardSeenBefore = !previouslySeenGuards.add(guard);
       if (guardSeenBefore) {
         deadCatchHandlers.add(targets.get(i));
@@ -708,7 +708,7 @@
           break;
         case TYPE:
           DexType oldType = argument.asDexValueType().value;
-          DexType newType = appView.graphLense().lookupType(oldType);
+          DexType newType = appView.graphLens().lookupType(oldType);
           if (newType != oldType) {
             newArgument = new DexValueType(newType);
           }
@@ -741,18 +741,18 @@
     if (methodHandle.isMethodHandle()) {
       DexMethod invokedMethod = methodHandle.asMethod();
       MethodHandleType oldType = methodHandle.type;
-      GraphLenseLookupResult lenseLookup =
+      GraphLensLookupResult lensLookup =
           appView
-              .graphLense()
+              .graphLens()
               .lookupMethod(invokedMethod, context.getReference(), oldType.toInvokeType());
-      DexMethod rewrittenTarget = lenseLookup.getMethod();
+      DexMethod rewrittenTarget = lensLookup.getMethod();
       DexMethod actualTarget;
       MethodHandleType newType;
       if (use == ARGUMENT_TO_LAMBDA_METAFACTORY) {
         // Lambda metafactory arguments will be lambda desugared away and therefore cannot flow
         // to a MethodHandle.invokeExact call. We can therefore member-rebind with no issues.
         actualTarget = rewrittenTarget;
-        newType = lenseLookup.getType().toMethodHandle(actualTarget);
+        newType = lensLookup.getType().toMethodHandle(actualTarget);
       } else {
         assert use == NOT_ARGUMENT_TO_LAMBDA_METAFACTORY;
         // MethodHandles that are not arguments to a lambda metafactory will not be desugared
@@ -769,7 +769,7 @@
           // If the method has changed from private to public we need to use virtual instead of
           // direct.
           assert rewrittenTarget.holder == actualTarget.holder;
-          newType = lenseLookup.getType().toMethodHandle(actualTarget);
+          newType = lensLookup.getType().toMethodHandle(actualTarget);
           assert newType == MethodHandleType.INVOKE_DIRECT
               || newType == MethodHandleType.INVOKE_INSTANCE;
         }
@@ -785,7 +785,7 @@
       }
     } else {
       DexField field = methodHandle.asField();
-      DexField actualField = appView.graphLense().lookupField(field);
+      DexField actualField = appView.graphLens().lookupField(field);
       if (actualField != field) {
         return new DexMethodHandle(methodHandle.type, actualField, methodHandle.isInterface);
       }
@@ -798,7 +798,7 @@
     DexProto newProto =
         appView
             .dexItemFactory()
-            .applyClassMappingToProto(oldProto, appView.graphLense()::lookupType, protoFixupCache);
+            .applyClassMappingToProto(oldProto, appView.graphLens()::lookupType, protoFixupCache);
     return newProto != oldProto ? new DexValueMethodType(newProto) : type;
   }
 
@@ -819,7 +819,7 @@
 
     void replaceInstructionIfTypeChanged(
         DexType type, BiFunction<DexType, Value, Instruction> constructor) {
-      DexType newType = appView.graphLense().lookupType(type);
+      DexType newType = appView.graphLens().lookupType(type);
       if (newType != type) {
         Value newOutValue = makeOutValue(current, code);
         Instruction newInstruction = constructor.apply(newType, newOutValue);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
index f1c403b..bf8fd80 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.conversion.MethodProcessingId.Factory.ReservedMethodProcessingIds;
@@ -105,14 +105,14 @@
     // Some optimizations may change methods, creating new instances of the encoded methods with a
     // new signature. The compiler needs to update the set of methods that must be reprocessed
     // according to the graph lens.
-    public void rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense applied) {
+    public void rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens applied) {
       methodsToReprocess.rewrittenWithLens(appView, applied);
       Map<DexEncodedMethod, Collection<CodeOptimization>> newOptimizationsMap =
           new IdentityHashMap<>();
       optimizationsMap.forEach(
           (method, optimizations) ->
               newOptimizationsMap.put(
-                  appView.graphLense().mapDexEncodedMethod(method, appView, applied),
+                  appView.graphLens().mapDexEncodedMethod(method, appView, applied),
                   optimizations));
       optimizationsMap.clear();
       optimizationsMap.putAll(newOptimizationsMap);
@@ -143,7 +143,7 @@
       }
       CallGraph callGraph =
           new PartialCallGraphBuilder(
-                  appView, methodsToReprocess.build(appView, appView.graphLense()))
+                  appView, methodsToReprocess.build(appView, appView.graphLens()))
               .build(executorService, timing);
       return new PostMethodProcessor(appView, optimizationsMap, callGraph);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
index 52a7d0a..fec0919 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchRemover.java
@@ -204,7 +204,6 @@
 
     @Override
     void removeStringSwitch() {
-      int nextBlockNumber = code.getHighestBlockNumber() + 1;
       // Remove outgoing control flow edges from the block containing the string switch.
       for (BasicBlock successor : block.getNormalSuccessors()) {
         successor.removePredecessor(block, null);
@@ -237,7 +236,8 @@
         if (blocksTargetedByMultipleSwitchCases.contains(targetBlock)) {
           // Need an intermediate block to avoid critical edges.
           BasicBlock intermediateBlock =
-              BasicBlock.createGotoBlock(nextBlockNumber++, Position.none(), code.metadata());
+              BasicBlock.createGotoBlock(
+                  code.getNextBlockNumber(), Position.none(), code.metadata());
           intermediateBlock.link(targetBlock);
           blockIterator.add(intermediateBlock);
           newBlocksWithStrings.add(intermediateBlock);
@@ -245,7 +245,7 @@
         }
         BasicBlock newBlock =
             BasicBlock.createIfBlock(
-                nextBlockNumber++,
+                code.getNextBlockNumber(),
                 ifInstruction,
                 code.metadata(),
                 constStringInstruction,
@@ -278,7 +278,6 @@
 
     Int2ReferenceMap<Map<DexString, BasicBlock>> structure;
 
-    private int nextBlockNumber;
     private int nextStringId;
 
     private SingleHashBasedStringSwitchRemover(
@@ -294,11 +293,10 @@
       this.idSwitchBlock = theSwitch.fallthroughBlock().getUniqueNormalSuccessor();
       this.idSwitchFallthroughBlock = idSwitchBlock.getUniqueNormalSuccessor();
       this.structure = createStructure(theSwitch);
-      this.nextBlockNumber = code.getHighestBlockNumber() + 1;
     }
 
     private int getAndIncrementNextBlockNumber() {
-      return nextBlockNumber++;
+      return code.getNextBlockNumber();
     }
 
     private Int2ReferenceMap<Map<DexString, BasicBlock>> createStructure(StringSwitch theSwitch)
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 fbf5a15..8c65c1e 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
@@ -282,9 +282,9 @@
     }
     return c -> method.method.hashCode();
   }
-  
+
   private MethodProvider getMethodProviderOrNull(DexMethod method) {
-    DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
+    DexMethod original = appView.graphLens().getOriginalMethodSignature(method);
     assert original != null;
     return rewritableMethods.getProvider(original);
   }
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 f537a6f..88f6f04 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
@@ -26,7 +26,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.IRCode;
@@ -38,7 +38,7 @@
 import com.android.tools.r8.ir.code.InvokeSuper;
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.desugar.DefaultMethodsHelper.Collection;
-import com.android.tools.r8.ir.desugar.InterfaceProcessor.InterfaceProcessorNestedGraphLense;
+import com.android.tools.r8.ir.desugar.InterfaceProcessor.InterfaceProcessorNestedGraphLens;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.SynthesizedOrigin;
 import com.android.tools.r8.position.MethodPosition;
@@ -1028,7 +1028,7 @@
   }
 
   private Map<DexType, DexProgramClass> processInterfaces(Builder<?> builder, Flavor flavour) {
-    NestedGraphLense.Builder graphLensBuilder = InterfaceProcessorNestedGraphLense.builder();
+    NestedGraphLens.Builder graphLensBuilder = InterfaceProcessorNestedGraphLens.builder();
     InterfaceProcessor processor = new InterfaceProcessor(appView, this);
     for (DexProgramClass clazz : builder.getProgramClasses()) {
       if (shouldProcess(clazz, flavour, true)) {
@@ -1040,7 +1040,7 @@
       dispatchClass.forEachProgramMethod(synthesizedMethods::add);
     }
     if (appView.enableWholeProgramOptimizations()) {
-      appView.setGraphLense(graphLensBuilder.build(appView.dexItemFactory(), appView.graphLense()));
+      appView.setGraphLens(graphLensBuilder.build(appView.dexItemFactory(), appView.graphLens()));
     }
     return processor.syntheticClasses;
   }
@@ -1132,7 +1132,7 @@
     if (shouldIgnoreFromReports(missing)) {
       return;
     }
-    DexMethod method = appView.graphLense().getOriginalMethodSignature(referencedFrom);
+    DexMethod method = appView.graphLens().getOriginalMethodSignature(referencedFrom);
     Origin origin = getMethodOrigin(method);
     MethodPosition position = new MethodPosition(method.asMethodReference());
     options.warningMissingTypeForDesugar(origin, position, missing, method);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 2b8ce66..0b653f7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -28,8 +28,8 @@
 import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.ir.code.Invoke.Type;
@@ -68,7 +68,7 @@
     this.rewriter = rewriter;
   }
 
-  void process(DexProgramClass iface, NestedGraphLense.Builder graphLensBuilder) {
+  void process(DexProgramClass iface, NestedGraphLens.Builder graphLensBuilder) {
     assert iface.isInterface();
     // The list of methods to be created in companion class.
     List<DexEncodedMethod> companionMethods = new ArrayList<>();
@@ -98,9 +98,9 @@
             code, companionMethod.getArity(), appView);
         if (!appView.options().isDesugaredLibraryCompilation()) {
           setOriginalMethodPosition(
-              code, appView.graphLense().getOriginalMethodSignature(virtual.method));
+              code, appView.graphLens().getOriginalMethodSignature(virtual.method));
         } else {
-          assert appView.graphLense().isIdentityLense();
+          assert appView.graphLens().isIdentityLens();
         }
         DexEncodedMethod implMethod =
             new DexEncodedMethod(
@@ -144,9 +144,9 @@
         DexMethod companionMethod = rewriter.staticAsMethodOfCompanionClass(oldMethod);
         if (!appView.options().isDesugaredLibraryCompilation()) {
           setOriginalMethodPosition(
-              direct.getCode(), appView.graphLense().getOriginalMethodSignature(oldMethod));
+              direct.getCode(), appView.graphLens().getOriginalMethodSignature(oldMethod));
         } else {
-          assert appView.graphLense().isIdentityLense();
+          assert appView.graphLens().isIdentityLens();
         }
         DexEncodedMethod implMethod =
             new DexEncodedMethod(
@@ -177,9 +177,9 @@
               code, companionMethod.getArity(), appView);
           if (!appView.options().isDesugaredLibraryCompilation()) {
             setOriginalMethodPosition(
-                code, appView.graphLense().getOriginalMethodSignature(oldMethod));
+                code, appView.graphLens().getOriginalMethodSignature(oldMethod));
           } else {
-            assert appView.graphLense().isIdentityLense();
+            assert appView.graphLens().isIdentityLens();
           }
           DexEncodedMethod implMethod =
               new DexEncodedMethod(
@@ -400,15 +400,15 @@
 
   // Specific lens which remaps invocation types to static since all rewrites performed here
   // are to static companion methods.
-  public static class InterfaceProcessorNestedGraphLense extends NestedGraphLense {
+  public static class InterfaceProcessorNestedGraphLens extends NestedGraphLens {
 
-    public InterfaceProcessorNestedGraphLense(
+    public InterfaceProcessorNestedGraphLens(
         Map<DexType, DexType> typeMap,
         Map<DexMethod, DexMethod> methodMap,
         Map<DexField, DexField> fieldMap,
         BiMap<DexField, DexField> originalFieldSignatures,
         BiMap<DexMethod, DexMethod> originalMethodSignatures,
-        GraphLense previousLense,
+        GraphLens previousLens,
         DexItemFactory dexItemFactory) {
       super(
           typeMap,
@@ -416,7 +416,7 @@
           fieldMap,
           originalFieldSignatures,
           originalMethodSignatures,
-          previousLense,
+          previousLens,
           dexItemFactory);
     }
 
@@ -425,23 +425,23 @@
       return Type.STATIC;
     }
 
-    public static GraphLense.Builder builder() {
+    public static GraphLens.Builder builder() {
       return new Builder();
     }
 
-    public static class Builder extends NestedGraphLense.Builder {
+    public static class Builder extends NestedGraphLens.Builder {
       @Override
-      public GraphLense build(DexItemFactory dexItemFactory, GraphLense previousLense) {
+      public GraphLens build(DexItemFactory dexItemFactory, GraphLens previousLens) {
         if (originalFieldSignatures.isEmpty() && originalMethodSignatures.isEmpty()) {
-          return previousLense;
+          return previousLens;
         }
-        return new InterfaceProcessorNestedGraphLense(
+        return new InterfaceProcessorNestedGraphLens(
             typeMap,
             methodMap,
             fieldMap,
             originalFieldSignatures,
             originalMethodSignatures,
-            previousLense,
+            previousLens,
             dexItemFactory);
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index fb66a2a..6e41b1a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -12,8 +12,8 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.type.Nullability;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -347,19 +347,19 @@
     return knownLambdaClasses;
   }
 
-  public GraphLense buildMappingLense(AppView<?> appView) {
+  public GraphLens buildMappingLens(AppView<?> appView) {
     if (originalMethodSignatures.isEmpty()) {
-      return appView.graphLense();
+      return appView.graphLens();
     }
-    return new LambdaRewriterLense(
-        originalMethodSignatures, appView.graphLense(), appView.dexItemFactory());
+    return new LambdaRewriterLens(
+        originalMethodSignatures, appView.graphLens(), appView.dexItemFactory());
   }
 
-  static class LambdaRewriterLense extends NestedGraphLense {
+  static class LambdaRewriterLens extends NestedGraphLens {
 
-    public LambdaRewriterLense(
+    public LambdaRewriterLens(
         BiMap<DexMethod, DexMethod> originalMethodSignatures,
-        GraphLense graphLense,
+        GraphLens graphLens,
         DexItemFactory factory) {
       super(
           ImmutableMap.of(),
@@ -367,7 +367,7 @@
           ImmutableMap.of(),
           null,
           originalMethodSignatures,
-          graphLense,
+          graphLens,
           factory);
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index 58730b9..bbe2ae0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -81,18 +81,18 @@
   abstract void reportIncompleteNest(List<DexType> nest);
 
   DexClass definitionFor(DexType type) {
-    return appView.definitionFor(appView.graphLense().lookupType(type));
+    return appView.definitionFor(appView.graphLens().lookupType(type));
   }
 
   private DexEncodedMethod lookupOnHolder(
       DexMethod method, DexClassAndMethod context, Invoke.Type invokeType) {
     DexMethod rewritten =
-        appView.graphLense().lookupMethod(method, context.getReference(), invokeType).getMethod();
+        appView.graphLens().lookupMethod(method, context.getReference(), invokeType).getMethod();
     return rewritten.lookupOnClass(appView.definitionForHolder(rewritten));
   }
 
   private DexEncodedField lookupOnHolder(DexField field) {
-    DexField rewritten = appView.graphLense().lookupField(field);
+    DexField rewritten = appView.graphLens().lookupField(field);
     return rewritten.lookupOnClass(appView.definitionForHolder(rewritten));
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
similarity index 77%
rename from src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java
rename to src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
index ded1538..cdca27a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLense.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestedPrivateMethodLens.java
@@ -8,35 +8,35 @@
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.ir.code.Invoke;
 import com.google.common.collect.ImmutableMap;
 import java.util.IdentityHashMap;
 import java.util.Map;
 
-public class NestedPrivateMethodLense extends NestedGraphLense {
+public class NestedPrivateMethodLens extends NestedGraphLens {
 
   // Map from nestHost to nest members including nest hosts
   private final DexType nestConstructorType;
   private final Map<DexField, DexMethod> getFieldMap;
   private final Map<DexField, DexMethod> putFieldMap;
 
-  NestedPrivateMethodLense(
+  NestedPrivateMethodLens(
       AppView<?> appView,
       DexType nestConstructorType,
       Map<DexMethod, DexMethod> methodMap,
       Map<DexField, DexMethod> getFieldMap,
       Map<DexField, DexMethod> putFieldMap,
-      GraphLense previousLense) {
+      GraphLens previousLens) {
     super(
         ImmutableMap.of(),
         methodMap,
         ImmutableMap.of(),
         null,
         null,
-        previousLense,
+        previousLens,
         appView.dexItemFactory());
     // No concurrent maps here, we do not want synchronization overhead.
     assert methodMap instanceof IdentityHashMap;
@@ -59,13 +59,13 @@
 
   @Override
   public DexMethod lookupGetFieldForMethod(DexField field, DexMethod context) {
-    assert previousLense.lookupGetFieldForMethod(field, context) == null;
+    assert previousLens.lookupGetFieldForMethod(field, context) == null;
     return lookupFieldForMethod(field, context, getFieldMap);
   }
 
   @Override
   public DexMethod lookupPutFieldForMethod(DexField field, DexMethod context) {
-    assert previousLense.lookupPutFieldForMethod(field, context) == null;
+    assert previousLens.lookupPutFieldForMethod(field, context) == null;
     return lookupFieldForMethod(field, context, putFieldMap);
   }
 
@@ -76,7 +76,7 @@
 
   @Override
   public boolean verifyIsContextFreeForMethod(DexMethod method) {
-    assert !methodMap.containsKey(previousLense.lookupMethod(method));
+    assert !methodMap.containsKey(previousLens.lookupMethod(method));
     return true;
   }
 
@@ -99,18 +99,17 @@
   public RewrittenPrototypeDescription lookupPrototypeChanges(DexMethod method) {
     if (isConstructorBridge(method)) {
       // TODO (b/132767654): Try to write a test which breaks that assertion.
-      assert previousLense.lookupPrototypeChanges(method).isEmpty();
+      assert previousLens.lookupPrototypeChanges(method).isEmpty();
       return RewrittenPrototypeDescription.none().withExtraNullParameter();
     } else {
-      return previousLense.lookupPrototypeChanges(method);
+      return previousLens.lookupPrototypeChanges(method);
     }
   }
 
   @Override
-  public GraphLenseLookupResult lookupMethod(
-      DexMethod method, DexMethod context, Invoke.Type type) {
+  public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Invoke.Type type) {
     assert originalMethodSignatures == null;
-    GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
+    GraphLensLookupResult previous = previousLens.lookupMethod(method, context, type);
     DexMethod bridge = methodMap.get(previous.getMethod());
     if (bridge == null) {
       return previous;
@@ -120,16 +119,16 @@
       return previous;
     }
     if (isConstructorBridge(bridge)) {
-      return new GraphLenseLookupResult(bridge, Invoke.Type.DIRECT);
+      return new GraphLensLookupResult(bridge, Invoke.Type.DIRECT);
     }
-    return new GraphLenseLookupResult(bridge, Invoke.Type.STATIC);
+    return new GraphLensLookupResult(bridge, Invoke.Type.STATIC);
   }
 
   public static Builder builder() {
     return new Builder();
   }
 
-  public static class Builder extends NestedGraphLense.Builder {
+  public static class Builder extends NestedGraphLens.Builder {
 
     private Map<DexField, DexMethod> getFieldMap = new IdentityHashMap<>();
     private Map<DexField, DexMethod> putFieldMap = new IdentityHashMap<>();
@@ -142,14 +141,14 @@
       putFieldMap.put(from, to);
     }
 
-    public NestedPrivateMethodLense build(AppView<?> appView, DexType nestConstructorType) {
+    public NestedPrivateMethodLens build(AppView<?> appView, DexType nestConstructorType) {
       assert typeMap.isEmpty();
       assert fieldMap.isEmpty();
       if (getFieldMap.isEmpty() && methodMap.isEmpty() && putFieldMap.isEmpty()) {
         return null;
       }
-      return new NestedPrivateMethodLense(
-          appView, nestConstructorType, methodMap, getFieldMap, putFieldMap, appView.graphLense());
+      return new NestedPrivateMethodLens(
+          appView, nestConstructorType, methodMap, getFieldMap, putFieldMap, appView.graphLens());
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
index b97888d..e9ac116 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/R8NestBasedAccessDesugaring.java
@@ -33,20 +33,20 @@
     super(appView);
   }
 
-  public NestedPrivateMethodLense run(
+  public NestedPrivateMethodLens run(
       ExecutorService executorService, DexApplication.Builder<?> appBuilder)
       throws ExecutionException {
     assert !appView.options().canUseNestBasedAccess()
         || appView.options().testing.enableForceNestBasedAccessDesugaringForTest;
     computeAndProcessNestsConcurrently(executorService);
-    NestedPrivateMethodLense.Builder lensBuilder = NestedPrivateMethodLense.builder();
+    NestedPrivateMethodLens.Builder lensBuilder = NestedPrivateMethodLens.builder();
     addDeferredBridgesAndMapMethods(lensBuilder);
     clearNestAttributes();
     synthesizeNestConstructor(appBuilder);
     return lensBuilder.build(appView, getNestConstructorType());
   }
 
-  private void addDeferredBridgesAndMapMethods(NestedPrivateMethodLense.Builder lensBuilder) {
+  private void addDeferredBridgesAndMapMethods(NestedPrivateMethodLens.Builder lensBuilder) {
     // Here we add the bridges and we fill the lens map.
     addDeferredBridgesAndMapMethods(bridges, lensBuilder::map);
     addDeferredBridgesAndMapMethods(getFieldBridges, lensBuilder::mapGetField);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
index 6f3aed5..4043023 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
@@ -104,7 +104,7 @@
   }
 
   public static boolean isSynthesizedCloseResourceMethod(DexMethod method, AppView<?> appView) {
-    DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
+    DexMethod original = appView.graphLens().getOriginalMethodSignature(method);
     assert original != null;
     // We consider all methods of *any* class with expected name and signature
     // to be synthesized by java 9 compiler for try-with-resources, reasoning:
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/BasicBlockInstructionsEquivalence.java b/src/main/java/com/android/tools/r8/ir/optimize/BasicBlockInstructionsEquivalence.java
index 17c8d1a..b7909df 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/BasicBlockInstructionsEquivalence.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/BasicBlockInstructionsEquivalence.java
@@ -21,7 +21,7 @@
 
   BasicBlockInstructionsEquivalence(IRCode code, RegisterAllocator allocator) {
     this.allocator = allocator;
-    hashes = new int[code.getHighestBlockNumber() + 1];
+    hashes = new int[code.getCurrentBlockNumber() + 1];
     Arrays.fill(hashes, UNKNOW_HASH);
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 4cb2fab..996b8d8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -710,7 +710,6 @@
     assert block == originalBlock;
 
     // Collect the new blocks for adding to the block list.
-    int nextBlockNumber = code.getHighestBlockNumber() + 1;
     LinkedList<BasicBlock> newBlocks = new LinkedList<>();
 
     // Build the switch-blocks backwards, to always have the fallthrough block in hand.
@@ -722,9 +721,7 @@
         int key = keys.getInt(j);
         switchBuilder.addKeyAndTarget(key, keyToTarget.get(key));
       }
-      switchBuilder
-          .setFallthrough(fallthroughBlock)
-          .setBlockNumber(nextBlockNumber++);
+      switchBuilder.setFallthrough(fallthroughBlock).setBlockNumber(code.getNextBlockNumber());
       BasicBlock newSwitchBlock = switchBuilder.build(code.metadata());
       newBlocks.addFirst(newSwitchBlock);
       fallthroughBlock = newSwitchBlock;
@@ -740,7 +737,7 @@
           .setRight(key)
           .setTarget(peeledOffTarget)
           .setFallthrough(fallthroughBlock)
-          .setBlockNumber(nextBlockNumber++);
+          .setBlockNumber(code.getNextBlockNumber());
       BasicBlock ifBlock = ifBuilder.build();
       newBlocks.addFirst(ifBlock);
       fallthroughBlock = ifBlock;
@@ -3478,7 +3475,8 @@
       iterator.add(new InvokeVirtual(print, null, ImmutableList.of(out, indent)));
 
       // Add a block for end-of-line printing.
-      BasicBlock eol = BasicBlock.createGotoBlock(code.blocks.size(), position, code.metadata());
+      BasicBlock eol =
+          BasicBlock.createGotoBlock(code.getNextBlockNumber(), position, code.metadata());
       code.blocks.add(eol);
 
       BasicBlock successor = block.unlinkSingleSuccessor();
@@ -3493,14 +3491,15 @@
         successor = block.unlinkSingleSuccessor();
         If theIf = new If(Type.NE, argument);
         theIf.setPosition(position);
-        BasicBlock ifBlock = BasicBlock.createIfBlock(code.blocks.size(), theIf, code.metadata());
+        BasicBlock ifBlock =
+            BasicBlock.createIfBlock(code.getNextBlockNumber(), theIf, code.metadata());
         code.blocks.add(ifBlock);
         // Fallthrough block must be added right after the if.
         BasicBlock isNullBlock =
-            BasicBlock.createGotoBlock(code.blocks.size(), position, code.metadata());
+            BasicBlock.createGotoBlock(code.getNextBlockNumber(), position, code.metadata());
         code.blocks.add(isNullBlock);
         BasicBlock isNotNullBlock =
-            BasicBlock.createGotoBlock(code.blocks.size(), position, code.metadata());
+            BasicBlock.createGotoBlock(code.getNextBlockNumber(), position, code.metadata());
         code.blocks.add(isNotNullBlock);
 
         // Link the added blocks together.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 97dbb2e..67b6310 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -18,7 +18,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.NestMemberClassAttribute;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
@@ -136,7 +136,7 @@
       return true;
     }
 
-    if (blacklist.contains(appView.graphLense().getOriginalMethodSignature(singleTargetReference))
+    if (blacklist.contains(appView.graphLens().getOriginalMethodSignature(singleTargetReference))
         || TwrCloseResourceRewriter.isSynthesizedCloseResourceMethod(
             singleTargetReference, appView)) {
       whyAreYouNotInliningReporter.reportBlacklisted();
@@ -183,7 +183,7 @@
 
     ConstraintWithTarget result = ConstraintWithTarget.ALWAYS;
     InliningConstraints inliningConstraints =
-        new InliningConstraints(appView, GraphLense.getIdentityLense());
+        new InliningConstraints(appView, GraphLens.getIdentityLens());
     for (Instruction instruction : code.instructions()) {
       ConstraintWithTarget state =
           instructionAllowedForInlining(instruction, inliningConstraints, context);
@@ -635,11 +635,9 @@
 
         code.prepareBlocksForCatchHandlers();
 
-        int nextBlockNumber = code.getHighestBlockNumber() + 1;
-
         // Create a block for holding the monitor-exit instruction.
         BasicBlock monitorExitBlock = new BasicBlock();
-        monitorExitBlock.setNumber(nextBlockNumber++);
+        monitorExitBlock.setNumber(code.getNextBlockNumber());
 
         // For each block in the code that may throw, add a catch-all handler targeting the
         // monitor-exit block.
@@ -654,7 +652,7 @@
           }
           BasicBlock moveExceptionBlock =
               BasicBlock.createGotoBlock(
-                  nextBlockNumber++, Position.none(), code.metadata(), monitorExitBlock);
+                  code.getNextBlockNumber(), Position.none(), code.metadata(), monitorExitBlock);
           InstructionListIterator moveExceptionBlockIterator =
               moveExceptionBlock.listIterator(code);
           moveExceptionBlockIterator.setInsertionPosition(Position.syntheticNone());
@@ -665,29 +663,32 @@
           moveExceptionBlocks.add(moveExceptionBlock);
         }
 
-        // Create a phi for the exception values such that we can rethrow the exception if needed.
-        Value exceptionValue;
-        if (moveExceptionBlocks.size() == 1) {
-          exceptionValue =
-              ListUtils.first(moveExceptionBlocks).getInstructions().getFirst().outValue();
-        } else {
-          Phi phi = code.createPhi(monitorExitBlock, throwableType);
-          List<Value> operands =
-              ListUtils.map(
-                  moveExceptionBlocks, block -> block.getInstructions().getFirst().outValue());
-          phi.addOperands(operands);
-          exceptionValue = phi;
+        InstructionListIterator monitorExitBlockIterator = null;
+        if (!moveExceptionBlocks.isEmpty()) {
+          // Create a phi for the exception values such that we can rethrow the exception if needed.
+          Value exceptionValue;
+          if (moveExceptionBlocks.size() == 1) {
+            exceptionValue =
+                ListUtils.first(moveExceptionBlocks).getInstructions().getFirst().outValue();
+          } else {
+            Phi phi = code.createPhi(monitorExitBlock, throwableType);
+            List<Value> operands =
+                ListUtils.map(
+                    moveExceptionBlocks, block -> block.getInstructions().getFirst().outValue());
+            phi.addOperands(operands);
+            exceptionValue = phi;
+          }
+
+          monitorExitBlockIterator = monitorExitBlock.listIterator(code);
+          monitorExitBlockIterator.setInsertionPosition(Position.syntheticNone());
+          monitorExitBlockIterator.add(new Throw(exceptionValue));
+          monitorExitBlock.getMutablePredecessors().addAll(moveExceptionBlocks);
+
+          // Insert the newly created blocks.
+          code.blocks.addAll(moveExceptionBlocks);
+          code.blocks.add(monitorExitBlock);
         }
 
-        InstructionListIterator monitorExitBlockIterator = monitorExitBlock.listIterator(code);
-        monitorExitBlockIterator.setInsertionPosition(Position.syntheticNone());
-        monitorExitBlockIterator.add(new Throw(exceptionValue));
-        monitorExitBlock.getMutablePredecessors().addAll(moveExceptionBlocks);
-
-        // Insert the newly created blocks.
-        code.blocks.addAll(moveExceptionBlocks);
-        code.blocks.add(monitorExitBlock);
-
         // Create a block for holding the monitor-enter instruction. Note that, since this block
         // is created after we attach catch-all handlers to the code, this block will not have any
         // catch handlers.
@@ -715,9 +716,11 @@
 
         // Insert the monitor-enter and monitor-exit instructions.
         monitorEnterBlockIterator.add(new Monitor(Monitor.Type.ENTER, lockValue));
-        monitorExitBlockIterator.previous();
-        monitorExitBlockIterator.add(new Monitor(Monitor.Type.EXIT, lockValue));
-        monitorExitBlock.close(null);
+        if (monitorExitBlockIterator != null) {
+          monitorExitBlockIterator.previous();
+          monitorExitBlockIterator.add(new Monitor(Monitor.Type.EXIT, lockValue));
+          monitorExitBlock.close(null);
+        }
 
         for (BasicBlock block : code.blocks) {
           if (block.exit().isReturn()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
index 890a23e..1d32c0b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
@@ -14,7 +14,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ResolutionResult;
 import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
 import com.android.tools.r8.ir.code.Invoke.Type;
@@ -38,23 +38,23 @@
   // being inlined into B.<init>() only because it is not declared in the same class as B (which
   // it would be after merging A and B).
   //
-  // To circumvent this problem, the vertical class merger creates a graph lense that maps the
+  // To circumvent this problem, the vertical class merger creates a graph lens that maps the
   // type A to B, to create a temporary view of what the world would look like after class merging.
-  private GraphLense graphLense;
+  private GraphLens graphLens;
 
-  public InliningConstraints(AppView<AppInfoWithLiveness> appView, GraphLense graphLense) {
-    assert graphLense.isContextFreeForMethods();
-    assert appView.graphLense() != graphLense || graphLense.isIdentityLense();
+  public InliningConstraints(AppView<AppInfoWithLiveness> appView, GraphLens graphLens) {
+    assert graphLens.isContextFreeForMethods();
+    assert appView.graphLens() != graphLens || graphLens.isIdentityLens();
     this.appView = appView;
-    this.graphLense = graphLense; // Note: Intentionally *not* appView.graphLense().
+    this.graphLens = graphLens; // Note: Intentionally *not* appView.graphLens().
   }
 
   public AppView<AppInfoWithLiveness> getAppView() {
     return appView;
   }
 
-  public GraphLense getGraphLense() {
-    return graphLense;
+  public GraphLens getGraphLens() {
+    return graphLens;
   }
 
   public void disallowStaticInterfaceMethodCalls() {
@@ -62,7 +62,7 @@
   }
 
   private boolean isVerticalClassMerging() {
-    return !graphLense.isIdentityLense();
+    return !graphLens.isIdentityLens();
   }
 
   public ConstraintWithTarget forAlwaysMaterializingUser() {
@@ -131,7 +131,7 @@
   }
 
   public ConstraintWithTarget forInstanceGet(DexField field, DexProgramClass context) {
-    DexField lookup = graphLense.lookupField(field);
+    DexField lookup = graphLens.lookupField(field);
     return forFieldInstruction(lookup, appView.appInfo().lookupInstanceTarget(lookup), context);
   }
 
@@ -140,7 +140,7 @@
   }
 
   public ConstraintWithTarget forInstancePut(DexField field, DexProgramClass context) {
-    DexField lookup = graphLense.lookupField(field);
+    DexField lookup = graphLens.lookupField(field);
     return forFieldInstruction(lookup, appView.appInfo().lookupInstanceTarget(lookup), context);
   }
 
@@ -183,7 +183,7 @@
     if (dexEncodedMethod != null) {
       return dexEncodedMethod;
     }
-    assert graphLense.lookupType(context.superType) == context.type;
+    assert graphLens.lookupType(context.superType) == context.type;
     DexProgramClass superContext = appView.definitionForProgramType(context.superType);
     if (superContext == null) {
       return null;
@@ -198,7 +198,7 @@
   }
 
   public ConstraintWithTarget forInvokeDirect(DexMethod method, DexProgramClass context) {
-    DexMethod lookup = graphLense.lookupMethod(method);
+    DexMethod lookup = graphLens.lookupMethod(method);
     DexEncodedMethod target =
         isVerticalClassMerging()
             ? lookupWhileVerticalClassMerging(
@@ -210,7 +210,7 @@
   }
 
   public ConstraintWithTarget forInvokeInterface(DexMethod method, DexProgramClass context) {
-    DexMethod lookup = graphLense.lookupMethod(method);
+    DexMethod lookup = graphLens.lookupMethod(method);
     return forVirtualInvoke(lookup, context, true);
   }
 
@@ -227,7 +227,7 @@
   }
 
   public ConstraintWithTarget forInvokeStatic(DexMethod method, DexProgramClass context) {
-    DexMethod lookup = graphLense.lookupMethod(method);
+    DexMethod lookup = graphLens.lookupMethod(method);
     DexEncodedMethod target =
         isVerticalClassMerging()
             ? lookupWhileVerticalClassMerging(
@@ -244,7 +244,7 @@
   }
 
   public ConstraintWithTarget forInvokeVirtual(DexMethod method, DexProgramClass context) {
-    DexMethod lookup = graphLense.lookupMethod(method);
+    DexMethod lookup = graphLens.lookupMethod(method);
     return forVirtualInvoke(lookup, context, false);
   }
 
@@ -293,12 +293,12 @@
   }
 
   public ConstraintWithTarget forStaticGet(DexField field, DexProgramClass context) {
-    DexField lookup = graphLense.lookupField(field);
+    DexField lookup = graphLens.lookupField(field);
     return forFieldInstruction(lookup, appView.appInfo().lookupStaticTarget(lookup), context);
   }
 
   public ConstraintWithTarget forStaticPut(DexField field, DexProgramClass context) {
-    DexField lookup = graphLense.lookupField(field);
+    DexField lookup = graphLens.lookupField(field);
     return forFieldInstruction(lookup, appView.appInfo().lookupStaticTarget(lookup), context);
   }
 
@@ -329,7 +329,7 @@
   private ConstraintWithTarget forFieldInstruction(
       DexField field, DexEncodedField target, DexProgramClass context) {
     // Resolve the field if possible and decide whether the instruction can inlined.
-    DexType fieldHolder = graphLense.lookupType(field.holder);
+    DexType fieldHolder = graphLens.lookupType(field.holder);
     DexClass fieldClass = appView.definitionFor(fieldHolder);
     if (target != null && fieldClass != null) {
       ConstraintWithTarget fieldConstraintWithTarget =
@@ -340,7 +340,7 @@
       //
       // See, for example, InlineNonReboundFieldTest (b/128604123).
       if (field.holder != target.holder()) {
-        DexType actualFieldHolder = graphLense.lookupType(target.holder());
+        DexType actualFieldHolder = graphLens.lookupType(target.holder());
         fieldConstraintWithTarget =
             ConstraintWithTarget.meet(
                 fieldConstraintWithTarget,
@@ -364,7 +364,7 @@
       return ConstraintWithTarget.ALWAYS;
     }
     if (target != null) {
-      DexType methodHolder = graphLense.lookupType(target.holder());
+      DexType methodHolder = graphLens.lookupType(target.holder());
       DexClass methodClass = appView.definitionFor(methodHolder);
       if (methodClass != null) {
         if (!allowStaticInterfaceMethodCalls && methodClass.isInterface() && target.hasCode()) {
@@ -405,7 +405,7 @@
       return ConstraintWithTarget.NEVER;
     }
 
-    DexType methodHolder = graphLense.lookupType(resolutionTarget.holder());
+    DexType methodHolder = graphLens.lookupType(resolutionTarget.holder());
     DexClass methodClass = appView.definitionFor(methodHolder);
     assert methodClass != null;
     ConstraintWithTarget methodConstraintWithTarget =
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/NestReducer.java b/src/main/java/com/android/tools/r8/ir/optimize/NestReducer.java
index 715c936..6fa08c8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/NestReducer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/NestReducer.java
@@ -35,8 +35,8 @@
   }
 
   private DexClass definitionFor(DexType type) {
-    assert appView.graphLense().lookupType(type) == type;
-    return appView.definitionFor(appView.graphLense().lookupType(type));
+    assert appView.graphLens().lookupType(type) == type;
+    return appView.definitionFor(appView.graphLens().lookupType(type));
   }
 
   public void run(ExecutorService executorService) throws ExecutionException {
@@ -113,8 +113,7 @@
   private void clearNestAttributes(DexClass nestHost) {
     nestHost.getNestMembersClassAttributes().clear();
     for (NestMemberClassAttribute attr : nestHost.getNestMembersClassAttributes()) {
-      DexClass member =
-          appView.definitionFor(appView.graphLense().lookupType(attr.getNestMember()));
+      DexClass member = appView.definitionFor(appView.graphLens().lookupType(attr.getNestMember()));
       member.clearNestHost();
     }
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index d9eb7f2..c7e7b6b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -25,7 +25,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -1268,7 +1268,7 @@
 
   public Outliner(AppView<AppInfoWithLiveness> appView) {
     this.appView = appView;
-    this.inliningConstraints = new InliningConstraints(appView, GraphLense.getIdentityLense());
+    this.inliningConstraints = new InliningConstraints(appView, GraphLens.getIdentityLens());
   }
 
   public void createOutlineMethodIdentifierGenerator() {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
index 958749e..a8cd620 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
@@ -242,7 +242,6 @@
       blocks.add(normalExit);
     }
     do {
-      int startNumberOfNewBlock = code.getHighestBlockNumber() + 1;
       Map<BasicBlock, BasicBlock> newBlocks = new IdentityHashMap<>();
       for (BasicBlock block : blocks) {
         InstructionEquivalence equivalence = new InstructionEquivalence(allocator);
@@ -294,10 +293,9 @@
           if (commonSuffixSize <= 1 || sizeDelta >= 0) {
             continue;
           }
-          int blockNumber = startNumberOfNewBlock + newBlocks.size();
           BasicBlock newBlock =
               createAndInsertBlockForSuffix(
-                  blockNumber,
+                  code.getNextBlockNumber(),
                   commonSuffixSize,
                   predsWithSameLastInstruction,
                   block == normalExit ? null : block,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
index 5178020..eb6bddd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -336,7 +336,7 @@
     assert verticallyMergedClasses.isTarget(method.getHolderType());
     assert appView
         .dexItemFactory()
-        .isConstructor(appView.graphLense().getOriginalMethodSignature(method.getReference()));
+        .isConstructor(appView.graphLens().getOriginalMethodSignature(method.getReference()));
     assert method.getDefinition().getOptimizationInfo().forceInline();
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
index 71a2a18..3b3d15d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
@@ -137,8 +137,11 @@
         continue;
       }
 
-      // Check that ClassLoader used is the ClassLoader defined for the the service configuration
+      // Check that ClassLoader used is the ClassLoader defined for the service configuration
       // that we are instantiating or NULL.
+      if (serviceLoaderLoad.inValues().get(1).isPhi()) {
+        continue;
+      }
       InvokeVirtual classLoaderInvoke =
           serviceLoaderLoad.inValues().get(1).definition.asInvokeVirtual();
       boolean isGetClassLoaderOnConstClassOrNull =
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index 6a8b6a5..885a1d0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -16,7 +16,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.FieldAccessInfo;
 import com.android.tools.r8.graph.FieldAccessInfoCollection;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
@@ -48,12 +48,12 @@
     DISALLOW_ARGUMENT_REMOVAL
   }
 
-  public static class UninstantiatedTypeOptimizationGraphLense extends NestedGraphLense {
+  public static class UninstantiatedTypeOptimizationGraphLens extends NestedGraphLens {
 
     private final AppView<?> appView;
     private final Map<DexMethod, ArgumentInfoCollection> removedArgumentsInfoPerMethod;
 
-    UninstantiatedTypeOptimizationGraphLense(
+    UninstantiatedTypeOptimizationGraphLens(
         BiMap<DexMethod, DexMethod> methodMap,
         Map<DexMethod, ArgumentInfoCollection> removedArgumentsInfoPerMethod,
         AppView<?> appView) {
@@ -63,7 +63,7 @@
           ImmutableMap.of(),
           null,
           methodMap.inverse(),
-          appView.graphLense(),
+          appView.graphLens(),
           appView.dexItemFactory());
       this.appView = appView;
       this.removedArgumentsInfoPerMethod = removedArgumentsInfoPerMethod;
@@ -72,7 +72,7 @@
     @Override
     public RewrittenPrototypeDescription lookupPrototypeChanges(DexMethod method) {
       DexMethod originalMethod = originalMethodSignatures.getOrDefault(method, method);
-      RewrittenPrototypeDescription result = previousLense.lookupPrototypeChanges(originalMethod);
+      RewrittenPrototypeDescription result = previousLens.lookupPrototypeChanges(originalMethod);
       if (originalMethod != method) {
         if (method.proto.returnType.isVoidType() && !originalMethod.proto.returnType.isVoidType()) {
           result = result.withConstantReturn(originalMethod.proto.returnType, appView);
@@ -123,7 +123,7 @@
     return this;
   }
 
-  public UninstantiatedTypeOptimizationGraphLense run(
+  public UninstantiatedTypeOptimizationGraphLens run(
       MethodPoolCollection methodPoolCollection, ExecutorService executorService, Timing timing) {
     try {
       methodPoolCollection.buildAll(executorService, timing);
@@ -147,7 +147,7 @@
                     removedArgumentsInfoPerMethod));
 
     if (!methodMapping.isEmpty()) {
-      return new UninstantiatedTypeOptimizationGraphLense(
+      return new UninstantiatedTypeOptimizationGraphLens(
           methodMapping, removedArgumentsInfoPerMethod, appView);
     }
     return null;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
index 7b60b90..e6bd21e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
@@ -14,8 +14,8 @@
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
@@ -51,17 +51,17 @@
   private final BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
   private final Map<DexMethod, ArgumentInfoCollection> removedArguments = new IdentityHashMap<>();
 
-  public static class UnusedArgumentsGraphLense extends NestedGraphLense {
+  public static class UnusedArgumentsGraphLens extends NestedGraphLens {
 
     private final Map<DexMethod, ArgumentInfoCollection> removedArguments;
 
-    UnusedArgumentsGraphLense(
+    UnusedArgumentsGraphLens(
         Map<DexType, DexType> typeMap,
         Map<DexMethod, DexMethod> methodMap,
         Map<DexField, DexField> fieldMap,
         BiMap<DexField, DexField> originalFieldSignatures,
         BiMap<DexMethod, DexMethod> originalMethodSignatures,
-        GraphLense previousLense,
+        GraphLens previousLens,
         DexItemFactory dexItemFactory,
         Map<DexMethod, ArgumentInfoCollection> removedArguments) {
       super(
@@ -70,7 +70,7 @@
           fieldMap,
           originalFieldSignatures,
           originalMethodSignatures,
-          previousLense,
+          previousLens,
           dexItemFactory);
       this.removedArguments = removedArguments;
     }
@@ -81,7 +81,7 @@
           originalMethodSignatures != null
               ? originalMethodSignatures.getOrDefault(method, method)
               : method;
-      RewrittenPrototypeDescription result = previousLense.lookupPrototypeChanges(originalMethod);
+      RewrittenPrototypeDescription result = previousLens.lookupPrototypeChanges(originalMethod);
       ArgumentInfoCollection removedArguments = this.removedArguments.get(method);
       return removedArguments != null ? result.withRemovedArguments(removedArguments) : result;
     }
@@ -93,7 +93,7 @@
     this.methodPoolCollection = methodPoolCollection;
   }
 
-  public UnusedArgumentsGraphLense run(ExecutorService executorService, Timing timing)
+  public UnusedArgumentsGraphLens run(ExecutorService executorService, Timing timing)
       throws ExecutionException {
     ThreadUtils.awaitFutures(
         Streams.stream(appView.appInfo().classes())
@@ -110,13 +110,13 @@
     appView.appInfo().classesWithDeterministicOrder().forEach(this::processVirtualMethods);
 
     if (!methodMapping.isEmpty()) {
-      return new UnusedArgumentsGraphLense(
+      return new UnusedArgumentsGraphLens(
           ImmutableMap.of(),
           methodMapping,
           ImmutableMap.of(),
           ImmutableBiMap.of(),
           methodMapping.inverse(),
-          appView.graphLense(),
+          appView.graphLens(),
           appView.dexItemFactory(),
           removedArguments);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 3824962..acd7477 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -1222,8 +1222,9 @@
 
     if (root.isStaticGet()) {
       // If we are class inlining a singleton instance from a static-get, then we don't know
-      // the value of the fields.
-      if (parameterUsage.hasFieldRead) {
+      // the value of the fields, and we also can't optimize away instance-field assignments, as
+      // they have global side effects.
+      if (parameterUsage.hasFieldAssignment || parameterUsage.hasFieldRead) {
         return false;
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index 3be53b2..c902868 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -23,8 +23,8 @@
 import com.android.tools.r8.graph.DexValue.DexValueInt;
 import com.android.tools.r8.graph.DexValue.DexValueNull;
 import com.android.tools.r8.graph.FieldResolutionResult;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
@@ -337,10 +337,10 @@
     // Update keep info on any of the enum methods of the removed classes.
     updatePinnedItems(enumsToUnbox);
     enumUnboxerRewriter = new EnumUnboxingRewriter(appView, enumsToUnbox);
-    NestedGraphLense enumUnboxingLens = new TreeFixer(enumsToUnbox).fixupTypeReferences();
+    NestedGraphLens enumUnboxingLens = new TreeFixer(enumsToUnbox).fixupTypeReferences();
     appView.setUnboxedEnums(enumUnboxerRewriter.getEnumsToUnbox());
-    GraphLense previousLens = appView.graphLense();
-    appView.setGraphLense(enumUnboxingLens);
+    GraphLens previousLens = appView.graphLens();
+    appView.setGraphLens(enumUnboxingLens);
     appView.setAppInfo(
         appView.appInfo().rewrittenWithLens(appView.appInfo().app().asDirect(), enumUnboxingLens));
     // Update optimization info.
@@ -354,8 +354,8 @@
             if (optimizationInfo.isMutableFieldOptimizationInfo()) {
               optimizationInfo
                   .asMutableFieldOptimizationInfo()
-                  .fixupClassTypeReferences(appView.graphLense()::lookupType, appView)
-                  .fixupAbstractValue(appView, appView.graphLense());
+                  .fixupClassTypeReferences(appView.graphLens()::lookupType, appView)
+                  .fixupAbstractValue(appView, appView.graphLens());
             } else {
               assert optimizationInfo.isDefaultFieldOptimizationInfo();
             }
@@ -367,9 +367,9 @@
             if (optimizationInfo.isUpdatableMethodOptimizationInfo()) {
               optimizationInfo
                   .asUpdatableMethodOptimizationInfo()
-                  .fixupClassTypeReferences(appView.graphLense()::lookupType, appView)
-                  .fixupAbstractReturnValue(appView, appView.graphLense())
-                  .fixupInstanceInitializerInfo(appView, appView.graphLense());
+                  .fixupClassTypeReferences(appView.graphLens()::lookupType, appView)
+                  .fixupAbstractReturnValue(appView, appView.graphLens())
+                  .fixupInstanceInitializerInfo(appView, appView.graphLens());
             } else {
               assert optimizationInfo.isDefaultMethodOptimizationInfo();
             }
@@ -718,7 +718,7 @@
       this.enumsToUnbox = enumsToUnbox;
     }
 
-    private NestedGraphLense fixupTypeReferences() {
+    private NestedGraphLens fixupTypeReferences() {
       assert enumUnboxerRewriter != null;
       // Fix all methods and fields using enums to unbox.
       for (DexProgramClass clazz : appView.appInfo().classes()) {
@@ -752,7 +752,7 @@
           appView.definitionForProgramType(factory.enumUnboxingUtilityType);
       assert utilityClass != null : "Should have been synthesized upfront";
       utilityClass.addDirectMethods(unboxedEnumsMethods);
-      return lensBuilder.build(factory, appView.graphLense(), enumsToUnbox);
+      return lensBuilder.build(factory, appView.graphLens(), enumsToUnbox);
     }
 
     private void clearEnumToUnboxMethod(DexEncodedMethod enumMethod) {
@@ -857,7 +857,7 @@
     }
   }
 
-  private static class EnumUnboxingLens extends NestedGraphLense {
+  private static class EnumUnboxingLens extends NestedGraphLens {
 
     private final Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges;
     private final Set<DexType> unboxedEnums;
@@ -868,7 +868,7 @@
         Map<DexField, DexField> fieldMap,
         BiMap<DexField, DexField> originalFieldSignatures,
         BiMap<DexMethod, DexMethod> originalMethodSignatures,
-        GraphLense previousLense,
+        GraphLens previousLens,
         DexItemFactory dexItemFactory,
         Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges,
         Set<DexType> unboxedEnums) {
@@ -878,7 +878,7 @@
           fieldMap,
           originalFieldSignatures,
           originalMethodSignatures,
-          previousLense,
+          previousLens,
           dexItemFactory);
       this.prototypeChanges = prototypeChanges;
       this.unboxedEnums = unboxedEnums;
@@ -889,7 +889,7 @@
       // During the second IR processing enum unboxing is the only optimization rewriting
       // prototype description, if this does not hold, remove the assertion and merge
       // the two prototype changes.
-      assert previousLense.lookupPrototypeChanges(method).isEmpty();
+      assert previousLens.lookupPrototypeChanges(method).isEmpty();
       return prototypeChanges.getOrDefault(method, RewrittenPrototypeDescription.none());
     }
 
@@ -908,7 +908,7 @@
       return new Builder();
     }
 
-    private static class Builder extends NestedGraphLense.Builder {
+    private static class Builder extends NestedGraphLens.Builder {
 
       private Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges =
           new IdentityHashMap<>();
@@ -941,7 +941,7 @@
       }
 
       public EnumUnboxingLens build(
-          DexItemFactory dexItemFactory, GraphLense previousLense, Set<DexType> unboxedEnums) {
+          DexItemFactory dexItemFactory, GraphLens previousLens, Set<DexType> unboxedEnums) {
         if (typeMap.isEmpty() && methodMap.isEmpty() && fieldMap.isEmpty()) {
           return null;
         }
@@ -951,7 +951,7 @@
             fieldMap,
             originalFieldSignatures,
             originalMethodSignatures,
-            previousLense,
+            previousLens,
             dexItemFactory,
             ImmutableMap.copyOf(prototypeChanges),
             ImmutableSet.copyOf(unboxedEnums));
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index d88f9d2..5542908 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -913,7 +913,7 @@
     Wrapper<DexMethod> throwParamIsNullException =
         wrapper.wrap(appView.dexItemFactory().kotlin.intrinsics.throwParameterIsNullException);
     DexMethod invokedMethod =
-        appView.graphLense().getOriginalMethodSignature(instr.asInvokeStatic().getInvokedMethod());
+        appView.graphLens().getOriginalMethodSignature(instr.asInvokeStatic().getInvokedMethod());
     Wrapper<DexMethod> methodWrap = wrapper.wrap(invokedMethod);
     if (methodWrap.equals(throwParamIsNullException)
         || (methodWrap.equals(checkParameterIsNotNull) && instr.inValues().get(0).equals(value))) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
index 3237c20..41ee658 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -69,7 +69,7 @@
     this.abstractValue = abstractValue;
   }
 
-  public void fixupAbstractValue(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+  public void fixupAbstractValue(AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     abstractValue = abstractValue.rewrittenWithLens(appView, lens);
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
index 3971c57..610bad0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -164,13 +164,13 @@
   }
 
   public UpdatableMethodOptimizationInfo fixupAbstractReturnValue(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     abstractReturnValue = abstractReturnValue.rewrittenWithLens(appView, lens);
     return this;
   }
 
   public UpdatableMethodOptimizationInfo fixupInstanceInitializerInfo(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     if (instanceInitializerInfo != null) {
       instanceInitializerInfo = instanceInitializerInfo.rewrittenWithLens(appView, lens);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
index fd7a84f..4e45bac 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.function.BiConsumer;
 
@@ -46,7 +46,7 @@
 
   @Override
   public InstanceFieldInitializationInfoCollection rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
index 757eec8..0b87005 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.optimize.info.field;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 /**
@@ -37,7 +37,7 @@
 
   @Override
   public InstanceFieldInitializationInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     // We don't have the context here to determine what should happen. It is the responsibility of
     // optimizations that change the proto of instance initializers to update the argument
     // initialization info.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
index 37757f1..aa3ab9b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.optimize.info.field;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.value.SingleValue;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
@@ -47,5 +47,5 @@
   }
 
   InstanceFieldInitializationInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
index 3ff1799..d26de6d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.IdentityHashMap;
 import java.util.Map;
@@ -36,7 +36,7 @@
   public abstract boolean isEmpty();
 
   public abstract InstanceFieldInitializationInfoCollection rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 
   public static class Builder {
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
index 3bfce16..fe09706 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.EnumValueInfoMapCollection;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -48,7 +48,7 @@
 
   @Override
   public InstanceFieldInitializationInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     EnumValueInfoMapCollection unboxedEnums = appView.unboxedEnums();
     if (dynamicLowerBoundType != null
         && unboxedEnums.containsEnum(dynamicLowerBoundType.getClassType())) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
index fe70918..e8daa83 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.Map;
 import java.util.function.BiConsumer;
@@ -56,7 +56,7 @@
 
   @Override
   public InstanceFieldInitializationInfoCollection rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     Builder builder = InstanceFieldInitializationInfoCollection.builder();
     infos.forEach(
         (field, info) -> {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
index b2b6ce9..ab4bbfe 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.ir.optimize.info.field;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
 /**
@@ -30,7 +30,7 @@
 
   @Override
   public InstanceFieldInitializationInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
index 4065fb0..e4424ec 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
 import com.android.tools.r8.ir.optimize.info.field.EmptyInstanceFieldInitializationInfoCollection;
@@ -56,7 +56,7 @@
 
   @Override
   public InstanceInitializerInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
index 1745e7d..1e36f40 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
 import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -57,5 +57,5 @@
   }
 
   public abstract InstanceInitializerInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens);
+      AppView<AppInfoWithLiveness> appView, GraphLens lens);
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
index f549927..84ce93f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.ConcreteMutableFieldSet;
 import com.android.tools.r8.ir.analysis.fieldvalueanalysis.EmptyFieldSet;
@@ -84,7 +84,7 @@
 
   @Override
   public NonTrivialInstanceInitializerInfo rewrittenWithLens(
-      AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
     return new NonTrivialInstanceInitializerInfo(
         data,
         fieldInitializationInfos.rewrittenWithLens(appView, lens),
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
index 6e0805e..4cba255 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -372,11 +372,11 @@
       // Eventually, we need to process synthesized methods in the lambda group.
       // Otherwise, abstract SynthesizedCode will be flown to Enqueuer.
       // But that process should not see the holder. Otherwise, lambda calls in the main dispatch
-      // method became recursive calls via the lense rewriter. They should remain, then inliner
+      // method became recursive calls via the lens rewriter. They should remain, then inliner
       // will inline methods from mergee lambdas to the main dispatch method.
       // Then, there is a dilemma: other sub optimizations trigger subtype lookup that will throw
       // NPE if it cannot find the holder for this synthesized lambda group.
-      // One hack here is to mark those methods `processed` so that the lense rewriter is skipped.
+      // One hack here is to mark those methods `processed` so that the lens rewriter is skipped.
       synthesizedClass.forEachMethod(
           encodedMethod -> encodedMethod.markProcessed(ConstraintWithTarget.NEVER));
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
similarity index 86%
rename from src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
rename to src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
index 318aae5..6eeeb46 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLens.java
@@ -7,14 +7,14 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.ImmutableMap;
 
-class ClassStaticizerGraphLense extends NestedGraphLense {
+class ClassStaticizerGraphLens extends NestedGraphLens {
 
-  ClassStaticizerGraphLense(
+  ClassStaticizerGraphLens(
       AppView<?> appView,
       BiMap<DexField, DexField> fieldMapping,
       BiMap<DexMethod, DexMethod> methodMapping) {
@@ -24,7 +24,7 @@
         fieldMapping,
         fieldMapping.inverse(),
         methodMapping.inverse(),
-        appView.graphLense(),
+        appView.graphLens(),
         appView.dexItemFactory());
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index 8dbb64a..6ad81c8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -773,7 +773,7 @@
     }
 
     if (!methodMapping.isEmpty() || !fieldMapping.isEmpty()) {
-      appView.setGraphLense(new ClassStaticizerGraphLense(appView, fieldMapping, methodMapping));
+      appView.setGraphLens(new ClassStaticizerGraphLens(appView, fieldMapping, methodMapping));
     }
     return staticizedMethods;
   }
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 01c3daa..7e98858 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -32,7 +32,7 @@
 import com.android.tools.r8.graph.DexValue.DexValueEnum;
 import com.android.tools.r8.graph.DexValue.DexValueInt;
 import com.android.tools.r8.graph.DexValue.DexValueString;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.NestMemberClassAttribute;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -70,7 +70,7 @@
 
   private final DexApplication application;
   private final AppView<?> appView;
-  private final GraphLense graphLense;
+  private final GraphLens graphLens;
   private final NamingLens namingLens;
   private final InternalOptions options;
   private final Marker marker;
@@ -82,12 +82,12 @@
       AppView<?> appView,
       InternalOptions options,
       Marker marker,
-      GraphLense graphLense,
+      GraphLens graphLens,
       NamingLens namingLens,
       ProguardMapSupplier proguardMapSupplier) {
     this.application = application;
     this.appView = appView;
-    this.graphLense = graphLense;
+    this.graphLens = graphLens;
     this.namingLens = namingLens;
     this.options = options;
     assert marker != null;
@@ -143,7 +143,7 @@
       }
     }
     ApplicationWriter.supplyAdditionalConsumers(
-        application, appView, graphLense, namingLens, options);
+        application, appView, graphLens, namingLens, options);
   }
 
   private void writeClass(
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
index 2171a00..281950c 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -188,8 +188,8 @@
     return v.asDexValueString().getValue().toString();
   }
 
-  private static class MetadataError extends RuntimeException {
-    MetadataError(String cause) {
+  public static class MetadataError extends RuntimeException {
+    private MetadataError(String cause) {
       super(cause);
     }
   }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index d709ea4..5e11d43 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -9,8 +9,10 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedAnnotation;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.graph.DexValue.DexValueInt;
@@ -25,6 +27,36 @@
 
 public class KotlinMetadataRewriter {
 
+  private static final class WriteMetadataFieldInfo {
+    final boolean writeKind;
+    final boolean writeMetadataVersion;
+    final boolean writeByteCodeVersion;
+    final boolean writeData1;
+    final boolean writeData2;
+    final boolean writeExtraString;
+    final boolean writePackageName;
+    final boolean writeExtraInt;
+
+    public WriteMetadataFieldInfo(
+        boolean writeKind,
+        boolean writeMetadataVersion,
+        boolean writeByteCodeVersion,
+        boolean writeData1,
+        boolean writeData2,
+        boolean writeExtraString,
+        boolean writePackageName,
+        boolean writeExtraInt) {
+      this.writeKind = writeKind;
+      this.writeMetadataVersion = writeMetadataVersion;
+      this.writeByteCodeVersion = writeByteCodeVersion;
+      this.writeData1 = writeData1;
+      this.writeData2 = writeData2;
+      this.writeExtraString = writeExtraString;
+      this.writePackageName = writePackageName;
+      this.writeExtraInt = writeExtraInt;
+    }
+  }
+
   private final AppView<?> appView;
   private final NamingLens lens;
   private final DexItemFactory factory;
@@ -42,6 +74,18 @@
   }
 
   public void run(ExecutorService executorService) throws ExecutionException {
+    final DexClass kotlinMetadata =
+        appView.definitionFor(appView.dexItemFactory().kotlinMetadataType);
+    final WriteMetadataFieldInfo writeMetadataFieldInfo =
+        new WriteMetadataFieldInfo(
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.kind),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.metadataVersion),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.bytecodeVersion),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data1),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.data2),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.extraString),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.packageName),
+            kotlinMetadataFieldExists(kotlinMetadata, appView, kotlin.metadata.extraInt));
     ThreadUtils.processItems(
         appView.appInfo().classes(),
         clazz -> {
@@ -66,7 +110,8 @@
           try {
             KotlinClassHeader kotlinClassHeader = kotlinInfo.rewrite(clazz, appView, lens);
             DexAnnotation newMeta =
-                createKotlinMetadataAnnotation(kotlinClassHeader, kotlinInfo.getPackageName());
+                createKotlinMetadataAnnotation(
+                    kotlinClassHeader, kotlinInfo.getPackageName(), writeMetadataFieldInfo);
             clazz.setAnnotations(
                 clazz.annotations().rewrite(anno -> anno == oldMeta ? newMeta : anno));
           } catch (Throwable t) {
@@ -79,33 +124,54 @@
         executorService);
   }
 
+  private boolean kotlinMetadataFieldExists(
+      DexClass kotlinMetadata, AppView<?> appView, DexString fieldName) {
+    if (!appView.appInfo().hasLiveness()) {
+      return true;
+    }
+    if (kotlinMetadata == null || kotlinMetadata.isNotProgramClass()) {
+      return true;
+    }
+    return kotlinMetadata.methods(method -> method.method.name == fieldName).iterator().hasNext();
+  }
+
   private DexAnnotation createKotlinMetadataAnnotation(
-      KotlinClassHeader header, String packageName) {
+      KotlinClassHeader header, String packageName, WriteMetadataFieldInfo writeMetadataFieldInfo) {
     List<DexAnnotationElement> elements = new ArrayList<>();
-    elements.add(
-        new DexAnnotationElement(
-            kotlin.metadata.metadataVersion, createIntArray(header.getMetadataVersion())));
-    elements.add(
-        new DexAnnotationElement(
-            kotlin.metadata.bytecodeVersion, createIntArray(header.getBytecodeVersion())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.kind, DexValueInt.create(header.getKind())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.data1, createStringArray(header.getData1())));
-    elements.add(
-        new DexAnnotationElement(kotlin.metadata.data2, createStringArray(header.getData2())));
-    if (packageName != null && !packageName.isEmpty()) {
+    if (writeMetadataFieldInfo.writeMetadataVersion) {
+      elements.add(
+          new DexAnnotationElement(
+              kotlin.metadata.metadataVersion, createIntArray(header.getMetadataVersion())));
+    }
+    if (writeMetadataFieldInfo.writeByteCodeVersion) {
+      elements.add(
+          new DexAnnotationElement(
+              kotlin.metadata.bytecodeVersion, createIntArray(header.getBytecodeVersion())));
+    }
+    if (writeMetadataFieldInfo.writeKind) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.kind, DexValueInt.create(header.getKind())));
+    }
+    if (writeMetadataFieldInfo.writeData1) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.data1, createStringArray(header.getData1())));
+    }
+    if (writeMetadataFieldInfo.writeData2) {
+      elements.add(
+          new DexAnnotationElement(kotlin.metadata.data2, createStringArray(header.getData2())));
+    }
+    if (writeMetadataFieldInfo.writePackageName && packageName != null && !packageName.isEmpty()) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.packageName, new DexValueString(factory.createString(packageName))));
     }
-    if (!header.getExtraString().isEmpty()) {
+    if (writeMetadataFieldInfo.writeExtraString && !header.getExtraString().isEmpty()) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.extraString,
               new DexValueString(factory.createString(header.getExtraString()))));
     }
-    if (header.getExtraInt() != 0) {
+    if (writeMetadataFieldInfo.writeExtraInt && header.getExtraInt() != 0) {
       elements.add(
           new DexAnnotationElement(
               kotlin.metadata.extraInt, DexValueInt.create(header.getExtraInt())));
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
index 1a51644..ca1d394 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
@@ -131,7 +131,7 @@
 
   private static String kotlinSyntheticClassToString(
       KotlinClassMetadata.SyntheticClass kMetadata, String indent) {
-    StringBuilder sb = new StringBuilder();
+    StringBuilder sb = new StringBuilder(indent);
     KotlinMetadataWriter.appendKmSection(
         indent,
         "Metadata.SyntheticClass",
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index 9b659a0..998fad3 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -255,7 +255,7 @@
         InnerClassAttribute attribute = clazz.getInnerClassAttributeForThisClass();
         assert attribute != null;
         // Note that, to be consistent with the way inner-class attribute is written via minifier
-        // lense, we are using attribute's outer-class, not the live context.
+        // lens, we are using attribute's outer-class, not the live context.
         String separator =
             computeInnerClassSeparator(attribute.getOuter(), type, attribute.getInnerName());
         if (separator == null) {
diff --git a/src/main/java/com/android/tools/r8/naming/NamingLens.java b/src/main/java/com/android/tools/r8/naming/NamingLens.java
index a142cbf..7aab96a 100644
--- a/src/main/java/com/android/tools/r8/naming/NamingLens.java
+++ b/src/main/java/com/android/tools/r8/naming/NamingLens.java
@@ -130,7 +130,7 @@
       Class<T> clazz, Predicate<T> predicate, Function<T, String> namer);
 
   /**
-   * Checks whether the target will be translated properly by this lense.
+   * Checks whether the target will be translated properly by this lens.
    *
    * <p>Normally, this means that the target corresponds to an actual definition that has been
    * renamed. For identity renamings, we are more relaxed, as no targets will be translated anyway.
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index 1f66108..92b4402 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -200,7 +200,7 @@
       }
       String originalDescriptor = getDescriptorFromClassBinaryName(name);
       DexType type =
-          appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
+          appView.graphLens().lookupType(appView.dexItemFactory().createType(originalDescriptor));
       if (appView.appInfo().hasLiveness() && appView.withLiveness().appInfo().wasPruned(type)) {
         type = appView.dexItemFactory().objectType;
       }
@@ -251,7 +251,7 @@
                       getClassBinaryNameFromDescriptor(enclosingDescriptor)
                           + DescriptorUtils.INNER_CLASS_SEPARATOR
                           + name));
-      type = appView.graphLense().lookupType(type);
+      type = appView.graphLens().lookupType(type);
       String renamedDescriptor = namingLens.lookupDescriptor(type).toString();
       if (!renamedDescriptor.equals(type.toDescriptorString())) {
         // TODO(b/147504070): If this is a merged class equal to the class context, do not add.
diff --git a/src/main/java/com/android/tools/r8/optimize/BridgeHoisting.java b/src/main/java/com/android/tools/r8/optimize/BridgeHoisting.java
index 1cfe21f..6e0168f 100644
--- a/src/main/java/com/android/tools/r8/optimize/BridgeHoisting.java
+++ b/src/main/java/com/android/tools/r8/optimize/BridgeHoisting.java
@@ -20,7 +20,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.ResolutionResult;
 import com.android.tools.r8.graph.SubtypingInfo;
@@ -87,7 +87,7 @@
         .visit(appView.appInfo().classes(), clazz -> processClass(clazz, subtypingInfo));
     if (!lensBuilder.isEmpty()) {
       BridgeHoistingLens lens = lensBuilder.build(appView);
-      boolean changed = appView.setGraphLense(lens);
+      boolean changed = appView.setGraphLens(lens);
       assert changed;
       appView.setAppInfo(
           appView.appInfo().rewrittenWithLens(appView.appInfo().app().asDirect(), lens));
@@ -367,7 +367,7 @@
         : code;
   }
 
-  static class BridgeHoistingLens extends NestedGraphLense {
+  static class BridgeHoistingLens extends NestedGraphLens {
 
     public BridgeHoistingLens(
         AppView<?> appView, BiMap<DexMethod, DexMethod> originalMethodSignatures) {
@@ -377,7 +377,7 @@
           ImmutableMap.of(),
           null,
           originalMethodSignatures,
-          appView.graphLense(),
+          appView.graphLens(),
           appView.dexItemFactory());
     }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java b/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
index db4613f..4edec01 100644
--- a/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
@@ -14,12 +14,12 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.SubtypingInfo;
 import com.android.tools.r8.ir.optimize.MethodPoolCollection;
-import com.android.tools.r8.optimize.PublicizerLense.PublicizedLenseBuilder;
+import com.android.tools.r8.optimize.PublicizerLens.PublicizedLensBuilder;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.OptionalBool;
 import com.android.tools.r8.utils.Timing;
@@ -35,7 +35,7 @@
   private final SubtypingInfo subtypingInfo;
   private final MethodPoolCollection methodPoolCollection;
 
-  private final PublicizedLenseBuilder lenseBuilder = PublicizerLense.createBuilder();
+  private final PublicizedLensBuilder lensBuilder = PublicizerLens.createBuilder();
 
   private ClassAndMemberPublicizer(
       DexApplication application,
@@ -56,7 +56,7 @@
    *
    * <p>This will destructively update the DexApplication passed in as argument.
    */
-  public static GraphLense run(
+  public static GraphLens run(
       ExecutorService executorService,
       Timing timing,
       DexApplication application,
@@ -67,8 +67,7 @@
         .run(executorService, timing);
   }
 
-  private GraphLense run(ExecutorService executorService, Timing timing)
-      throws ExecutionException {
+  private GraphLens run(ExecutorService executorService, Timing timing) throws ExecutionException {
     // Phase 1: Collect methods to check if private instance methods don't have conflicts.
     methodPoolCollection.buildAll(executorService, timing);
 
@@ -80,7 +79,7 @@
     publicizeType(appView.dexItemFactory().objectType);
     timing.end();
 
-    return lenseBuilder.build(appView);
+    return lensBuilder.build(appView);
   }
 
   private void publicizeType(DexType type) {
@@ -171,7 +170,7 @@
         // TODO(b/111118390): Renaming will enable more private instance methods to be publicized.
         return false;
       }
-      lenseBuilder.add(method.method);
+      lensBuilder.add(method.method);
       accessFlags.promoteToFinal();
       accessFlags.promoteToPublic();
       // The method just became public and is therefore not a library override.
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 1c1de57..dcd003c6 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -15,7 +15,7 @@
 import com.android.tools.r8.graph.FieldAccessInfo;
 import com.android.tools.r8.graph.FieldAccessInfoCollection;
 import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -29,17 +29,17 @@
 public class MemberRebindingAnalysis {
 
   private final AppView<AppInfoWithLiveness> appView;
-  private final GraphLense lense;
+  private final GraphLens lens;
   private final InternalOptions options;
 
-  private final MemberRebindingLense.Builder builder;
+  private final MemberRebindingLens.Builder builder;
 
   public MemberRebindingAnalysis(AppView<AppInfoWithLiveness> appView) {
-    assert appView.graphLense().isContextFreeForMethods();
+    assert appView.graphLens().isContextFreeForMethods();
     this.appView = appView;
-    this.lense = appView.graphLense();
+    this.lens = appView.graphLens();
     this.options = appView.options();
-    this.builder = MemberRebindingLense.builder(appView);
+    this.builder = MemberRebindingLens.builder(appView);
   }
 
   private DexMethod validTargetFor(DexMethod target, DexMethod original) {
@@ -168,7 +168,7 @@
                     method, target, originalClass, targetClass, lookupTarget);
           }
         }
-        builder.map(method, lense.lookupMethod(validTargetFor(target.method, method)), invokeType);
+        builder.map(method, lens.lookupMethod(validTargetFor(target.method, method)), invokeType);
       }
     }
   }
@@ -331,11 +331,11 @@
     if (accessibleInAllContexts) {
       builder.map(
           field,
-          lense.lookupField(validTargetFor(resolvedField.field, field, DexClass::lookupField)));
+          lens.lookupField(validTargetFor(resolvedField.field, field, DexClass::lookupField)));
     }
   }
 
-  public GraphLense run() {
+  public GraphLens run() {
     AppInfoWithLiveness appInfo = appView.appInfo();
     // Virtual invokes are on classes, so use class resolution.
     computeMethodRebinding(appInfo.virtualInvokes, this::classLookup, Type.VIRTUAL);
@@ -348,7 +348,7 @@
     // Likewise static invokes.
     computeMethodRebinding(appInfo.staticInvokes, this::anyLookup, Type.STATIC);
     computeFieldRebinding();
-    GraphLense lens = builder.build(lense);
+    GraphLens lens = builder.build(this.lens);
     appInfo.getFieldAccessInfoCollection().flattenAccessContexts();
     return lens;
   }
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingLens.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java
rename to src/main/java/com/android/tools/r8/optimize/MemberRebindingLens.java
index 01c923d..8883f5b 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingLense.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingLens.java
@@ -7,8 +7,8 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.ir.code.Invoke;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.google.common.collect.ImmutableMap;
@@ -16,7 +16,7 @@
 import java.util.IdentityHashMap;
 import java.util.Map;
 
-public class MemberRebindingLense extends NestedGraphLense {
+public class MemberRebindingLens extends NestedGraphLens {
 
   public static class Builder {
 
@@ -48,29 +48,29 @@
       methodMap.put(from, to);
     }
 
-    public GraphLense build(GraphLense previousLense) {
+    public GraphLens build(GraphLens previousLens) {
       if (fieldMap.isEmpty() && methodMaps.isEmpty()) {
-        return previousLense;
+        return previousLens;
       }
-      return new MemberRebindingLense(appView, methodMaps, fieldMap, previousLense);
+      return new MemberRebindingLens(appView, methodMaps, fieldMap, previousLens);
     }
   }
 
   private final AppView<?> appView;
   private final Map<Invoke.Type, Map<DexMethod, DexMethod>> methodMaps;
 
-  public MemberRebindingLense(
+  public MemberRebindingLens(
       AppView<?> appView,
       Map<Invoke.Type, Map<DexMethod, DexMethod>> methodMaps,
       Map<DexField, DexField> fieldMap,
-      GraphLense previousLense) {
+      GraphLens previousLens) {
     super(
         ImmutableMap.of(),
         ImmutableMap.of(),
         fieldMap,
         null,
         null,
-        previousLense,
+        previousLens,
         appView.dexItemFactory());
     this.appView = appView;
     this.methodMaps = methodMaps;
@@ -86,12 +86,12 @@
   }
 
   @Override
-  public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
-    GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
+  public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+    GraphLensLookupResult previous = previousLens.lookupMethod(method, context, type);
     Map<DexMethod, DexMethod> methodMap = methodMaps.getOrDefault(type, Collections.emptyMap());
     DexMethod newMethod = methodMap.get(previous.getMethod());
     if (newMethod != null) {
-      return new GraphLenseLookupResult(
+      return new GraphLensLookupResult(
           newMethod, mapInvocationType(newMethod, method, previous.getType()));
     }
     return previous;
diff --git a/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
similarity index 67%
rename from src/main/java/com/android/tools/r8/optimize/PublicizerLense.java
rename to src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
index ab8999a..a2c44ce 100644
--- a/src/main/java/com/android/tools/r8/optimize/PublicizerLense.java
+++ b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
@@ -7,26 +7,26 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 import java.util.Set;
 
-final class PublicizerLense extends NestedGraphLense {
+final class PublicizerLens extends NestedGraphLens {
 
   private final AppView appView;
   private final Set<DexMethod> publicizedMethods;
 
-  private PublicizerLense(AppView appView, Set<DexMethod> publicizedMethods) {
+  private PublicizerLens(AppView appView, Set<DexMethod> publicizedMethods) {
     super(
         ImmutableMap.of(),
         ImmutableMap.of(),
         ImmutableMap.of(),
         null,
         null,
-        appView.graphLense(),
+        appView.graphLens(),
         appView.dexItemFactory());
     this.appView = appView;
     this.publicizedMethods = publicizedMethods;
@@ -34,26 +34,25 @@
 
   @Override
   protected boolean isLegitimateToHaveEmptyMappings() {
-    // This lense does not map any DexItem's at all.
+    // This lens does not map any DexItem's at all.
     // It will just tweak invoke type for publicized methods from invoke-direct to invoke-virtual.
     return true;
   }
 
   @Override
-  public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
-    GraphLenseLookupResult previous = previousLense.lookupMethod(method, context, type);
+  public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+    GraphLensLookupResult previous = previousLens.lookupMethod(method, context, type);
     method = previous.getMethod();
     type = previous.getType();
     if (type == Type.DIRECT && publicizedMethods.contains(method)) {
       assert publicizedMethodIsPresentOnHolder(method, context);
-      return new GraphLenseLookupResult(method, Type.VIRTUAL);
+      return new GraphLensLookupResult(method, Type.VIRTUAL);
     }
     return super.lookupMethod(method, context, type);
   }
 
   private boolean publicizedMethodIsPresentOnHolder(DexMethod method, DexMethod context) {
-    GraphLenseLookupResult lookup =
-        appView.graphLense().lookupMethod(method, context, Type.VIRTUAL);
+    GraphLensLookupResult lookup = appView.graphLens().lookupMethod(method, context, Type.VIRTUAL);
     DexMethod signatureInCurrentWorld = lookup.getMethod();
     DexClass clazz = appView.definitionFor(signatureInCurrentWorld.holder);
     assert clazz != null;
@@ -63,21 +62,20 @@
     return true;
   }
 
-  static PublicizedLenseBuilder createBuilder() {
-    return new PublicizedLenseBuilder();
+  static PublicizedLensBuilder createBuilder() {
+    return new PublicizedLensBuilder();
   }
 
-  static class PublicizedLenseBuilder {
+  static class PublicizedLensBuilder {
     private final Set<DexMethod> publicizedMethods = Sets.newIdentityHashSet();
 
-    private PublicizedLenseBuilder() {
-    }
+    private PublicizedLensBuilder() {}
 
-    public GraphLense build(AppView appView) {
+    public GraphLens build(AppView appView) {
       if (publicizedMethods.isEmpty()) {
-        return appView.graphLense();
+        return appView.graphLens();
       }
-      return new PublicizerLense(appView, publicizedMethods);
+      return new PublicizerLens(appView, publicizedMethods);
     }
 
     public void add(DexMethod publicizedMethod) {
diff --git a/src/main/java/com/android/tools/r8/relocator/Relocator.java b/src/main/java/com/android/tools/r8/relocator/Relocator.java
index 176e058..a33424b 100644
--- a/src/main/java/com/android/tools/r8/relocator/Relocator.java
+++ b/src/main/java/com/android/tools/r8/relocator/Relocator.java
@@ -15,7 +15,7 @@
 import com.android.tools.r8.graph.AppServices;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.jar.CfApplicationWriter;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
@@ -94,7 +94,7 @@
               appView,
               options,
               new Marker(Tool.Relocator),
-              GraphLense.getIdentityLense(),
+              GraphLens.getIdentityLens(),
               namingLens,
               null)
           .write(command.getConsumer());
diff --git a/src/main/java/com/android/tools/r8/retrace/Retrace.java b/src/main/java/com/android/tools/r8/retrace/Retrace.java
index 0cb273e..0689227 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -141,13 +141,13 @@
           ClassNameMapper.mapperFromString(
               command.proguardMapProducer.get(), command.diagnosticsHandler);
       timing.end();
-      RetraceBase retraceBase = RetraceBaseImpl.create(classNameMapper);
+      RetraceApi retracer = Retracer.create(classNameMapper);
       RetraceCommandLineResult result;
       timing.begin("Parse and Retrace");
       if (command.regularExpression != null) {
         result =
             new RetraceRegularExpression(
-                    retraceBase,
+                    retracer,
                     command.stackTrace,
                     command.diagnosticsHandler,
                     command.regularExpression)
@@ -155,7 +155,7 @@
       } else {
         result =
             new RetraceStackTrace(
-                    retraceBase, command.stackTrace, command.diagnosticsHandler, command.isVerbose)
+                    retracer, command.stackTrace, command.diagnosticsHandler, command.isVerbose)
                 .retrace();
       }
       timing.end();
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceBase.java b/src/main/java/com/android/tools/r8/retrace/RetraceApi.java
similarity index 84%
rename from src/main/java/com/android/tools/r8/retrace/RetraceBase.java
rename to src/main/java/com/android/tools/r8/retrace/RetraceApi.java
index ee7d7ab..7bb9232 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceBase.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceApi.java
@@ -4,12 +4,15 @@
 
 package com.android.tools.r8.retrace;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.TypeReference;
 
-public interface RetraceBase {
+/** This is the main api interface for retrace. */
+@Keep
+public interface RetraceApi {
 
   RetraceMethodResult retrace(MethodReference methodReference);
 
@@ -18,6 +21,4 @@
   RetraceClassResult retrace(ClassReference classReference);
 
   RetraceTypeResult retrace(TypeReference typeReference);
-
-  RetraceSourceFileResult retraceSourceFile(ClassReference classReference, String sourceFile);
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java b/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
index e2e78b2..b35bb12 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
@@ -27,7 +27,7 @@
 
 public class RetraceRegularExpression {
 
-  private final RetraceBase retraceBase;
+  private final RetraceApi retracer;
   private final List<String> stackTrace;
   private final DiagnosticsHandler diagnosticsHandler;
   private final String regularExpression;
@@ -52,11 +52,11 @@
   private static final String CAPTURE_GROUP_PREFIX = "captureGroup";
 
   RetraceRegularExpression(
-      RetraceBase retraceBase,
+      RetraceApi retracer,
       List<String> stackTrace,
       DiagnosticsHandler diagnosticsHandler,
       String regularExpression) {
-    this.retraceBase = retraceBase;
+    this.retracer = retracer;
     this.stackTrace = stackTrace;
     this.diagnosticsHandler = diagnosticsHandler;
     this.regularExpression = regularExpression;
@@ -73,7 +73,7 @@
           Lists.newArrayList(RetraceStringBuilder.create(string).build());
       if (matcher.matches()) {
         for (RegularExpressionGroupHandler handler : handlers) {
-          retracedStrings = handler.handleMatch(retracedStrings, matcher, retraceBase);
+          retracedStrings = handler.handleMatch(retracedStrings, matcher, retracer);
         }
       }
       if (retracedStrings.isEmpty()) {
@@ -422,7 +422,7 @@
   private interface RegularExpressionGroupHandler {
 
     List<RetraceString> handleMatch(
-        List<RetraceString> strings, Matcher matcher, RetraceBase retraceBase);
+        List<RetraceString> strings, Matcher matcher, RetraceApi retracer);
   }
 
   private abstract static class RegularExpressionGroup {
@@ -450,12 +450,12 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
         String typeName = matcher.group(captureGroup);
-        RetraceClassResult retraceResult = retraceBase.retrace(classFromMatch(typeName));
+        RetraceClassResult retraceResult = retracer.retrace(classFromMatch(typeName));
         List<RetraceString> retracedStrings = new ArrayList<>();
         for (RetraceString retraceString : strings) {
           retraceResult.forEach(
@@ -537,7 +537,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -606,7 +606,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -660,7 +660,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -707,7 +707,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -808,7 +808,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -819,7 +819,7 @@
         }
         TypeReference typeReference = Reference.returnTypeFromDescriptor(descriptor);
         List<RetraceString> retracedStrings = new ArrayList<>();
-        RetraceTypeResult retracedType = retraceBase.retrace(typeReference);
+        RetraceTypeResult retracedType = retracer.retrace(typeReference);
         for (RetraceString retraceString : strings) {
           retracedType.forEach(
               element -> {
@@ -854,7 +854,7 @@
 
     @Override
     RegularExpressionGroupHandler createHandler(String captureGroup) {
-      return (strings, matcher, retraceBase) -> {
+      return (strings, matcher, retracer) -> {
         if (matcher.start(captureGroup) == NO_MATCH) {
           return strings;
         }
@@ -872,7 +872,7 @@
                       }
                       TypeReference typeReference = Reference.returnTypeFromDescriptor(descriptor);
                       Set<List<TypeReference>> retracedTypes = new LinkedHashSet<>();
-                      retraceBase
+                      retracer
                           .retrace(typeReference)
                           .forEach(
                               element -> {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceStackTrace.java b/src/main/java/com/android/tools/r8/retrace/RetraceStackTrace.java
index 719dd44..88d048f 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceStackTrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceStackTrace.java
@@ -86,17 +86,17 @@
     }
   }
 
-  private final RetraceBase retraceBase;
+  private final RetraceApi retracer;
   private final List<String> stackTrace;
   private final DiagnosticsHandler diagnosticsHandler;
   private final boolean verbose;
 
   RetraceStackTrace(
-      RetraceBase retraceBase,
+      RetraceApi retracer,
       List<String> stackTrace,
       DiagnosticsHandler diagnosticsHandler,
       boolean verbose) {
-    this.retraceBase = retraceBase;
+    this.retracer = retracer;
     this.stackTrace = stackTrace;
     this.diagnosticsHandler = diagnosticsHandler;
     this.verbose = verbose;
@@ -117,7 +117,7 @@
       return;
     }
     StackTraceLine stackTraceLine = parseLine(index + 1, stackTrace.get(index));
-    List<StackTraceLine> retraced = stackTraceLine.retrace(retraceBase, verbose);
+    List<StackTraceLine> retraced = stackTraceLine.retrace(retracer, verbose);
     StackTraceNode node = new StackTraceNode(retraced);
     result.add(node);
     retraceLine(stackTrace, index + 1, result);
@@ -125,7 +125,7 @@
 
   abstract static class StackTraceLine {
 
-    abstract List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose);
+    abstract List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose);
 
     static int firstNonWhiteSpaceCharacterFromIndex(String line, int index) {
       return firstFromIndex(line, index, not(Character::isWhitespace));
@@ -225,9 +225,9 @@
     }
 
     @Override
-    List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose) {
+    List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose) {
       List<StackTraceLine> exceptionLines = new ArrayList<>();
-      retraceBase
+      retracer
           .retrace(Reference.classFromTypeName(exceptionClass))
           .forEach(
               element ->
@@ -397,31 +397,28 @@
     }
 
     @Override
-    List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose) {
+    List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose) {
       List<StackTraceLine> lines = new ArrayList<>();
       String retraceClassLoaderName = classLoaderName;
       if (retraceClassLoaderName != null) {
         ClassReference classLoaderReference = Reference.classFromTypeName(retraceClassLoaderName);
-        retraceBase
+        retracer
             .retrace(classLoaderReference)
             .forEach(
                 classElement -> {
                   retraceClassAndMethods(
-                      retraceBase, verbose, lines, classElement.getClassReference().getTypeName());
+                      retracer, verbose, lines, classElement.getClassReference().getTypeName());
                 });
       } else {
-        retraceClassAndMethods(retraceBase, verbose, lines, retraceClassLoaderName);
+        retraceClassAndMethods(retracer, verbose, lines, retraceClassLoaderName);
       }
       return lines;
     }
 
     private void retraceClassAndMethods(
-        RetraceBase retraceBase,
-        boolean verbose,
-        List<StackTraceLine> lines,
-        String classLoaderName) {
+        RetraceApi retracer, boolean verbose, List<StackTraceLine> lines, String classLoaderName) {
       ClassReference classReference = Reference.classFromTypeName(clazz);
-      RetraceClassResult classResult = retraceBase.retrace(classReference);
+      RetraceClassResult classResult = retracer.retrace(classReference);
       RetraceMethodResult retraceResult = classResult.lookupMethod(method);
       if (linePosition != NO_POSITION && linePosition != INVALID_POSITION) {
         retraceResult = retraceResult.narrowByLine(linePosition);
@@ -509,7 +506,7 @@
     }
 
     @Override
-    List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose) {
+    List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose) {
       return ImmutableList.of(new MoreLine(line));
     }
 
@@ -562,9 +559,9 @@
     }
 
     @Override
-    List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose) {
+    List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose) {
       List<StackTraceLine> exceptionLines = new ArrayList<>();
-      retraceBase
+      retracer
           .retrace(Reference.classFromTypeName(exceptionClass))
           .forEach(
               element ->
@@ -590,7 +587,7 @@
     }
 
     @Override
-    List<StackTraceLine> retrace(RetraceBase retraceBase, boolean verbose) {
+    List<StackTraceLine> retrace(RetraceApi retracer, boolean verbose) {
       return ImmutableList.of(new UnknownLine(line));
     }
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
index 2ab72a7..8ea169f 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceTypeResult.java
@@ -13,11 +13,11 @@
 public class RetraceTypeResult extends Result<Element, RetraceTypeResult> {
 
   private final TypeReference obfuscatedType;
-  private final RetraceBase retraceBase;
+  private final RetraceApi retracer;
 
-  RetraceTypeResult(TypeReference obfuscatedType, RetraceBase retraceBase) {
+  RetraceTypeResult(TypeReference obfuscatedType, RetraceApi retracer) {
     this.obfuscatedType = obfuscatedType;
-    this.retraceBase = retraceBase;
+    this.retracer = retracer;
   }
 
   @Override
@@ -28,10 +28,10 @@
     }
     if (obfuscatedType.isArray()) {
       int dimensions = obfuscatedType.asArray().getDimensions();
-      return retraceBase.retrace(obfuscatedType.asArray().getBaseType()).stream()
+      return retracer.retrace(obfuscatedType.asArray().getBaseType()).stream()
           .map(base -> new Element(Reference.array(base.getTypeReference(), dimensions)));
     }
-    return retraceBase.retrace(obfuscatedType.asClass()).stream()
+    return retracer.retrace(obfuscatedType.asClass()).stream()
         .map(clazz -> new Element(clazz.getClassReference()));
   }
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceBaseImpl.java b/src/main/java/com/android/tools/r8/retrace/Retracer.java
similarity index 68%
rename from src/main/java/com/android/tools/r8/retrace/RetraceBaseImpl.java
rename to src/main/java/com/android/tools/r8/retrace/Retracer.java
index 1561457..b2dad89 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceBaseImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retracer.java
@@ -4,23 +4,25 @@
 
 package com.android.tools.r8.retrace;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.TypeReference;
-import com.android.tools.r8.utils.Box;
 
-public class RetraceBaseImpl implements RetraceBase {
+/** A default implementation for the retrace api using the ClassNameMapper defined in R8. */
+@Keep
+public class Retracer implements RetraceApi {
 
   private final ClassNameMapper classNameMapper;
 
-  private RetraceBaseImpl(ClassNameMapper classNameMapper) {
+  private Retracer(ClassNameMapper classNameMapper) {
     this.classNameMapper = classNameMapper;
   }
 
-  public static RetraceBase create(ClassNameMapper classNameMapper) {
-    return new RetraceBaseImpl(classNameMapper);
+  public static RetraceApi create(ClassNameMapper classNameMapper) {
+    return new Retracer(classNameMapper);
   }
 
   @Override
@@ -40,15 +42,6 @@
   }
 
   @Override
-  public RetraceSourceFileResult retraceSourceFile(
-      ClassReference classReference, String sourceFile) {
-    Box<RetraceSourceFileResult> retracedSourceFile = new Box<>();
-    retrace(classReference)
-        .forEach(element -> retracedSourceFile.set(element.retraceSourceFile(sourceFile)));
-    return retracedSourceFile.get();
-  }
-
-  @Override
   public RetraceTypeResult retrace(TypeReference typeReference) {
     return new RetraceTypeResult(typeReference, this);
   }
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java b/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
index 0fe561c..a67af38 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
@@ -14,15 +14,15 @@
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.graph.DexValue.DexValueType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.utils.ArrayUtils;
 
 public class AnnotationFixer {
 
-  private final GraphLense lense;
+  private final GraphLens lens;
 
-  public AnnotationFixer(GraphLense lense) {
-    this.lense = lense;
+  public AnnotationFixer(GraphLens lens) {
+    this.lens = lens;
   }
 
   public void run(Iterable<DexProgramClass> classes) {
@@ -50,7 +50,7 @@
 
   private DexEncodedAnnotation rewriteEncodedAnnotation(DexEncodedAnnotation original) {
     DexEncodedAnnotation rewritten =
-        original.rewrite(lense::lookupType, this::rewriteAnnotationElement);
+        original.rewrite(lens::lookupType, this::rewriteAnnotationElement);
     assert rewritten != null;
     return rewritten;
   }
@@ -66,7 +66,7 @@
   private DexValue rewriteValue(DexValue value) {
     if (value.isDexValueType()) {
       DexType originalType = value.asDexValueType().value;
-      DexType rewrittenType = lense.lookupType(originalType);
+      DexType rewrittenType = lens.lookupType(originalType);
       if (rewrittenType != originalType) {
         return new DexValueType(rewrittenType);
       }
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index 3c0d9dd..1a8d708 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -16,7 +16,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
@@ -225,15 +225,15 @@
   }
 
   private DexEncodedAnnotation rewriteEncodedAnnotation(DexEncodedAnnotation original) {
-    GraphLense graphLense = appView.graphLense();
+    GraphLens graphLens = appView.graphLens();
     DexType annotationType = original.type.toBaseType(appView.dexItemFactory());
     if (removedClasses.contains(annotationType)) {
       return null;
     }
-    DexType rewrittenType = graphLense.lookupType(annotationType);
+    DexType rewrittenType = graphLens.lookupType(annotationType);
     DexEncodedAnnotation rewrite =
         original.rewrite(
-            graphLense::lookupType, element -> rewriteAnnotationElement(rewrittenType, element));
+            graphLens::lookupType, element -> rewriteAnnotationElement(rewrittenType, element));
     assert rewrite != null;
     DexClass annotationClass = appView.appInfo().definitionFor(rewrittenType);
     assert annotationClass == null
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index d3afad2..5f68d46 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -28,8 +28,8 @@
 import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
 import com.android.tools.r8.graph.FieldAccessInfoImpl;
 import com.android.tools.r8.graph.FieldResolutionResult;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.InstantiatedSubTypeInfo;
 import com.android.tools.r8.graph.LookupResult.LookupResultSuccess;
 import com.android.tools.r8.graph.LookupTarget;
@@ -889,7 +889,7 @@
   }
 
   private static SortedMap<DexMethod, ProgramMethodSet> rewriteInvokesWithContexts(
-      Map<DexMethod, ProgramMethodSet> invokes, GraphLense lens) {
+      Map<DexMethod, ProgramMethodSet> invokes, GraphLens lens) {
     SortedMap<DexMethod, ProgramMethodSet> result = new TreeMap<>(PresortedComparable::slowCompare);
     invokes.forEach(
         (method, contexts) ->
@@ -966,17 +966,17 @@
   }
 
   public AppInfoWithLiveness rewrittenWithLens(
-      DirectMappedDexApplication application, NestedGraphLense lens) {
+      DirectMappedDexApplication application, NestedGraphLens lens) {
     assert checkIfObsolete();
     // The application has already been rewritten with all of lens' parent lenses. Therefore, we
     // temporarily replace lens' parent lens with an identity lens to avoid the overhead of
     // traversing the entire lens chain upon each lookup during the rewriting.
     return lens.withAlternativeParentLens(
-        GraphLense.getIdentityLense(), () -> createRewrittenAppInfoWithLiveness(application, lens));
+        GraphLens.getIdentityLens(), () -> createRewrittenAppInfoWithLiveness(application, lens));
   }
 
   private AppInfoWithLiveness createRewrittenAppInfoWithLiveness(
-      DirectMappedDexApplication application, NestedGraphLense lens) {
+      DirectMappedDexApplication application, NestedGraphLens lens) {
     // Switchmap classes should never be affected by renaming.
     assert lens.assertDefinitionsNotModified(
         switchMaps.keySet().stream()
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 5c0f735..281561b 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -57,7 +57,7 @@
 import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
 import com.android.tools.r8.graph.FieldAccessInfoImpl;
 import com.android.tools.r8.graph.FieldResolutionResult;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.LookupLambdaTarget;
 import com.android.tools.r8.graph.LookupTarget;
@@ -2007,6 +2007,12 @@
         clazz, context, instantiationReason, keepReason, appInfo);
   }
 
+  void markAnnotationAsInstantiated(DexProgramClass clazz, KeepReasonWitness witness) {
+    assert clazz.isAnnotation();
+    markTypeAsLive(clazz, witness);
+    transitionDependentItemsForInstantiatedInterface(clazz);
+  }
+
   void markInterfaceAsInstantiated(DexProgramClass clazz, KeepReasonWitness witness) {
     assert !clazz.isAnnotation();
     assert clazz.isInterface();
@@ -2373,6 +2379,10 @@
     return liveFields.contains(field);
   }
 
+  public boolean isFieldLive(DexEncodedField field) {
+    return liveFields.contains(field);
+  }
+
   public boolean isFieldRead(ProgramField field) {
     FieldAccessInfoImpl info = fieldAccessInfoCollection.get(field.getReference());
     return info != null && info.isRead();
@@ -2723,10 +2733,8 @@
     return appInfoWithLiveness;
   }
 
-  public GraphLense buildGraphLense(AppView<?> appView) {
-    return lambdaRewriter != null
-        ? lambdaRewriter.buildMappingLense(appView)
-        : appView.graphLense();
+  public GraphLens buildGraphLens(AppView<?> appView) {
+    return lambdaRewriter != null ? lambdaRewriter.buildMappingLens(appView) : appView.graphLens();
   }
 
   private void keepClassWithRules(DexProgramClass clazz, Set<ProguardKeepRuleBase> rules) {
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index 3c9649d..2bc8459 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -101,7 +101,7 @@
 
     @Override
     public void run(Enqueuer enqueuer) {
-      enqueuer.markTypeAsLive(target, reason);
+      enqueuer.markAnnotationAsInstantiated(target, reason);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
index d8fbb6d..8841f15 100644
--- a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
+++ b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
@@ -228,8 +228,12 @@
         filteredMembers,
         targetClass.fields(
             f ->
-                (enqueuer.isFieldReferenced(f) || f.getOptimizationInfo().valueHasBeenPropagated())
-                    && appView.graphLense().getOriginalFieldSignature(f.field).holder
+                // Fields referenced only by -keep may not be referenced, we therefore have to
+                // filter on both live and referenced.
+                (enqueuer.isFieldLive(f)
+                        || enqueuer.isFieldReferenced(f)
+                        || f.getOptimizationInfo().valueHasBeenPropagated())
+                    && appView.graphLens().getOriginalFieldSignature(f.field).holder
                         == sourceClass.type));
     Iterables.addAll(
         filteredMembers,
@@ -238,7 +242,7 @@
                 (enqueuer.isMethodLive(m)
                         || enqueuer.isMethodTargeted(m)
                         || m.getOptimizationInfo().returnValueHasBeenPropagated())
-                    && appView.graphLense().getOriginalMethodSignature(m.method).holder
+                    && appView.graphLens().getOriginalMethodSignature(m.method).holder
                         == sourceClass.type));
 
     // If the number of member rules to hold is more than live members, we can't make it.
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index 53af669..ee30fce 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -16,7 +16,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.ProgramField;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.shaking.KeepFieldInfo.Joiner;
@@ -160,7 +160,7 @@
   @Deprecated
   public abstract void forEachPinnedField(Consumer<DexField> consumer);
 
-  public abstract KeepInfoCollection rewrite(NestedGraphLense lens);
+  public abstract KeepInfoCollection rewrite(NestedGraphLens lens);
 
   public abstract KeepInfoCollection mutate(Consumer<MutableKeepInfoCollection> mutator);
 
@@ -196,7 +196,7 @@
     }
 
     @Override
-    public KeepInfoCollection rewrite(NestedGraphLense lens) {
+    public KeepInfoCollection rewrite(NestedGraphLens lens) {
       Map<DexType, KeepClassInfo> newClassInfo = new IdentityHashMap<>(keepClassInfo.size());
       keepClassInfo.forEach(
           (type, info) -> {
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
index 3034f6d..5163a69 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
@@ -184,7 +184,7 @@
       AppView<?> appView,
       Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
       DexStringCache stringCache) {
-    DexField originalSignature = appView.graphLense().getOriginalFieldSignature(field.field);
+    DexField originalSignature = appView.graphLens().getOriginalFieldSignature(field.field);
     switch (getRuleType()) {
       case ALL:
       case ALL_FIELDS:
@@ -235,7 +235,7 @@
       AppView<?> appView,
       Consumer<AnnotationMatchResult> matchedAnnotationsConsumer,
       DexStringCache stringCache) {
-    DexMethod originalSignature = appView.graphLense().getOriginalMethodSignature(method.method);
+    DexMethod originalSignature = appView.graphLens().getOriginalMethodSignature(method.method);
     switch (getRuleType()) {
       case ALL_METHODS:
         if (method.isClassInitializer()) {
diff --git a/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java b/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
index a96194f..ed87cff 100644
--- a/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/StaticClassMerger.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.shaking.VerticalClassMerger.IllegalAccessDetector;
 import com.android.tools.r8.utils.FieldSignatureEquivalence;
@@ -226,7 +226,7 @@
     this.mainDexClasses = mainDexClasses;
   }
 
-  public NestedGraphLense run() {
+  public NestedGraphLens run() {
     for (DexProgramClass clazz : appView.appInfo().app().classesWithDeterministicOrder()) {
       MergeGroup group = satisfiesMergeCriteria(clazz);
       if (group != MergeGroup.DONT_MERGE) {
@@ -240,20 +240,20 @@
           numberOfMergedClasses,
           fieldMapping.size() + methodMapping.size());
     }
-    return buildGraphLense();
+    return buildGraphLens();
   }
 
-  private NestedGraphLense buildGraphLense() {
+  private NestedGraphLens buildGraphLens() {
     if (!fieldMapping.isEmpty() || !methodMapping.isEmpty()) {
       BiMap<DexField, DexField> originalFieldSignatures = fieldMapping.inverse();
       BiMap<DexMethod, DexMethod> originalMethodSignatures = methodMapping.inverse();
-      return new NestedGraphLense(
+      return new NestedGraphLens(
           ImmutableMap.of(),
           methodMapping,
           fieldMapping,
           originalFieldSignatures,
           originalMethodSignatures,
-          appView.graphLense(),
+          appView.graphLens(),
           appView.dexItemFactory());
     }
     return null;
@@ -293,7 +293,7 @@
             method ->
                 method.accessFlags.isNative()
                     || appView.appInfo().isPinned(method.method)
-                    // TODO(christofferqa): Remove the invariant that the graph lense should not
+                    // TODO(christofferqa): Remove the invariant that the graph lens should not
                     // modify any methods from the sets alwaysInline and noSideEffects.
                     || appView.appInfo().alwaysInline.contains(method.method)
                     || appView.appInfo().noSideEffects.keySet().contains(method.method))) {
@@ -343,7 +343,7 @@
         return false;
       }
       if (appView.appInfo().constClassReferences.contains(clazz.type)) {
-        // Since the type is const-class referenced (and the static merger does not create a lense
+        // Since the type is const-class referenced (and the static merger does not create a lens
         // to map the merged type) the class will likely remain and there is no gain from merging.
         return false;
       }
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 79d472d..c2b3627 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -27,8 +27,8 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.GraphLenseLookupResult;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.GraphLensLookupResult;
 import com.android.tools.r8.graph.LookupResult.LookupResultSuccess;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ObjectAllocationInfoCollection;
@@ -89,7 +89,7 @@
  * <p>A common use-case for this is to merge an interface into its single implementation.
  *
  * <p>The class merger only fixes the structure of the graph but leaves the actual instructions
- * untouched. Fixup of instructions is deferred via a {@link GraphLense} to the IR building phase.
+ * untouched. Fixup of instructions is deferred via a {@link GraphLens} to the IR building phase.
  */
 public class VerticalClassMerger {
 
@@ -210,8 +210,8 @@
   // Set of types that must not be merged into their subtype.
   private final Set<DexType> pinnedTypes = Sets.newIdentityHashSet();
 
-  // The resulting graph lense that should be used after class merging.
-  private final VerticalClassMergerGraphLense.Builder renamedMembersLense;
+  // The resulting graph lens that should be used after class merging.
+  private final VerticalClassMergerGraphLens.Builder renamedMembersLens;
 
   // All the bridge methods that have been synthesized during vertical class merging.
   private final List<SynthesizedBridgeCode> synthesizedBridges = new ArrayList<>();
@@ -230,7 +230,7 @@
     this.subtypingInfo = appInfo.computeSubtypingInfo();
     this.executorService = executorService;
     this.methodPoolCollection = new MethodPoolCollection(appView, subtypingInfo);
-    this.renamedMembersLense = new VerticalClassMergerGraphLense.Builder(appView.dexItemFactory());
+    this.renamedMembersLens = new VerticalClassMergerGraphLens.Builder(appView.dexItemFactory());
     this.timing = timing;
     this.mainDexClasses = mainDexClasses;
 
@@ -629,7 +629,7 @@
     }
   }
 
-  public VerticalClassMergerGraphLense run() {
+  public VerticalClassMergerGraphLens run() {
     timing.begin("merge");
     // Visit the program classes in a top-down order according to the class hierarchy.
     TopDownClassHierarchyTraversal.forProgramClasses(appView)
@@ -639,13 +639,13 @@
     }
     timing.end();
     timing.begin("fixup");
-    VerticalClassMergerGraphLense lens = new TreeFixer().fixupTypeReferences();
+    VerticalClassMergerGraphLens lens = new TreeFixer().fixupTypeReferences();
     timing.end();
     assert lens == null || verifyGraphLens(lens);
     return lens;
   }
 
-  private boolean verifyGraphLens(VerticalClassMergerGraphLense graphLense) {
+  private boolean verifyGraphLens(VerticalClassMergerGraphLens graphLens) {
     // Note that the method assertReferencesNotModified() relies on getRenamedFieldSignature() and
     // getRenamedMethodSignature() instead of lookupField() and lookupMethod(). This is important
     // for this check to succeed, since it is not guaranteed that calling lookupMethod() with a
@@ -672,13 +672,13 @@
     // that `invoke-super A.method` instructions, which are in one of the methods from C, needs to
     // be rewritten to `invoke-direct C.method$B`. This is valid even though A.method() is actually
     // pinned, because this rewriting does not affect A.method() in any way.
-    assert graphLense.assertPinnedNotModified(appInfo.getKeepInfo());
+    assert graphLens.assertPinnedNotModified(appInfo.getKeepInfo());
 
     for (DexProgramClass clazz : appInfo.classes()) {
       for (DexEncodedMethod encodedMethod : clazz.methods()) {
         DexMethod method = encodedMethod.method;
-        DexMethod originalMethod = graphLense.getOriginalMethodSignature(method);
-        DexMethod renamedMethod = graphLense.getRenamedMethodSignature(originalMethod);
+        DexMethod originalMethod = graphLens.getOriginalMethodSignature(method);
+        DexMethod renamedMethod = graphLens.getRenamedMethodSignature(originalMethod);
 
         // Must be able to map back and forth.
         if (encodedMethod.hasCode() && encodedMethod.getCode() instanceof SynthesizedBridgeCode) {
@@ -690,7 +690,7 @@
           DexMethod implementationMethod =
               ((SynthesizedBridgeCode) encodedMethod.getCode()).invocationTarget;
           DexMethod originalImplementationMethod =
-              graphLense.getOriginalMethodSignature(implementationMethod);
+              graphLens.getOriginalMethodSignature(implementationMethod);
           assert originalMethod == originalImplementationMethod;
           assert implementationMethod == renamedMethod;
         } else {
@@ -832,8 +832,8 @@
       throw new RuntimeException(e);
     }
     if (merged) {
-      // Commit the changes to the graph lense.
-      renamedMembersLense.merge(merger.getRenamings());
+      // Commit the changes to the graph lens.
+      renamedMembersLens.merge(merger.getRenamings());
       synthesizedBridges.addAll(merger.getSynthesizedBridges());
     }
     if (Log.ENABLED) {
@@ -888,8 +888,8 @@
 
     private final DexProgramClass source;
     private final DexProgramClass target;
-    private final VerticalClassMergerGraphLense.Builder deferredRenamings =
-        new VerticalClassMergerGraphLense.Builder(appView.dexItemFactory());
+    private final VerticalClassMergerGraphLens.Builder deferredRenamings =
+        new VerticalClassMergerGraphLens.Builder(appView.dexItemFactory());
     private final List<SynthesizedBridgeCode> synthesizedBridges = new ArrayList<>();
 
     private boolean abortMerge = false;
@@ -1120,7 +1120,7 @@
       return true;
     }
 
-    public VerticalClassMergerGraphLense.Builder getRenamings() {
+    public VerticalClassMergerGraphLens.Builder getRenamings() {
       return deferredRenamings;
     }
 
@@ -1138,7 +1138,7 @@
         // if I has a supertype J. This is due to the fact that invoke-super instructions that
         // resolve to a method on an interface never hit an implementation below that interface.
         deferredRenamings.mapVirtualMethodToDirectInType(
-            oldTarget, new GraphLenseLookupResult(newTarget, STATIC), target.type);
+            oldTarget, new GraphLensLookupResult(newTarget, STATIC), target.type);
       } else {
         // If we merge class B into class C, and class C contains an invocation super.m(), then it
         // is insufficient to rewrite "invoke-super B.m()" to "invoke-direct C.m$B()" (the method
@@ -1157,7 +1157,7 @@
                   || appInfo.lookupSuperTarget(signatureInHolder, holder) != null;
           if (resolutionSucceeds) {
             deferredRenamings.mapVirtualMethodToDirectInType(
-                signatureInHolder, new GraphLenseLookupResult(newTarget, DIRECT), target.type);
+                signatureInHolder, new GraphLensLookupResult(newTarget, DIRECT), target.type);
           } else {
             break;
           }
@@ -1175,11 +1175,11 @@
               // Resolution would have succeeded if the method used to be in [type], or if one of
               // its super classes declared the method.
               boolean resolutionSucceededBeforeMerge =
-                  renamedMembersLense.hasMappingForSignatureInContext(holder, signatureInType)
+                  renamedMembersLens.hasMappingForSignatureInContext(holder, signatureInType)
                       || appInfo.lookupSuperTarget(signatureInHolder, holder) != null;
               if (resolutionSucceededBeforeMerge) {
                 deferredRenamings.mapVirtualMethodToDirectInType(
-                    signatureInType, new GraphLenseLookupResult(newTarget, DIRECT), target.type);
+                    signatureInType, new GraphLensLookupResult(newTarget, DIRECT), target.type);
               }
             }
           }
@@ -1226,7 +1226,7 @@
       SynthesizedBridgeCode code =
           new SynthesizedBridgeCode(
               newMethod,
-              appView.graphLense().getOriginalMethodSignature(method.method),
+              appView.graphLens().getOriginalMethodSignature(method.method),
               invocationTarget.method,
               invocationTarget.isPrivateMethod() ? DIRECT : STATIC,
               target.isInterface());
@@ -1444,12 +1444,12 @@
 
   private class TreeFixer {
 
-    private final VerticalClassMergerGraphLense.Builder lensBuilder =
-        VerticalClassMergerGraphLense.Builder.createBuilderForFixup(
-            renamedMembersLense, mergedClasses);
+    private final VerticalClassMergerGraphLens.Builder lensBuilder =
+        VerticalClassMergerGraphLens.Builder.createBuilderForFixup(
+            renamedMembersLens, mergedClasses);
     private final Map<DexProto, DexProto> protoFixupCache = new IdentityHashMap<>();
 
-    private VerticalClassMergerGraphLense fixupTypeReferences() {
+    private VerticalClassMergerGraphLens fixupTypeReferences() {
       // Globally substitute merged class types in protos and holders.
       for (DexProgramClass clazz : appInfo.classes()) {
         clazz.getMethodCollection().replaceMethods(this::fixupMethod);
@@ -1459,7 +1459,7 @@
       for (SynthesizedBridgeCode synthesizedBridge : synthesizedBridges) {
         synthesizedBridge.updateMethodSignatures(this::fixupMethod);
       }
-      VerticalClassMergerGraphLense lens = lensBuilder.build(appView, mergedClasses);
+      VerticalClassMergerGraphLens lens = lensBuilder.build(appView, mergedClasses);
       if (lens != null) {
         new AnnotationFixer(lens).run(appView.appInfo().classes());
       }
@@ -1667,7 +1667,7 @@
             cfCode.computeInliningConstraint(
                 method,
                 appView,
-                new SingleTypeMapperGraphLense(method.getHolderType(), context),
+                new SingleTypeMapperGraphLens(method.getHolderType(), context),
                 context);
         if (constraint == ConstraintWithTarget.NEVER) {
           return AbortReason.UNSAFE_INLINING;
@@ -1686,12 +1686,12 @@
     return AbortReason.UNSAFE_INLINING;
   }
 
-  private class SingleTypeMapperGraphLense extends GraphLense {
+  private class SingleTypeMapperGraphLens extends GraphLens {
 
     private final DexType source;
     private final DexProgramClass target;
 
-    public SingleTypeMapperGraphLense(DexType source, DexProgramClass target) {
+    public SingleTypeMapperGraphLens(DexType source, DexProgramClass target) {
       this.source = source;
       this.target = target;
     }
@@ -1717,7 +1717,7 @@
     }
 
     @Override
-    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLense applied) {
+    public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
       throw new Unreachable();
     }
 
@@ -1727,14 +1727,14 @@
     }
 
     @Override
-    public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
-      // First look up the method using the existing graph lense (for example, the type will have
+    public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+      // First look up the method using the existing graph lens (for example, the type will have
       // changed if the method was publicized by ClassAndMemberPublicizer).
-      GraphLenseLookupResult lookup = appView.graphLense().lookupMethod(method, context, type);
+      GraphLensLookupResult lookup = appView.graphLens().lookupMethod(method, context, type);
       DexMethod previousMethod = lookup.getMethod();
       Type previousType = lookup.getType();
       // Then check if there is a renaming due to the vertical class merger.
-      DexMethod newMethod = renamedMembersLense.methodMap.get(previousMethod);
+      DexMethod newMethod = renamedMembersLens.methodMap.get(previousMethod);
       if (newMethod != null) {
         if (previousType == Type.INTERFACE) {
           // If an interface has been merged into a class, invoke-interface needs to be translated
@@ -1742,12 +1742,12 @@
           DexClass clazz = appInfo.definitionFor(newMethod.holder);
           if (clazz != null && !clazz.accessFlags.isInterface()) {
             assert appInfo.definitionFor(method.holder).accessFlags.isInterface();
-            return new GraphLenseLookupResult(newMethod, Type.VIRTUAL);
+            return new GraphLensLookupResult(newMethod, Type.VIRTUAL);
           }
         }
-        return new GraphLenseLookupResult(newMethod, previousType);
+        return new GraphLensLookupResult(newMethod, previousType);
       }
-      return new GraphLenseLookupResult(previousMethod, previousType);
+      return new GraphLensLookupResult(previousMethod, previousType);
     }
 
     @Override
@@ -1757,7 +1757,7 @@
 
     @Override
     public DexField lookupField(DexField field) {
-      return renamedMembersLense.fieldMap.getOrDefault(field, field);
+      return renamedMembersLens.fieldMap.getOrDefault(field, field);
     }
 
     @Override
@@ -1793,7 +1793,7 @@
     private boolean checkFieldReference(DexField field) {
       if (!foundIllegalAccess) {
         DexType baseType =
-            appView.graphLense().lookupType(field.holder.toBaseType(appView.dexItemFactory()));
+            appView.graphLens().lookupType(field.holder.toBaseType(appView.dexItemFactory()));
         if (baseType.isClassType() && baseType.isSamePackage(source.type)) {
           checkTypeReference(field.holder);
           checkTypeReference(field.type);
@@ -1810,7 +1810,7 @@
     private boolean checkMethodReference(DexMethod method, OptionalBool isInterface) {
       if (!foundIllegalAccess) {
         DexType baseType =
-            appView.graphLense().lookupType(method.holder.toBaseType(appView.dexItemFactory()));
+            appView.graphLens().lookupType(method.holder.toBaseType(appView.dexItemFactory()));
         if (baseType.isClassType() && baseType.isSamePackage(source.type)) {
           checkTypeReference(method.holder);
           checkTypeReference(method.proto.returnType);
@@ -1833,7 +1833,7 @@
     private boolean checkTypeReference(DexType type) {
       if (!foundIllegalAccess) {
         DexType baseType =
-            appView.graphLense().lookupType(type.toBaseType(appView.dexItemFactory()));
+            appView.graphLens().lookupType(type.toBaseType(appView.dexItemFactory()));
         if (baseType.isClassType() && baseType.isSamePackage(source.type)) {
           DexClass clazz = appView.definitionFor(baseType);
           if (clazz == null || !clazz.accessFlags.isPublic()) {
@@ -1852,51 +1852,51 @@
     @Override
     public boolean registerInvokeVirtual(DexMethod method) {
       assert context != null;
-      GraphLenseLookupResult lookup =
-          appView.graphLense().lookupMethod(method, context.getReference(), Type.VIRTUAL);
+      GraphLensLookupResult lookup =
+          appView.graphLens().lookupMethod(method, context.getReference(), Type.VIRTUAL);
       return checkMethodReference(lookup.getMethod(), OptionalBool.FALSE);
     }
 
     @Override
     public boolean registerInvokeDirect(DexMethod method) {
       assert context != null;
-      GraphLenseLookupResult lookup =
-          appView.graphLense().lookupMethod(method, context.getReference(), Type.DIRECT);
+      GraphLensLookupResult lookup =
+          appView.graphLens().lookupMethod(method, context.getReference(), Type.DIRECT);
       return checkMethodReference(lookup.getMethod(), OptionalBool.UNKNOWN);
     }
 
     @Override
     public boolean registerInvokeStatic(DexMethod method) {
       assert context != null;
-      GraphLenseLookupResult lookup =
-          appView.graphLense().lookupMethod(method, context.getReference(), Type.STATIC);
+      GraphLensLookupResult lookup =
+          appView.graphLens().lookupMethod(method, context.getReference(), Type.STATIC);
       return checkMethodReference(lookup.getMethod(), OptionalBool.UNKNOWN);
     }
 
     @Override
     public boolean registerInvokeInterface(DexMethod method) {
       assert context != null;
-      GraphLenseLookupResult lookup =
-          appView.graphLense().lookupMethod(method, context.getReference(), Type.INTERFACE);
+      GraphLensLookupResult lookup =
+          appView.graphLens().lookupMethod(method, context.getReference(), Type.INTERFACE);
       return checkMethodReference(lookup.getMethod(), OptionalBool.TRUE);
     }
 
     @Override
     public boolean registerInvokeSuper(DexMethod method) {
       assert context != null;
-      GraphLenseLookupResult lookup =
-          appView.graphLense().lookupMethod(method, context.getReference(), Type.SUPER);
+      GraphLensLookupResult lookup =
+          appView.graphLens().lookupMethod(method, context.getReference(), Type.SUPER);
       return checkMethodReference(lookup.getMethod(), OptionalBool.UNKNOWN);
     }
 
     @Override
     public boolean registerInstanceFieldWrite(DexField field) {
-      return checkFieldReference(appView.graphLense().lookupField(field));
+      return checkFieldReference(appView.graphLens().lookupField(field));
     }
 
     @Override
     public boolean registerInstanceFieldRead(DexField field) {
-      return checkFieldReference(appView.graphLense().lookupField(field));
+      return checkFieldReference(appView.graphLens().lookupField(field));
     }
 
     @Override
@@ -1906,12 +1906,12 @@
 
     @Override
     public boolean registerStaticFieldRead(DexField field) {
-      return checkFieldReference(appView.graphLense().lookupField(field));
+      return checkFieldReference(appView.graphLens().lookupField(field));
     }
 
     @Override
     public boolean registerStaticFieldWrite(DexField field) {
-      return checkFieldReference(appView.graphLense().lookupField(field));
+      return checkFieldReference(appView.graphLens().lookupField(field));
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
similarity index 84%
rename from src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
rename to src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
index 2a0a843..db59152 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLens.java
@@ -11,8 +11,8 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
-import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
@@ -21,7 +21,7 @@
 import java.util.Map;
 import java.util.Set;
 
-// This graph lense is instantiated during vertical class merging. The graph lense is context
+// This graph lens is instantiated during vertical class merging. The graph lens is context
 // sensitive in the enclosing class of a given invoke *and* the type of the invoke (e.g., invoke-
 // super vs invoke-virtual). This is illustrated by the following example.
 //
@@ -40,38 +40,38 @@
 // During this process, the method corresponding to A.m will be made private such that it can be
 // called via an invoke-direct instruction.
 //
-// For the invocation "invoke-super A.m()" in B.m, this graph lense will return the newly created,
+// For the invocation "invoke-super A.m()" in B.m, this graph lens will return the newly created,
 // private method corresponding to A.m (that is now in B.m with a fresh name), such that the
 // invocation will hit the same implementation as the original super.m() call.
 //
-// For the invocation "invoke-virtual A.m()" in B.m2, this graph lense will return the method B.m.
-public class VerticalClassMergerGraphLense extends NestedGraphLense {
+// For the invocation "invoke-virtual A.m()" in B.m2, this graph lens will return the method B.m.
+public class VerticalClassMergerGraphLens extends NestedGraphLens {
 
   private final AppView<?> appView;
 
-  private final Map<DexType, Map<DexMethod, GraphLenseLookupResult>>
+  private final Map<DexType, Map<DexMethod, GraphLensLookupResult>>
       contextualVirtualToDirectMethodMaps;
   private Set<DexMethod> mergedMethods;
   private final Map<DexMethod, DexMethod> originalMethodSignaturesForBridges;
 
-  private VerticalClassMergerGraphLense(
+  private VerticalClassMergerGraphLens(
       AppView<?> appView,
       Map<DexType, DexType> typeMap,
       Map<DexField, DexField> fieldMap,
       Map<DexMethod, DexMethod> methodMap,
       Set<DexMethod> mergedMethods,
-      Map<DexType, Map<DexMethod, GraphLenseLookupResult>> contextualVirtualToDirectMethodMaps,
+      Map<DexType, Map<DexMethod, GraphLensLookupResult>> contextualVirtualToDirectMethodMaps,
       BiMap<DexField, DexField> originalFieldSignatures,
       BiMap<DexMethod, DexMethod> originalMethodSignatures,
       Map<DexMethod, DexMethod> originalMethodSignaturesForBridges,
-      GraphLense previousLense) {
+      GraphLens previousLens) {
     super(
         typeMap,
         methodMap,
         fieldMap,
         originalFieldSignatures,
         originalMethodSignatures,
-        previousLense,
+        previousLens,
         appView.dexItemFactory());
     this.appView = appView;
     this.contextualVirtualToDirectMethodMaps = contextualVirtualToDirectMethodMaps;
@@ -81,7 +81,7 @@
 
   @Override
   public DexType getOriginalType(DexType type) {
-    return previousLense.getOriginalType(type);
+    return previousLens.getOriginalType(type);
   }
 
   @Override
@@ -91,19 +91,19 @@
   }
 
   @Override
-  public GraphLenseLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
+  public GraphLensLookupResult lookupMethod(DexMethod method, DexMethod context, Type type) {
     assert context != null || verifyIsContextFreeForMethod(method);
     assert context == null || type != null;
     DexMethod previousContext =
         originalMethodSignaturesForBridges.containsKey(context)
             ? originalMethodSignaturesForBridges.get(context)
             : originalMethodSignatures.getOrDefault(context, context);
-    GraphLenseLookupResult previous = previousLense.lookupMethod(method, previousContext, type);
+    GraphLensLookupResult previous = previousLens.lookupMethod(method, previousContext, type);
     if (previous.getType() == Type.SUPER && !mergedMethods.contains(context)) {
-      Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
+      Map<DexMethod, GraphLensLookupResult> virtualToDirectMethodMap =
           contextualVirtualToDirectMethodMaps.get(context.holder);
       if (virtualToDirectMethodMap != null) {
-        GraphLenseLookupResult lookup = virtualToDirectMethodMap.get(previous.getMethod());
+        GraphLensLookupResult lookup = virtualToDirectMethodMap.get(previous.getMethod());
         if (lookup != null) {
           // If the super class A of the enclosing class B (i.e., context.holder())
           // has been merged into B during vertical class merging, and this invoke-super instruction
@@ -125,13 +125,13 @@
 
   @Override
   public boolean isContextFreeForMethods() {
-    return contextualVirtualToDirectMethodMaps.isEmpty() && previousLense.isContextFreeForMethods();
+    return contextualVirtualToDirectMethodMaps.isEmpty() && previousLens.isContextFreeForMethods();
   }
 
   @Override
   public boolean verifyIsContextFreeForMethod(DexMethod method) {
-    assert previousLense.verifyIsContextFreeForMethod(method);
-    DexMethod previous = previousLense.lookupMethod(method);
+    assert previousLens.verifyIsContextFreeForMethod(method);
+    DexMethod previous = previousLens.lookupMethod(method);
     assert contextualVirtualToDirectMethodMaps.values().stream()
         .noneMatch(virtualToDirectMethodMap -> virtualToDirectMethodMap.containsKey(previous));
     return true;
@@ -144,7 +144,7 @@
     protected final BiMap<DexField, DexField> fieldMap = HashBiMap.create();
     protected final Map<DexMethod, DexMethod> methodMap = new IdentityHashMap<>();
     private final ImmutableSet.Builder<DexMethod> mergedMethodsBuilder = ImmutableSet.builder();
-    private final Map<DexType, Map<DexMethod, GraphLenseLookupResult>>
+    private final Map<DexType, Map<DexMethod, GraphLensLookupResult>>
         contextualVirtualToDirectMethodMaps = new IdentityHashMap<>();
 
     private final BiMap<DexMethod, DexMethod> originalMethodSignatures = HashBiMap.create();
@@ -173,18 +173,17 @@
         newBuilder.markMethodAsMerged(
             builder.getMethodSignatureAfterClassMerging(method, mergedClasses));
       }
-      for (Map.Entry<DexType, Map<DexMethod, GraphLenseLookupResult>> entry :
+      for (Map.Entry<DexType, Map<DexMethod, GraphLensLookupResult>> entry :
           builder.contextualVirtualToDirectMethodMaps.entrySet()) {
         DexType context = entry.getKey();
         assert context == builder.getTypeAfterClassMerging(context, mergedClasses);
-        for (Map.Entry<DexMethod, GraphLenseLookupResult> innerEntry :
-            entry.getValue().entrySet()) {
+        for (Map.Entry<DexMethod, GraphLensLookupResult> innerEntry : entry.getValue().entrySet()) {
           DexMethod from = innerEntry.getKey();
-          GraphLenseLookupResult rewriting = innerEntry.getValue();
+          GraphLensLookupResult rewriting = innerEntry.getValue();
           DexMethod to =
               builder.getMethodSignatureAfterClassMerging(rewriting.getMethod(), mergedClasses);
           newBuilder.mapVirtualMethodToDirectInType(
-              from, new GraphLenseLookupResult(to, rewriting.getType()), context);
+              from, new GraphLensLookupResult(to, rewriting.getType()), context);
         }
       }
       for (Map.Entry<DexMethod, DexMethod> entry : builder.originalMethodSignatures.entrySet()) {
@@ -201,14 +200,14 @@
       return newBuilder;
     }
 
-    public VerticalClassMergerGraphLense build(
+    public VerticalClassMergerGraphLens build(
         AppView<?> appView, Map<DexType, DexType> mergedClasses) {
       if (mergedClasses.isEmpty()) {
         return null;
       }
       BiMap<DexField, DexField> originalFieldSignatures = fieldMap.inverse();
-      // Build new graph lense.
-      return new VerticalClassMergerGraphLense(
+      // Build new graph lens.
+      return new VerticalClassMergerGraphLens(
           appView,
           mergedClasses,
           fieldMap,
@@ -218,7 +217,7 @@
           originalFieldSignatures,
           originalMethodSignatures,
           originalMethodSignaturesForBridges,
-          appView.graphLense());
+          appView.graphLens());
     }
 
     private DexField getFieldSignatureAfterClassMerging(
@@ -268,7 +267,7 @@
     }
 
     public boolean hasMappingForSignatureInContext(DexProgramClass context, DexMethod signature) {
-      Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
+      Map<DexMethod, GraphLensLookupResult> virtualToDirectMethodMap =
           contextualVirtualToDirectMethodMaps.get(context.type);
       if (virtualToDirectMethodMap != null) {
         return virtualToDirectMethodMap.containsKey(signature);
@@ -307,22 +306,22 @@
     }
 
     public void mapVirtualMethodToDirectInType(
-        DexMethod from, GraphLenseLookupResult to, DexType type) {
-      Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
+        DexMethod from, GraphLensLookupResult to, DexType type) {
+      Map<DexMethod, GraphLensLookupResult> virtualToDirectMethodMap =
           contextualVirtualToDirectMethodMaps.computeIfAbsent(type, key -> new IdentityHashMap<>());
       virtualToDirectMethodMap.put(from, to);
     }
 
-    public void merge(VerticalClassMergerGraphLense.Builder builder) {
+    public void merge(VerticalClassMergerGraphLens.Builder builder) {
       fieldMap.putAll(builder.fieldMap);
       methodMap.putAll(builder.methodMap);
       mergedMethodsBuilder.addAll(builder.mergedMethodsBuilder.build());
       originalMethodSignatures.putAll(builder.originalMethodSignatures);
       originalMethodSignaturesForBridges.putAll(builder.originalMethodSignaturesForBridges);
       for (DexType context : builder.contextualVirtualToDirectMethodMaps.keySet()) {
-        Map<DexMethod, GraphLenseLookupResult> current =
+        Map<DexMethod, GraphLensLookupResult> current =
             contextualVirtualToDirectMethodMaps.get(context);
-        Map<DexMethod, GraphLenseLookupResult> other =
+        Map<DexMethod, GraphLensLookupResult> other =
             builder.contextualVirtualToDirectMethodMaps.get(context);
         if (current != null) {
           current.putAll(other);
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
index e349c9a..c230a6d 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
@@ -171,8 +171,10 @@
             .addClasspathFiles(classpath)
             .addProguardConfigurationFiles(config)
             .setOutput(outputPath, outputMode)
-            .setMode(compilationMode)
-            .setMinApiLevel(minApi);
+            .setMode(compilationMode);
+    if (outputMode != OutputMode.ClassFile) {
+      commandBuilder.setMinApiLevel(minApi);
+    }
     features.forEach(
         (in, out) ->
             commandBuilder.addFeatureSplit(
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 6cc73f4..6d85a4e 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -819,7 +819,7 @@
     List<String> classPathClasses = new ArrayList<>();
     List<String> libraryClasses = new ArrayList<>();
     for (DexType type : nest) {
-      DexClass clazz = appView.definitionFor(appView.graphLense().lookupType(type));
+      DexClass clazz = appView.definitionFor(appView.graphLens().lookupType(type));
       if (clazz == null) {
         unavailableClasses.add(type.getName());
       } else if (clazz.isLibraryClass()) {
diff --git a/src/main/java/com/android/tools/r8/utils/LensUtils.java b/src/main/java/com/android/tools/r8/utils/LensUtils.java
index 325d6fa..a039fb6 100644
--- a/src/main/java/com/android/tools/r8/utils/LensUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/LensUtils.java
@@ -6,14 +6,14 @@
 
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.google.common.collect.Sets;
 import java.util.Set;
 
 public class LensUtils {
 
   public static Set<DexEncodedMethod> rewrittenWithRenamedSignature(
-      Set<DexEncodedMethod> methods, DexDefinitionSupplier definitions, GraphLense lens) {
+      Set<DexEncodedMethod> methods, DexDefinitionSupplier definitions, GraphLens lens) {
     Set<DexEncodedMethod> result = Sets.newIdentityHashSet();
     for (DexEncodedMethod method : methods) {
       result.add(lens.mapDexEncodedMethod(method, definitions));
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index 6907805..9c703e7 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -35,7 +35,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue.DexValueString;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.kotlin.KotlinSourceDebugExtensionParser;
 import com.android.tools.r8.kotlin.KotlinSourceDebugExtensionParser.Result;
@@ -274,12 +274,12 @@
     // Collect which files contain which classes that need to have their line numbers optimized.
     for (DexProgramClass clazz : application.classes()) {
       IdentityHashMap<DexString, List<DexEncodedMethod>> methodsByRenamedName =
-          groupMethodsByRenamedName(appView.graphLense(), namingLens, clazz);
+          groupMethodsByRenamedName(appView.graphLens(), namingLens, clazz);
 
       // At this point we don't know if we really need to add this class to the builder.
       // It depends on whether any methods/fields are renamed or some methods contain positions.
       // Create a supplier which creates a new, cached ClassNaming.Builder on-demand.
-      DexType originalType = appView.graphLense().getOriginalType(clazz.type);
+      DexType originalType = appView.graphLens().getOriginalType(clazz.type);
       DexString renamedClassName = namingLens.lookupDescriptor(clazz.getType());
       Supplier<ClassNaming.Builder> onDemandClassNamingBuilder =
           Suppliers.memoize(
@@ -302,7 +302,7 @@
       addClassToClassNaming(originalType, renamedClassName, onDemandClassNamingBuilder);
 
       // First transfer renamed fields to classNamingBuilder.
-      addFieldsToClassNaming(appView.graphLense(), namingLens, clazz, onDemandClassNamingBuilder);
+      addFieldsToClassNaming(appView.graphLens(), namingLens, clazz, onDemandClassNamingBuilder);
 
       // Then process the methods, ordered by renamed name.
       List<DexString> renamedMethodNames = new ArrayList<>(methodsByRenamedName.keySet());
@@ -355,7 +355,7 @@
             }
           }
 
-          DexMethod originalMethod = appView.graphLense().getOriginalMethodSignature(method.method);
+          DexMethod originalMethod = appView.graphLens().getOriginalMethodSignature(method.method);
           MethodSignature originalSignature =
               MethodSignature.fromDexMethod(originalMethod, originalMethod.holder != clazz.type);
 
@@ -536,14 +536,14 @@
   }
 
   private static void addFieldsToClassNaming(
-      GraphLense graphLense,
+      GraphLens graphLens,
       NamingLens namingLens,
       DexProgramClass clazz,
       Supplier<Builder> onDemandClassNamingBuilder) {
     clazz.forEachField(
         dexEncodedField -> {
           DexField dexField = dexEncodedField.field;
-          DexField originalField = graphLense.getOriginalFieldSignature(dexField);
+          DexField originalField = graphLens.getOriginalFieldSignature(dexField);
           DexString renamedName = namingLens.lookupName(dexField);
           if (renamedName != originalField.name || originalField.holder != clazz.type) {
             FieldSignature originalSignature =
@@ -555,7 +555,7 @@
   }
 
   private static IdentityHashMap<DexString, List<DexEncodedMethod>> groupMethodsByRenamedName(
-      GraphLense graphLens, NamingLens namingLens, DexProgramClass clazz) {
+      GraphLens graphLens, NamingLens namingLens, DexProgramClass clazz) {
     IdentityHashMap<DexString, List<DexEncodedMethod>> methodsByRenamedName =
         new IdentityHashMap<>(clazz.getMethodCollection().size());
     for (DexEncodedMethod encodedMethod : clazz.methods()) {
diff --git a/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodMultisetBuilder.java b/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodMultisetBuilder.java
index f3ba06b..765f373 100644
--- a/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodMultisetBuilder.java
+++ b/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodMultisetBuilder.java
@@ -34,7 +34,7 @@
     ProgramMethodMultiset result = ProgramMethodMultiset.createHash();
     backing.forEachEntry(
         (oldMethod, occurrences) -> {
-          DexMethod method = appView.graphLense().getRenamedMethodSignature(oldMethod);
+          DexMethod method = appView.graphLens().getRenamedMethodSignature(oldMethod);
           DexProgramClass holder = appView.definitionForHolder(method).asProgramClass();
           result.createAndAdd(holder, holder.lookupMethod(method), occurrences);
         });
diff --git a/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodSetBuilder.java b/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodSetBuilder.java
index 1c6d63a..4b4eccb 100644
--- a/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/utils/collections/LongLivedProgramMethodSetBuilder.java
@@ -7,7 +7,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.google.common.collect.Sets;
@@ -39,10 +39,10 @@
     methods.forEach(this::add);
   }
 
-  public void rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense applied) {
+  public void rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLens applied) {
     Set<DexMethod> newMethods = Sets.newIdentityHashSet();
     for (DexMethod method : methods) {
-      newMethods.add(appView.graphLense().getRenamedMethodSignature(method, applied));
+      newMethods.add(appView.graphLens().getRenamedMethodSignature(method, applied));
     }
     methods.clear();
     methods.addAll(newMethods);
@@ -52,10 +52,10 @@
     return build(appView, null);
   }
 
-  public T build(AppView<AppInfoWithLiveness> appView, GraphLense applied) {
+  public T build(AppView<AppInfoWithLiveness> appView, GraphLens applied) {
     T result = factory.apply(methods.size());
     for (DexMethod oldMethod : methods) {
-      DexMethod method = appView.graphLense().getRenamedMethodSignature(oldMethod, applied);
+      DexMethod method = appView.graphLens().getRenamedMethodSignature(oldMethod, applied);
       DexProgramClass holder = appView.definitionForHolder(method).asProgramClass();
       result.createAndAdd(holder, holder.lookupMethod(method));
     }
diff --git a/src/test/examples/classmerging/RewritePinnedMethodTest.java b/src/test/examples/classmerging/RewritePinnedMethodTest.java
index 3d25805..81f6c5f 100644
--- a/src/test/examples/classmerging/RewritePinnedMethodTest.java
+++ b/src/test/examples/classmerging/RewritePinnedMethodTest.java
@@ -32,7 +32,7 @@
     public void m() {
       System.out.println("In C.m");
       // This invocation is changed from invoke-super to invoke-direct. It would be valid for this
-      // instruction to be on the form "invoke-super A.m". Therefore, the graph lense contains a
+      // instruction to be on the form "invoke-super A.m". Therefore, the graph lens contains a
       // mapping for "A.m" from (context: "C.m", type: SUPER) to C.m$B, where the method C.m$B is
       // the direct method that gets created for B.m during vertical class merging.
       super.m();
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 31150c4..9b83a88fa2 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -20,7 +20,7 @@
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.origin.Origin;
@@ -2092,7 +2092,7 @@
         Executors.newSingleThreadExecutor(),
         application,
         null,
-        GraphLense.getIdentityLense(),
+        GraphLens.getIdentityLens(),
         InitClassLens.getDefault(),
         NamingLens.getIdentityLens(),
         options,
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
index 5c04f51..8c2adf3 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
@@ -64,12 +64,13 @@
       String expectedException,
       Consumer<CodeInspector> inspectorConsumer) throws Exception {
     AndroidApp app = buildApplication(builder);
-    List<String> pgConfigs = ImmutableList.of(
-        keepMainProguardConfiguration(CLASS_NAME),
-        // We're testing lense-based invocation type conversions.
-        "-dontoptimize",
-        "-dontobfuscate",
-        "-allowaccessmodification");
+    List<String> pgConfigs =
+        ImmutableList.of(
+            keepMainProguardConfiguration(CLASS_NAME),
+            // We're testing lens-based invocation type conversions.
+            "-dontoptimize",
+            "-dontobfuscate",
+            "-allowaccessmodification");
     R8Command.Builder command = ToolHelper.prepareR8CommandBuilder(app);
     command.addProguardConfiguration(pgConfigs, Origin.unknown());
     AndroidApp processedApp = ToolHelper.runR8(command.build(), o -> {
@@ -88,7 +89,7 @@
   }
 
   // The following test checks invoke-direct, which refers to the private static method, is *not*
-  // rewritten by publicizer lense, resulting in IncompatibleClassChangeError, which is expected.
+  // rewritten by publicizer lens, resulting in IncompatibleClassChangeError, which is expected.
   //
   // class Example {
   //   private int foo() { return 0; }
@@ -118,7 +119,7 @@
   }
 
   // The following test checks invoke-direct, which refers to the private instance method, *is*
-  // rewritten by publicizer lense, as the target method will be publicized.
+  // rewritten by publicizer lens, as the target method will be publicized.
   //
   // class Example {
   //   private int foo() { return 0; }
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index 817abcd..49e7256 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -23,7 +23,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -155,7 +155,7 @@
             null,
             options,
             null,
-            GraphLense.getIdentityLense(),
+            GraphLens.getIdentityLens(),
             InitClassLens.getDefault(),
             NamingLens.getIdentityLens(),
             null);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
index dc6bc19..c139dcf 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
@@ -70,8 +70,9 @@
     //
     // Then test that peephole optimization realizes that the last const number
     // is needed and the value 10 is *not* still in register 0 at that point.
+    final ValueNumberGenerator basicBlockNumberGenerator = new ValueNumberGenerator();
     BasicBlock block = new BasicBlock();
-    block.setNumber(0);
+    block.setNumber(basicBlockNumberGenerator.next());
 
     IRMetadata metadata = IRMetadata.unknown();
     Position position = Position.testingPosition();
@@ -141,6 +142,7 @@
             null,
             blocks,
             new ValueNumberGenerator(),
+            basicBlockNumberGenerator,
             IRMetadata.unknown(),
             Origin.unknown());
     PeepholeOptimizer.optimize(code, new MockLinearScanRegisterAllocator(appView, code));
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 7d7785f..69394e0 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -62,18 +62,20 @@
     //   throw v0
     // block2:
     //   return
+    final ValueNumberGenerator basicBlockNumberGenerator = new ValueNumberGenerator();
     Position position = Position.testingPosition();
     BasicBlock block2 = new BasicBlock();
-    block2.setNumber(2);
-    BasicBlock block0 = BasicBlock.createGotoBlock(0, position, metadata, block2);
+    BasicBlock block0 =
+        BasicBlock.createGotoBlock(basicBlockNumberGenerator.next(), position, metadata, block2);
+    BasicBlock block1 = new BasicBlock();
+    block1.setNumber(basicBlockNumberGenerator.next());
+    block2.setNumber(basicBlockNumberGenerator.next());
     block0.setFilledForTesting();
     block2.getMutablePredecessors().add(block0);
     Instruction ret = new Return();
     ret.setPosition(position);
     block2.add(ret, metadata);
     block2.setFilledForTesting();
-    BasicBlock block1 = new BasicBlock();
-    block1.setNumber(1);
     Value value = new Value(0, TypeElement.getInt(), null);
     Instruction number = new ConstNumber(value, 0);
     number.setPosition(position);
@@ -97,6 +99,7 @@
             null,
             blocks,
             new ValueNumberGenerator(),
+            basicBlockNumberGenerator,
             IRMetadata.unknown(),
             Origin.unknown());
     CodeRewriter.collapseTrivialGotos(code);
@@ -123,28 +126,30 @@
     //
     // block3:
     //   goto block3
+    final ValueNumberGenerator basicBlockNumberGenerator = new ValueNumberGenerator();
     Position position = Position.testingPosition();
+    BasicBlock block0 = new BasicBlock();
+    block0.setNumber(basicBlockNumberGenerator.next());
     BasicBlock block2 = new BasicBlock();
-    block2.setNumber(2);
+    BasicBlock block1 =
+        BasicBlock.createGotoBlock(basicBlockNumberGenerator.next(), position, metadata);
+    block2.setNumber(basicBlockNumberGenerator.next());
     Instruction ret = new Return();
     ret.setPosition(position);
     block2.add(ret, metadata);
     block2.setFilledForTesting();
 
     BasicBlock block3 = new BasicBlock();
-    block3.setNumber(3);
+    block3.setNumber(basicBlockNumberGenerator.next());
     Instruction instruction = new Goto();
     instruction.setPosition(position);
     block3.add(instruction, metadata);
     block3.setFilledForTesting();
     block3.getMutableSuccessors().add(block3);
 
-    BasicBlock block1 = BasicBlock.createGotoBlock(1, position, metadata);
     block1.getMutableSuccessors().add(block3);
     block1.setFilledForTesting();
 
-    BasicBlock block0 = new BasicBlock();
-    block0.setNumber(0);
     Value value =
         new Value(
             0,
@@ -181,6 +186,7 @@
             null,
             blocks,
             new ValueNumberGenerator(),
+            basicBlockNumberGenerator,
             IRMetadata.unknown(),
             Origin.unknown());
     CodeRewriter.collapseTrivialGotos(code);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningTest.java
new file mode 100644
index 0000000..17ccc82
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningTest.java
@@ -0,0 +1,71 @@
+// 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.optimize.classinliner;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class StatefulSingletonClassInliningTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public StatefulSingletonClassInliningTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(StatefulSingletonClassInliningTest.class)
+        .addKeepMainRule(TestClass.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutputLines("true");
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      State.get().set();
+      State.get().print();
+    }
+  }
+
+  static class State {
+
+    static StatefulSingleton SINGLETON = new StatefulSingleton();
+
+    static StatefulSingleton get() {
+      return SINGLETON;
+    }
+  }
+
+  static class StatefulSingleton {
+
+    boolean field;
+
+    @NeverInline
+    void set() {
+      field = true;
+    }
+
+    void print() {
+      System.out.println(field);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningWithStaticEscapeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningWithStaticEscapeTest.java
new file mode 100644
index 0000000..681f958
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/StatefulSingletonClassInliningWithStaticEscapeTest.java
@@ -0,0 +1,72 @@
+// 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.optimize.classinliner;
+
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class StatefulSingletonClassInliningWithStaticEscapeTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public StatefulSingletonClassInliningWithStaticEscapeTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(StatefulSingletonClassInliningWithStaticEscapeTest.class)
+        .addKeepMainRule(TestClass.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutputLines("true");
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      State.set(State.get());
+      State.get().print();
+    }
+  }
+
+  static class State {
+
+    static StatefulSingleton SINGLETON = new StatefulSingleton();
+
+    static StatefulSingleton get() {
+      return SINGLETON;
+    }
+
+    @NeverInline
+    static void set(StatefulSingleton state) {
+      state.field = true;
+    }
+  }
+
+  static class StatefulSingleton {
+
+    boolean field;
+
+    void print() {
+      System.out.println(field);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynchronizedMethodTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynchronizedMethodTest.java
new file mode 100644
index 0000000..45997a8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynchronizedMethodTest.java
@@ -0,0 +1,67 @@
+// 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.optimize.inliner;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class InlineSynchronizedMethodTest extends TestBase {
+
+  static final String EXPECTED = StringUtils.lines("Hello, world");
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().withAllApiLevels().build();
+  }
+
+  public InlineSynchronizedMethodTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(InlineSynchronizedMethodTest.class)
+        .addKeepMainRule(TestClass.class)
+        .setMinApi(parameters.getApiLevel())
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED)
+        .inspect(
+            inspector -> {
+              // TODO(b/163007704): Identify and remove trivial/unobservable monitor enter/exit
+              // pairs.
+              assertEquals(
+                  2,
+                  inspector
+                      .clazz(TestClass.class)
+                      .uniqueMethodWithName("main")
+                      .streamInstructions()
+                      .filter(i -> i.isMonitorEnter() || i.isMonitorExit())
+                      .count());
+            });
+  }
+
+  static class TestClass {
+
+    public static synchronized String foo(String msg) {
+      // No throwing instructions, so no need to join exceptions on exit.
+      return msg;
+    }
+
+    public static void main(String[] args) {
+      System.out.println(foo(args.length == 1 ? args[0] : "Hello, world"));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/movetohost/MoveToHostFieldOnlyTestClass.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/movetohost/MoveToHostFieldOnlyTestClass.java
index eb8e6a4..0ec6935 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/movetohost/MoveToHostFieldOnlyTestClass.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/movetohost/MoveToHostFieldOnlyTestClass.java
@@ -23,7 +23,7 @@
     // Any other uses other than invoke-virtual or invoke-direct (to either <init> or private) are
     // not allowed, e.g., System.out.println(INSTANCE), null check, or static-put to somewhere else.
     // Therefore, it's merely dead code, and thus it has not been harmful to forget to create a
-    // staticizer lense when there is no method mapping (for instance methods to staticized ones)
+    // staticizer lens when there is no method mapping (for instance methods to staticized ones)
     // while there are field mappings as shown in this example.
     Object x = HostOkFieldOnly.INSTANCE;
   }
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
new file mode 100644
index 0000000..77134d8
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataPrunedFieldsTest.java
@@ -0,0 +1,85 @@
+// 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.kotlin.metadata;
+
+import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.kotlin.metadata.metadata_pruned_fields.Main;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/** This is a reproduction of b/161230424. */
+@RunWith(Parameterized.class)
+public class MetadataPrunedFieldsTest extends KotlinMetadataTestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0} target: {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(), KotlinTargetVersion.values());
+  }
+
+  public MetadataPrunedFieldsTest(TestParameters parameters, KotlinTargetVersion targetVersion) {
+    super(targetVersion);
+    this.parameters = parameters;
+  }
+
+  private static Map<KotlinTargetVersion, Path> libJars = new HashMap<>();
+
+  @BeforeClass
+  public static void createLibJar() throws Exception {
+    String baseLibFolder = PKG_PREFIX + "/metadata_pruned_fields";
+    for (KotlinTargetVersion targetVersion : KotlinTargetVersion.values()) {
+      Path baseLibJar =
+          kotlinc(KOTLINC, targetVersion)
+              .addSourceFiles(getKotlinFileInTest(baseLibFolder, "Methods"))
+              .compile();
+      libJars.put(targetVersion, baseLibJar);
+    }
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
+        .addProgramFiles(libJars.get(targetVersion))
+        .addProgramClassFileData(Main.dump())
+        .addKeepRules("-keep class " + PKG + ".metadata_pruned_fields.MethodsKt { *; }")
+        .addKeepRules("-keep class kotlin.Metadata { *** pn(); }")
+        .addKeepMainRule(Main.class)
+        .allowDiagnosticWarningMessages()
+        .setMinApi(parameters.getApiLevel())
+        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+        .compile()
+        .inspect(
+            codeInspector -> {
+              final ClassSubject clazz = codeInspector.clazz("kotlin.Metadata");
+              assertThat(clazz, isPresent());
+              assertThat(clazz.uniqueMethodWithName("pn"), isPresent());
+              assertThat(clazz.uniqueMethodWithName("d1"), not(isPresent()));
+              assertThat(clazz.uniqueMethodWithName("d2"), not(isPresent()));
+              assertThat(clazz.uniqueMethodWithName("bv"), not(isPresent()));
+            })
+        .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("", "Hello World!");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
index bb77f38..8be744d 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInRenamedTypeTest.java
@@ -101,7 +101,7 @@
         .addProgramFiles(inputJarMap.get(targetVersion))
         .addKeepRules(OBFUSCATE_RENAMED, KEEP_KEPT)
         .addKeepRules("-keep class **.Anno")
-        .addKeepRules("-keep class kotlin.Metadata")
+        .addKeepKotlinMetadata()
         .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
         .allowDiagnosticWarningMessages()
         .compile()
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
index 295f26a..0f80128 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteKeepTest.java
@@ -4,9 +4,6 @@
 
 package com.android.tools.r8.kotlin.metadata;
 
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
@@ -14,7 +11,6 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
 import com.android.tools.r8.shaking.ProguardKeepAttributes;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
 import java.util.Collection;
@@ -51,52 +47,12 @@
   }
 
   @Test
-  public void testR8KeepPartial() throws Exception {
-    // This test is a bit weird, since it shows that we can remove params from the kotlin.Metadata
-    // class, but still be able to fully read the kotlin.Metadata.
-    testForR8(parameters.getBackend())
-        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
-        .setMinApi(parameters.getApiLevel())
-        .addKeepRules("-keep class kotlin.Metadata { *** d1(); }")
-        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
-        .compile()
-        .inspect(
-            inspector -> {
-              inspect(inspector);
-              ClassSubject kotlinMetadataClass = inspector.clazz("kotlin.Metadata");
-              assertThat(kotlinMetadataClass, isPresent());
-              assertEquals(1, kotlinMetadataClass.allMethods().size());
-              assertNotNull(kotlinMetadataClass.getKmClass().getName());
-            });
-  }
-
-  @Test
-  public void testR8KeepPartialCooking() throws Exception {
-    // This test is a bit weird, since it shows that we can remove params from the kotlin.Metadata
-    // class, but still be able to fully read the kotlin.Metadata externally.
-    testForR8(parameters.getBackend())
-        .addProgramFiles(ToolHelper.getKotlinStdlibJar())
-        .setMinApi(parameters.getApiLevel())
-        .addKeepRules("-keep class kotlin.Metadata { *** d1(); }")
-        .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
-        .compile()
-        .inspect(
-            inspector -> {
-              inspect(inspector);
-              ClassSubject kotlinMetadataClass = inspector.clazz("kotlin.Metadata");
-              assertThat(kotlinMetadataClass, isPresent());
-              assertEquals(1, kotlinMetadataClass.allMethods().size());
-              assertNotNull(kotlinMetadataClass.getKmClass().getName());
-            });
-  }
-
-  @Test
   public void testR8KeepIf() throws Exception {
     testForR8(parameters.getBackend())
         .addProgramFiles(ToolHelper.getKotlinStdlibJar())
         .setMinApi(parameters.getApiLevel())
         .addKeepRules("-keep class kotlin.io.** { *; }")
-        .addKeepRules("-if class * { *** $VALUES; }", "-keep class kotlin.Metadata { *; }")
+        .addKeepRules("-if class *", "-keep class kotlin.Metadata { *; }")
         .addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
         .compile()
         .inspect(this::inspect);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java
new file mode 100644
index 0000000..10ebf6b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main.java
@@ -0,0 +1,81 @@
+// 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.kotlin.metadata.metadata_pruned_fields;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class Main implements Opcodes {
+
+  // The dump is generated from the code below, which cannot compile because of a missing
+  // reference to MethodsKt.
+  //
+  // public static void main(String[] args) {
+  //   final kotlin.Metadata annotation = MethodsKt.class.getAnnotation(kotlin.Metadata.class);
+  //   System.out.println(annotation.pn());
+  //   MethodsKt.staticMethod();
+  // }
+
+  public static byte[] dump() {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    MethodVisitor methodVisitor;
+
+    classWriter.visit(
+        V1_8,
+        ACC_PUBLIC | ACC_SUPER,
+        "com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Main",
+        null,
+        "java/lang/Object",
+        new String[] {});
+
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitLdcInsn(
+          Type.getType("Lcom/android/tools/r8/kotlin/metadata/metadata_pruned_fields/MethodsKt;"));
+      methodVisitor.visitLdcInsn(Type.getType("Lkotlin/Metadata;"));
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL,
+          "java/lang/Class",
+          "getAnnotation",
+          "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;",
+          false);
+      methodVisitor.visitTypeInsn(CHECKCAST, "kotlin/Metadata");
+      methodVisitor.visitVarInsn(ASTORE, 1);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitVarInsn(ALOAD, 1);
+      methodVisitor.visitMethodInsn(
+          INVOKEINTERFACE, "kotlin/Metadata", "pn", "()Ljava/lang/String;", true);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/MethodsKt",
+          "staticMethod",
+          "()V",
+          false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 2);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt
new file mode 100644
index 0000000..5f67164
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/metadata_pruned_fields/Methods.kt
@@ -0,0 +1,9 @@
+// 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.kotlin.metadata.metadata_pruned_fields
+
+fun staticMethod() {
+  println("Hello World!")
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index b3cbe0e..984d813 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -46,7 +46,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -871,7 +871,7 @@
             null,
             options,
             null,
-            GraphLense.getIdentityLense(),
+            GraphLens.getIdentityLens(),
             InitClassLens.getDefault(),
             NamingLens.getIdentityLens(),
             null);
diff --git a/src/test/java/com/android/tools/r8/rewrite/ServiceLoaderRewritingTest.java b/src/test/java/com/android/tools/r8/rewrite/ServiceLoaderRewritingTest.java
index 5e18734..cd7964f 100644
--- a/src/test/java/com/android/tools/r8/rewrite/ServiceLoaderRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/ServiceLoaderRewritingTest.java
@@ -135,6 +135,20 @@
     }
   }
 
+  public static class LoadWhereClassLoaderIsPhi {
+
+    public static void main(String[] args) {
+      ServiceLoader.load(
+              Service.class,
+              System.currentTimeMillis() > 0
+                  ? Thread.currentThread().getContextClassLoader()
+                  : null)
+          .iterator()
+          .next()
+          .print();
+    }
+  }
+
   @Parameterized.Parameters(name = "{0}")
   public static TestParametersCollection data() {
     return getTestParameters().withAllRuntimesAndApiLevels().build();
@@ -207,7 +221,7 @@
     testForR8(parameters.getBackend())
         .addInnerClasses(ServiceLoaderRewritingTest.class)
         .addKeepMainRule(MainWithTryCatchRunner.class)
-        .setMinApi(parameters.getRuntime())
+        .setMinApi(parameters.getApiLevel())
         .addDataEntryResources(
             DataEntryResource.fromBytes(
                 StringUtils.lines(ServiceImpl.class.getTypeName(), ServiceImpl2.class.getTypeName())
@@ -267,7 +281,7 @@
             .addInnerClasses(ServiceLoaderRewritingTest.class)
             .addKeepMainRule(EscapingRunner.class)
             .enableInliningAnnotations()
-            .setMinApi(parameters.getRuntime())
+            .setMinApi(parameters.getApiLevel())
             .noMinification()
             .addDataEntryResources(
                 DataEntryResource.fromBytes(
@@ -291,6 +305,37 @@
   }
 
   @Test
+  public void testDoNoRewriteWhenClassLoaderIsPhi()
+      throws IOException, CompilationFailedException, ExecutionException {
+    Path path = temp.newFile("out.zip").toPath();
+    CodeInspector inspector =
+        testForR8(parameters.getBackend())
+            .addInnerClasses(ServiceLoaderRewritingTest.class)
+            .addKeepMainRule(LoadWhereClassLoaderIsPhi.class)
+            .enableInliningAnnotations()
+            .setMinApi(parameters.getApiLevel())
+            .addDataEntryResources(
+                DataEntryResource.fromBytes(
+                    StringUtils.lines(ServiceImpl.class.getTypeName()).getBytes(),
+                    "META-INF/services/" + Service.class.getTypeName(),
+                    Origin.unknown()))
+            .compile()
+            .writeToZip(path)
+            .run(parameters.getRuntime(), LoadWhereClassLoaderIsPhi.class)
+            .assertSuccessWithOutputLines("Hello World!")
+            .inspector();
+
+    // Check that we have not rewritten the calls to ServiceLoader.load.
+    assertEquals(1, getServiceLoaderLoads(inspector, LoadWhereClassLoaderIsPhi.class));
+
+    // Check that we have not removed the service configuration from META-INF/services.
+    ZipFile zip = new ZipFile(path.toFile());
+    ClassSubject serviceImpl = inspector.clazz(ServiceImpl.class);
+    assertTrue(serviceImpl.isPresent());
+    assertNotNull(zip.getEntry("META-INF/services/" + serviceImpl.getFinalName()));
+  }
+
+  @Test
   public void testKeepAsOriginal()
       throws IOException, CompilationFailedException, ExecutionException {
     // The CL that changed behaviour after Nougat is:
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationWithWildcardTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationWithWildcardTest.java
new file mode 100644
index 0000000..3bb240a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationWithWildcardTest.java
@@ -0,0 +1,87 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.shaking.ifrule;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class IfOnAnnotationWithWildcardTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public IfOnAnnotationWithWildcardTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testR8WithTripleStars() throws Exception {
+    runTest(
+        "-if class ** { @"
+            + MyAnnotation.class.getTypeName()
+            + " *** *; }\n"
+            + "-keep class <1> { *; }");
+  }
+
+  @Test
+  public void testR8WithFields() throws Exception {
+    runTest(
+        "-if class ** { @"
+            + MyAnnotation.class.getTypeName()
+            + " <fields>; }\n"
+            + "-keep class <1> { *; }");
+  }
+
+  @Test
+  public void testR8WithAny() throws Exception {
+    runTest(
+        "-if class ** { @"
+            + MyAnnotation.class.getTypeName()
+            + " *; }\n"
+            + "-keep class <1> { *; }");
+  }
+
+  private void runTest(String ifRule) throws Exception {
+    testForR8Compat(parameters.getBackend())
+        .addProgramClasses(MyClass.class, MyAnnotation.class)
+        .setMinApi(parameters.getApiLevel())
+        .addKeepClassAndMembersRules(MyAnnotation.class)
+        .addKeepRules("-keep class * { @" + MyAnnotation.class.getTypeName() + " <fields>; }")
+        .addKeepRules(ifRule)
+        .addRunClasspathFiles(buildOnDexRuntime(parameters, Main.class))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("Hello World = 42");
+  }
+
+  public static class MyClass {
+    @MyAnnotation int x;
+    int y;
+
+    public void foo() {
+      System.out.println("Hello World = " + y);
+    }
+  }
+
+  public @interface MyAnnotation {}
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      final MyClass myClass = new MyClass();
+      myClass.y = 42;
+      myClass.foo();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfRuleWithKeepAllTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfRuleWithKeepAllTest.java
new file mode 100644
index 0000000..c4dd92f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfRuleWithKeepAllTest.java
@@ -0,0 +1,96 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.shaking.ifrule;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class IfRuleWithKeepAllTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public IfRuleWithKeepAllTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testR8WithKeepOnAllMembers() throws Exception {
+    runTest("-if class ** { *; }");
+  }
+
+  @Test
+  public void testR8WithKeepOnClass() throws Exception {
+    runTest("-if class **");
+  }
+
+  private void runTest(String precondition) throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(DirectlyKept.class, KeptByIf.class)
+        .addKeepClassAndMembersRules(DirectlyKept.class)
+        .addKeepRules(precondition + "\n-keep class " + KeptByIf.class.getTypeName() + " { *; }")
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            codeInspector -> {
+              assertThat(codeInspector.clazz(DirectlyKept.class), isPresent());
+              final ClassSubject keptByIf = codeInspector.clazz(KeptByIf.class);
+              assertThat(keptByIf, isPresent());
+              assertEquals(1, keptByIf.allMethods().size());
+            })
+        .addRunClasspathFiles(buildOnDexRuntime(parameters, Main.class))
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("Hello World!");
+  }
+
+  @KeptByIf()
+  public static class DirectlyKept {
+    final int foo = 42;
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface KeptByIf {
+    String key() default "";
+  }
+
+  public static class Main implements KeptByIf {
+
+    public static void main(String[] args) {
+      runKeptByIf(new Main());
+    }
+
+    public static void runKeptByIf(KeptByIf keptByIf) {
+      System.out.println(keptByIf.key());
+    }
+
+    @Override
+    public String key() {
+      return "Hello World!";
+    }
+
+    @Override
+    public Class<? extends Annotation> annotationType() {
+      return null;
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/Smali.java b/src/test/java/com/android/tools/r8/utils/Smali.java
index cb9ace0..2bb72cd 100644
--- a/src/test/java/com/android/tools/r8/utils/Smali.java
+++ b/src/test/java/com/android/tools/r8/utils/Smali.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.ApplicationWriter;
 import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.origin.Origin;
@@ -117,7 +117,7 @@
               null,
               options,
               null,
-              GraphLense.getIdentityLense(),
+              GraphLens.getIdentityLens(),
               InitClassLens.getDefault(),
               NamingLens.getIdentityLens(),
               null);
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 43ba1fb..1428897 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -38,8 +38,8 @@
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.retrace.RetraceBase;
-import com.android.tools.r8.retrace.RetraceBaseImpl;
+import com.android.tools.r8.retrace.RetraceApi;
+import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.BiMapContainer;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -481,7 +481,7 @@
     }
   }
 
-  public RetraceBase retrace() {
-    return RetraceBaseImpl.create(mapping);
+  public RetraceApi retrace() {
+    return Retracer.create(mapping);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
index bfcda02..ad9b5c2 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.retrace.RetraceBase;
+import com.android.tools.r8.retrace.RetraceApi;
 import com.android.tools.r8.retrace.RetraceMethodResult;
 
 public interface InstructionSubject {
@@ -129,18 +129,17 @@
     return lineNumberTable == null ? -1 : lineNumberTable.getLineForInstruction(this);
   }
 
-  default RetraceMethodResult retrace(RetraceBase retraceBase) {
+  default RetraceMethodResult retrace(RetraceApi retracer) {
     MethodSubject methodSubject = getMethodSubject();
     assert methodSubject.isPresent();
-    return retraceBase.retrace(methodSubject.asFoundMethodSubject().asMethodReference());
+    return retracer.retrace(methodSubject.asFoundMethodSubject().asMethodReference());
   }
 
-  default RetraceMethodResult retraceLinePosition(RetraceBase retraceBase) {
-    return retrace(retraceBase).narrowByLine(getLineNumber());
+  default RetraceMethodResult retraceLinePosition(RetraceApi retracer) {
+    return retrace(retracer).narrowByLine(getLineNumber());
   }
 
-  default RetraceMethodResult retracePcPosition(
-      RetraceBase retraceBase, MethodSubject methodSubject) {
-    return retrace(retraceBase).narrowByLine(getOffset(methodSubject).offset);
+  default RetraceMethodResult retracePcPosition(RetraceApi retracer, MethodSubject methodSubject) {
+    return retrace(retracer).narrowByLine(getOffset(methodSubject).offset);
   }
 }