Merge commit 'de30207755784daa2e1ededd0de58f26fbabec12' into dev-release
diff --git a/build.gradle b/build.gradle
index d157084..9981676 100644
--- a/build.gradle
+++ b/build.gradle
@@ -781,6 +781,7 @@
 
 def r8CreateTask(name, baseName, sources, includeSwissArmyKnife) {
     return tasks.create("r8Create${name}", Jar) {
+        entryCompression ZipEntryCompression.STORED
         dependsOn sources
         from consolidatedLicense.outputs.files
         from sources.collect { zipTree(it) }
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index 6893b8f..238f3ee 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -165,6 +165,16 @@
   ],
   "program_flags": [
     {
+      "api_level_below_or_equal": 32,
+      "api_level_greater_or_equal": 26,
+      "covariant_retarget_method": {
+        "java.time.chrono.IsoEra java.time.LocalDate#getEra()": "java.time.chrono.Era"
+      },
+      "amend_library_method": [
+        "public java.time.chrono.IsoEra java.time.LocalDate#getEra()"
+      ]
+    },
+    {
       "api_level_below_or_equal": 30,
       "retarget_method": {
         "java.time.Instant java.util.Calendar#toInstant()": "java.util.DesugarCalendar",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json b/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
index 730a294..b92af9f 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
@@ -1,14 +1,14 @@
 {
-  "configuration_format_version": 4,
+  "configuration_format_version": 5,
   "group_id" : "com.tools.android",
   "artifact_id" : "desugar_jdk_libs",
-  "version": "1.2.0-alpha01",
+  "version": "1.2.0",
   "required_compilation_api_level": 30,
   "synthesized_library_classes_package_prefix": "j$.",
   "support_all_callbacks_from_library": true,
   "common_flags": [
     {
-      "api_level_below_or_equal": 30,
+      "api_level_below_or_equal": 10000,
       "rewrite_prefix": {
         "java.time.": "j$.time.",
         "java.util.Desugar": "j$.util.Desugar"
@@ -37,20 +37,15 @@
       }
     },
     {
-      "api_level_below_or_equal": 28,
+      "api_level_below_or_equal": 23,
       "rewrite_prefix": {
-        "java.util.DoubleSummaryStatistics": "j$.util.DoubleSummaryStatistics",
-        "java.util.IntSummaryStatistics": "j$.util.IntSummaryStatistics",
-        "java.util.LongSummaryStatistics": "j$.util.LongSummaryStatistics",
-        "java.util.Optional": "j$.util.Optional",
-        "java.util.PrimitiveIterator": "j$.util.PrimitiveIterator",
-        "java.util.Spliterator": "j$.util.Spliterator",
-        "java.util.StringJoiner": "j$.util.StringJoiner",
-        "java.util.concurrent.ConcurrentHashMap": "j$.util.concurrent.ConcurrentHashMap",
-        "java.util.concurrent.ThreadLocalRandom": "j$.util.concurrent.ThreadLocalRandom",
-        "java.util.concurrent.atomic.DesugarAtomic": "j$.util.concurrent.atomic.DesugarAtomic",
-        "java.util.function.": "j$.util.function.",
-        "java.util.stream.": "j$.util.stream."
+        "java.util.concurrent.atomic.DesugarAtomic": "j$.util.concurrent.atomic.DesugarAtomic"
+      }
+    },
+    {
+      "api_level_below_or_equal": 23,
+      "rewrite_prefix": {
+        "java.util.function.": "j$.util.function."
       },
       "emulate_interface": {
         "java.lang.Iterable": "j$.lang.Iterable",
@@ -66,7 +61,22 @@
       },
       "dont_rewrite": [
         "java.util.Iterator#remove"
-      ],
+      ]
+    },
+    {
+      "api_level_below_or_equal": 10000,
+      "rewrite_prefix": {
+        "java.util.DoubleSummaryStatistics": "j$.util.DoubleSummaryStatistics",
+        "java.util.IntSummaryStatistics": "j$.util.IntSummaryStatistics",
+        "java.util.LongSummaryStatistics": "j$.util.LongSummaryStatistics",
+        "java.util.Optional": "j$.util.Optional",
+        "java.util.PrimitiveIterator": "j$.util.PrimitiveIterator",
+        "java.util.Spliterator": "j$.util.Spliterator",
+        "java.util.StringJoiner": "j$.util.StringJoiner",
+        "java.util.concurrent.ConcurrentHashMap": "j$.util.concurrent.ConcurrentHashMap",
+        "java.util.concurrent.ThreadLocalRandom": "j$.util.concurrent.ThreadLocalRandom",
+        "java.util.stream.": "j$.util.stream."
+      },
       "retarget_lib_member": {
         "java.util.Arrays#spliterator": "java.util.DesugarArrays",
         "java.util.Arrays#stream": "java.util.DesugarArrays",
@@ -137,7 +147,7 @@
   ],
   "program_flags": [
     {
-      "api_level_below_or_equal": 30,
+      "api_level_below_or_equal": 10000,
       "retarget_lib_member": {
         "java.util.TimeZone#getTimeZone": "java.util.DesugarTimeZone",
         "java.util.Calendar#toInstant": "java.util.DesugarCalendar",
@@ -167,9 +177,10 @@
   ],
   "library_flags": [
     {
-      "api_level_below_or_equal": 30,
+      "api_level_below_or_equal": 10000,
       "rewrite_prefix": {
         "j$.time.": "java.time.",
+        "java.lang.Desugar": "j$.lang.Desugar",
         "jdk.internal.": "j$.jdk.internal.",
         "sun.misc.Desugar": "j$.sun.misc.Desugar",
         "sun.security.action.": "j$.sun.security.action."
@@ -182,7 +193,7 @@
       }
     },
     {
-      "api_level_below_or_equal": 28,
+      "api_level_below_or_equal": 10000,
       "rewrite_prefix": {
         "java.util.AbstractList": "j$.util.AbstractList",
         "java.util.CollSer": "j$.util.CollSer",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_path.json b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
index a61df55..03ca930 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
@@ -268,6 +268,16 @@
   ],
   "program_flags": [
     {
+      "api_level_below_or_equal": 32,
+      "api_level_greater_or_equal": 26,
+      "covariant_retarget_method": {
+        "java.time.chrono.IsoEra java.time.LocalDate#getEra()": "java.time.chrono.Era"
+      },
+      "amend_library_method": [
+        "public java.time.chrono.IsoEra java.time.LocalDate#getEra()"
+      ]
+    },
+    {
       "api_level_below_or_equal": 30,
       "retarget_method": {
         "java.time.Instant java.util.Calendar#toInstant()": "java.util.DesugarCalendar",
diff --git a/src/main/java/com/android/tools/r8/CompilationMode.java b/src/main/java/com/android/tools/r8/CompilationMode.java
index fb02504..9288a35 100644
--- a/src/main/java/com/android/tools/r8/CompilationMode.java
+++ b/src/main/java/com/android/tools/r8/CompilationMode.java
@@ -9,5 +9,13 @@
   /** Preserves debugging information during compilation, eg, line-numbers and locals. */
   DEBUG,
   /** Strips debugging information that cannot affect stack traces. */
-  RELEASE
+  RELEASE;
+
+  public boolean isDebug() {
+    return this == DEBUG;
+  }
+
+  public boolean isRelease() {
+    return this == RELEASE;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 7cb5133..9393f4d 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -281,9 +281,8 @@
       Marker.checkCompatibleDesugaredLibrary(markers, options.reporter);
 
       InspectorImpl.runInspections(options.outputInspections, appView.appInfo().classes());
-      NamingLens namingLens = NamingLens.getIdentityLens();
-      namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
-      namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView, namingLens);
+      appView.setNamingLens(PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView));
+      appView.setNamingLens(RecordRewritingNamingLens.createRecordRewritingNamingLens(appView));
 
       if (options.isGeneratingDex()
           && hasDexResources
@@ -294,17 +293,15 @@
         // without iterating again the IR. We fall-back to writing one app with rewriting and
         // merging it with the other app in rewriteNonDexInputs.
         timing.begin("Rewrite non-dex inputs");
-        DexApplication app =
-            rewriteNonDexInputs(
-                appView, inputApp, options, executor, timing, appView.appInfo().app(), namingLens);
+        DexApplication app = rewriteNonDexInputs(appView, inputApp, executor, timing);
         timing.end();
         appView.setAppInfo(
             new AppInfo(
                 appView.appInfo().getSyntheticItems().commit(app),
                 appView.appInfo().getMainDexInfo()));
-        namingLens = NamingLens.getIdentityLens();
+        appView.setNamingLens(NamingLens.getIdentityLens());
       } else if (options.isGeneratingDex() && hasDexResources) {
-        namingLens = NamingLens.getIdentityLens();
+        appView.setNamingLens(NamingLens.getIdentityLens());
       }
 
       // Since tracing is not lens aware, this needs to be done prior to synthetic finalization
@@ -322,21 +319,16 @@
 
       HorizontalClassMerger.createForD8ClassMerging(appView).runIfNecessary(executor, timing);
 
-      new GenericSignatureRewriter(appView, namingLens)
-          .runForD8(appView.appInfo().classes(), executor);
-      new KotlinMetadataRewriter(appView, namingLens).runForD8(executor);
+      new GenericSignatureRewriter(appView).runForD8(appView.appInfo().classes(), executor);
+      new KotlinMetadataRewriter(appView).runForD8(executor);
 
       if (options.isGeneratingClassFiles()) {
-        new CfApplicationWriter(appView, marker, namingLens)
-            .write(options.getClassFileConsumer(), inputApp);
+        new CfApplicationWriter(appView, marker).write(options.getClassFileConsumer(), inputApp);
       } else {
         if (options.apiModelingOptions().enableStubbingOfClasses) {
           new ApiReferenceStubber(appView).run(executor);
         }
-        new ApplicationWriter(
-                appView,
-                marker == null ? null : ImmutableList.copyOf(markers),
-                namingLens)
+        new ApplicationWriter(appView, marker == null ? null : ImmutableList.copyOf(markers))
             .write(executor, inputApp);
       }
       options.printWarnings();
@@ -357,13 +349,7 @@
   }
 
   private static DexApplication rewriteNonDexInputs(
-      AppView<AppInfo> appView,
-      AndroidApp inputApp,
-      InternalOptions options,
-      ExecutorService executor,
-      Timing timing,
-      DexApplication app,
-      NamingLens desugaringLens)
+      AppView<AppInfo> appView, AndroidApp inputApp, ExecutorService executor, Timing timing)
       throws IOException, ExecutionException {
     // TODO(b/154575955): Remove the naming lens in D8.
     appView
@@ -376,33 +362,33 @@
                     + " dex the class file inputs and dex merging only dex files."));
     List<DexProgramClass> dexProgramClasses = new ArrayList<>();
     List<DexProgramClass> nonDexProgramClasses = new ArrayList<>();
-    for (DexProgramClass aClass : app.classes()) {
+    for (DexProgramClass aClass : appView.appInfo().classes()) {
       if (aClass.originatesFromDexResource()) {
         dexProgramClasses.add(aClass);
       } else {
         nonDexProgramClasses.add(aClass);
       }
     }
-    DexApplication cfApp = app.builder().replaceProgramClasses(nonDexProgramClasses).build();
+    DexApplication cfApp =
+        appView.app().builder().replaceProgramClasses(nonDexProgramClasses).build();
     appView.setAppInfo(
         new AppInfo(
             appView.appInfo().getSyntheticItems().commit(cfApp),
             appView.appInfo().getMainDexInfo()));
     ConvertedCfFiles convertedCfFiles = new ConvertedCfFiles();
-    new GenericSignatureRewriter(appView, desugaringLens)
-        .run(appView.appInfo().classes(), executor);
-    new KotlinMetadataRewriter(appView, desugaringLens).runForD8(executor);
+    new GenericSignatureRewriter(appView).run(appView.appInfo().classes(), executor);
+    new KotlinMetadataRewriter(appView).runForD8(executor);
     new ApplicationWriter(
             appView,
             null,
-            desugaringLens,
             convertedCfFiles)
         .write(executor);
     AndroidApp.Builder builder = AndroidApp.builder(inputApp);
     builder.getProgramResourceProviders().clear();
     builder.addProgramResourceProvider(convertedCfFiles);
     AndroidApp newAndroidApp = builder.build();
-    DexApplication newApp = new ApplicationReader(newAndroidApp, options, timing).read(executor);
+    DexApplication newApp =
+        new ApplicationReader(newAndroidApp, appView.options(), timing).read(executor);
     DexApplication.Builder<?> finalDexApp = newApp.builder();
     for (DexProgramClass dexProgramClass : dexProgramClasses) {
       finalDexApp.addProgramClass(dexProgramClass);
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index c158fc8..1495071 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -92,6 +92,7 @@
     private boolean minimalMainDex = false;
     private boolean skipDump = false;
     private final List<ProguardConfigurationSource> mainDexRules = new ArrayList<>();
+    private boolean enableMissingLibraryApiModeling = false;
 
     private Builder() {
       this(new DefaultD8DiagnosticsHandler());
@@ -322,6 +323,18 @@
       return self();
     }
 
+    /**
+     * Enable experimental/pre-release support for modeling missing library APIs.
+     *
+     * <p>This allows enabling the feature while it is still default disabled by the compiler. Once
+     * the feature is default enabled, calling this method will have no affect.
+     */
+    @Deprecated
+    public Builder setEnableExperimentalMissingLibraryApiModeling(boolean enable) {
+      this.enableMissingLibraryApiModeling = enable;
+      return self();
+    }
+
     @Override
     void validate() {
       if (isPrintHelp()) {
@@ -411,6 +424,7 @@
           getDumpInputFlags(),
           getMapIdProvider(),
           proguardMapConsumer,
+          enableMissingLibraryApiModeling,
           factory);
     }
   }
@@ -426,6 +440,7 @@
   private final boolean minimalMainDex;
   private final ImmutableList<ProguardConfigurationRule> mainDexKeepRules;
   private final StringConsumer proguardMapConsumer;
+  private final boolean enableMissingLibraryApiModeling;
   private final DexItemFactory factory;
 
   public static Builder builder() {
@@ -500,6 +515,7 @@
       DumpInputFlags dumpInputFlags,
       MapIdProvider mapIdProvider,
       StringConsumer proguardMapConsumer,
+      boolean enableMissingLibraryApiModeling,
       DexItemFactory factory) {
     super(
         inputApp,
@@ -529,6 +545,7 @@
     this.minimalMainDex = minimalMainDex;
     this.mainDexKeepRules = mainDexKeepRules;
     this.proguardMapConsumer = proguardMapConsumer;
+    this.enableMissingLibraryApiModeling = enableMissingLibraryApiModeling;
     this.factory = factory;
   }
 
@@ -545,6 +562,7 @@
     minimalMainDex = false;
     mainDexKeepRules = null;
     proguardMapConsumer = null;
+    enableMissingLibraryApiModeling = false;
     factory = null;
   }
 
@@ -602,6 +620,11 @@
     internal.synthesizedClassPrefix = synthesizedClassPrefix;
     internal.desugaredLibraryKeepRuleConsumer = desugaredLibraryKeepRuleConsumer;
 
+    if (!enableMissingLibraryApiModeling) {
+      internal.apiModelingOptions().disableApiCallerIdentification();
+      internal.apiModelingOptions().disableMissingApiModeling();
+    }
+
     // Default is to remove all javac generated assertion code when generating dex.
     assert internal.assertionsConfiguration == null;
     internal.assertionsConfiguration =
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index f6149c8..b8163c7 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -13,7 +13,6 @@
 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.naming.NamingLens;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ExceptionUtils;
@@ -103,11 +102,7 @@
         List<Marker> markers = appView.dexItemFactory().extractMarkers();
 
         assert !options.hasMethodsFilter();
-        ApplicationWriter writer =
-            new ApplicationWriter(
-                appView,
-                markers,
-                NamingLens.getIdentityLens());
+        ApplicationWriter writer = new ApplicationWriter(appView, markers);
         writer.write(executor);
         options.printWarnings();
       } catch (ExecutionException e) {
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index b90b736..43b8e9a 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -16,7 +16,6 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.MainDexInfo;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.ExceptionUtils;
@@ -113,7 +112,6 @@
           new ApplicationWriter(
                   appView,
                   markers,
-                  NamingLens.getIdentityLens(),
                   consumer)
               .write(executor);
           options.printWarnings();
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index 417fb63..27bdafd 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -38,7 +38,6 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.jar.CfApplicationWriter;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.AndroidApiLevel;
@@ -348,11 +347,7 @@
         AppView.createForD8(
             AppInfo.createInitialAppInfo(
                 builder.build(), GlobalSyntheticsStrategy.forNonSynthesizing()));
-    CfApplicationWriter writer =
-        new CfApplicationWriter(
-            appView,
-            options.getMarker(Tool.L8),
-            NamingLens.getIdentityLens());
+    CfApplicationWriter writer = new CfApplicationWriter(appView, options.getMarker(Tool.L8));
     ClassFileConsumer consumer =
         new ClassFileConsumer.ArchiveConsumer(
             lintFile(compilationApiLevel, minApiLevel, FileUtils.JAR_EXTENSION));
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 8a8769a..f8d95ab 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -15,7 +15,6 @@
 import com.android.tools.r8.ir.desugar.TypeRewriter;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAmender;
 import com.android.tools.r8.jar.CfApplicationWriter;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
 import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.origin.CommandLineOrigin;
@@ -143,10 +142,10 @@
 
       SyntheticFinalization.finalize(appView, executor);
 
-      NamingLens namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView);
-      new GenericSignatureRewriter(appView, namingLens).run(appView.appInfo().classes(), executor);
+      appView.setNamingLens(PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView));
+      new GenericSignatureRewriter(appView).run(appView.appInfo().classes(), executor);
 
-      new CfApplicationWriter(appView, options.getMarker(Tool.L8), namingLens)
+      new CfApplicationWriter(appView, options.getMarker(Tool.L8))
           .write(options.getClassFileConsumer());
       options.printWarnings();
     } catch (ExecutionException e) {
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 6c8f251..2b50253 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -213,6 +213,8 @@
 
     // Disable global optimizations.
     internal.disableGlobalOptimizations();
+    internal.apiModelingOptions().disableApiCallerIdentification();
+    internal.apiModelingOptions().disableMissingApiModeling();
 
     internal.setDumpInputFlags(getDumpInputFlags(), false);
     internal.dumpOptions = dumpOptions();
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 25a91e7..5d07a1c 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -63,7 +63,6 @@
 import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
 import com.android.tools.r8.kotlin.KotlinMetadataUtils;
 import com.android.tools.r8.naming.Minifier;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
 import com.android.tools.r8.naming.ProguardMapMinifier;
 import com.android.tools.r8.naming.RecordRewritingNamingLens;
@@ -208,29 +207,24 @@
   }
 
   static void writeApplication(
-      ExecutorService executorService,
-      AppView<?> appView,
-      NamingLens namingLens,
-      InternalOptions options,
-      AndroidApp inputApp)
+      AppView<?> appView, AndroidApp inputApp, ExecutorService executorService)
       throws ExecutionException {
+    InternalOptions options = appView.options();
     InspectorImpl.runInspections(options.outputInspections, appView.appInfo().classes());
     try {
       Marker marker = options.getMarker(Tool.R8);
       assert marker != null;
       // Get the markers from the input which are different from the one created for this
       // compilation
-      Set<Marker> markers = new HashSet<>(options.itemFactory.extractMarkers());
+      Set<Marker> markers = new HashSet<>(appView.dexItemFactory().extractMarkers());
       markers.remove(marker);
       if (options.isGeneratingClassFiles()) {
-        new CfApplicationWriter(appView, marker, namingLens)
-            .write(options.getClassFileConsumer(), inputApp);
+        new CfApplicationWriter(appView, marker).write(options.getClassFileConsumer(), inputApp);
       } else {
         new ApplicationWriter(
                 appView,
                 // Ensure that the marker for this compilation is the first in the list.
-                ImmutableList.<Marker>builder().add(marker).addAll(markers).build(),
-                namingLens)
+                ImmutableList.<Marker>builder().add(marker).addAll(markers).build())
             .write(executorService, inputApp);
       }
     } catch (IOException e) {
@@ -431,7 +425,7 @@
               annotationRemoverBuilder
                   .build(appViewWithLiveness, removedClasses);
           annotationRemover.ensureValid().run(executorService);
-          new GenericSignatureRewriter(appView, NamingLens.getIdentityLens(), genericContextBuilder)
+          new GenericSignatureRewriter(appView, genericContextBuilder)
               .run(appView.appInfo().classes(), executorService);
 
           assert appView.checkForTesting(() -> allReferencesAssignedApiLevel(appViewWithLiveness));
@@ -650,8 +644,7 @@
             AnnotationRemover.builder(Mode.FINAL_TREE_SHAKING)
                 .build(appView.withLiveness(), removedClasses)
                 .run(executorService);
-            new GenericSignatureRewriter(
-                    appView, NamingLens.getIdentityLens(), genericContextBuilder)
+            new GenericSignatureRewriter(appView, genericContextBuilder)
                 .run(appView.appInfo().classes(), executorService);
             assert appView.checkForTesting(
                     () ->
@@ -761,19 +754,17 @@
                   : null);
 
       // Perform minification.
-      NamingLens namingLens;
       if (options.getProguardConfiguration().hasApplyMappingFile()) {
         timing.begin("apply-mapping");
-        namingLens = new ProguardMapMinifier(appView.withLiveness()).run(executorService, timing);
+        appView.setNamingLens(
+            new ProguardMapMinifier(appView.withLiveness()).run(executorService, timing));
         timing.end();
         // Clear the applymapping data
         appView.clearApplyMappingSeedMapper();
       } else if (options.isMinifying()) {
         timing.begin("Minification");
-        namingLens = new Minifier(appView.withLiveness()).run(executorService, timing);
+        appView.setNamingLens(new Minifier(appView.withLiveness()).run(executorService, timing));
         timing.end();
-      } else {
-        namingLens = NamingLens.getIdentityLens();
       }
 
       assert verifyMovedMethodsHaveOriginalMethodPosition(appView, getDirectApp(appView));
@@ -808,16 +799,16 @@
         options.syntheticProguardRulesConsumer.accept(synthesizedProguardRules);
       }
 
-      namingLens = PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView, namingLens);
-      namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView, namingLens);
+      appView.setNamingLens(PrefixRewritingNamingLens.createPrefixRewritingNamingLens(appView));
+      appView.setNamingLens(RecordRewritingNamingLens.createRecordRewritingNamingLens(appView));
 
       new ApiReferenceStubber(appView).run(executorService);
 
       timing.begin("MinifyKotlinMetadata");
-      new KotlinMetadataRewriter(appView, namingLens).runForR8(executorService);
+      new KotlinMetadataRewriter(appView).runForR8(executorService);
       timing.end();
 
-      new GenericSignatureRewriter(appView, namingLens, genericContextBuilderBeforeFinalMerging)
+      new GenericSignatureRewriter(appView, genericContextBuilderBeforeFinalMerging)
           .run(appView.appInfo().classes(), executorService);
 
       assert appView.checkForTesting(
@@ -829,15 +820,10 @@
                           .isValid())
           : "Could not validate generic signatures";
 
-      new DesugaredLibraryKeepRuleGenerator(appView, namingLens).runIfNecessary(timing);
+      new DesugaredLibraryKeepRuleGenerator(appView).runIfNecessary(timing);
 
       // Generate the resulting application resources.
-      writeApplication(
-          executorService,
-          appView,
-          namingLens,
-          options,
-          inputApp);
+      writeApplication(appView, inputApp, executorService);
 
       assert appView.getDontWarnConfiguration().validate(options);
 
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 4e3e190..4e7ca32 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -114,6 +114,7 @@
     private final List<FeatureSplit> featureSplits = new ArrayList<>();
     private String synthesizedClassPrefix = "";
     private boolean skipDump = false;
+    private boolean enableMissingLibraryApiModeling = false;
 
     private boolean allowTestProguardOptions =
         System.getProperty("com.android.tools.r8.allowTestProguardOptions") != null;
@@ -431,6 +432,18 @@
       return self();
     }
 
+    /**
+     * Enable experimental/pre-release support for modeling missing library APIs.
+     *
+     * <p>This allows enabling the feature while it is still default disabled by the compiler. Once
+     * the feature is default enabled, calling this method will have no affect.
+     */
+    @Deprecated
+    public Builder setEnableExperimentalMissingLibraryApiModeling(boolean enable) {
+      this.enableMissingLibraryApiModeling = enable;
+      return self();
+    }
+
     @Override
     protected InternalProgramOutputPathConsumer createProgramOutputConsumer(
         Path path,
@@ -619,7 +632,8 @@
               getThreadCount(),
               getDumpInputFlags(),
               getMapIdProvider(),
-              getSourceFileProvider());
+              getSourceFileProvider(),
+              enableMissingLibraryApiModeling);
 
       if (inputDependencyGraphConsumer != null) {
         inputDependencyGraphConsumer.finished();
@@ -704,6 +718,7 @@
   private final FeatureSplitConfiguration featureSplitConfiguration;
   private final String synthesizedClassPrefix;
   private final boolean skipDump;
+  private final boolean enableMissingLibraryApiModeling;
 
   /** Get a new {@link R8Command.Builder}. */
   public static Builder builder() {
@@ -792,7 +807,8 @@
       int threadCount,
       DumpInputFlags dumpInputFlags,
       MapIdProvider mapIdProvider,
-      SourceFileProvider sourceFileProvider) {
+      SourceFileProvider sourceFileProvider,
+      boolean enableMissingLibraryApiModeling) {
     super(
         inputApp,
         mode,
@@ -831,6 +847,7 @@
     this.featureSplitConfiguration = featureSplitConfiguration;
     this.synthesizedClassPrefix = synthesizedClassPrefix;
     this.skipDump = skipDump;
+    this.enableMissingLibraryApiModeling = enableMissingLibraryApiModeling;
   }
 
   private R8Command(boolean printHelp, boolean printVersion) {
@@ -854,6 +871,7 @@
     featureSplitConfiguration = null;
     synthesizedClassPrefix = null;
     skipDump = false;
+    enableMissingLibraryApiModeling = false;
   }
 
   public DexItemFactory getDexItemFactory() {
@@ -960,6 +978,10 @@
 
     internal.outputInspections = InspectorImpl.wrapInspections(getOutputInspections());
 
+    if (!enableMissingLibraryApiModeling) {
+      internal.apiModelingOptions().disableMissingApiModeling();
+    }
+
     // Default is to remove all javac generated assertion code when generating dex.
     assert internal.assertionsConfiguration == null;
     AssertionsConfiguration.Builder builder = AssertionsConfiguration.builder(getReporter());
diff --git a/src/main/java/com/android/tools/r8/ResourceShrinker.java b/src/main/java/com/android/tools/r8/ResourceShrinker.java
index bf40d89..b5ab2b6 100644
--- a/src/main/java/com/android/tools/r8/ResourceShrinker.java
+++ b/src/main/java/com/android/tools/r8/ResourceShrinker.java
@@ -3,38 +3,38 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-import com.android.tools.r8.code.Const;
-import com.android.tools.r8.code.Const16;
-import com.android.tools.r8.code.Const4;
-import com.android.tools.r8.code.ConstHigh16;
-import com.android.tools.r8.code.ConstString;
-import com.android.tools.r8.code.ConstStringJumbo;
-import com.android.tools.r8.code.ConstWide16;
-import com.android.tools.r8.code.ConstWide32;
-import com.android.tools.r8.code.FillArrayData;
-import com.android.tools.r8.code.FillArrayDataPayload;
-import com.android.tools.r8.code.Format35c;
-import com.android.tools.r8.code.Format3rc;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.code.InvokeDirect;
-import com.android.tools.r8.code.InvokeDirectRange;
-import com.android.tools.r8.code.InvokeInterface;
-import com.android.tools.r8.code.InvokeInterfaceRange;
-import com.android.tools.r8.code.InvokeStatic;
-import com.android.tools.r8.code.InvokeStaticRange;
-import com.android.tools.r8.code.InvokeSuper;
-import com.android.tools.r8.code.InvokeSuperRange;
-import com.android.tools.r8.code.InvokeVirtual;
-import com.android.tools.r8.code.InvokeVirtualRange;
-import com.android.tools.r8.code.NewArray;
-import com.android.tools.r8.code.Sget;
-import com.android.tools.r8.code.SgetBoolean;
-import com.android.tools.r8.code.SgetByte;
-import com.android.tools.r8.code.SgetChar;
-import com.android.tools.r8.code.SgetObject;
-import com.android.tools.r8.code.SgetShort;
-import com.android.tools.r8.code.SgetWide;
 import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.dex.code.DexConst;
+import com.android.tools.r8.dex.code.DexConst16;
+import com.android.tools.r8.dex.code.DexConst4;
+import com.android.tools.r8.dex.code.DexConstHigh16;
+import com.android.tools.r8.dex.code.DexConstString;
+import com.android.tools.r8.dex.code.DexConstStringJumbo;
+import com.android.tools.r8.dex.code.DexConstWide16;
+import com.android.tools.r8.dex.code.DexConstWide32;
+import com.android.tools.r8.dex.code.DexFillArrayData;
+import com.android.tools.r8.dex.code.DexFillArrayDataPayload;
+import com.android.tools.r8.dex.code.DexFormat35c;
+import com.android.tools.r8.dex.code.DexFormat3rc;
+import com.android.tools.r8.dex.code.DexInstruction;
+import com.android.tools.r8.dex.code.DexInvokeDirect;
+import com.android.tools.r8.dex.code.DexInvokeDirectRange;
+import com.android.tools.r8.dex.code.DexInvokeInterface;
+import com.android.tools.r8.dex.code.DexInvokeInterfaceRange;
+import com.android.tools.r8.dex.code.DexInvokeStatic;
+import com.android.tools.r8.dex.code.DexInvokeStaticRange;
+import com.android.tools.r8.dex.code.DexInvokeSuper;
+import com.android.tools.r8.dex.code.DexInvokeSuperRange;
+import com.android.tools.r8.dex.code.DexInvokeVirtual;
+import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
+import com.android.tools.r8.dex.code.DexNewArray;
+import com.android.tools.r8.dex.code.DexSget;
+import com.android.tools.r8.dex.code.DexSgetBoolean;
+import com.android.tools.r8.dex.code.DexSgetByte;
+import com.android.tools.r8.dex.code.DexSgetChar;
+import com.android.tools.r8.dex.code.DexSgetObject;
+import com.android.tools.r8.dex.code.DexSgetShort;
+import com.android.tools.r8.dex.code.DexSgetWide;
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
@@ -219,12 +219,12 @@
         final Set<Integer> methodIntArrayPayloadOffsets = Sets.newHashSet();
         // First we collect payloads, and then we process them because payload can be before the
         // fill-array-data instruction referencing it.
-        final List<FillArrayDataPayload> payloads = Lists.newArrayList();
+        final List<DexFillArrayDataPayload> payloads = Lists.newArrayList();
 
-        Instruction[] instructions = implementation.asDexCode().instructions;
+        DexInstruction[] instructions = implementation.asDexCode().instructions;
         int current = 0;
         while (current < instructions.length) {
-          Instruction instruction = instructions[current];
+          DexInstruction instruction = instructions[current];
           if (isIntConstInstruction(instruction)) {
             processIntConstInstruction(instruction);
           } else if (isStringConstInstruction(instruction)) {
@@ -235,15 +235,15 @@
             processInvokeInstruction(instruction);
           } else if (isInvokeRangeInstruction(instruction)) {
             processInvokeRangeInstruction(instruction);
-          } else if (instruction instanceof FillArrayData) {
+          } else if (instruction instanceof DexFillArrayData) {
             processFillArray(instructions, current, methodIntArrayPayloadOffsets);
-          } else if (instruction instanceof FillArrayDataPayload) {
-            payloads.add((FillArrayDataPayload) instruction);
+          } else if (instruction instanceof DexFillArrayDataPayload) {
+            payloads.add((DexFillArrayDataPayload) instruction);
           }
           current++;
         }
 
-        for (FillArrayDataPayload payload : payloads) {
+        for (DexFillArrayDataPayload payload : payloads) {
           if (isIntArrayPayload(payload, methodIntArrayPayloadOffsets)) {
             processIntArrayPayload(payload);
           }
@@ -272,8 +272,8 @@
               });
     }
 
-    private void processIntArrayPayload(Instruction instruction) {
-      FillArrayDataPayload payload = (FillArrayDataPayload) instruction;
+    private void processIntArrayPayload(DexInstruction instruction) {
+      DexFillArrayDataPayload payload = (DexFillArrayDataPayload) instruction;
 
       for (int i = 0; i < payload.data.length / 2; i++) {
         int intValue = payload.data[2 * i + 1] << 16 | payload.data[2 * i];
@@ -282,20 +282,20 @@
     }
 
     private boolean isIntArrayPayload(
-        Instruction instruction, Set<Integer> methodIntArrayPayloadOffsets) {
-      if (!(instruction instanceof FillArrayDataPayload)) {
+        DexInstruction instruction, Set<Integer> methodIntArrayPayloadOffsets) {
+      if (!(instruction instanceof DexFillArrayDataPayload)) {
         return false;
       }
 
-      FillArrayDataPayload payload = (FillArrayDataPayload) instruction;
+      DexFillArrayDataPayload payload = (DexFillArrayDataPayload) instruction;
       return methodIntArrayPayloadOffsets.contains(payload.getOffset());
     }
 
     private void processFillArray(
-        Instruction[] instructions, int current, Set<Integer> methodIntArrayPayloadOffsets) {
-      FillArrayData fillArrayData = (FillArrayData) instructions[current];
-      if (current > 0 && instructions[current - 1] instanceof NewArray) {
-        NewArray newArray = (NewArray) instructions[current - 1];
+        DexInstruction[] instructions, int current, Set<Integer> methodIntArrayPayloadOffsets) {
+      DexFillArrayData fillArrayData = (DexFillArrayData) instructions[current];
+      if (current > 0 && instructions[current - 1] instanceof DexNewArray) {
+        DexNewArray newArray = (DexNewArray) instructions[current - 1];
         if (!Objects.equals(newArray.getType().descriptor.toString(), "[I")) {
           return;
         }
@@ -334,17 +334,17 @@
       }
     }
 
-    private boolean isIntConstInstruction(Instruction instruction) {
+    private boolean isIntConstInstruction(DexInstruction instruction) {
       int opcode = instruction.getOpcode();
-      return opcode == Const4.OPCODE
-          || opcode == Const16.OPCODE
-          || opcode == Const.OPCODE
-          || opcode == ConstWide32.OPCODE
-          || opcode == ConstHigh16.OPCODE
-          || opcode == ConstWide16.OPCODE;
+      return opcode == DexConst4.OPCODE
+          || opcode == DexConst16.OPCODE
+          || opcode == DexConst.OPCODE
+          || opcode == DexConstWide32.OPCODE
+          || opcode == DexConstHigh16.OPCODE
+          || opcode == DexConstWide16.OPCODE;
     }
 
-    private void processIntConstInstruction(Instruction instruction) {
+    private void processIntConstInstruction(DexInstruction instruction) {
       assert isIntConstInstruction(instruction);
 
       int constantValue;
@@ -365,20 +365,20 @@
       callback.referencedInt(constantValue);
     }
 
-    private boolean isStringConstInstruction(Instruction instruction) {
+    private boolean isStringConstInstruction(DexInstruction instruction) {
       int opcode = instruction.getOpcode();
-      return opcode == ConstString.OPCODE || opcode == ConstStringJumbo.OPCODE;
+      return opcode == DexConstString.OPCODE || opcode == DexConstStringJumbo.OPCODE;
     }
 
-    private void processStringConstantInstruction(Instruction instruction) {
+    private void processStringConstantInstruction(DexInstruction instruction) {
       assert isStringConstInstruction(instruction);
 
       String constantValue;
-      if (instruction instanceof ConstString) {
-        ConstString constString = (ConstString) instruction;
+      if (instruction instanceof DexConstString) {
+        DexConstString constString = (DexConstString) instruction;
         constantValue = constString.getString().toString();
-      } else if (instruction instanceof ConstStringJumbo) {
-        ConstStringJumbo constStringJumbo = (ConstStringJumbo) instruction;
+      } else if (instruction instanceof DexConstStringJumbo) {
+        DexConstStringJumbo constStringJumbo = (DexConstStringJumbo) instruction;
         constantValue = constStringJumbo.getString().toString();
       } else {
         throw new AssertionError("Not a string constant instruction.");
@@ -387,41 +387,41 @@
       callback.referencedString(constantValue);
     }
 
-    private boolean isGetStatic(Instruction instruction) {
+    private boolean isGetStatic(DexInstruction instruction) {
       int opcode = instruction.getOpcode();
-      return opcode == Sget.OPCODE
-          || opcode == SgetBoolean.OPCODE
-          || opcode == SgetByte.OPCODE
-          || opcode == SgetChar.OPCODE
-          || opcode == SgetObject.OPCODE
-          || opcode == SgetShort.OPCODE
-          || opcode == SgetWide.OPCODE;
+      return opcode == DexSget.OPCODE
+          || opcode == DexSgetBoolean.OPCODE
+          || opcode == DexSgetByte.OPCODE
+          || opcode == DexSgetChar.OPCODE
+          || opcode == DexSgetObject.OPCODE
+          || opcode == DexSgetShort.OPCODE
+          || opcode == DexSgetWide.OPCODE;
     }
 
-    private void processGetStatic(Instruction instruction) {
+    private void processGetStatic(DexInstruction instruction) {
       assert isGetStatic(instruction);
 
       DexField field;
-      if (instruction instanceof Sget) {
-        Sget sget = (Sget) instruction;
+      if (instruction instanceof DexSget) {
+        DexSget sget = (DexSget) instruction;
         field = sget.getField();
-      } else if (instruction instanceof SgetBoolean) {
-        SgetBoolean sgetBoolean = (SgetBoolean) instruction;
+      } else if (instruction instanceof DexSgetBoolean) {
+        DexSgetBoolean sgetBoolean = (DexSgetBoolean) instruction;
         field = sgetBoolean.getField();
-      } else if (instruction instanceof SgetByte) {
-        SgetByte sgetByte = (SgetByte) instruction;
+      } else if (instruction instanceof DexSgetByte) {
+        DexSgetByte sgetByte = (DexSgetByte) instruction;
         field = sgetByte.getField();
-      } else if (instruction instanceof SgetChar) {
-        SgetChar sgetChar = (SgetChar) instruction;
+      } else if (instruction instanceof DexSgetChar) {
+        DexSgetChar sgetChar = (DexSgetChar) instruction;
         field = sgetChar.getField();
-      } else if (instruction instanceof SgetObject) {
-        SgetObject sgetObject = (SgetObject) instruction;
+      } else if (instruction instanceof DexSgetObject) {
+        DexSgetObject sgetObject = (DexSgetObject) instruction;
         field = sgetObject.getField();
-      } else if (instruction instanceof SgetShort) {
-        SgetShort sgetShort = (SgetShort) instruction;
+      } else if (instruction instanceof DexSgetShort) {
+        DexSgetShort sgetShort = (DexSgetShort) instruction;
         field = sgetShort.getField();
-      } else if (instruction instanceof SgetWide) {
-        SgetWide sgetWide = (SgetWide) instruction;
+      } else if (instruction instanceof DexSgetWide) {
+        DexSgetWide sgetWide = (DexSgetWide) instruction;
         field = sgetWide.getField();
       } else {
         throw new AssertionError("Not a get static instruction");
@@ -430,19 +430,19 @@
       callback.referencedStaticField(field.holder.getInternalName(), field.name.toString());
     }
 
-    private boolean isInvokeInstruction(Instruction instruction) {
+    private boolean isInvokeInstruction(DexInstruction instruction) {
       int opcode = instruction.getOpcode();
-      return opcode == InvokeVirtual.OPCODE
-          || opcode == InvokeSuper.OPCODE
-          || opcode == InvokeDirect.OPCODE
-          || opcode == InvokeStatic.OPCODE
-          || opcode == InvokeInterface.OPCODE;
+      return opcode == DexInvokeVirtual.OPCODE
+          || opcode == DexInvokeSuper.OPCODE
+          || opcode == DexInvokeDirect.OPCODE
+          || opcode == DexInvokeStatic.OPCODE
+          || opcode == DexInvokeInterface.OPCODE;
     }
 
-    private void processInvokeInstruction(Instruction instruction) {
+    private void processInvokeInstruction(DexInstruction instruction) {
       assert isInvokeInstruction(instruction);
 
-      Format35c ins35c = (Format35c) instruction;
+      DexFormat35c ins35c = (DexFormat35c) instruction;
       DexMethod method = (DexMethod) ins35c.BBBB;
 
       callback.referencedMethod(
@@ -451,19 +451,19 @@
           method.proto.toDescriptorString());
     }
 
-    private boolean isInvokeRangeInstruction(Instruction instruction) {
+    private boolean isInvokeRangeInstruction(DexInstruction instruction) {
       int opcode = instruction.getOpcode();
-      return opcode == InvokeVirtualRange.OPCODE
-          || opcode == InvokeSuperRange.OPCODE
-          || opcode == InvokeDirectRange.OPCODE
-          || opcode == InvokeStaticRange.OPCODE
-          || opcode == InvokeInterfaceRange.OPCODE;
+      return opcode == DexInvokeVirtualRange.OPCODE
+          || opcode == DexInvokeSuperRange.OPCODE
+          || opcode == DexInvokeDirectRange.OPCODE
+          || opcode == DexInvokeStaticRange.OPCODE
+          || opcode == DexInvokeInterfaceRange.OPCODE;
     }
 
-    private void processInvokeRangeInstruction(Instruction instruction) {
+    private void processInvokeRangeInstruction(DexInstruction instruction) {
       assert isInvokeRangeInstruction(instruction);
 
-      Format3rc ins3rc = (Format3rc) instruction;
+      DexFormat3rc ins3rc = (DexFormat3rc) instruction;
       DexMethod method = (DexMethod) ins3rc.BBBB;
 
       callback.referencedMethod(
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiDataAccess.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiDataAccess.java
index 37acc4d..0539dcf 100644
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiDataAccess.java
+++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiDataAccess.java
@@ -5,15 +5,29 @@
 package com.android.tools.r8.androidapi;
 
 import static com.android.tools.r8.lightir.ByteUtils.unsetBitAtIndex;
+import static com.android.tools.r8.utils.ZipUtils.getOffsetOfResourceInZip;
 
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.dex.CompatByteBuffer;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.utils.ExceptionDiagnostic;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.StringDiagnostic;
 import com.google.common.io.ByteStreams;
 import com.google.common.primitives.Ints;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.JarURLConnection;
 import java.net.URL;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
 import java.util.function.BiPredicate;
 
 /**
@@ -30,9 +44,13 @@
   private static final int PAYLOAD_OFFSET_WITH_LENGTH = 4 + 2;
   private static final byte ZERO_BYTE = (byte) 0;
 
+  public static boolean isApiDatabaseEntry(String entry) {
+    return RESOURCE_NAME.equals(entry);
+  }
+
   private static class PositionAndLength {
 
-    private static PositionAndLength EMPTY = new PositionAndLength(0, 0);
+    private static final PositionAndLength EMPTY = new PositionAndLength(0, 0);
 
     private final int position;
     private final int length;
@@ -46,7 +64,7 @@
       if (position == 0 && length == 0) {
         return EMPTY;
       }
-      if ((position < 0 && length != 0) || (position > 0 && length == 0)) {
+      if ((position < 0 && length > 0) || (position > 0 && length == 0)) {
         assert false : "Unexpected position and length";
         return EMPTY;
       }
@@ -70,6 +88,61 @@
     }
   }
 
+  public static AndroidApiDataAccess create(
+      InternalOptions options, DiagnosticsHandler diagnosticsHandler) {
+    URL resource = AndroidApiDataAccess.class.getClassLoader().getResource(RESOURCE_NAME);
+    if (resource == null) {
+      throw new CompilationError("Could not find the api database at " + RESOURCE_NAME);
+    }
+    if (options.apiModelingOptions().useMemoryMappedByteBuffer) {
+      try {
+        // The resource is encoded as protocol and a path, where we should have one of either:
+        // protocol: file, path: <path-to-file>
+        // protocol: jar, path: file:<path-to-jar>!/<resource-name-in-jar>
+        if (resource.getProtocol().equals("file")) {
+          return getDataAccessFromPathAndOffset(Paths.get(resource.toURI()), 0);
+        } else if (resource.getProtocol().equals("jar") && resource.getPath().startsWith("file:")) {
+          // The path is on form 'file:<path-to-jar>!/<resource-name-in-jar>
+          JarURLConnection jarUrl = (JarURLConnection) resource.openConnection();
+          File jarFile = new File(jarUrl.getJarFileURL().getFile());
+          String databaseEntry = jarUrl.getEntryName();
+          long offsetInJar = getOffsetOfResourceInZip(jarFile, databaseEntry);
+          if (offsetInJar > 0) {
+            return getDataAccessFromPathAndOffset(jarFile.toPath(), offsetInJar);
+          }
+        }
+        // On older DEX platforms creating a new byte channel may fail:
+        // Error: java.lang.NoSuchMethodError: No static method newByteChannel(Ljava/nio/file/Path;
+        // [Ljava/nio/file/OpenOption;)Ljava/nio/channels/SeekableByteChannel;
+        // in class Ljava/nio/file/Files
+      } catch (Exception | NoSuchMethodError e) {
+        diagnosticsHandler.warning(new ExceptionDiagnostic(e));
+      }
+      diagnosticsHandler.warning(
+          new StringDiagnostic(
+              "Unable to use a memory mapped byte buffer to access the api database. Falling back"
+                  + " to loading the database into program which requires more memory"));
+    }
+    try (InputStream apiInputStream =
+        AndroidApiDataAccess.class.getClassLoader().getResourceAsStream(RESOURCE_NAME)) {
+      if (apiInputStream == null) {
+        throw new CompilationError("Could not find the api database at: " + resource);
+      }
+      return new AndroidApiDataAccessInMemory(ByteStreams.toByteArray(apiInputStream));
+    } catch (IOException e) {
+      throw new CompilationError("Could not read the api database.", e);
+    }
+  }
+
+  private static AndroidApiDataAccessByteMapped getDataAccessFromPathAndOffset(
+      Path path, long offset) throws IOException {
+    FileChannel fileChannel = (FileChannel) Files.newByteChannel(path, StandardOpenOption.READ);
+    MappedByteBuffer mappedByteBuffer =
+        fileChannel.map(FileChannel.MapMode.READ_ONLY, offset, fileChannel.size() - offset);
+    // Ensure that we can run on JDK 8 by using the CompatByteBuffer.
+    return new AndroidApiDataAccessByteMapped(new CompatByteBuffer(mappedByteBuffer));
+  }
+
   public static int entrySizeInBitsForConstantPoolMap() {
     return ENTRY_SIZE_IN_BITS_FOR_CONSTANT_POOL_MAP;
   }
@@ -102,25 +175,44 @@
     return PAYLOAD_OFFSET_WITH_LENGTH;
   }
 
-  static int constantPoolOffset() {
+  /** The start of the constant pool */
+  public static int constantPoolOffset() {
     return 4;
   }
 
-  static int constantPoolHashMapOffset(int constantPoolSize) {
+  /** The start of the constant pool hash map. */
+  public static int constantPoolHashMapOffset(int constantPoolSize) {
     return (constantPoolSize * constantPoolEntrySize()) + constantPoolOffset();
   }
 
-  static int apiLevelHashMapOffset(int constantPoolSize) {
+  /** The start of the api level hash map. */
+  public static int apiLevelHashMapOffset(int constantPoolSize) {
     int constantPoolHashMapSize =
         (1 << entrySizeInBitsForConstantPoolMap()) * constantPoolMapEntrySize();
     return constantPoolHashMapOffset(constantPoolSize) + constantPoolHashMapSize;
   }
 
-  static int payloadOffset(int constantPoolSize) {
+  /** The start of the payload section. */
+  public static int payloadOffset(int constantPoolSize) {
     int apiLevelSize = (1 << entrySizeInBitsForApiLevelMap()) * apiLevelHashMapEntrySize();
     return apiLevelHashMapOffset(constantPoolSize) + apiLevelSize;
   }
 
+  /** The actual byte index of the constant pool index. */
+  public int constantPoolIndexOffset(int index) {
+    return constantPoolOffset() + (index * constantPoolEntrySize());
+  }
+
+  /** The actual byte index of the constant pool hash key. */
+  protected int constantPoolHashMapIndexOffset(int hash) {
+    return constantPoolHashMapOffset(getConstantPoolSize()) + (hash * constantPoolMapEntrySize());
+  }
+
+  /** The actual byte index of the api hash key. */
+  protected int apiLevelHashMapIndexOffset(int hash) {
+    return apiLevelHashMapOffset(getConstantPoolSize()) + (hash * apiLevelHashMapEntrySize());
+  }
+
   static int readIntFromOffset(byte[] data, int offset) {
     return Ints.fromBytes(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
   }
@@ -133,11 +225,7 @@
 
   abstract int readConstantPoolSize();
 
-  abstract PositionAndLength getConstantPoolPayloadOffset(int index);
-
-  abstract PositionAndLength getConstantPoolHashMapPayloadOffset(int hash);
-
-  abstract PositionAndLength getApiLevelHashMapPayloadOffset(int hash);
+  abstract PositionAndLength readPositionAndLength(int offset);
 
   abstract boolean payloadHasConstantPoolValue(int offset, int length, byte[] value);
 
@@ -169,7 +257,7 @@
 
   public int getConstantPoolIndex(DexString string) {
     PositionAndLength constantPoolIndex =
-        getConstantPoolHashMapPayloadOffset(constantPoolHash(string));
+        readPositionAndLength(constantPoolHashMapIndexOffset(constantPoolHash(string)));
     if (constantPoolIndex.isEmpty()) {
       return -1;
     }
@@ -183,56 +271,108 @@
     } else {
       assert length > 0;
       return payloadContainsConstantPoolValue(
-          position, length, string.content, this::isConstantPoolEntry);
+          payloadOffset(getConstantPoolSize()) + position,
+          length,
+          string.content,
+          this::isConstantPoolEntry);
     }
     return -1;
   }
 
   public boolean isConstantPoolEntry(int index, byte[] value) {
-    PositionAndLength constantPoolPayloadOffset = getConstantPoolPayloadOffset(index);
+    PositionAndLength constantPoolPayloadOffset =
+        readPositionAndLength(constantPoolIndexOffset(index));
     if (constantPoolPayloadOffset.isEmpty()) {
       return false;
     }
+    if (value.length != constantPoolPayloadOffset.getLength()) {
+      return false;
+    }
     return payloadHasConstantPoolValue(
-        constantPoolPayloadOffset.getPosition(), constantPoolPayloadOffset.getLength(), value);
+        payloadOffset(getConstantPoolSize()) + constantPoolPayloadOffset.getPosition(),
+        constantPoolPayloadOffset.getLength(),
+        value);
   }
 
   public byte getApiLevelForReference(byte[] serialized, DexReference reference) {
     PositionAndLength apiLevelPayloadOffset =
-        getApiLevelHashMapPayloadOffset(apiLevelHash(reference));
+        readPositionAndLength(apiLevelHashMapIndexOffset(apiLevelHash(reference)));
     if (apiLevelPayloadOffset.isEmpty()) {
       return 0;
     }
     return readApiLevelForPayloadOffset(
-        apiLevelPayloadOffset.getPosition(), apiLevelPayloadOffset.getLength(), serialized);
+        payloadOffset(getConstantPoolSize()) + apiLevelPayloadOffset.getPosition(),
+        apiLevelPayloadOffset.getLength(),
+        serialized);
   }
 
-  public static byte findApiForReferenceHelper(byte[] data, int offset, int length, byte[] value) {
-    int index = offset;
-    while (index < offset + length) {
-      // Read size of entry
-      int lengthOfEntry = Ints.fromBytes(ZERO_BYTE, ZERO_BYTE, data[index], data[index + 1]);
-      int startIndex = index + 2;
-      int endIndex = startIndex + lengthOfEntry;
-      if (isSerializedDescriptor(value, data, startIndex, lengthOfEntry)) {
-        return data[endIndex];
-      }
-      index = endIndex + 1;
-    }
-    return 0;
-  }
+  public static class AndroidApiDataAccessByteMapped extends AndroidApiDataAccess {
 
-  protected static boolean isSerializedDescriptor(
-      byte[] serialized, byte[] candidate, int offset, int length) {
-    if (serialized.length != length) {
-      return false;
+    private final CompatByteBuffer mappedByteBuffer;
+
+    public AndroidApiDataAccessByteMapped(CompatByteBuffer mappedByteBuffer) {
+      this.mappedByteBuffer = mappedByteBuffer;
     }
-    for (int i = 0; i < length; i++) {
-      if (serialized[i] != candidate[i + offset]) {
-        return false;
+
+    @Override
+    int readConstantPoolSize() {
+      return mappedByteBuffer.getInt(0);
+    }
+
+    @Override
+    public PositionAndLength readPositionAndLength(int offset) {
+      return PositionAndLength.create(
+          mappedByteBuffer.getInt(offset), mappedByteBuffer.getShort(offset + 4));
+    }
+
+    @Override
+    boolean payloadHasConstantPoolValue(int offset, int length, byte[] value) {
+      assert length == value.length;
+      mappedByteBuffer.position(offset);
+      for (byte expected : value) {
+        if (expected != mappedByteBuffer.get()) {
+          return false;
+        }
       }
+      return true;
     }
-    return true;
+
+    @Override
+    int payloadContainsConstantPoolValue(
+        int offset, int length, byte[] value, BiPredicate<Integer, byte[]> predicate) {
+      for (int i = offset; i < offset + length; i += 2) {
+        // Do not use mappedByteBuffer.getShort() since that will add the sign.
+        int index =
+            Ints.fromBytes(
+                ZERO_BYTE, ZERO_BYTE, mappedByteBuffer.get(i), mappedByteBuffer.get(i + 1));
+        if (predicate.test(index, value)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    @Override
+    byte readApiLevelForPayloadOffset(int offset, int length, byte[] value) {
+      int currentOffset = offset;
+      while (currentOffset < offset + length) {
+        // Read the length
+        int lengthOfEntry =
+            Ints.fromBytes(
+                ZERO_BYTE,
+                ZERO_BYTE,
+                mappedByteBuffer.get(currentOffset),
+                mappedByteBuffer.get(currentOffset + 1));
+        int startPosition = currentOffset + 2;
+        if (value.length == lengthOfEntry
+            && payloadHasConstantPoolValue(startPosition, lengthOfEntry, value)) {
+          return mappedByteBuffer.get(startPosition + lengthOfEntry);
+        }
+        // Advance our current position + length of entry + api level.
+        currentOffset = startPosition + lengthOfEntry + 1;
+      }
+      return -1;
+    }
   }
 
   public static class AndroidApiDataAccessInMemory extends AndroidApiDataAccess {
@@ -243,62 +383,36 @@
       this.data = data;
     }
 
-    public static AndroidApiDataAccessInMemory create() {
-      byte[] data;
-      try (InputStream apiInputStream =
-          AndroidApiDataAccess.class.getClassLoader().getResourceAsStream(RESOURCE_NAME); ) {
-        if (apiInputStream == null) {
-          URL resource = AndroidApiDataAccess.class.getClassLoader().getResource(RESOURCE_NAME);
-          throw new CompilationError("Could not find the api database at: " + resource);
-        }
-        data = ByteStreams.toByteArray(apiInputStream);
-      } catch (IOException e) {
-        throw new CompilationError("Could not read the api database.", e);
-      }
-      return new AndroidApiDataAccessInMemory(data);
-    }
-
     @Override
     public int readConstantPoolSize() {
       return readIntFromOffset(data, 0);
     }
 
     @Override
-    PositionAndLength getConstantPoolPayloadOffset(int index) {
-      int offset = constantPoolOffset() + (index * constantPoolEntrySize());
-      return PositionAndLength.create(data, offset);
-    }
-
-    @Override
-    PositionAndLength getConstantPoolHashMapPayloadOffset(int hash) {
-      int offset =
-          constantPoolHashMapOffset(getConstantPoolSize()) + (hash * constantPoolMapEntrySize());
-      return PositionAndLength.create(data, offset);
-    }
-
-    @Override
-    PositionAndLength getApiLevelHashMapPayloadOffset(int hash) {
-      int offset =
-          apiLevelHashMapOffset(getConstantPoolSize()) + (hash * apiLevelHashMapEntrySize());
+    PositionAndLength readPositionAndLength(int offset) {
       return PositionAndLength.create(data, offset);
     }
 
     @Override
     boolean payloadHasConstantPoolValue(int offset, int length, byte[] value) {
-      return isSerializedDescriptor(
-          value, data, payloadOffset(getConstantPoolSize()) + offset, length);
+      if (value.length != length) {
+        return false;
+      }
+      for (int i = 0; i < length; i++) {
+        if (value[i] != data[i + offset]) {
+          return false;
+        }
+      }
+      return true;
     }
 
     @Override
     int payloadContainsConstantPoolValue(
         int offset, int length, byte[] value, BiPredicate<Integer, byte[]> predicate) {
-      int payloadOffset = payloadOffset(getConstantPoolSize());
-      int startInPayload = payloadOffset + offset;
-      int endInPayload = startInPayload + length;
-      if (data.length < endInPayload) {
+      if (data.length < length) {
         return -1;
       }
-      for (int i = startInPayload; i < endInPayload; i += 2) {
+      for (int i = offset; i < offset + length; i += 2) {
         int index = Ints.fromBytes(ZERO_BYTE, ZERO_BYTE, data[i], data[i + 1]);
         if (predicate.test(index, value)) {
           return index;
@@ -309,8 +423,18 @@
 
     @Override
     byte readApiLevelForPayloadOffset(int offset, int length, byte[] value) {
-      return findApiForReferenceHelper(
-          data, payloadOffset(getConstantPoolSize()) + offset, length, value);
+      int index = offset;
+      while (index < offset + length) {
+        // Read size of entry
+        int lengthOfEntry = Ints.fromBytes(ZERO_BYTE, ZERO_BYTE, data[index], data[index + 1]);
+        int startIndex = index + 2;
+        int endIndex = startIndex + lengthOfEntry;
+        if (payloadHasConstantPoolValue(startIndex, lengthOfEntry, value)) {
+          return data[endIndex];
+        }
+        index = endIndex + 1;
+      }
+      return 0;
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelHashingDatabaseImpl.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelHashingDatabaseImpl.java
index 5e0a407..22d0c6d 100644
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelHashingDatabaseImpl.java
+++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiLevelHashingDatabaseImpl.java
@@ -7,13 +7,14 @@
 import static com.android.tools.r8.lightir.ByteUtils.isU2;
 import static com.android.tools.r8.utils.AndroidApiLevel.ANDROID_PLATFORM;
 
-import com.android.tools.r8.androidapi.AndroidApiDataAccess.AndroidApiDataAccessInMemory;
+import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ThrowingFunction;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -126,13 +127,16 @@
 
   private final Map<DexReference, AndroidApiLevel> lookupCache = new ConcurrentHashMap<>();
   private final Map<DexString, Integer> constantPoolCache = new ConcurrentHashMap<>();
+  private final InternalOptions options;
+  private final DiagnosticsHandler diagnosticsHandler;
   private static volatile AndroidApiDataAccess dataAccess;
 
-  private static AndroidApiDataAccess getDataAccess() {
+  private static AndroidApiDataAccess getDataAccess(
+      InternalOptions options, DiagnosticsHandler diagnosticsHandler) {
     if (dataAccess == null) {
       synchronized (AndroidApiDataAccess.class) {
         if (dataAccess == null) {
-          dataAccess = AndroidApiDataAccessInMemory.create();
+          dataAccess = AndroidApiDataAccess.create(options, diagnosticsHandler);
         }
       }
     }
@@ -140,7 +144,11 @@
   }
 
   public AndroidApiLevelHashingDatabaseImpl(
-      List<AndroidApiForHashingReference> predefinedApiTypeLookup) {
+      List<AndroidApiForHashingReference> predefinedApiTypeLookup,
+      InternalOptions options,
+      DiagnosticsHandler diagnosticsHandler) {
+    this.options = options;
+    this.diagnosticsHandler = diagnosticsHandler;
     predefinedApiTypeLookup.forEach(
         predefinedApiReference -> {
           // Do not use computeIfAbsent since a return value of null implies the key should not be
@@ -169,7 +177,7 @@
 
   private int getConstantPoolId(DexString string) {
     return constantPoolCache.computeIfAbsent(
-        string, key -> getDataAccess().getConstantPoolIndex(string));
+        string, key -> getDataAccess(options, diagnosticsHandler).getConstantPoolIndex(string));
   }
 
   private AndroidApiLevel lookupApiLevel(DexReference reference) {
@@ -190,7 +198,8 @@
                 return ANDROID_PLATFORM;
               } else {
                 byte apiLevelForReference =
-                    getDataAccess().getApiLevelForReference(uniqueDescriptorForReference, ref);
+                    getDataAccess(options, diagnosticsHandler)
+                        .getApiLevelForReference(uniqueDescriptorForReference, ref);
                 return (apiLevelForReference <= 0)
                     ? ANDROID_PLATFORM
                     : AndroidApiLevel.getAndroidApiLevel(apiLevelForReference);
diff --git a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java b/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
index 0e08965..b1b581b 100644
--- a/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
+++ b/src/main/java/com/android/tools/r8/androidapi/AndroidApiReferenceLevelCache.java
@@ -30,7 +30,8 @@
     this.apiLevelCompute = apiLevelCompute;
     factory = appView.dexItemFactory();
     androidApiLevelDatabase =
-        new AndroidApiLevelHashingDatabaseImpl(predefinedApiTypeLookupForHashing);
+        new AndroidApiLevelHashingDatabaseImpl(
+            predefinedApiTypeLookupForHashing, appView.options(), appView.reporter());
   }
 
   public static AndroidApiReferenceLevelCache create(
diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
index f8ed446..6d8c09d 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
@@ -10,10 +10,10 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DefaultInstanceInitializerCode;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
@@ -29,9 +29,7 @@
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.WorkList;
 import com.google.common.collect.Sets;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -78,22 +76,22 @@
 
     @Override
     public void registerInstanceFieldRead(DexField field) {
-      checkReferenceToLibraryClass(field.type);
+      checkReferenceToLibraryClass(field);
     }
 
     @Override
     public void registerInstanceFieldWrite(DexField field) {
-      checkReferenceToLibraryClass(field.type);
+      checkReferenceToLibraryClass(field);
     }
 
     @Override
     public void registerStaticFieldRead(DexField field) {
-      checkReferenceToLibraryClass(field.type);
+      checkReferenceToLibraryClass(field);
     }
 
     @Override
     public void registerStaticFieldWrite(DexField field) {
-      checkReferenceToLibraryClass(field.type);
+      checkReferenceToLibraryClass(field);
     }
 
     @Override
@@ -104,17 +102,13 @@
     private void checkReferenceToLibraryClass(DexReference reference) {
       DexType rewrittenType = appView.graphLens().lookupType(reference.getContextType());
       findReferencedLibraryClasses(rewrittenType, getContext().getContextClass());
-      if (reference.isDexMethod()) {
-        findReferencedLibraryMethod(reference.asDexMethod(), getContext().getContextClass());
-      }
     }
   }
 
   private final AppView<?> appView;
   private final Map<DexLibraryClass, Set<ProgramDefinition>> referencingContexts =
       new ConcurrentHashMap<>();
-  private final Map<DexLibraryClass, Set<DexMethod>> libraryClassesToMock =
-      new ConcurrentHashMap<>();
+  private final Set<DexLibraryClass> libraryClassesToMock = Sets.newConcurrentHashSet();
   private final Set<DexType> seenTypes = Sets.newConcurrentHashSet();
   private final AndroidApiLevelCompute apiLevelCompute;
 
@@ -133,10 +127,9 @@
       return;
     }
     libraryClassesToMock.forEach(
-        (clazz, methods) ->
+        clazz ->
             mockMissingLibraryClass(
                 clazz,
-                methods,
                 ThrowExceptionCode.create(appView.dexItemFactory().noClassDefFoundErrorType)));
     // Commit the synthetic items.
     CommittedItems committedItems = appView.getSyntheticItems().commit(appView.appInfo().app());
@@ -171,37 +164,6 @@
         method -> method.registerCodeReferences(new ReferencesToApiLevelUseRegistry(method)));
   }
 
-  private void findReferencedLibraryMethod(DexMethod method, DexProgramClass context) {
-    DexType holderType = method.getHolderType();
-    if (!holderType.isClassType()) {
-      return;
-    }
-    DexType rewrittenType = appView.graphLens().lookupType(holderType);
-    DexClass clazz = appView.definitionFor(rewrittenType);
-    if (clazz == null || !clazz.isLibraryClass()) {
-      return;
-    }
-    ComputedApiLevel apiLevel =
-        apiLevelCompute.computeApiLevelForLibraryReference(method, ComputedApiLevel.unknown());
-    if (apiLevel.isGreaterThan(appView.computedMinApiLevel())) {
-      ComputedApiLevel holderApiLevel =
-          apiLevelCompute.computeApiLevelForLibraryReference(
-              rewrittenType, ComputedApiLevel.unknown());
-      if (holderApiLevel.isUnknownApiLevel()) {
-        // Do not mock methods or classes where the holder is unknown.
-        return;
-      }
-      if (holderApiLevel.isGreaterThan(appView.computedMinApiLevel())) {
-        libraryClassesToMock
-            .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
-            .add(method);
-        referencingContexts
-            .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
-            .add(context);
-      }
-    }
-  }
-
   private void findReferencedLibraryClasses(DexType type, DexProgramClass context) {
     if (!type.isClassType()) {
       return;
@@ -218,8 +180,7 @@
                 clazz.type, ComputedApiLevel.unknown());
         if (androidApiLevel.isGreaterThan(appView.computedMinApiLevel())
             && !androidApiLevel.isUnknownApiLevel()) {
-          libraryClassesToMock.computeIfAbsent(
-              clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet));
+          libraryClassesToMock.add(clazz.asLibraryClass());
           referencingContexts
               .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
               .add(context);
@@ -231,9 +192,9 @@
 
   private void mockMissingLibraryClass(
       DexLibraryClass libraryClass,
-      Set<DexMethod> methodsToStub,
       ThrowExceptionCode throwExceptionCode) {
-    if (libraryClass.getType() == appView.dexItemFactory().objectType
+    DexItemFactory factory = appView.dexItemFactory();
+    if (libraryClass.getType() == factory.objectType
         || libraryClass.getType().toDescriptorString().startsWith("Ljava/")) {
       return;
     }
@@ -260,9 +221,14 @@
               classBuilder
                   .setSuperType(libraryClass.getSuperType())
                   .setInterfaces(Arrays.asList(libraryClass.getInterfaces().values))
-                  .setVirtualMethods(
-                      buildLibraryMethodsForProgram(
-                          libraryClass, libraryClass.virtualMethods(), methodsToStub));
+                  // Add throwing static initializer
+                  .addMethod(
+                      methodBuilder ->
+                          methodBuilder
+                              .setName(factory.classConstructorMethodName)
+                              .setProto(factory.createProto(factory.voidType))
+                              .setAccessFlags(MethodAccessFlags.createForClassInitializer())
+                              .setCode(method -> throwExceptionCode));
               // Based on b/138781768#comment57 there is no significant reason to synthesize fields.
               if (libraryClass.isInterface()) {
                 classBuilder.setInterface();
@@ -270,60 +236,7 @@
               if (!libraryClass.isFinal()) {
                 classBuilder.unsetFinal();
               }
-              List<DexEncodedMethod> directMethods =
-                  (!libraryClass.isInterface()
-                          || appView.options().canUseDefaultAndStaticInterfaceMethods())
-                      ? buildLibraryMethodsForProgram(
-                          libraryClass, libraryClass.directMethods(), methodsToStub)
-                      : new ArrayList<>();
-              // Add throwing static initializer
-              directMethods.add(
-                  DexEncodedMethod.syntheticBuilder()
-                      .setMethod(
-                          appView.dexItemFactory().createClassInitializer(libraryClass.getType()))
-                      .setAccessFlags(MethodAccessFlags.createForClassInitializer())
-                      .setCode(throwExceptionCode)
-                      .build());
-              classBuilder.setDirectMethods(directMethods);
             },
             ignored -> {});
   }
-
-  private List<DexEncodedMethod> buildLibraryMethodsForProgram(
-      DexLibraryClass clazz, Iterable<DexEncodedMethod> methods, Set<DexMethod> methodsToMock) {
-    List<DexEncodedMethod> newMethods = new ArrayList<>();
-    methods.forEach(
-        method -> {
-          if (methodsToMock.contains(method.getReference())) {
-            DexEncodedMethod newMethod = buildLibraryMethodForProgram(clazz, method);
-            if (newMethod != null) {
-              newMethods.add(newMethod);
-            }
-          }
-        });
-    return newMethods;
-  }
-
-  private DexEncodedMethod buildLibraryMethodForProgram(
-      DexLibraryClass clazz, DexEncodedMethod method) {
-    assert !clazz.isInterface()
-        || !method.isStatic()
-        || appView.options().canUseDefaultAndStaticInterfaceMethods();
-    DexMethod newMethod = method.getReference().withHolder(clazz.type, appView.dexItemFactory());
-    DexEncodedMethod.Builder methodBuilder =
-        DexEncodedMethod.syntheticBuilder(method)
-            .setMethod(newMethod)
-            .modifyAccessFlags(MethodAccessFlags::setSynthetic);
-    if (method.isInstanceInitializer()) {
-      methodBuilder.setCode(DefaultInstanceInitializerCode.get());
-    } else if (method.isVirtualMethod() && clazz.isInterface()) {
-      methodBuilder.modifyAccessFlags(MethodAccessFlags::setAbstract);
-    } else if (method.isAbstract()) {
-      methodBuilder.modifyAccessFlags(MethodAccessFlags::setAbstract);
-    } else {
-      // To allow us not adding a trivial throwing code body we set the access flag as native.
-      methodBuilder.modifyAccessFlags(MethodAccessFlags::setNative);
-    }
-    return methodBuilder.build();
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/bisect/Bisect.java b/src/main/java/com/android/tools/r8/bisect/Bisect.java
index 4228cf4..c7547a8 100644
--- a/src/main/java/com/android/tools/r8/bisect/Bisect.java
+++ b/src/main/java/com/android/tools/r8/bisect/Bisect.java
@@ -14,7 +14,6 @@
 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.naming.NamingLens;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.AndroidAppConsumers;
@@ -175,7 +174,7 @@
   }
 
   private DexApplication readApp(Path apk, InternalOptions options, ExecutorService executor)
-      throws IOException, ExecutionException {
+      throws IOException {
     AndroidApp app = AndroidApp.builder().addProgramFiles(apk).build();
     return new ApplicationReader(app, options, timing).read(executor);
   }
@@ -191,8 +190,7 @@
         new ApplicationWriter(
             AppView.createForD8(
                 AppInfo.createInitialAppInfo(app, GlobalSyntheticsStrategy.forNonSynthesizing())),
-            null,
-            NamingLens.getIdentityLens());
+            null);
     writer.write(executor);
     options.signalFinishedToConsumers();
     compatSink.build().writeToDirectory(output, OutputMode.DexIndexed);
diff --git a/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java b/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
index 22fbe8e..9798222 100644
--- a/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
+++ b/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
@@ -536,24 +536,7 @@
     } else if (frameType.isUninitializedNew()) {
       return frameTypeType() + ".uninitializedNew(new " + cfType("CfLabel") + "())";
     } else if (frameType.isPrimitive()) {
-      if (frameType.isSingle()) {
-        if (frameType.isInt()) {
-          return frameTypeType() + ".intType()";
-        } else {
-          return frameTypeType()
-              + ".initialized("
-              + dexType(frameType.asSingleInitializedType().getInitializedType())
-              + ")";
-        }
-      } else {
-        assert frameType.isWide();
-        if (frameType.isDouble()) {
-          return frameTypeType() + ".doubleType()";
-        } else {
-          assert frameType.isLong();
-          return frameTypeType() + ".longType()";
-        }
-      }
+      return frameTypeType() + "." + frameType.asPrimitive().getTypeName() + "Type()";
     } else {
       assert frameType.isInitialized();
       if (frameType.isNullType()) {
diff --git a/src/main/java/com/android/tools/r8/cf/CfPrinter.java b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
index 035e416..6030119 100644
--- a/src/main/java/com/android/tools/r8/cf/CfPrinter.java
+++ b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
@@ -456,17 +456,7 @@
 
   private void print(FrameType type) {
     if (type.isPrimitive()) {
-      if (type.isInt()) {
-        builder.append("int");
-      } else if (type.isDouble()) {
-        builder.append("double");
-      } else if (type.isLong()) {
-        assert type.isLong();
-        builder.append("long");
-      } else {
-        assert type.isSingleInitialized();
-        appendType(type.asSingleInitializedType().getInitializedType());
-      }
+      builder.append(type.asPrimitive().getTypeName());
     } else if (type.isInitialized()) {
       appendType(type.asSingleInitializedType().getInitializedType());
     } else if (type.isUninitializedNew()) {
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
index bf9dc6b..993dd8e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -220,11 +221,14 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState state,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ..., result
-    return state.popInitialized(appView, type).popInitialized(appView, type).push(appView, type);
+    return state
+        .popInitialized(appView, type)
+        .popInitialized(appView, type)
+        .push(appView, config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index e696048..8a39916 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -96,13 +97,13 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., arrayref →
     // ..., length
     return frame
         .popInitialized(appView, dexItemFactory.objectArrayType)
-        .push(dexItemFactory.intType);
+        .push(config, dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index fbcad69..129219b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -141,14 +142,14 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., arrayref, index →
     // ..., value
     return frame
         .popInitialized(appView, dexItemFactory.intType)
         .popInitialized(appView, dexItemFactory.objectArrayType)
-        .push(appView, type);
+        .push(appView, config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
index 31ad222..965c413 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -133,8 +134,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., arrayref, index, value →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfAssignability.java b/src/main/java/com/android/tools/r8/cf/code/CfAssignability.java
index 184afb2..8335908 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfAssignability.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfAssignability.java
@@ -33,7 +33,7 @@
   // Based on https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.2.
   public static boolean isFrameTypeAssignable(
       SingleFrameType source, SingleFrameType target, AppView<?> appView) {
-    if (source == target || target.isOneWord()) {
+    if (source.equals(target) || target.isOneWord()) {
       return true;
     }
     if (source.isOneWord()) {
@@ -49,11 +49,21 @@
     }
     // TODO(b/168190267): Clean-up the lattice.
     DexItemFactory factory = appView.dexItemFactory();
+    if (target.isPrimitive()) {
+      return source.isPrimitive()
+          && source.asSinglePrimitive().hasIntVerificationType()
+          && target.asSinglePrimitive().hasIntVerificationType();
+    }
+    if (source.isPrimitive()) {
+      return false;
+    }
     if (target.isInitialized()) {
       if (source.isInitialized()) {
         // Both are instantiated types and we resort to primitive type/java type hierarchy checking.
         return isAssignable(
-            source.getInitializedType(factory), target.getInitializedType(factory), appView);
+            source.asSingleInitializedType().getInitializedType(),
+            target.asSingleInitializedType().getInitializedType(),
+            appView);
       }
       return target.asSingleInitializedType().getInitializedType() == factory.objectType;
     }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 323a253..6ad249b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -145,11 +146,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref →
     // ..., objectref
-    return frame.popInitialized(appView, dexItemFactory.objectType).push(type);
+    return frame.popInitialized(appView, dexItemFactory.objectType).push(config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
index 4a42ca3..5d3f7b9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
@@ -25,6 +25,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -145,14 +146,14 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ..., result
     return frame
         .popInitialized(appView, type)
         .popInitialized(appView, type)
-        .push(dexItemFactory.intType);
+        .push(config, dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index ff36775..43e8eee 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -152,11 +153,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.classType);
+    return frame.push(config, dexItemFactory.classType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
index 54c7820..da94a6ba 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
@@ -31,6 +31,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -239,11 +240,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.classType);
+    return frame.push(config, dexItemFactory.classType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index 50564e3..ad9f25e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -116,11 +117,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.methodHandleType);
+    return frame.push(config, dexItemFactory.methodHandleType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index b262ff9..dc1bee0 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -114,11 +115,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.methodTypeType);
+    return frame.push(config, dexItemFactory.methodTypeType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
index e849e05..546fd6b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -86,11 +87,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(DexItemFactory.nullValueType);
+    return frame.push(config, DexItemFactory.nullValueType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
index 34f67c7..3277d2b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.StructuralSpecification;
@@ -244,12 +245,12 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
     assert type.isPrimitive();
-    return frame.push(appView, type);
+    return frame.push(appView, config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 4e4a325..e143829 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -117,11 +118,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.stringType);
+    return frame.push(config, dexItemFactory.stringType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index 8bccf77..374b722 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -136,11 +137,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., value
-    return frame.push(dexItemFactory.stringType);
+    return frame.push(config, dexItemFactory.stringType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index c40062c..fafcb67 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -6,6 +6,7 @@
 import static org.objectweb.asm.Opcodes.F_NEW;
 
 import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.cf.code.frame.PrimitiveFrameType;
 import com.android.tools.r8.cf.code.frame.SingleFrameType;
 import com.android.tools.r8.cf.code.frame.WideFrameType;
 import com.android.tools.r8.errors.Unimplemented;
@@ -29,6 +30,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.IntObjConsumer;
 import com.android.tools.r8.utils.collections.ImmutableDeque;
@@ -52,10 +54,26 @@
 
   public abstract static class FrameType {
 
+    public static BooleanFrameType booleanType() {
+      return BooleanFrameType.SINGLETON;
+    }
+
+    public static ByteFrameType byteType() {
+      return ByteFrameType.SINGLETON;
+    }
+
+    public static CharFrameType charType() {
+      return CharFrameType.SINGLETON;
+    }
+
     public static DoubleFrameType doubleType() {
       return DoubleFrameType.SINGLETON;
     }
 
+    public static FloatFrameType floatType() {
+      return FloatFrameType.SINGLETON;
+    }
+
     public static IntFrameType intType() {
       return IntFrameType.SINGLETON;
     }
@@ -64,12 +82,32 @@
       return LongFrameType.SINGLETON;
     }
 
+    public static ShortFrameType shortType() {
+      return ShortFrameType.SINGLETON;
+    }
+
     public static FrameType initialized(DexType type) {
       if (type.isPrimitiveType()) {
-        if (type.isWideType()) {
-          return type.isDoubleType() ? doubleType() : longType();
-        } else if (type.isIntType()) {
-          return intType();
+        char c = (char) type.getDescriptor().content[0];
+        switch (c) {
+          case 'Z':
+            return booleanType();
+          case 'B':
+            return byteType();
+          case 'C':
+            return charType();
+          case 'D':
+            return doubleType();
+          case 'F':
+            return floatType();
+          case 'I':
+            return intType();
+          case 'J':
+            return longType();
+          case 'S':
+            return shortType();
+          default:
+            throw new Unreachable("Unexpected primitive type: " + type.getTypeName());
         }
       }
       return new SingleInitializedType(type);
@@ -97,10 +135,26 @@
 
     abstract Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens);
 
+    public boolean isBoolean() {
+      return false;
+    }
+
+    public boolean isByte() {
+      return false;
+    }
+
+    public boolean isChar() {
+      return false;
+    }
+
     public boolean isDouble() {
       return false;
     }
 
+    public boolean isFloat() {
+      return false;
+    }
+
     public boolean isInt() {
       return false;
     }
@@ -109,6 +163,10 @@
       return false;
     }
 
+    public boolean isShort() {
+      return false;
+    }
+
     public boolean isNullType() {
       return false;
     }
@@ -117,7 +175,7 @@
       return false;
     }
 
-    public DexType getObjectType(ProgramMethod context) {
+    public DexType getObjectType(DexType context) {
       assert false : "Unexpected use of getObjectType() for non-object FrameType";
       return null;
     }
@@ -126,6 +184,10 @@
       return false;
     }
 
+    public PrimitiveFrameType asPrimitive() {
+      return null;
+    }
+
     public final boolean isSingle() {
       return !isWide();
     }
@@ -134,6 +196,10 @@
       return null;
     }
 
+    public SinglePrimitiveFrameType asSinglePrimitive() {
+      return null;
+    }
+
     public SingleInitializedType asSingleInitializedType() {
       return null;
     }
@@ -146,6 +212,11 @@
       return null;
     }
 
+    public int getWidth() {
+      assert isSingle();
+      return 1;
+    }
+
     public boolean isUninitializedNew() {
       return false;
     }
@@ -166,10 +237,6 @@
       return false;
     }
 
-    public boolean isSingleInitialized() {
-      return false;
-    }
-
     public DexType getInitializedType(DexItemFactory dexItemFactory) {
       return null;
     }
@@ -283,26 +350,181 @@
     return CfCompareHelper.compareIdUniquelyDeterminesEquality(this, other);
   }
 
-  public abstract static class SinglePrimitiveType extends SingletonFrameType
-      implements SingleFrameType {
+  public abstract static class SinglePrimitiveFrameType extends SingletonFrameType
+      implements PrimitiveFrameType, SingleFrameType {
+
+    public boolean hasIntVerificationType() {
+      return false;
+    }
 
     @Override
-    public boolean isInitialized() {
+    public final boolean isInitialized() {
       return true;
     }
 
     @Override
-    public boolean isPrimitive() {
+    public final boolean isPrimitive() {
       return true;
     }
 
     @Override
-    public SingleFrameType asSingle() {
+    public PrimitiveFrameType asPrimitive() {
       return this;
     }
+
+    @Override
+    public final SingleFrameType asSingle() {
+      return this;
+    }
+
+    @Override
+    public final SinglePrimitiveFrameType asSinglePrimitive() {
+      return this;
+    }
+
+    @Override
+    public final SingleFrameType join(SingleFrameType frameType) {
+      if (this == frameType) {
+        return this;
+      }
+      if (hasIntVerificationType()
+          && frameType.isPrimitive()
+          && frameType.asSinglePrimitive().hasIntVerificationType()) {
+        return intType();
+      }
+      return oneWord();
+    }
+
+    @Override
+    public final String toString() {
+      return getTypeName();
+    }
   }
 
-  public static class IntFrameType extends SinglePrimitiveType {
+  public static class BooleanFrameType extends SinglePrimitiveFrameType {
+
+    private static final BooleanFrameType SINGLETON = new BooleanFrameType();
+
+    private BooleanFrameType() {}
+
+    @Override
+    public DexType getInitializedType(DexItemFactory dexItemFactory) {
+      return dexItemFactory.booleanType;
+    }
+
+    @Override
+    public String getTypeName() {
+      return "boolean";
+    }
+
+    @Override
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      throw new Unreachable("Unexpected value type: " + this);
+    }
+
+    @Override
+    public boolean hasIntVerificationType() {
+      return true;
+    }
+
+    @Override
+    public boolean isBoolean() {
+      return true;
+    }
+  }
+
+  public static class ByteFrameType extends SinglePrimitiveFrameType {
+
+    private static final ByteFrameType SINGLETON = new ByteFrameType();
+
+    private ByteFrameType() {}
+
+    @Override
+    public DexType getInitializedType(DexItemFactory dexItemFactory) {
+      return dexItemFactory.byteType;
+    }
+
+    @Override
+    public String getTypeName() {
+      return "byte";
+    }
+
+    @Override
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      throw new Unreachable("Unexpected value type: " + this);
+    }
+
+    @Override
+    public boolean hasIntVerificationType() {
+      return true;
+    }
+
+    @Override
+    public boolean isByte() {
+      return true;
+    }
+  }
+
+  public static class CharFrameType extends SinglePrimitiveFrameType {
+
+    private static final CharFrameType SINGLETON = new CharFrameType();
+
+    private CharFrameType() {}
+
+    @Override
+    public DexType getInitializedType(DexItemFactory dexItemFactory) {
+      return dexItemFactory.charType;
+    }
+
+    @Override
+    public String getTypeName() {
+      return "char";
+    }
+
+    @Override
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      throw new Unreachable("Unexpected value type: " + this);
+    }
+
+    @Override
+    public boolean hasIntVerificationType() {
+      return true;
+    }
+
+    @Override
+    public boolean isChar() {
+      return true;
+    }
+  }
+
+  public static class FloatFrameType extends SinglePrimitiveFrameType {
+
+    private static final FloatFrameType SINGLETON = new FloatFrameType();
+
+    private FloatFrameType() {}
+
+    @Override
+    public DexType getInitializedType(DexItemFactory dexItemFactory) {
+      return dexItemFactory.floatType;
+    }
+
+    @Override
+    public String getTypeName() {
+      return "float";
+    }
+
+    @Override
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      return Opcodes.FLOAT;
+    }
+
+    @Override
+    public boolean isFloat() {
+      return true;
+    }
+  }
+
+  public static class IntFrameType extends SinglePrimitiveFrameType {
 
     private static final IntFrameType SINGLETON = new IntFrameType();
 
@@ -314,8 +536,8 @@
     }
 
     @Override
-    public boolean isInt() {
-      return true;
+    public String getTypeName() {
+      return "int";
     }
 
     @Override
@@ -324,23 +546,45 @@
     }
 
     @Override
-    public SingleFrameType join(SingleFrameType frameType) {
-      if (this == frameType) {
-        return this;
-      }
-      if (frameType.isOneWord() || frameType.isUninitializedObject()) {
-        return oneWord();
-      }
-      assert frameType.isInitialized();
-      return CfAssignability.hasIntVerificationType(
-              frameType.asSingleInitializedType().getInitializedType())
-          ? this
-          : oneWord();
+    public boolean hasIntVerificationType() {
+      return true;
     }
 
     @Override
-    public String toString() {
-      return "int";
+    public boolean isInt() {
+      return true;
+    }
+  }
+
+  public static class ShortFrameType extends SinglePrimitiveFrameType {
+
+    private static final ShortFrameType SINGLETON = new ShortFrameType();
+
+    private ShortFrameType() {}
+
+    @Override
+    public DexType getInitializedType(DexItemFactory dexItemFactory) {
+      return dexItemFactory.shortType;
+    }
+
+    @Override
+    public String getTypeName() {
+      return "short";
+    }
+
+    @Override
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      throw new Unreachable("Unexpected value type: " + this);
+    }
+
+    @Override
+    public boolean hasIntVerificationType() {
+      return true;
+    }
+
+    @Override
+    public boolean isShort() {
+      return true;
     }
   }
 
@@ -350,7 +594,7 @@
 
     private SingleInitializedType(DexType type) {
       assert type != null;
-      assert !type.isIntType();
+      assert type.isReferenceType();
       this.type = type;
     }
 
@@ -364,26 +608,11 @@
       if (equals(frameType)) {
         return this;
       }
-      if (frameType.isOneWord() || frameType.isUninitializedObject()) {
+      if (frameType.isOneWord() || frameType.isPrimitive() || frameType.isUninitializedObject()) {
         return oneWord();
       }
-      assert frameType.isInitialized();
-      if (frameType.isPrimitive()) {
-        if (frameType.isInt()) {
-          return CfAssignability.hasIntVerificationType(type) ? frameType : oneWord();
-        }
-        // The rest of the primitives are still represented using SingleInitializedType.
-        DexType otherType = frameType.asSingleInitializedType().getInitializedType();
-        return CfAssignability.hasIntVerificationType(type)
-                && CfAssignability.hasIntVerificationType(otherType)
-            ? intType()
-            : oneWord();
-      }
       DexType otherType = frameType.asSingleInitializedType().getInitializedType();
       assert type != otherType;
-      if (type.isPrimitiveType()) {
-        return oneWord();
-      }
       assert type.isReferenceType();
       if (isNullType()) {
         return otherType.isReferenceType() ? frameType : oneWord();
@@ -456,16 +685,6 @@
       return true;
     }
 
-    @Override
-    public boolean isPrimitive() {
-      return type.isPrimitiveType();
-    }
-
-    @Override
-    public boolean isSingleInitialized() {
-      return true;
-    }
-
     public DexType getInitializedType() {
       return type;
     }
@@ -486,14 +705,14 @@
     }
 
     @Override
-    public DexType getObjectType(ProgramMethod context) {
+    public DexType getObjectType(DexType context) {
       assert isObject() : "Unexpected use of getObjectType() for non-object FrameType";
       return type;
     }
   }
 
-  public abstract static class WideInitializedType extends SingletonFrameType
-      implements WideFrameType {
+  public abstract static class WidePrimitiveFrameType extends SingletonFrameType
+      implements PrimitiveFrameType, WideFrameType {
 
     @Override
     public boolean isInitialized() {
@@ -506,6 +725,11 @@
     }
 
     @Override
+    public PrimitiveFrameType asPrimitive() {
+      return this;
+    }
+
+    @Override
     public boolean isWide() {
       return true;
     }
@@ -516,12 +740,22 @@
     }
 
     @Override
+    public int getWidth() {
+      return 2;
+    }
+
+    @Override
     public WideFrameType join(WideFrameType frameType) {
       return this == frameType ? this : twoWord();
     }
+
+    @Override
+    public final String toString() {
+      return getTypeName();
+    }
   }
 
-  private static class DoubleFrameType extends WideInitializedType {
+  public static class DoubleFrameType extends WidePrimitiveFrameType {
 
     private static final DoubleFrameType SINGLETON = new DoubleFrameType();
 
@@ -538,17 +772,17 @@
     }
 
     @Override
-    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
-      return Opcodes.DOUBLE;
+    public String getTypeName() {
+      return "double";
     }
 
     @Override
-    public String toString() {
-      return "double";
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      return Opcodes.DOUBLE;
     }
   }
 
-  public static class LongFrameType extends WideInitializedType {
+  public static class LongFrameType extends WidePrimitiveFrameType {
 
     private static final LongFrameType SINGLETON = new LongFrameType();
 
@@ -565,13 +799,13 @@
     }
 
     @Override
-    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
-      return Opcodes.LONG;
+    public String getTypeName() {
+      return "long";
     }
 
     @Override
-    public String toString() {
-      return "long";
+    Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
+      return Opcodes.LONG;
     }
   }
 
@@ -628,7 +862,7 @@
     }
 
     @Override
-    public DexType getObjectType(ProgramMethod context) {
+    public DexType getObjectType(DexType context) {
       return type;
     }
 
@@ -688,8 +922,8 @@
     }
 
     @Override
-    public DexType getObjectType(ProgramMethod context) {
-      return context.getHolderType();
+    public DexType getObjectType(DexType context) {
+      return context;
     }
 
     @Override
@@ -767,6 +1001,11 @@
     }
 
     @Override
+    public int getWidth() {
+      return 2;
+    }
+
+    @Override
     public WideFrameType join(WideFrameType frameType) {
       // The join of wide with one of {double, long, wide} is wide.
       return this;
@@ -843,10 +1082,20 @@
     return locals;
   }
 
+  public Int2ObjectAVLTreeMap<FrameType> getMutableLocals() {
+    assert locals instanceof Int2ObjectAVLTreeMap<?>;
+    return (Int2ObjectAVLTreeMap<FrameType>) locals;
+  }
+
   public Deque<FrameType> getStack() {
     return stack;
   }
 
+  public ArrayDeque<FrameType> getMutableStack() {
+    assert stack instanceof ArrayDeque<?>;
+    return (ArrayDeque<FrameType>) stack;
+  }
+
   @Override
   public boolean equals(Object obj) {
     if (this == obj) {
@@ -898,7 +1147,7 @@
   public int computeStackSize() {
     int size = 0;
     for (FrameType frameType : stack) {
-      size += frameType.isWide() ? 2 : 1;
+      size += frameType.getWidth();
     }
     return size;
   }
@@ -989,8 +1238,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame.check(appView, this);
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
index 10a85b9..490de77 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -119,8 +120,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame;
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIf.java b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
index 8388a88..78acd72 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -117,8 +118,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
index 7c30583..96f5832 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -118,8 +119,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
index 5a121bd..8135aa9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.FunctionUtils;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -109,8 +110,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame.readLocal(appView, getLocalIndex(), ValueType.INT, FunctionUtils::getFirst);
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
index a168090..fe8f36e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -129,11 +130,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., →
     // ..., value
-    return frame.push(dexItemFactory.intType);
+    return frame.push(config, dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
index c461c07..1eb4b5d 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldRead.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.cf.code;
 
-import com.android.tools.r8.code.CfOrDexInstanceFieldRead;
+import com.android.tools.r8.dex.code.CfOrDexInstanceFieldRead;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import java.util.ListIterator;
 import org.objectweb.asm.Opcodes;
@@ -80,11 +81,13 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref →
     // ..., value
-    return frame.popInitialized(appView, getField().getHolderType()).push(getField().getType());
+    return frame
+        .popInitialized(appView, getField().getHolderType())
+        .push(config, getField().getType());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldWrite.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldWrite.java
index ea0d0f8..b7bf3ec 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldWrite.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceFieldWrite.java
@@ -4,8 +4,10 @@
 
 package com.android.tools.r8.cf.code;
 
+import static com.android.tools.r8.optimize.interfaces.analysis.ErroneousCfFrameState.formatActual;
 import static com.android.tools.r8.utils.BiPredicateUtils.or;
 
+import com.android.tools.r8.cf.code.CfFrame.FrameType;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -20,7 +22,9 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
+import com.android.tools.r8.optimize.interfaces.analysis.ErroneousCfFrameState;
 import java.util.ListIterator;
 import org.objectweb.asm.Opcodes;
 
@@ -83,8 +87,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref, value →
     // ...
@@ -93,7 +97,15 @@
         .popObject(
             appView,
             getField().getHolderType(),
-            context,
-            (state, head) -> head.isUninitializedNew() ? CfFrameState.error() : state);
+            config,
+            (state, head) -> head.isUninitializedNew() ? error(head) : state);
+  }
+
+  private ErroneousCfFrameState error(FrameType objectType) {
+    return CfFrameState.error(
+        "Frame type "
+            + formatActual(objectType)
+            + " is not assignable to "
+            + getField().getHolderType().getTypeName());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index 53f9904..e42e7e3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -139,11 +140,13 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref →
     // ..., result
-    return frame.popInitialized(appView, dexItemFactory.objectType).push(dexItemFactory.intType);
+    return frame
+        .popInitialized(appView, dexItemFactory.objectType)
+        .push(config, dexItemFactory.intType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
index 6599e60..dc1f4de 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.cf.code;
 
 import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.code.CfOrDexInstruction;
-import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.dex.code.CfOrDexInstruction;
+import com.android.tools.r8.dex.code.DexInstruction;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
@@ -25,6 +25,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -127,7 +128,12 @@
       CT initialValue) {
     // The method is overridden in each jump instruction.
     assert !isJump();
-    return fn.apply(fallthroughInstruction, initialValue);
+    if (fallthroughInstruction != null) {
+      return fn.apply(fallthroughInstruction, initialValue);
+    }
+    // There may be a label after the last return.
+    assert isLabel();
+    return TraversalContinuation.doContinue(initialValue);
   }
 
   @Override
@@ -141,7 +147,7 @@
   }
 
   @Override
-  public Instruction asDexInstruction() {
+  public DexInstruction asDexInstruction() {
     return null;
   }
 
@@ -355,5 +361,8 @@
       DexItemFactory dexItemFactory);
 
   public abstract CfFrameState evaluate(
-      CfFrameState frame, ProgramMethod context, AppView<?> appView, DexItemFactory dexItemFactory);
+      CfFrameState frame,
+      AppView<?> appView,
+      CfAnalysisConfig config,
+      DexItemFactory dexItemFactory);
 }
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 c972e4e..bbaf8b5 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
@@ -32,6 +32,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.StructuralSpecification;
@@ -341,8 +342,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref, [arg1, [arg2 ...]] →
     // ... [ returnType ]
@@ -352,14 +353,14 @@
     frame = frame.popInitialized(appView, method.getParameters().getBacking());
     if (opcode != Opcodes.INVOKESTATIC) {
       frame =
-          opcode == Opcodes.INVOKESPECIAL && context.getDefinition().isInstanceInitializer()
-              ? frame.popAndInitialize(appView, method, context)
+          opcode == Opcodes.INVOKESPECIAL && method.isInstanceInitializer(dexItemFactory)
+              ? frame.popAndInitialize(appView, method, config)
               : frame.popInitialized(appView, method.getHolderType());
     }
     if (method.getReturnType().isVoidType()) {
       return frame;
     }
-    return frame.push(method.getReturnType());
+    return frame.push(config, method.getReturnType());
   }
 
   private Type computeInvokeTypeForInvokeSpecial(
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index 121c288..dc81cfc 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ArrayList;
@@ -183,8 +184,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., [arg1, [arg2 ...]] →
     // ...
@@ -193,6 +194,6 @@
     if (returnType.isVoidType()) {
       return frame;
     }
-    return frame.push(returnType);
+    return frame.push(config, returnType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
index ab730fb..f132e94 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -97,10 +98,10 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
-    return CfFrameState.error();
+    return CfFrameState.error("Unexpected JSR/RET instruction");
   }
 
   public int getLocal() {
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
index 0e1ee11..7705bce 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.Label;
@@ -107,8 +108,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame;
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
index 225ad07..22e8e44 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -144,11 +145,12 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., objectref
-    return frame.readLocal(appView, getLocalIndex(), type, CfFrameState::push);
+    return frame.readLocal(
+        appView, getLocalIndex(), type, (state, frameType) -> state.push(config, frameType));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
index 3cf6f34..18bf0d3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -202,8 +203,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value1, value2 →
     // ..., result
@@ -221,6 +222,6 @@
     return frame
         .popInitialized(appView, value2Type)
         .popInitialized(appView, value1Type)
-        .push(appView, value1Type);
+        .push(appView, config, value1Type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
index f860f58..9b6e582 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -108,8 +109,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index a69ff20..0d48a12 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -145,14 +146,14 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., count1, [count2, ...] →
     // ..., arrayref
     for (int i = 0; i < dimensions; i++) {
       frame = frame.popInitialized(appView, dexItemFactory.intType);
     }
-    return frame.push(type);
+    return frame.push(config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
index c25b0ff..5150a97 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -134,11 +135,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value →
     // ..., result
-    return frame.popInitialized(appView, type).push(appView, type);
+    return frame.popInitialized(appView, type).push(appView, config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNew.java b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
index bcfae83..94fbd54 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNew.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -145,11 +146,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., objectref
-    return frame.push(FrameType.uninitializedNew(getLabel(), type));
+    return frame.push(config, FrameType.uninitializedNew(getLabel(), type));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
index 261db2e..6d176fa 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -178,11 +179,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., count →
     // ..., arrayref
-    return frame.popInitialized(appView, dexItemFactory.intType).push(type);
+    return frame.popInitialized(appView, dexItemFactory.intType).push(config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
index 73d04d1..7814564 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.util.ListIterator;
@@ -131,11 +132,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ... →
     // ..., objectref
-    return frame.push(type);
+    return frame.push(config, type);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNop.java b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
index 7bc083c..db3ea6a 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -88,8 +89,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame;
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
index ee83adb..f302df8 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -206,11 +207,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value →
     // ..., result
-    return frame.popInitialized(appView, from).push(appView, to);
+    return frame.popInitialized(appView, from).push(appView, config, to);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index 42ebf38..1df0826 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -121,8 +122,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame;
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
index ba04a1c..2d2456e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.StructuralSpecification;
@@ -124,12 +125,12 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     for (DexField ignored : fields) {
       frame = frame.popInitialized(appView, dexItemFactory.objectType);
     }
-    return frame.push(dexItemFactory.objectArrayType);
+    return frame.push(config, dexItemFactory.objectArrayType);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
index be09285..6c007cc 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -131,10 +132,10 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
-    assert !context.getReturnType().isVoidType();
-    return frame.popInitialized(appView, context.getReturnType()).clear();
+    assert !config.getCurrentContext().getReturnType().isVoidType();
+    return frame.popInitialized(appView, config.getCurrentContext().getReturnType()).clear();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
index 0572c8b..e21e6c7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -103,8 +104,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     return frame.clear();
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
index e27498e..345cc84 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.FunctionUtils;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -510,8 +511,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     switch (opcode) {
       case Pop:
@@ -532,13 +533,13 @@
       case Dup:
         // ..., value →
         // ..., value, value
-        return frame.popSingle((state, single) -> state.push(single, single));
+        return frame.popSingle((state, single) -> state.push(config, single, single));
       case DupX1:
         {
           // ..., value2, value1 →
           // ..., value1, value2, value1
           return frame.popSingles(
-              (state, single2, single1) -> state.push(single1, single2, single1));
+              (state, single2, single1) -> state.push(config, single1, single2, single1));
         }
       case DupX2:
         {
@@ -550,8 +551,9 @@
           return frame.popSingle(
               (state1, single1) ->
                   state1.popSingleSingleOrWide(
-                      (state2, single3, single2) -> state2.push(single1, single3, single2, single1),
-                      (state2, wide2) -> state2.push(single1, wide2, single1)));
+                      (state2, single3, single2) ->
+                          state2.push(config, single1, single3, single2, single1),
+                      (state2, wide2) -> state2.push(config, single1, wide2, single1)));
         }
       case Dup2:
         {
@@ -561,8 +563,8 @@
           // ..., value →
           // ..., value, value
           return frame.popSingleSingleOrWide(
-              (state, single2, single1) -> state.push(single2, single1, single2, single1),
-              (state, wide) -> state.push(wide, wide));
+              (state, single2, single1) -> state.push(config, single2, single1, single2, single1),
+              (state, wide) -> state.push(config, wide, wide));
         }
       case Dup2X1:
         {
@@ -575,9 +577,10 @@
               (state1, single2, single1) ->
                   state1.popSingle(
                       (state2, single3) ->
-                          state2.push(single2, single1, single3, single2, single1)),
+                          state2.push(config, single2, single1, single3, single2, single1)),
               (state1, wide1) ->
-                  state1.popSingle((state2, single2) -> state2.push(wide1, single2, wide1)));
+                  state1.popSingle(
+                      (state2, single2) -> state2.push(config, wide1, single2, wide1)));
         }
       case Dup2X2:
         {
@@ -597,18 +600,21 @@
               (state1, single2, single1) ->
                   state1.popSingleSingleOrWide(
                       (state2, single4, single3) ->
-                          state2.push(single2, single1, single4, single3, single2, single1),
-                      (state2, wide3) -> state2.push(single2, single1, wide3, single2, single1)),
+                          state2.push(config, single2, single1, single4, single3, single2, single1),
+                      (state2, wide3) ->
+                          state2.push(config, single2, single1, wide3, single2, single1)),
               (state1, wide1) ->
                   state1.popSingleSingleOrWide(
-                      (state2, single3, single2) -> state2.push(wide1, single3, single2, wide1),
-                      (state2, wide2) -> state2.push(wide1, wide2, wide1)));
+                      (state2, single3, single2) ->
+                          state2.push(config, wide1, single3, single2, wide1),
+                      (state2, wide2) -> state2.push(config, wide1, wide2, wide1)));
         }
       case Swap:
         {
           // ..., value2, value1 →
           // ..., value1, value2
-          return frame.popSingles((state, single2, single1) -> state.push(single1, single2));
+          return frame.popSingles(
+              (state, single2, single1) -> state.push(config, single1, single2));
         }
       default:
         throw new Unreachable("Invalid opcode for CfStackInstruction");
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldRead.java b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldRead.java
index 3950a9c..e0d1ab1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldRead.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldRead.java
@@ -4,7 +4,7 @@
 
 package com.android.tools.r8.cf.code;
 
-import com.android.tools.r8.code.CfOrDexStaticFieldRead;
+import com.android.tools.r8.dex.code.CfOrDexStaticFieldRead;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -18,6 +18,7 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import java.util.ListIterator;
 import org.objectweb.asm.Opcodes;
@@ -83,11 +84,11 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., →
     // ..., value
-    return frame.push(getField().getType());
+    return frame.push(config, getField().getType());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
index 3c64e6a..dc25d3f 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStaticFieldWrite.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import java.util.ListIterator;
 import org.objectweb.asm.Opcodes;
@@ -79,8 +80,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., value →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStore.java b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
index 2d1bf34..e5406bb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
@@ -25,6 +25,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -177,19 +178,20 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., ref →
     // ...
     if (type.isObject()) {
-      return frame.popObject((state, head) -> state.storeLocal(getLocalIndex(), head));
+      return frame.popObject((state, head) -> state.storeLocal(getLocalIndex(), head, config));
     } else {
       assert type.isPrimitive();
       return frame.popInitialized(
           appView,
           type,
-          (state, head) -> state.storeLocal(getLocalIndex(), type.toPrimitiveType(), appView));
+          (state, head) ->
+              state.storeLocal(getLocalIndex(), type.toPrimitiveType(), appView, config));
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
index 695bd9c..44bb2c9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.TraversalUtils;
@@ -184,8 +185,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., index/key →
     // ...
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
index ef2ab8b..126c0ad 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -114,8 +115,8 @@
   @Override
   public CfFrameState evaluate(
       CfFrameState frame,
-      ProgramMethod context,
       AppView<?> appView,
+      CfAnalysisConfig config,
       DexItemFactory dexItemFactory) {
     // ..., objectref →
     // objectref
diff --git a/src/main/java/com/android/tools/r8/cf/code/frame/PrimitiveFrameType.java b/src/main/java/com/android/tools/r8/cf/code/frame/PrimitiveFrameType.java
new file mode 100644
index 0000000..2db1925
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/cf/code/frame/PrimitiveFrameType.java
@@ -0,0 +1,10 @@
+// Copyright (c) 2022, 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.cf.code.frame;
+
+public interface PrimitiveFrameType {
+
+  String getTypeName();
+}
diff --git a/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java b/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
index 1723418..ce215b6 100644
--- a/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.cf.code.CfFrame.FrameType;
 import com.android.tools.r8.cf.code.CfFrame.SingleInitializedType;
+import com.android.tools.r8.cf.code.CfFrame.SinglePrimitiveFrameType;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
 
@@ -27,6 +28,8 @@
 
   boolean isPrimitive();
 
+  SinglePrimitiveFrameType asSinglePrimitive();
+
   boolean isUninitializedNew();
 
   DexType getUninitializedNewType();
diff --git a/src/main/java/com/android/tools/r8/code/BaseInstructionFactory.java b/src/main/java/com/android/tools/r8/code/BaseInstructionFactory.java
deleted file mode 100644
index 4e15eb9..0000000
--- a/src/main/java/com/android/tools/r8/code/BaseInstructionFactory.java
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright (c) 2016, 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.code;
-
-import com.android.tools.r8.graph.OffsetToObjectMapping;
-
-abstract class BaseInstructionFactory {
-
-  static Instruction create(int high, int opcode, BytecodeStream stream,
-      OffsetToObjectMapping mapping) {
-    switch (opcode) {
-      case 0x0:
-        return Nop.create(high, stream);
-      case Move.OPCODE:
-        return new Move(high, stream);
-      case MoveFrom16.OPCODE:
-        return new MoveFrom16(high, stream);
-      case Move16.OPCODE:
-        return new Move16(high, stream);
-      case MoveWide.OPCODE:
-        return new MoveWide(high, stream);
-      case MoveWideFrom16.OPCODE:
-        return new MoveWideFrom16(high, stream);
-      case MoveWide16.OPCODE:
-        return new MoveWide16(high, stream);
-      case MoveObject.OPCODE:
-        return new MoveObject(high, stream);
-      case MoveObjectFrom16.OPCODE:
-        return new MoveObjectFrom16(high, stream);
-      case MoveObject16.OPCODE:
-        return new MoveObject16(high, stream);
-      case MoveResult.OPCODE:
-        return new MoveResult(high, stream);
-      case MoveResultWide.OPCODE:
-        return new MoveResultWide(high, stream);
-      case MoveResultObject.OPCODE:
-        return new MoveResultObject(high, stream);
-      case MoveException.OPCODE:
-        return new MoveException(high, stream);
-      case ReturnVoid.OPCODE:
-        return new ReturnVoid(high, stream);
-      case Return.OPCODE:
-        return new Return(high, stream);
-      case ReturnWide.OPCODE:
-        return new ReturnWide(high, stream);
-      case ReturnObject.OPCODE:
-        return new ReturnObject(high, stream);
-      case Const4.OPCODE:
-        return new Const4(high, stream);
-      case Const16.OPCODE:
-        return new Const16(high, stream);
-      case Const.OPCODE:
-        return new Const(high, stream);
-      case ConstHigh16.OPCODE:
-        return new ConstHigh16(high, stream);
-      case ConstWide16.OPCODE:
-        return new ConstWide16(high, stream);
-      case ConstWide32.OPCODE:
-        return new ConstWide32(high, stream);
-      case ConstWide.OPCODE:
-        return new ConstWide(high, stream);
-      case ConstWideHigh16.OPCODE:
-        return new ConstWideHigh16(high, stream);
-      case ConstString.OPCODE:
-        return new ConstString(high, stream, mapping);
-      case ConstStringJumbo.OPCODE:
-        return new ConstStringJumbo(high, stream, mapping);
-      case ConstClass.OPCODE:
-        return new ConstClass(high, stream, mapping);
-      case MonitorEnter.OPCODE:
-        return new MonitorEnter(high, stream);
-      case MonitorExit.OPCODE:
-        return new MonitorExit(high, stream);
-      case CheckCast.OPCODE:
-        return new CheckCast(high, stream, mapping);
-      case InstanceOf.OPCODE:
-        return new InstanceOf(high, stream, mapping);
-      case ArrayLength.OPCODE:
-        return new ArrayLength(high, stream);
-      case NewInstance.OPCODE:
-        return new NewInstance(high, stream, mapping);
-      case NewArray.OPCODE:
-        return new NewArray(high, stream, mapping);
-      case FilledNewArray.OPCODE:
-        return new FilledNewArray(high, stream, mapping);
-      case FilledNewArrayRange.OPCODE:
-        return new FilledNewArrayRange(high, stream, mapping);
-      case FillArrayData.OPCODE:
-        return new FillArrayData(high, stream);
-      case Throw.OPCODE:
-        return new Throw(high, stream);
-      case Goto.OPCODE:
-        return new Goto(high, stream);
-      case Goto16.OPCODE:
-        return new Goto16(high, stream);
-      case Goto32.OPCODE:
-        return new Goto32(high, stream);
-      case PackedSwitch.OPCODE:
-        return new PackedSwitch(high, stream);
-      case SparseSwitch.OPCODE:
-        return new SparseSwitch(high, stream);
-      case CmplFloat.OPCODE:
-        return new CmplFloat(high, stream);
-      case CmpgFloat.OPCODE:
-        return new CmpgFloat(high, stream);
-      case CmplDouble.OPCODE:
-        return new CmplDouble(high, stream);
-      case CmpgDouble.OPCODE:
-        return new CmpgDouble(high, stream);
-      case CmpLong.OPCODE:
-        return new CmpLong(high, stream);
-      case IfEq.OPCODE:
-        return new IfEq(high, stream);
-      case IfNe.OPCODE:
-        return new IfNe(high, stream);
-      case IfLt.OPCODE:
-        return new IfLt(high, stream);
-      case IfGe.OPCODE:
-        return new IfGe(high, stream);
-      case IfGt.OPCODE:
-        return new IfGt(high, stream);
-      case IfLe.OPCODE:
-        return new IfLe(high, stream);
-      case IfEqz.OPCODE:
-        return new IfEqz(high, stream);
-      case IfNez.OPCODE:
-        return new IfNez(high, stream);
-      case IfLtz.OPCODE:
-        return new IfLtz(high, stream);
-      case IfGez.OPCODE:
-        return new IfGez(high, stream);
-      case IfGtz.OPCODE:
-        return new IfGtz(high, stream);
-      case IfLez.OPCODE:
-        return new IfLez(high, stream);
-      case Aget.OPCODE:
-        return new Aget(high, stream);
-      case AgetWide.OPCODE:
-        return new AgetWide(high, stream);
-      case AgetObject.OPCODE:
-        return new AgetObject(high, stream);
-      case AgetBoolean.OPCODE:
-        return new AgetBoolean(high, stream);
-      case AgetByte.OPCODE:
-        return new AgetByte(high, stream);
-      case AgetChar.OPCODE:
-        return new AgetChar(high, stream);
-      case AgetShort.OPCODE:
-        return new AgetShort(high, stream);
-      case Aput.OPCODE:
-        return new Aput(high, stream);
-      case AputWide.OPCODE:
-        return new AputWide(high, stream);
-      case AputObject.OPCODE:
-        return new AputObject(high, stream);
-      case AputBoolean.OPCODE:
-        return new AputBoolean(high, stream);
-      case AputByte.OPCODE:
-        return new AputByte(high, stream);
-      case AputChar.OPCODE:
-        return new AputChar(high, stream);
-      case AputShort.OPCODE:
-        return new AputShort(high, stream);
-      case Iget.OPCODE:
-        return new Iget(high, stream, mapping);
-      case IgetWide.OPCODE:
-        return new IgetWide(high, stream, mapping);
-      case IgetObject.OPCODE:
-        return new IgetObject(high, stream, mapping);
-      case IgetBoolean.OPCODE:
-        return new IgetBoolean(high, stream, mapping);
-      case IgetByte.OPCODE:
-        return new IgetByte(high, stream, mapping);
-      case IgetChar.OPCODE:
-        return new IgetChar(high, stream, mapping);
-      case IgetShort.OPCODE:
-        return new IgetShort(high, stream, mapping);
-      case Iput.OPCODE:
-        return new Iput(high, stream, mapping);
-      case IputWide.OPCODE:
-        return new IputWide(high, stream, mapping);
-      case IputObject.OPCODE:
-        return new IputObject(high, stream, mapping);
-      case IputBoolean.OPCODE:
-        return new IputBoolean(high, stream, mapping);
-      case IputByte.OPCODE:
-        return new IputByte(high, stream, mapping);
-      case IputChar.OPCODE:
-        return new IputChar(high, stream, mapping);
-      case IputShort.OPCODE:
-        return new IputShort(high, stream, mapping);
-      case Sget.OPCODE:
-        return new Sget(high, stream, mapping);
-      case SgetWide.OPCODE:
-        return new SgetWide(high, stream, mapping);
-      case SgetObject.OPCODE:
-        return new SgetObject(high, stream, mapping);
-      case SgetBoolean.OPCODE:
-        return new SgetBoolean(high, stream, mapping);
-      case SgetByte.OPCODE:
-        return new SgetByte(high, stream, mapping);
-      case SgetChar.OPCODE:
-        return new SgetChar(high, stream, mapping);
-      case SgetShort.OPCODE:
-        return new SgetShort(high, stream, mapping);
-      case Sput.OPCODE:
-        return new Sput(high, stream, mapping);
-      case SputWide.OPCODE:
-        return new SputWide(high, stream, mapping);
-      case SputObject.OPCODE:
-        return new SputObject(high, stream, mapping);
-      case SputBoolean.OPCODE:
-        return new SputBoolean(high, stream, mapping);
-      case SputByte.OPCODE:
-        return new SputByte(high, stream, mapping);
-      case SputChar.OPCODE:
-        return new SputChar(high, stream, mapping);
-      case SputShort.OPCODE:
-        return new SputShort(high, stream, mapping);
-      case InvokeVirtual.OPCODE:
-        return new InvokeVirtual(high, stream, mapping);
-      case InvokeSuper.OPCODE:
-        return new InvokeSuper(high, stream, mapping);
-      case InvokeDirect.OPCODE:
-        return new InvokeDirect(high, stream, mapping);
-      case InvokeStatic.OPCODE:
-        return new InvokeStatic(high, stream, mapping);
-      case InvokeInterface.OPCODE:
-        return new InvokeInterface(high, stream, mapping);
-      case InvokeVirtualRange.OPCODE:
-        return new InvokeVirtualRange(high, stream, mapping);
-      case InvokeSuperRange.OPCODE:
-        return new InvokeSuperRange(high, stream, mapping);
-      case InvokeDirectRange.OPCODE:
-        return new InvokeDirectRange(high, stream, mapping);
-      case InvokeStaticRange.OPCODE:
-        return new InvokeStaticRange(high, stream, mapping);
-      case InvokeInterfaceRange.OPCODE:
-        return new InvokeInterfaceRange(high, stream, mapping);
-      case NegInt.OPCODE:
-        return new NegInt(high, stream);
-      case NotInt.OPCODE:
-        return new NotInt(high, stream);
-      case NegLong.OPCODE:
-        return new NegLong(high, stream);
-      case NotLong.OPCODE:
-        return new NotLong(high, stream);
-      case NegFloat.OPCODE:
-        return new NegFloat(high, stream);
-      case NegDouble.OPCODE:
-        return new NegDouble(high, stream);
-      case IntToLong.OPCODE:
-        return new IntToLong(high, stream);
-      case IntToFloat.OPCODE:
-        return new IntToFloat(high, stream);
-      case IntToDouble.OPCODE:
-        return new IntToDouble(high, stream);
-      case LongToInt.OPCODE:
-        return new LongToInt(high, stream);
-      case LongToFloat.OPCODE:
-        return new LongToFloat(high, stream);
-      case LongToDouble.OPCODE:
-        return new LongToDouble(high, stream);
-      case FloatToInt.OPCODE:
-        return new FloatToInt(high, stream);
-      case FloatToLong.OPCODE:
-        return new FloatToLong(high, stream);
-      case FloatToDouble.OPCODE:
-        return new FloatToDouble(high, stream);
-      case DoubleToInt.OPCODE:
-        return new DoubleToInt(high, stream);
-      case DoubleToLong.OPCODE:
-        return new DoubleToLong(high, stream);
-      case DoubleToFloat.OPCODE:
-        return new DoubleToFloat(high, stream);
-      case IntToByte.OPCODE:
-        return new IntToByte(high, stream);
-      case IntToChar.OPCODE:
-        return new IntToChar(high, stream);
-      case IntToShort.OPCODE:
-        return new IntToShort(high, stream);
-      case AddInt.OPCODE:
-        return new AddInt(high, stream);
-      case SubInt.OPCODE:
-        return new SubInt(high, stream);
-      case MulInt.OPCODE:
-        return new MulInt(high, stream);
-      case DivInt.OPCODE:
-        return new DivInt(high, stream);
-      case RemInt.OPCODE:
-        return new RemInt(high, stream);
-      case AndInt.OPCODE:
-        return new AndInt(high, stream);
-      case OrInt.OPCODE:
-        return new OrInt(high, stream);
-      case XorInt.OPCODE:
-        return new XorInt(high, stream);
-      case ShlInt.OPCODE:
-        return new ShlInt(high, stream);
-      case ShrInt.OPCODE:
-        return new ShrInt(high, stream);
-      case UshrInt.OPCODE:
-        return new UshrInt(high, stream);
-      case AddLong.OPCODE:
-        return new AddLong(high, stream);
-      case SubLong.OPCODE:
-        return new SubLong(high, stream);
-      case MulLong.OPCODE:
-        return new MulLong(high, stream);
-      case DivLong.OPCODE:
-        return new DivLong(high, stream);
-      case RemLong.OPCODE:
-        return new RemLong(high, stream);
-      case AndLong.OPCODE:
-        return new AndLong(high, stream);
-      case OrLong.OPCODE:
-        return new OrLong(high, stream);
-      case XorLong.OPCODE:
-        return new XorLong(high, stream);
-      case ShlLong.OPCODE:
-        return new ShlLong(high, stream);
-      case ShrLong.OPCODE:
-        return new ShrLong(high, stream);
-      case UshrLong.OPCODE:
-        return new UshrLong(high, stream);
-      case AddFloat.OPCODE:
-        return new AddFloat(high, stream);
-      case SubFloat.OPCODE:
-        return new SubFloat(high, stream);
-      case MulFloat.OPCODE:
-        return new MulFloat(high, stream);
-      case DivFloat.OPCODE:
-        return new DivFloat(high, stream);
-      case RemFloat.OPCODE:
-        return new RemFloat(high, stream);
-      case AddDouble.OPCODE:
-        return new AddDouble(high, stream);
-      case SubDouble.OPCODE:
-        return new SubDouble(high, stream);
-      case MulDouble.OPCODE:
-        return new MulDouble(high, stream);
-      case DivDouble.OPCODE:
-        return new DivDouble(high, stream);
-      case RemDouble.OPCODE:
-        return new RemDouble(high, stream);
-      case AddInt2Addr.OPCODE:
-        return new AddInt2Addr(high, stream);
-      case SubInt2Addr.OPCODE:
-        return new SubInt2Addr(high, stream);
-      case MulInt2Addr.OPCODE:
-        return new MulInt2Addr(high, stream);
-      case DivInt2Addr.OPCODE:
-        return new DivInt2Addr(high, stream);
-      case RemInt2Addr.OPCODE:
-        return new RemInt2Addr(high, stream);
-      case AndInt2Addr.OPCODE:
-        return new AndInt2Addr(high, stream);
-      case OrInt2Addr.OPCODE:
-        return new OrInt2Addr(high, stream);
-      case XorInt2Addr.OPCODE:
-        return new XorInt2Addr(high, stream);
-      case ShlInt2Addr.OPCODE:
-        return new ShlInt2Addr(high, stream);
-      case ShrInt2Addr.OPCODE:
-        return new ShrInt2Addr(high, stream);
-      case UshrInt2Addr.OPCODE:
-        return new UshrInt2Addr(high, stream);
-      case AddLong2Addr.OPCODE:
-        return new AddLong2Addr(high, stream);
-      case SubLong2Addr.OPCODE:
-        return new SubLong2Addr(high, stream);
-      case MulLong2Addr.OPCODE:
-        return new MulLong2Addr(high, stream);
-      case DivLong2Addr.OPCODE:
-        return new DivLong2Addr(high, stream);
-      case RemLong2Addr.OPCODE:
-        return new RemLong2Addr(high, stream);
-      case AndLong2Addr.OPCODE:
-        return new AndLong2Addr(high, stream);
-      case OrLong2Addr.OPCODE:
-        return new OrLong2Addr(high, stream);
-      case XorLong2Addr.OPCODE:
-        return new XorLong2Addr(high, stream);
-      case ShlLong2Addr.OPCODE:
-        return new ShlLong2Addr(high, stream);
-      case ShrLong2Addr.OPCODE:
-        return new ShrLong2Addr(high, stream);
-      case UshrLong2Addr.OPCODE:
-        return new UshrLong2Addr(high, stream);
-      case AddFloat2Addr.OPCODE:
-        return new AddFloat2Addr(high, stream);
-      case SubFloat2Addr.OPCODE:
-        return new SubFloat2Addr(high, stream);
-      case MulFloat2Addr.OPCODE:
-        return new MulFloat2Addr(high, stream);
-      case DivFloat2Addr.OPCODE:
-        return new DivFloat2Addr(high, stream);
-      case RemFloat2Addr.OPCODE:
-        return new RemFloat2Addr(high, stream);
-      case AddDouble2Addr.OPCODE:
-        return new AddDouble2Addr(high, stream);
-      case SubDouble2Addr.OPCODE:
-        return new SubDouble2Addr(high, stream);
-      case MulDouble2Addr.OPCODE:
-        return new MulDouble2Addr(high, stream);
-      case DivDouble2Addr.OPCODE:
-        return new DivDouble2Addr(high, stream);
-      case RemDouble2Addr.OPCODE:
-        return new RemDouble2Addr(high, stream);
-      case AddIntLit16.OPCODE:
-        return new AddIntLit16(high, stream);
-      case RsubInt.OPCODE:
-        return new RsubInt(high, stream);
-      case MulIntLit16.OPCODE:
-        return new MulIntLit16(high, stream);
-      case DivIntLit16.OPCODE:
-        return new DivIntLit16(high, stream);
-      case RemIntLit16.OPCODE:
-        return new RemIntLit16(high, stream);
-      case AndIntLit16.OPCODE:
-        return new AndIntLit16(high, stream);
-      case OrIntLit16.OPCODE:
-        return new OrIntLit16(high, stream);
-      case XorIntLit16.OPCODE:
-        return new XorIntLit16(high, stream);
-      case AddIntLit8.OPCODE:
-        return new AddIntLit8(high, stream);
-      case RsubIntLit8.OPCODE:
-        return new RsubIntLit8(high, stream);
-      case MulIntLit8.OPCODE:
-        return new MulIntLit8(high, stream);
-      case DivIntLit8.OPCODE:
-        return new DivIntLit8(high, stream);
-      case RemIntLit8.OPCODE:
-        return new RemIntLit8(high, stream);
-      case AndIntLit8.OPCODE:
-        return new AndIntLit8(high, stream);
-      case OrIntLit8.OPCODE:
-        return new OrIntLit8(high, stream);
-      case XorIntLit8.OPCODE:
-        return new XorIntLit8(high, stream);
-      case ShlIntLit8.OPCODE:
-        return new ShlIntLit8(high, stream);
-      case ShrIntLit8.OPCODE:
-        return new ShrIntLit8(high, stream);
-      case UshrIntLit8.OPCODE:
-        return new UshrIntLit8(high, stream);
-      case InvokePolymorphic.OPCODE:
-        return new InvokePolymorphic(high, stream, mapping);
-      case InvokePolymorphicRange.OPCODE:
-        return new InvokePolymorphicRange(high, stream, mapping);
-      case InvokeCustom.OPCODE:
-        return new InvokeCustom(high, stream, mapping);
-      case InvokeCustomRange.OPCODE:
-        return new InvokeCustomRange(high, stream, mapping);
-      case ConstMethodHandle.OPCODE:
-        return new ConstMethodHandle(high, stream, mapping);
-      case ConstMethodType.OPCODE:
-        return new ConstMethodType(high, stream, mapping);
-      default:
-        throw new IllegalArgumentException("Illegal Opcode: 0x" + Integer.toString(opcode, 16));
-    }
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java b/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
index 173ddd1..e9b23e7 100644
--- a/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
+++ b/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
@@ -3,17 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.debuginfo;
 
-import com.android.tools.r8.code.Instruction;
 import com.android.tools.r8.dex.VirtualFile;
+import com.android.tools.r8.dex.code.DexInstruction;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexDebugInfo;
 import com.android.tools.r8.graph.DexDebugInfo.PcBasedDebugInfo;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.LebUtils;
 import com.android.tools.r8.utils.LineNumberOptimizer;
@@ -69,8 +68,8 @@
     this.paramToInfo = paramToInfo;
   }
 
-  public static void computeForFile(
-      VirtualFile file, GraphLens graphLens, NamingLens namingLens, InternalOptions options) {
+  public static void computeForFile(AppView<?> appView, VirtualFile file) {
+    InternalOptions options = appView.options();
     if (!options.canUseDexPc2PcAsDebugInformation()
         || options.canUseNativeDexPcInsteadOfDebugInfo()
         || options.testing.forcePcBasedEncoding) {
@@ -81,7 +80,7 @@
     Int2ReferenceMap<CostSummary> paramCountToCosts = new Int2ReferenceOpenHashMap<>();
     for (DexProgramClass clazz : file.classes()) {
       IdentityHashMap<DexString, List<ProgramMethod>> overloads =
-          LineNumberOptimizer.groupMethodsByRenamedName(graphLens, namingLens, clazz);
+          LineNumberOptimizer.groupMethodsByRenamedName(appView, clazz);
       for (List<ProgramMethod> methods : overloads.values()) {
         if (methods.size() != 1) {
           // Never use PC info for overloaded methods. They need distinct lines to disambiguate.
@@ -94,7 +93,7 @@
         }
         DexCode code = definition.getCode().asDexCode();
         DexDebugInfo debugInfo = code.getDebugInfo();
-        Instruction lastInstruction = getLastExecutableInstruction(code);
+        DexInstruction lastInstruction = getLastExecutableInstruction(code);
         if (lastInstruction == null) {
           continue;
         }
@@ -120,7 +119,7 @@
     if (conversionInfo.cutoff < 0) {
       return false;
     }
-    Instruction lastInstruction = getLastExecutableInstruction(code);
+    DexInstruction lastInstruction = getLastExecutableInstruction(code);
     if (lastInstruction == null) {
       return false;
     }
@@ -264,9 +263,9 @@
     }
   }
 
-  private static Instruction getLastExecutableInstruction(DexCode code) {
-    Instruction lastInstruction = null;
-    for (Instruction instruction : code.instructions) {
+  private static DexInstruction getLastExecutableInstruction(DexCode code) {
+    DexInstruction lastInstruction = null;
+    for (DexInstruction instruction : code.instructions) {
       if (!instruction.isPayload()) {
         lastInstruction = instruction;
       }
diff --git a/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java b/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java
index eaec5a0..8dc8979 100644
--- a/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java
+++ b/src/main/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryKeepRuleGenerator.java
@@ -44,13 +44,10 @@
 public class DesugaredLibraryKeepRuleGenerator {
 
   private final AppView<AppInfoWithClassHierarchy> appView;
-  private final NamingLens namingLens;
   private final InternalOptions options;
 
-  public DesugaredLibraryKeepRuleGenerator(
-      AppView<AppInfoWithClassHierarchy> appView, NamingLens namingLens) {
+  public DesugaredLibraryKeepRuleGenerator(AppView<AppInfoWithClassHierarchy> appView) {
     this.appView = appView;
-    this.namingLens = namingLens;
     this.options = appView.options();
   }
 
@@ -68,7 +65,7 @@
         || !options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
       return false;
     }
-    return namingLens.hasPrefixRewritingLogic()
+    return appView.getNamingLens().hasPrefixRewritingLogic()
         || options.machineDesugaredLibrarySpecification.hasEmulatedInterfaces();
   }
 
@@ -83,6 +80,7 @@
     byte[] synthesizedLibraryClassesPackageDescriptorPrefix =
         DexString.encodeToMutf8(
             "L" + desugaredLibrarySpecification.getSynthesizedLibraryClassesPackagePrefix());
+    NamingLens namingLens = appView.getNamingLens();
     return type ->
         namingLens.prefixRewrittenType(type) != null
             || desugaredLibrarySpecification.isEmulatedInterfaceRewrittenType(type)
@@ -91,7 +89,7 @@
   }
 
   private KeepRuleGenerator createTraceReferencesConsumer() {
-    return new KeepRuleGenerator(appView, namingLens);
+    return new KeepRuleGenerator(appView);
   }
 
   private static class KeepRuleGenerator extends TraceReferencesConsumer.ForwardingConsumer {
@@ -111,14 +109,13 @@
     // ArrayReference to DexType, nor conversions from (formal types, return type) to DexProto.
     private final Map<TypeReference, DexType> typeConversionCache = new ConcurrentHashMap<>();
 
-    private KeepRuleGenerator(
-        AppView<? extends AppInfoWithClassHierarchy> appView, NamingLens namingLens) {
+    private KeepRuleGenerator(AppView<? extends AppInfoWithClassHierarchy> appView) {
       super(
           TraceReferencesKeepRules.builder()
               .setOutputConsumer(appView.options().desugaredLibraryKeepRuleConsumer)
               .build());
       this.factory = appView.dexItemFactory();
-      this.namingLens = namingLens;
+      this.namingLens = appView.getNamingLens();
     }
 
     @Override
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 cc04d01..d2cff23 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -83,7 +83,6 @@
 public class ApplicationWriter {
 
   public final AppView<?> appView;
-  public final NamingLens namingLens;
   public final InternalOptions options;
   private final CodeToKeep desugaredLibraryCodeToKeep;
   private final Predicate<DexType> isTypeMissing;
@@ -151,38 +150,42 @@
     }
 
     @Override
-    public boolean setAnnotationsDirectoryForClass(DexProgramClass clazz,
-        DexAnnotationDirectory annotationDirectory) {
-      return true;
+    public void setAnnotationsDirectoryForClass(
+        DexProgramClass clazz, DexAnnotationDirectory annotationDirectory) {
+      // Intentionally empty.
+    }
+
+    @Override
+    public void setStaticFieldValuesForClass(
+        DexProgramClass clazz, DexEncodedArray staticFieldValues) {
+      add(staticFieldValues);
     }
   }
 
-  public ApplicationWriter(
-      AppView<?> appView,
-      List<Marker> markers,
-      NamingLens namingLens) {
+  public ApplicationWriter(AppView<?> appView, List<Marker> markers) {
     this(
         appView,
         markers,
-        namingLens,
         null);
   }
 
   public ApplicationWriter(
       AppView<?> appView,
       List<Marker> markers,
-      NamingLens namingLens,
       DexIndexedConsumer consumer) {
     this.appView = appView;
     this.options = appView.options();
-    this.desugaredLibraryCodeToKeep = CodeToKeep.createCodeToKeep(options, namingLens);
+    this.desugaredLibraryCodeToKeep = CodeToKeep.createCodeToKeep(appView);
     this.markers = markers;
-    this.namingLens = namingLens;
     this.programConsumer = consumer;
     this.isTypeMissing =
         PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
   }
 
+  private NamingLens getNamingLens() {
+    return appView.getNamingLens();
+  }
+
   private List<VirtualFile> distribute(ExecutorService executorService)
       throws ExecutionException, IOException {
     Collection<DexProgramClass> classes = appView.appInfo().classes();
@@ -242,12 +245,12 @@
     Collection<DexProgramClass> classes = appView.appInfo().classes();
     Reference2LongMap<DexString> inputChecksums = new Reference2LongOpenHashMap<>(classes.size());
     for (DexProgramClass clazz : classes) {
-      inputChecksums.put(namingLens.lookupDescriptor(clazz.getType()), clazz.getChecksum());
+      inputChecksums.put(getNamingLens().lookupDescriptor(clazz.getType()), clazz.getChecksum());
     }
     for (VirtualFile file : files) {
       ClassesChecksum toWrite = new ClassesChecksum();
       for (DexProgramClass clazz : file.classes()) {
-        DexString desc = namingLens.lookupDescriptor(clazz.type);
+        DexString desc = getNamingLens().lookupDescriptor(clazz.type);
         toWrite.addChecksum(desc.toString(), inputChecksums.getLong(desc));
       }
       file.injectString(appView.dexItemFactory().createString(toWrite.toJsonString()));
@@ -307,7 +310,7 @@
 
       // TODO(b/151313617): Sorting annotations mutates elements so run single threaded on main.
       timing.begin("Sort Annotations");
-      SortAnnotations sortAnnotations = new SortAnnotations(namingLens);
+      SortAnnotations sortAnnotations = new SortAnnotations(getNamingLens());
       appView.appInfo().classes().forEach((clazz) -> clazz.addDependencies(sortAnnotations));
       timing.end();
 
@@ -322,8 +325,7 @@
                   Timing fileTiming = Timing.create("VirtualFile " + virtualFile.getId(), options);
                   computeOffsetMappingAndRewriteJumboStrings(
                       virtualFile, lazyDexStrings, fileTiming);
-                  DebugRepresentation.computeForFile(
-                      virtualFile, appView.graphLens(), namingLens, options);
+                  DebugRepresentation.computeForFile(appView, virtualFile);
                   fileTiming.end();
                   return fileTiming;
                 },
@@ -332,15 +334,14 @@
         merger.end();
       }
 
-
-      // Now code offsets are fixed, compute the mapping file content.
+      // Now that the instruction offsets in each code object are fixed, compute the mapping file
+      // content.
       if (willComputeProguardMap()) {
         // TODO(b/220999985): Refactor line number optimization to be per file and thread it above.
         DebugRepresentationPredicate representation =
             DebugRepresentation.fromFiles(virtualFiles, options);
         delayedProguardMapId.set(
-            runAndWriteMap(
-                inputApp, appView, namingLens, timing, originalSourceFiles, representation));
+            runAndWriteMap(inputApp, appView, timing, originalSourceFiles, representation));
       }
 
       // With the mapping id/hash known, it is safe to compute the remaining dex strings.
@@ -368,7 +369,7 @@
         merger.add(timings);
         merger.end();
         if (globalsSyntheticsConsumer != null) {
-          globalsSyntheticsConsumer.finished(appView, namingLens);
+          globalsSyntheticsConsumer.finished(appView);
         }
       }
 
@@ -380,7 +381,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(appView.appInfo().app(), appView, namingLens, options);
+      supplyAdditionalConsumers(appView);
     } finally {
       timing.end();
     }
@@ -484,7 +485,7 @@
       return;
     }
     timing.begin("Compute object offset mapping");
-    virtualFile.computeMapping(appView, namingLens, lazyDexStrings.size(), timing);
+    virtualFile.computeMapping(appView, lazyDexStrings.size(), timing);
     timing.end();
     timing.begin("Rewrite jumbo strings");
     rewriteCodeWithJumboStrings(
@@ -528,7 +529,7 @@
     timing.end();
 
     timing.begin("Write bytes");
-    ByteBufferResult result = writeDexFile(objectMapping, byteBufferProvider, timing);
+    ByteBufferResult result = writeDexFile(objectMapping, byteBufferProvider, virtualFile, timing);
     ByteDataView data =
         new ByteDataView(result.buffer.array(), result.buffer.arrayOffset(), result.length);
     timing.end();
@@ -550,11 +551,8 @@
     byteBufferProvider.releaseByteBuffer(result.buffer.asByteBuffer());
   }
 
-  public static void supplyAdditionalConsumers(
-      DexApplication application,
-      AppView<?> appView,
-      NamingLens namingLens,
-      InternalOptions options) {
+  public static void supplyAdditionalConsumers(AppView<?> appView) {
+    InternalOptions options = appView.options();
     if (options.configurationConsumer != null) {
       ExceptionUtils.withConsumeResourceHandler(
           options.reporter, options.configurationConsumer,
@@ -563,22 +561,22 @@
     }
     if (options.mainDexListConsumer != null) {
       ExceptionUtils.withConsumeResourceHandler(
-          options.reporter, options.mainDexListConsumer, writeMainDexList(appView, namingLens));
+          options.reporter, options.mainDexListConsumer, writeMainDexList(appView));
       ExceptionUtils.withFinishedResourceHandler(options.reporter, options.mainDexListConsumer);
     }
 
     DataResourceConsumer dataResourceConsumer = options.dataResourceConsumer;
     if (dataResourceConsumer != null) {
-      ImmutableList<DataResourceProvider> dataResourceProviders = application.dataResourceProviders;
-      ResourceAdapter resourceAdapter =
-          new ResourceAdapter(appView, application.dexItemFactory, namingLens, options);
-
+      ImmutableList<DataResourceProvider> dataResourceProviders =
+          appView.app().dataResourceProviders;
+      ResourceAdapter resourceAdapter = new ResourceAdapter(appView);
       adaptAndPassDataResources(
           options, dataResourceConsumer, dataResourceProviders, resourceAdapter);
 
       // Write the META-INF/services resources. Sort on service names and keep the order from
       // the input for the implementation lines for deterministic output.
       if (!appView.appServices().isEmpty()) {
+        NamingLens namingLens = appView.getNamingLens();
         appView
             .appServices()
             .visit(
@@ -605,8 +603,7 @@
     if (options.featureSplitConfiguration != null) {
       for (DataResourceProvidersAndConsumer entry :
           options.featureSplitConfiguration.getDataResourceProvidersAndConsumers()) {
-        ResourceAdapter resourceAdapter =
-            new ResourceAdapter(appView, application.dexItemFactory, namingLens, options);
+        ResourceAdapter resourceAdapter = new ResourceAdapter(appView);
         adaptAndPassDataResources(
             options, entry.getConsumer(), entry.getProviders(), resourceAdapter);
       }
@@ -704,7 +701,7 @@
           } else {
             annotations.add(
                 DexAnnotation.createInnerClassAnnotation(
-                    namingLens.lookupInnerName(innerClass, options),
+                    getNamingLens().lookupInnerName(innerClass, options),
                     innerClass.getAccess(),
                     options.itemFactory));
             if (innerClass.getOuter() != null && innerClass.isNamed()) {
@@ -726,7 +723,7 @@
     if (clazz.getClassSignature().hasSignature()) {
       annotations.add(
           DexAnnotation.createSignatureAnnotation(
-              clazz.getClassSignature().toRenamedString(namingLens, isTypeMissing),
+              clazz.getClassSignature().toRenamedString(getNamingLens(), isTypeMissing),
               options.itemFactory));
     }
 
@@ -756,7 +753,7 @@
             ArrayUtils.appendSingleElement(
                 field.annotations().annotations,
                 DexAnnotation.createSignatureAnnotation(
-                    field.getGenericSignature().toRenamedString(namingLens, isTypeMissing),
+                    field.getGenericSignature().toRenamedString(getNamingLens(), isTypeMissing),
                     options.itemFactory))));
     field.clearGenericSignature();
   }
@@ -771,7 +768,7 @@
             ArrayUtils.appendSingleElement(
                 method.annotations().annotations,
                 DexAnnotation.createSignatureAnnotation(
-                    method.getGenericSignature().toRenamedString(namingLens, isTypeMissing),
+                    method.getGenericSignature().toRenamedString(getNamingLens(), isTypeMissing),
                     options.itemFactory))));
     method.clearGenericSignature();
   }
@@ -827,15 +824,12 @@
   }
 
   private ByteBufferResult writeDexFile(
-      ObjectToOffsetMapping objectMapping, ByteBufferProvider provider, Timing timing) {
+      ObjectToOffsetMapping objectMapping,
+      ByteBufferProvider provider,
+      VirtualFile virtualFile,
+      Timing timing) {
     FileWriter fileWriter =
-        new FileWriter(
-            provider,
-            objectMapping,
-            appView.appInfo(),
-            options,
-            namingLens,
-            desugaredLibraryCodeToKeep);
+        new FileWriter(appView, provider, objectMapping, desugaredLibraryCodeToKeep, virtualFile);
     // Collect the non-fixed sections.
     timing.time("collect", fileWriter::collect);
     // Generate and write the bytes.
@@ -847,7 +841,7 @@
         .replace('.', '/') + ".class";
   }
 
-  private static String writeMainDexList(AppView<?> appView, NamingLens namingLens) {
+  private static String writeMainDexList(AppView<?> appView) {
     // TODO(b/178231294): Clean up by streaming directly to the consumer.
     MainDexInfo mainDexInfo = appView.appInfo().getMainDexInfo();
     StringBuilder builder = new StringBuilder();
@@ -855,7 +849,7 @@
     mainDexInfo.forEach(list::add);
     list.sort(DexType::compareTo);
     list.forEach(
-        type -> builder.append(mapMainDexListName(type, namingLens)).append('\n'));
+        type -> builder.append(mapMainDexListName(type, appView.getNamingLens())).append('\n'));
     return builder.toString();
   }
 
diff --git a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
index 6b77d5b..5a0ec34 100644
--- a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
+++ b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.dex;
 
 import com.android.tools.r8.errors.Unreachable;
+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.DexProgramClass;
@@ -24,7 +25,9 @@
 
 public abstract class CodeToKeep {
 
-  static CodeToKeep createCodeToKeep(InternalOptions options, NamingLens namingLens) {
+  static CodeToKeep createCodeToKeep(AppView<?> appView) {
+    InternalOptions options = appView.options();
+    NamingLens namingLens = appView.getNamingLens();
     if ((!namingLens.hasPrefixRewritingLogic()
             && options.machineDesugaredLibrarySpecification.getMaintainType().isEmpty()
             && !options.machineDesugaredLibrarySpecification.hasEmulatedInterfaces())
@@ -32,7 +35,7 @@
         || options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
       return new NopCodeToKeep();
     }
-    return new DesugaredLibraryCodeToKeep(namingLens, options);
+    return new DesugaredLibraryCodeToKeep(appView);
   }
 
   public abstract void recordMethod(DexMethod method);
@@ -58,17 +61,16 @@
       boolean all = false;
     }
 
-    private final NamingLens namingLens;
+    private final AppView<?> appView;
     private final Map<DexType, KeepStruct> toKeep = new ConcurrentHashMap<>();
-    private final InternalOptions options;
 
-    public DesugaredLibraryCodeToKeep(NamingLens namingLens, InternalOptions options) {
-      this.namingLens = namingLens;
-      this.options = options;
+    public DesugaredLibraryCodeToKeep(AppView<?> appView) {
+      this.appView = appView;
     }
 
     private boolean shouldKeep(DexType givenType) {
-      if (namingLens.prefixRewrittenType(givenType) != null
+      InternalOptions options = appView.options();
+      if (appView.getNamingLens().prefixRewrittenType(givenType) != null
           || options.machineDesugaredLibrarySpecification.isCustomConversionRewrittenType(givenType)
           || options.machineDesugaredLibrarySpecification.isEmulatedInterfaceRewrittenType(
               givenType)
@@ -84,14 +86,14 @@
       DexType type =
           InterfaceDesugaringSyntheticHelper.isCompanionClassType(givenType)
               ? InterfaceDesugaringSyntheticHelper.getInterfaceClassType(
-                  givenType, options.dexItemFactory())
+                  givenType, appView.dexItemFactory())
               : givenType;
       return options.machineDesugaredLibrarySpecification.getMaintainType().contains(type);
     }
 
     @Override
     public void recordMethod(DexMethod method) {
-      DexType baseType = method.holder.toBaseType(options.dexItemFactory());
+      DexType baseType = method.holder.toBaseType(appView.dexItemFactory());
       if (shouldKeep(baseType)) {
         keepClass(baseType);
         if (!method.holder.isArrayType()) {
@@ -110,7 +112,7 @@
 
     @Override
     public void recordField(DexField field) {
-      DexType baseType = field.holder.toBaseType(options.dexItemFactory());
+      DexType baseType = field.holder.toBaseType(appView.dexItemFactory());
       if (shouldKeep(baseType)) {
         keepClass(baseType);
         if (!field.holder.isArrayType()) {
@@ -146,7 +148,7 @@
     }
 
     private void keepClass(DexType type) {
-      DexType baseType = type.lookupBaseType(options.itemFactory);
+      DexType baseType = type.lookupBaseType(appView.dexItemFactory());
       toKeep.putIfAbsent(baseType, new KeepStruct());
     }
 
@@ -156,7 +158,7 @@
     }
 
     private String convertType(DexType type) {
-      DexString rewriteType = namingLens.prefixRewrittenType(type);
+      DexString rewriteType = appView.getNamingLens().prefixRewrittenType(type);
       DexString descriptor = rewriteType != null ? rewriteType : type.descriptor;
       return DescriptorUtils.descriptorToJavaType(descriptor.toString());
     }
@@ -166,13 +168,6 @@
       // TODO(b/134734081): Stream the consumer instead of building the String.
       StringBuilder sb = new StringBuilder();
       String cr = System.lineSeparator();
-      Comparator<DexReference> comparator =
-          new Comparator<DexReference>() {
-            @Override
-            public int compare(DexReference o1, DexReference o2) {
-              return o1.compareTo(o2);
-            }
-          };
       for (DexType type : CollectionUtils.sort(toKeep.keySet(), getComparator())) {
         KeepStruct keepStruct = toKeep.get(type);
         sb.append("-keep class ").append(convertType(type));
@@ -214,12 +209,7 @@
     }
 
     private static <T extends DexReference> Comparator<T> getComparator() {
-      return new Comparator<T>() {
-        @Override
-        public int compare(T o1, T o2) {
-          return o1.compareTo(o2);
-        }
-      };
+      return DexReference::compareTo;
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/dex/CompatByteBuffer.java b/src/main/java/com/android/tools/r8/dex/CompatByteBuffer.java
index 6e32c6e..0d36470 100644
--- a/src/main/java/com/android/tools/r8/dex/CompatByteBuffer.java
+++ b/src/main/java/com/android/tools/r8/dex/CompatByteBuffer.java
@@ -117,6 +117,10 @@
     return asByteBuffer().getShort();
   }
 
+  public short getShort(int offset) {
+    return asByteBuffer().getShort(offset);
+  }
+
   public void put(byte aByte) {
     asByteBuffer().put(aByte);
   }
diff --git a/src/main/java/com/android/tools/r8/dex/DefaultMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/DefaultMixedSectionLayoutStrategy.java
new file mode 100644
index 0000000..dee0f55
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/dex/DefaultMixedSectionLayoutStrategy.java
@@ -0,0 +1,118 @@
+// Copyright (c) 2022, 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.dex;
+
+import com.android.tools.r8.dex.FileWriter.MixedSectionOffsets;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexAnnotation;
+import com.android.tools.r8.graph.DexAnnotationDirectory;
+import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexEncodedArray;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.DexWritableCode;
+import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.naming.MemberNaming.Signature;
+import com.android.tools.r8.utils.collections.ProgramMethodMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+
+public class DefaultMixedSectionLayoutStrategy extends MixedSectionLayoutStrategy {
+
+  final AppView<?> appView;
+  final MixedSectionOffsets mixedSectionOffsets;
+
+  public DefaultMixedSectionLayoutStrategy(
+      AppView<?> appView, MixedSectionOffsets mixedSectionOffsets) {
+    this.appView = appView;
+    this.mixedSectionOffsets = mixedSectionOffsets;
+  }
+
+  @Override
+  public Collection<DexAnnotation> getAnnotationLayout() {
+    return mixedSectionOffsets.getAnnotations();
+  }
+
+  @Override
+  public Collection<DexAnnotationDirectory> getAnnotationDirectoryLayout() {
+    return mixedSectionOffsets.getAnnotationDirectories();
+  }
+
+  @Override
+  public Collection<DexAnnotationSet> getAnnotationSetLayout() {
+    return mixedSectionOffsets.getAnnotationSets();
+  }
+
+  @Override
+  public Collection<ParameterAnnotationsList> getAnnotationSetRefListLayout() {
+    return mixedSectionOffsets.getAnnotationSetRefLists();
+  }
+
+  @Override
+  public Collection<DexProgramClass> getClassDataLayout() {
+    return mixedSectionOffsets.getClassesWithData();
+  }
+
+  @Override
+  public Collection<ProgramMethod> getCodeLayout() {
+    return getCodeLayoutForClasses(mixedSectionOffsets.getClassesWithData());
+  }
+
+  final Collection<ProgramMethod> getCodeLayoutForClasses(Collection<DexProgramClass> classes) {
+    ProgramMethodMap<String> codeToSignatureMap = ProgramMethodMap.create();
+    List<ProgramMethod> codesSorted = new ArrayList<>();
+    for (DexProgramClass clazz : classes) {
+      clazz.forEachProgramMethodMatching(
+          DexEncodedMethod::hasCode,
+          method -> {
+            DexWritableCode code = method.getDefinition().getDexWritableCodeOrNull();
+            assert code != null || method.getDefinition().shouldNotHaveCode();
+            if (code != null) {
+              codesSorted.add(method);
+              codeToSignatureMap.put(
+                  method, getKeyForDexCodeSorting(method, appView.app().getProguardMap()));
+            }
+          });
+    }
+    codesSorted.sort(Comparator.comparing(codeToSignatureMap::get));
+    return codesSorted;
+  }
+
+  private static String getKeyForDexCodeSorting(ProgramMethod method, ClassNameMapper proguardMap) {
+    // TODO(b/173999869): Could this instead compute sorting using dex items?
+    Signature signature;
+    String originalClassName;
+    if (proguardMap != null) {
+      signature = proguardMap.originalSignatureOf(method.getReference());
+      originalClassName = proguardMap.originalNameOf(method.getHolderType());
+    } else {
+      signature = MethodSignature.fromDexMethod(method.getReference());
+      originalClassName = method.getHolderType().toSourceString();
+    }
+    return originalClassName + signature;
+  }
+
+  @Override
+  public Collection<DexEncodedArray> getEncodedArrayLayout() {
+    return mixedSectionOffsets.getEncodedArrays();
+  }
+
+  @Override
+  public Collection<DexString> getStringDataLayout() {
+    return mixedSectionOffsets.getStringData();
+  }
+
+  @Override
+  public Collection<DexTypeList> getTypeListLayout() {
+    return mixedSectionOffsets.getTypeLists();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 7a3ccf5..8705bb4 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -9,8 +9,8 @@
 import static com.android.tools.r8.utils.EncodedValueUtils.parseUnsigned;
 
 import com.android.tools.r8.ProgramResource.Kind;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.code.InstructionFactory;
+import com.android.tools.r8.dex.code.DexInstruction;
+import com.android.tools.r8.dex.code.DexInstructionFactory;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.ApplicationReaderMap;
 import com.android.tools.r8.graph.ClassAccessFlags;
@@ -167,7 +167,7 @@
       dexReader.position(offset);
       dexReader.align(4);
       DexCode code = parseCodeItem();
-      codes.put(offset, code);  // Update the file local offset to code mapping.
+      codes.put(offset, code); // Update the file local offset to code mapping.
       dexReader.position(currentPos);
     }
   }
@@ -297,7 +297,7 @@
           DexMethodHandle value =
               indexedItems.getMethodHandle((int) parseUnsigned(dexReader, size));
           return new DexValue.DexValueMethodHandle(value);
-      }
+        }
       default:
         throw new IndexOutOfBoundsException();
     }
@@ -306,9 +306,10 @@
   private void checkName(DexString name) {
     if (!options.itemFactory.getSkipNameValidationForTesting()
         && !name.isValidSimpleName(options.getMinApiLevel())) {
-      throw new CompilationError("Space characters in SimpleName '"
-        + name.toASCIIString()
-        + "' are not allowed prior to DEX version 040");
+      throw new CompilationError(
+          "Space characters in SimpleName '"
+              + name.toASCIIString()
+              + "' are not allowed prior to DEX version 040");
     }
   }
 
@@ -333,7 +334,6 @@
     return values;
   }
 
-
   private DexEncodedArray parseEncodedArray() {
     return new DexEncodedArray(parseEncodedArrayValues());
   }
@@ -415,10 +415,11 @@
     DexParameterAnnotation[] result = new DexParameterAnnotation[size];
     for (int i = 0; i < size; i++) {
       DexMethod method = indexedItems.getMethod(methodIndices[i]);
-      result[i] = new DexParameterAnnotation(
-          method,
-          annotationSetRefListAt(annotationOffsets[i])
-              .withParameterCount(method.proto.parameters.size()));
+      result[i] =
+          new DexParameterAnnotation(
+              method,
+              annotationSetRefListAt(annotationOffsets[i])
+                  .withParameterCount(method.proto.parameters.size()));
     }
     dexReader.position(saved);
     return result;
@@ -433,11 +434,11 @@
 
   private <S> Object cacheAt(int offset, Supplier<S> function) {
     if (offset == 0) {
-      return null;  // return null for offset zero.
+      return null; // return null for offset zero.
     }
     Object result = offsetMap.get(offset);
     if (result != null) {
-      return result;  // return the cached result.
+      return result; // return the cached result.
     }
     // Cache is empty so parse the structure.
     dexReader.position(offset);
@@ -484,8 +485,7 @@
     }
     DexType dupType = DexAnnotationSet.findDuplicateEntryType(result);
     if (dupType != null) {
-      throw new CompilationError(
-          "Multiple annotations of type `" + dupType.toSourceString() + "`");
+      throw new CompilationError("Multiple annotations of type `" + dupType.toSourceString() + "`");
     }
     return DexAnnotationSet.create(result);
   }
@@ -500,8 +500,8 @@
   }
 
   private AnnotationsDirectory annotationsDirectoryAt(int offset) {
-    return (AnnotationsDirectory) cacheAt(offset, this::parseAnnotationsDirectory,
-        AnnotationsDirectory::empty);
+    return (AnnotationsDirectory)
+        cacheAt(offset, this::parseAnnotationsDirectory, AnnotationsDirectory::empty);
   }
 
   private AnnotationsDirectory parseAnnotationsDirectory() {
@@ -513,10 +513,7 @@
     final DexMethodAnnotation[] methods = parseMethodAnnotations(methodsSize);
     final DexParameterAnnotation[] parameters = parseParameterAnnotations(parametersSize);
     return new AnnotationsDirectory(
-        annotationSetAt(classAnnotationsOff),
-        fields,
-        methods,
-        parameters);
+        annotationSetAt(classAnnotationsOff), fields, methods, parameters);
   }
 
   private DexDebugInfo debugInfoAt(int offset) {
@@ -548,72 +545,82 @@
           events.add(dexItemFactory.createAdvanceLine(dexReader.getSleb128()));
           isPcBasedDebugInfo = false;
           break;
-        case Constants.DBG_START_LOCAL: {
-          int registerNum = dexReader.getUleb128();
-          int nameIdx = dexReader.getUleb128p1();
-          int typeIdx = dexReader.getUleb128p1();
-          events.add(new DexDebugEvent.StartLocal(
-              registerNum,
-              nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
-              typeIdx == NO_INDEX ? null : indexedItems.getType(typeIdx),
-              null));
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_START_LOCAL_EXTENDED: {
-          int registerNum = dexReader.getUleb128();
-          int nameIdx = dexReader.getUleb128p1();
-          int typeIdx = dexReader.getUleb128p1();
-          int sigIdx = dexReader.getUleb128p1();
-          events.add(new DexDebugEvent.StartLocal(
-              registerNum,
-              nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
-              typeIdx == NO_INDEX ? null : indexedItems.getType(typeIdx),
-              sigIdx == NO_INDEX ? null : indexedItems.getString(sigIdx)));
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_END_LOCAL: {
-          events.add(dexItemFactory.createEndLocal(dexReader.getUleb128()));
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_RESTART_LOCAL: {
-          events.add(dexItemFactory.createRestartLocal(dexReader.getUleb128()));
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_SET_PROLOGUE_END: {
-          events.add(dexItemFactory.createSetPrologueEnd());
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_SET_EPILOGUE_BEGIN: {
-          events.add(dexItemFactory.createSetEpilogueBegin());
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        case Constants.DBG_SET_FILE: {
-          int nameIdx = dexReader.getUleb128p1();
-          DexString sourceFile = nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx);
-          if (options.readDebugSetFileEvent) {
-            events.add(dexItemFactory.createSetFile(sourceFile));
+        case Constants.DBG_START_LOCAL:
+          {
+            int registerNum = dexReader.getUleb128();
+            int nameIdx = dexReader.getUleb128p1();
+            int typeIdx = dexReader.getUleb128p1();
+            events.add(
+                new DexDebugEvent.StartLocal(
+                    registerNum,
+                    nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
+                    typeIdx == NO_INDEX ? null : indexedItems.getType(typeIdx),
+                    null));
+            isPcBasedDebugInfo = false;
+            break;
           }
-          isPcBasedDebugInfo = false;
-          break;
-        }
-        default: {
-          assert head >= 0x0a && head <= 0xff;
-          Default event = dexItemFactory.createDefault(head);
-          events.add(event);
-          if (isPcBasedDebugInfo) {
-            if (events.size() == 1) {
-              isPcBasedDebugInfo = event.equals(dexItemFactory.zeroChangeDefaultEvent);
-            } else {
-              isPcBasedDebugInfo = event.equals(dexItemFactory.oneChangeDefaultEvent);
+        case Constants.DBG_START_LOCAL_EXTENDED:
+          {
+            int registerNum = dexReader.getUleb128();
+            int nameIdx = dexReader.getUleb128p1();
+            int typeIdx = dexReader.getUleb128p1();
+            int sigIdx = dexReader.getUleb128p1();
+            events.add(
+                new DexDebugEvent.StartLocal(
+                    registerNum,
+                    nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
+                    typeIdx == NO_INDEX ? null : indexedItems.getType(typeIdx),
+                    sigIdx == NO_INDEX ? null : indexedItems.getString(sigIdx)));
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        case Constants.DBG_END_LOCAL:
+          {
+            events.add(dexItemFactory.createEndLocal(dexReader.getUleb128()));
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        case Constants.DBG_RESTART_LOCAL:
+          {
+            events.add(dexItemFactory.createRestartLocal(dexReader.getUleb128()));
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        case Constants.DBG_SET_PROLOGUE_END:
+          {
+            events.add(dexItemFactory.createSetPrologueEnd());
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        case Constants.DBG_SET_EPILOGUE_BEGIN:
+          {
+            events.add(dexItemFactory.createSetEpilogueBegin());
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        case Constants.DBG_SET_FILE:
+          {
+            int nameIdx = dexReader.getUleb128p1();
+            DexString sourceFile = nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx);
+            if (options.readDebugSetFileEvent) {
+              events.add(dexItemFactory.createSetFile(sourceFile));
+            }
+            isPcBasedDebugInfo = false;
+            break;
+          }
+        default:
+          {
+            assert head >= 0x0a && head <= 0xff;
+            Default event = dexItemFactory.createDefault(head);
+            events.add(event);
+            if (isPcBasedDebugInfo) {
+              if (events.size() == 1) {
+                isPcBasedDebugInfo = event.equals(dexItemFactory.zeroChangeDefaultEvent);
+              } else {
+                isPcBasedDebugInfo = event.equals(dexItemFactory.oneChangeDefaultEvent);
+              }
             }
           }
-        }
       }
     }
     return isPcBasedDebugInfo
@@ -650,8 +657,8 @@
     }
   }
 
-  private DexEncodedField[] readFields(int size, DexFieldAnnotation[] annotations,
-      DexValue[] staticValues) {
+  private DexEncodedField[] readFields(
+      int size, DexFieldAnnotation[] annotations, DexValue[] staticValues) {
     DexEncodedField[] fields = new DexEncodedField[size];
     int fieldIndex = 0;
     MemberAnnotationIterator<DexField, DexAnnotationSet> annotationIterator =
@@ -784,8 +791,9 @@
       // Check if constraints from
       // https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1 are met.
       if (!flags.areValid(Constants.CORRESPONDING_CLASS_FILE_VERSION, false)) {
-        throw new CompilationError("Class " + type.toSourceString()
-            + " has illegal access flags. Found: " + flags, origin);
+        throw new CompilationError(
+            "Class " + type.toSourceString() + " has illegal access flags. Found: " + flags,
+            origin);
       }
       DexEncodedField[] staticFields = DexEncodedField.EMPTY_ARRAY;
       DexEncodedField[] instanceFields = DexEncodedField.EMPTY_ARRAY;
@@ -811,8 +819,11 @@
         int directMethodsSize = dexReader.getUleb128();
         int virtualMethodsSize = dexReader.getUleb128();
 
-        staticFields = readFields(staticFieldsSize, annotationsDirectory.fields,
-            staticValues != null ? staticValues.values : null);
+        staticFields =
+            readFields(
+                staticFieldsSize,
+                annotationsDirectory.fields,
+                staticValues != null ? staticValues.values : null);
         instanceFields = readFields(instanceFieldsSize, annotationsDirectory.fields, null);
         directMethods =
             readMethods(
@@ -857,7 +868,7 @@
               dexItemFactory.getSkipNameValidationForTesting(),
               checksumSupplier,
               null);
-      classCollection.accept(clazz);  // Update the application object.
+      classCollection.accept(clazz); // Update the application object.
     }
   }
 
@@ -913,8 +924,13 @@
       for (int i = 0; i < result.length; i++) {
         DexSection dexSection = result[i];
         int nextOffset = i < result.length - 1 ? result[i + 1].offset : dexSection.offset;
-        Log.debug(this.getClass(), "Read section 0x%04x @ 0x%08x #items %08d size 0x%08x.",
-            dexSection.type, dexSection.offset, dexSection.length, nextOffset - dexSection.offset);
+        Log.debug(
+            this.getClass(),
+            "Read section 0x%04x @ 0x%08x #items %08d size 0x%08x.",
+            dexSection.type,
+            dexSection.offset,
+            dexSection.length,
+            nextOffset - dexSection.offset);
       }
     }
     for (int i = 0; i < mapSize - 1; i++) {
@@ -940,7 +956,7 @@
         code[i] = dexReader.getShort();
       }
       if (insnsSize % 2 != 0) {
-        dexReader.getUshort();  // Skip padding ushort
+        dexReader.getUshort(); // Skip padding ushort
       }
       if (triesSize > 0) {
         Int2IntArrayMap handlerMap = new Int2IntArrayMap();
@@ -987,20 +1003,20 @@
     int saved = dexReader.position();
     DexDebugInfo debugInfo = debugInfoAt(debugInfoOff);
     dexReader.position(saved);
-    InstructionFactory factory = new InstructionFactory();
-    Instruction[] instructions =
+    DexInstructionFactory factory = new DexInstructionFactory();
+    DexInstruction[] instructions =
         factory.readSequenceFrom(ShortBuffer.wrap(code), 0, code.length, indexedItems);
     return new DexCode(registerSize, insSize, outsSize, instructions, tries, handlers, debugInfo);
   }
 
   void populateIndexTables() {
     // Populate structures that are already sorted upon read.
-    populateStrings();  // Depends on nothing.
+    populateStrings(); // Depends on nothing.
     populateChecksums(); // Depends on Strings.
-    populateTypes();  // Depends on Strings.
-    populateFields();  // Depends on Types, and Strings.
-    populateProtos();  // Depends on Types and Strings.
-    populateMethods();  // Depends on Protos, Types, and Strings.
+    populateTypes(); // Depends on Strings.
+    populateFields(); // Depends on Types, and Strings.
+    populateProtos(); // Depends on Types and Strings.
+    populateMethods(); // Depends on Protos, Types, and Strings.
     populateMethodHandles(); // Depends on Methods and Fields
     populateCallSites(); // Depends on MethodHandles
   }
@@ -1176,9 +1192,8 @@
    * From https://source.android.com/devices/tech/dalvik/dex-format#file-layout:
    *
    * <p>This list must be sorted, where the defining type (by type_id index) is the major order,
-   * method name (by string_id index) is the intermediate order, and method prototype
-   * (by proto_id index) is the minor order. The list must not contain any duplicate entries.
-   *
+   * method name (by string_id index) is the intermediate order, and method prototype (by proto_id
+   * index) is the minor order. The list must not contain any duplicate entries.
    */
   private boolean verifyOrderOfMethodIds(DexSection dexSection) {
     if (dexSection.length >= 2) {
@@ -1288,18 +1303,20 @@
       case INSTANCE_GET:
       case INSTANCE_PUT:
       case STATIC_GET:
-      case STATIC_PUT: {
-        fieldOrMethod = indexedItems.getField(indexFieldOrMethod);
-        break;
-      }
+      case STATIC_PUT:
+        {
+          fieldOrMethod = indexedItems.getField(indexFieldOrMethod);
+          break;
+        }
       case INVOKE_CONSTRUCTOR:
       case INVOKE_DIRECT:
       case INVOKE_INTERFACE:
       case INVOKE_INSTANCE:
-      case INVOKE_STATIC: {
-        fieldOrMethod = indexedItems.getMethod(indexFieldOrMethod);
-        break;
-      }
+      case INVOKE_STATIC:
+        {
+          fieldOrMethod = indexedItems.getMethod(indexFieldOrMethod);
+          break;
+        }
       default:
         throw new AssertionError("Method handle type unsupported in a dex file.");
     }
@@ -1367,15 +1384,15 @@
     private static final DexParameterAnnotation[] NO_PARAMETER_ANNOTATIONS =
         new DexParameterAnnotation[0];
 
-    private static final DexFieldAnnotation[] NO_FIELD_ANNOTATIONS =
-        new DexFieldAnnotation[0];
+    private static final DexFieldAnnotation[] NO_FIELD_ANNOTATIONS = new DexFieldAnnotation[0];
 
-    private static final DexMethodAnnotation[] NO_METHOD_ANNOTATIONS =
-        new DexMethodAnnotation[0];
+    private static final DexMethodAnnotation[] NO_METHOD_ANNOTATIONS = new DexMethodAnnotation[0];
 
     private static final AnnotationsDirectory THE_EMPTY_ANNOTATIONS_DIRECTORY =
-        new AnnotationsDirectory(DexAnnotationSet.empty(),
-            NO_FIELD_ANNOTATIONS, new DexMethodAnnotation[0],
+        new AnnotationsDirectory(
+            DexAnnotationSet.empty(),
+            NO_FIELD_ANNOTATIONS,
+            new DexMethodAnnotation[0],
             NO_PARAMETER_ANNOTATIONS);
 
     public final DexAnnotationSet clazz;
@@ -1383,7 +1400,8 @@
     public final DexMethodAnnotation[] methods;
     public final DexParameterAnnotation[] parameters;
 
-    AnnotationsDirectory(DexAnnotationSet clazz,
+    AnnotationsDirectory(
+        DexAnnotationSet clazz,
         DexFieldAnnotation[] fields,
         DexMethodAnnotation[] methods,
         DexParameterAnnotation[] parameters) {
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index ebf21c6..2c9ca25 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -11,14 +11,12 @@
 import com.android.tools.r8.errors.InvokeCustomDiagnostic;
 import com.android.tools.r8.errors.PrivateInterfaceMethodDiagnostic;
 import com.android.tools.r8.errors.StaticInterfaceMethodDiagnostic;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationDirectory;
 import com.android.tools.r8.graph.DexAnnotationElement;
 import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexCallSite;
-import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexCode.Try;
 import com.android.tools.r8.graph.DexCode.TryHandler;
 import com.android.tools.r8.graph.DexCode.TryHandler.TypeAddrPair;
@@ -46,12 +44,8 @@
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramClassVisitor;
-import com.android.tools.r8.graph.ProgramDexCode;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.logging.Log;
-import com.android.tools.r8.naming.ClassNameMapper;
-import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.position.MethodPosition;
 import com.android.tools.r8.synthesis.SyntheticNaming;
@@ -70,8 +64,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
@@ -96,31 +88,33 @@
     }
   }
 
-  private final ObjectToOffsetMapping mapping;
-  private final DexApplication application;
-  private final InternalOptions options;
+  private final AppView<?> appView;
   private final GraphLens graphLens;
-  private final NamingLens namingLens;
+  private final ObjectToOffsetMapping mapping;
+  private final InternalOptions options;
   private final DexOutputBuffer dest;
   private final MixedSectionOffsets mixedSectionOffsets;
   private final CodeToKeep desugaredLibraryCodeToKeep;
-  private final Map<DexProgramClass, DexEncodedArray> staticFieldValues = new IdentityHashMap<>();
+  private final VirtualFile virtualFile;
 
   public FileWriter(
+      AppView<?> appView,
       ByteBufferProvider provider,
       ObjectToOffsetMapping mapping,
-      AppInfo appInfo,
-      InternalOptions options,
-      NamingLens namingLens,
-      CodeToKeep desugaredLibraryCodeToKeep) {
+      CodeToKeep desugaredLibraryCodeToKeep,
+      VirtualFile virtualFile) {
+    this.appView = appView;
+    this.graphLens = appView.graphLens();
     this.mapping = mapping;
-    this.application = appInfo.app();
-    this.options = options;
-    this.graphLens = mapping.getGraphLens();
-    this.namingLens = namingLens;
+    this.options = appView.options();
     this.dest = new DexOutputBuffer(provider);
     this.mixedSectionOffsets = new MixedSectionOffsets(options);
     this.desugaredLibraryCodeToKeep = desugaredLibraryCodeToKeep;
+    this.virtualFile = virtualFile;
+  }
+
+  private NamingLens getNamingLens() {
+    return appView.getNamingLens();
   }
 
   public static void writeEncodedAnnotation(
@@ -140,20 +134,19 @@
 
   public FileWriter collect() {
     // Use the class array from the mapping, as it has a deterministic iteration order.
-    new ProgramClassDependencyCollector(application, mapping.getClasses())
-        .run(mapping.getClasses());
+    new ProgramClassDependencyCollector(appView, mapping.getClasses()).run(mapping.getClasses());
 
     // Add the static values for all fields now that we have committed to their sorting.
     mixedSectionOffsets.getClassesWithData().forEach(this::addStaticFieldValues);
 
-    // String data is not tracked by the MixedSectionCollection.new AppInfo(application, null)
+    // String data is not tracked by the MixedSectionCollection.
     assert mixedSectionOffsets.stringData.size() == 0;
     for (DexString string : mapping.getStrings()) {
       mixedSectionOffsets.add(string);
     }
     // Neither are the typelists in protos...
     for (DexProto proto : mapping.getProtos()) {
-      mixedSectionOffsets.add(proto.parameters);
+      mixedSectionOffsets.add(proto.getParameters());
     }
 
     DexItem.collectAll(mixedSectionOffsets, mapping.getCallSites());
@@ -174,7 +167,9 @@
     layout.setCodesOffset(layout.dataSectionOffset);
 
     // Sort the codes first, as their order might impact size due to alignment constraints.
-    List<ProgramDexCode> codes = sortDexCodesByClassName();
+    MixedSectionLayoutStrategy mixedSectionLayoutStrategy =
+        MixedSectionLayoutStrategy.create(appView, mixedSectionOffsets, virtualFile);
+    Collection<ProgramMethod> codes = mixedSectionLayoutStrategy.getCodeLayout();
 
     // Output the debug_info_items first, as they have no dependencies.
     dest.moveTo(layout.getCodesOffset() + sizeOfCodeItems(codes));
@@ -184,10 +179,11 @@
       // Ensure deterministic ordering of debug info by sorting consistent with the code objects.
       layout.setDebugInfosOffset(dest.align(1));
       Set<DexDebugInfoForWriting> seen = new HashSet<>(mixedSectionOffsets.getDebugInfos().size());
-      for (ProgramDexCode code : codes) {
-        DexDebugInfoForWriting info = code.getCode().getDebugInfoForWriting();
+      for (ProgramMethod method : codes) {
+        DexDebugInfoForWriting info =
+            method.getDefinition().getCode().asDexWritableCode().getDebugInfoForWriting();
         if (info != null && seen.add(info)) {
-          writeDebugItem(info, graphLens);
+          writeDebugItem(info);
         }
       }
     }
@@ -203,21 +199,41 @@
 
     // Now the type lists and rest.
     dest.moveTo(layout.getTypeListsOffset());
-    writeItems(mixedSectionOffsets.getTypeLists(), layout::alreadySetOffset, this::writeTypeList);
-    writeItems(mixedSectionOffsets.getStringData(), layout::setStringDataOffsets,
+    writeItems(
+        mixedSectionLayoutStrategy.getTypeListLayout(),
+        layout::alreadySetOffset,
+        this::writeTypeList);
+    writeItems(
+        mixedSectionLayoutStrategy.getStringDataLayout(),
+        layout::setStringDataOffsets,
         this::writeStringData);
-    writeItems(mixedSectionOffsets.getAnnotations(), layout::setAnnotationsOffset,
+    writeItems(
+        mixedSectionLayoutStrategy.getAnnotationLayout(),
+        layout::setAnnotationsOffset,
         this::writeAnnotation);
-    writeItems(mixedSectionOffsets.getClassesWithData(), layout::setClassDataOffset,
+    writeItems(
+        mixedSectionLayoutStrategy.getClassDataLayout(),
+        layout::setClassDataOffset,
         this::writeClassData);
-    writeItems(mixedSectionOffsets.getEncodedArrays(), layout::setEncodedArrarysOffset,
+    writeItems(
+        mixedSectionLayoutStrategy.getEncodedArrayLayout(),
+        layout::setEncodedArraysOffset,
         this::writeEncodedArray);
-    writeItems(mixedSectionOffsets.getAnnotationSets(), layout::setAnnotationSetsOffset,
-        this::writeAnnotationSet, 4);
-    writeItems(mixedSectionOffsets.getAnnotationSetRefLists(),
-        layout::setAnnotationSetRefListsOffset, this::writeAnnotationSetRefList, 4);
-    writeItems(mixedSectionOffsets.getAnnotationDirectories(),
-        layout::setAnnotationDirectoriesOffset, this::writeAnnotationDirectory, 4);
+    writeItems(
+        mixedSectionLayoutStrategy.getAnnotationSetLayout(),
+        layout::setAnnotationSetsOffset,
+        this::writeAnnotationSet,
+        4);
+    writeItems(
+        mixedSectionLayoutStrategy.getAnnotationSetRefListLayout(),
+        layout::setAnnotationSetRefListsOffset,
+        this::writeAnnotationSetRefList,
+        4);
+    writeItems(
+        mixedSectionLayoutStrategy.getAnnotationDirectoryLayout(),
+        layout::setAnnotationDirectoriesOffset,
+        this::writeAnnotationDirectory,
+        4);
 
     // Add the map at the end
     layout.setMapOffset(dest.align(4));
@@ -265,7 +281,7 @@
   //     static methods, as well as public non-abstract (default)
   //     and private instance methods.
   private void checkInterfaceMethod(DexEncodedMethod method) {
-    if (application.dexItemFactory.isClassConstructor(method.getReference())) {
+    if (appView.dexItemFactory().isClassConstructor(method.getReference())) {
       return; // Class constructor is always OK.
     }
     if (method.accessFlags.isStatic()) {
@@ -304,7 +320,7 @@
   }
 
   private boolean verifyNames() {
-    if (options.itemFactory.getSkipNameValidationForTesting()) {
+    if (appView.dexItemFactory().getSkipNameValidationForTesting()) {
       return true;
     }
 
@@ -325,40 +341,6 @@
     return true;
   }
 
-  private List<ProgramDexCode> sortDexCodesByClassName() {
-    Map<ProgramDexCode, String> codeToSignatureMap = new IdentityHashMap<>();
-    List<ProgramDexCode> codesSorted = new ArrayList<>();
-    for (DexProgramClass clazz : mapping.getClasses()) {
-      clazz.forEachProgramMethod(
-          method -> {
-            DexWritableCode code = method.getDefinition().getDexWritableCodeOrNull();
-            assert code != null || method.getDefinition().shouldNotHaveCode();
-            if (code != null) {
-              ProgramDexCode programCode = new ProgramDexCode(code, method);
-              codesSorted.add(programCode);
-              codeToSignatureMap.put(
-                  programCode, getKeyForDexCodeSorting(method, application.getProguardMap()));
-            }
-          });
-    }
-    codesSorted.sort(Comparator.comparing(codeToSignatureMap::get));
-    return codesSorted;
-  }
-
-  private static String getKeyForDexCodeSorting(ProgramMethod method, ClassNameMapper proguardMap) {
-    // TODO(b/173999869): Could this instead compute sorting using dex items?
-    Signature signature;
-    String originalClassName;
-    if (proguardMap != null) {
-      signature = proguardMap.originalSignatureOf(method.getReference());
-      originalClassName = proguardMap.originalNameOf(method.getHolderType());
-    } else {
-      signature = MethodSignature.fromDexMethod(method.getReference());
-      originalClassName = method.getHolderType().toSourceString();
-    }
-    return originalClassName + signature;
-  }
-
   private <T extends IndexedDexItem> void writeFixedSectionItems(
       Collection<T> items, int offset, Consumer<T> writer) {
     assert dest.position() == offset;
@@ -390,11 +372,11 @@
     }
   }
 
-  private int sizeOfCodeItems(Iterable<ProgramDexCode> codes) {
+  private int sizeOfCodeItems(Iterable<ProgramMethod> methods) {
     int size = 0;
-    for (ProgramDexCode code : codes) {
+    for (ProgramMethod method : methods) {
       size = alignSize(4, size);
-      size += sizeOfCodeItem(code.getCode());
+      size += sizeOfCodeItem(method.getDefinition().getCode().asDexWritableCode());
     }
     return size;
   }
@@ -431,7 +413,7 @@
   }
 
   private void writeTypeItem(DexType type) {
-    DexString descriptor = namingLens.lookupDescriptor(type);
+    DexString descriptor = getNamingLens().lookupDescriptor(type);
     dest.putInt(mapping.getOffsetFor(descriptor));
   }
 
@@ -448,7 +430,7 @@
     int typeIdx = mapping.getOffsetFor(field.type);
     assert (typeIdx & 0xFFFF) == typeIdx;
     dest.putShort((short) typeIdx);
-    DexString name = namingLens.lookupName(field);
+    DexString name = getNamingLens().lookupName(field);
     dest.putInt(mapping.getOffsetFor(name));
   }
 
@@ -459,13 +441,12 @@
     int protoIdx = mapping.getOffsetFor(method.proto);
     assert (protoIdx & 0xFFFF) == protoIdx;
     dest.putShort((short) protoIdx);
-    DexString name = namingLens.lookupName(method);
+    DexString name = getNamingLens().lookupName(method);
     dest.putInt(mapping.getOffsetFor(name));
   }
 
   private void writeClassDefItem(DexProgramClass clazz) {
     desugaredLibraryCodeToKeep.recordHierarchyOf(clazz);
-
     dest.putInt(mapping.getOffsetFor(clazz.type));
     dest.putInt(clazz.accessFlags.getAsDexAccessFlags());
     dest.putInt(
@@ -476,19 +457,20 @@
     dest.putInt(mixedSectionOffsets.getOffsetForAnnotationsDirectory(clazz));
     dest.putInt(
         clazz.hasMethodsOrFields() ? mixedSectionOffsets.getOffsetFor(clazz) : Constants.NO_OFFSET);
-    dest.putInt(mixedSectionOffsets.getOffsetFor(staticFieldValues.get(clazz)));
+    dest.putInt(
+        mixedSectionOffsets.getOffsetFor(mixedSectionOffsets.getStaticFieldValuesForClass(clazz)));
   }
 
-  private void writeDebugItem(DexDebugInfoForWriting debugInfo, GraphLens graphLens) {
+  private void writeDebugItem(DexDebugInfoForWriting debugInfo) {
     mixedSectionOffsets.setOffsetFor(debugInfo, dest.position());
     dest.putBytes(new DebugBytecodeWriter(debugInfo, mapping, graphLens).generate());
   }
 
-  private void writeCodeItem(ProgramDexCode code) {
-    writeCodeItem(code.getCode(), code.getMethod());
+  private void writeCodeItem(ProgramMethod method) {
+    writeCodeItem(method, method.getDefinition().getCode().asDexWritableCode());
   }
 
-  private void writeCodeItem(DexWritableCode code, ProgramMethod method) {
+  private void writeCodeItem(ProgramMethod method, DexWritableCode code) {
     mixedSectionOffsets.setOffsetFor(method.getDefinition(), code, dest.align(4));
     // Fixed size header information.
     dest.putShort((short) code.getRegisterSize(method));
@@ -630,7 +612,7 @@
             a.getReference().acceptCompareTo(b.getReference(), mapping.getCompareToVisitor()));
     int currentOffset = 0;
     for (DexEncodedField field : fields) {
-      assert field.validateDexValue(application.dexItemFactory);
+      assert field.validateDexValue(appView.dexItemFactory());
       int nextOffset = mapping.getOffsetFor(field.getReference());
       assert nextOffset - currentOffset >= 0;
       dest.putUleb128(nextOffset - currentOffset);
@@ -683,10 +665,9 @@
     // We have collected the individual components of this array due to the data stored in
     // DexEncodedField#staticValues. However, we have to collect the DexEncodedArray itself
     // here.
-    DexEncodedArray staticValues = clazz.computeStaticValuesArray(namingLens);
+    DexEncodedArray staticValues = clazz.computeStaticValuesArray(getNamingLens());
     if (staticValues != null) {
-      staticFieldValues.put(clazz, staticValues);
-      mixedSectionOffsets.add(staticValues);
+      mixedSectionOffsets.setStaticFieldValuesForClass(clazz, staticValues);
     }
   }
 
@@ -780,8 +761,11 @@
         mixedSectionOffsets.getAnnotations().size());
     size += writeMapItem(Constants.TYPE_CLASS_DATA_ITEM, layout.getClassDataOffset(),
         mixedSectionOffsets.getClassesWithData().size());
-    size += writeMapItem(Constants.TYPE_ENCODED_ARRAY_ITEM, layout.getEncodedArrarysOffset(),
-        mixedSectionOffsets.getEncodedArrays().size());
+    size +=
+        writeMapItem(
+            Constants.TYPE_ENCODED_ARRAY_ITEM,
+            layout.getEncodedArraysOffset(),
+            mixedSectionOffsets.getEncodedArrays().size());
     size += writeMapItem(Constants.TYPE_ANNOTATION_SET_ITEM, layout.getAnnotationSetsOffset(),
         mixedSectionOffsets.getAnnotationSets().size());
     size += writeMapItem(Constants.TYPE_ANNOTATION_SET_REF_LIST,
@@ -885,12 +869,19 @@
     private int annotationSetRefListsOffset = NOT_SET; // aligned
     private int annotationDirectoriesOffset = NOT_SET; // aligned
     private int classDataOffset = NOT_SET;
-    private int encodedArrarysOffset = NOT_SET;
+    private int encodedArraysOffset = NOT_SET;
     private int mapOffset = NOT_SET;
     private int endOfFile = NOT_SET;
 
-    private Layout(int stringIdsOffset, int typeIdsOffset, int protoIdsOffset, int fieldIdsOffset,
-        int methodIdsOffset, int classDefsOffset, int callSiteIdsOffset, int methodHandleIdsOffset,
+    private Layout(
+        int stringIdsOffset,
+        int typeIdsOffset,
+        int protoIdsOffset,
+        int fieldIdsOffset,
+        int methodIdsOffset,
+        int classDefsOffset,
+        int callSiteIdsOffset,
+        int methodHandleIdsOffset,
         int dataSectionOffset) {
       this.stringIdsOffset = stringIdsOffset;
       this.typeIdsOffset = typeIdsOffset;
@@ -1029,14 +1020,14 @@
       this.classDataOffset = classDataOffset;
     }
 
-    public int getEncodedArrarysOffset() {
-      assert isValidOffset(encodedArrarysOffset, false);
-      return encodedArrarysOffset;
+    public int getEncodedArraysOffset() {
+      assert isValidOffset(encodedArraysOffset, false);
+      return encodedArraysOffset;
     }
 
-    public void setEncodedArrarysOffset(int encodedArrarysOffset) {
-      assert this.encodedArrarysOffset == NOT_SET;
-      this.encodedArrarysOffset = encodedArrarysOffset;
+    public void setEncodedArraysOffset(int encodedArraysOffset) {
+      assert this.encodedArraysOffset == NOT_SET;
+      this.encodedArraysOffset = encodedArraysOffset;
     }
 
     public int getMapOffset() {
@@ -1063,7 +1054,7 @@
    * These offsets are then used to resolve cross-references between items from different sections
    * into a file offset.
    */
-  private static class MixedSectionOffsets extends MixedSectionCollection {
+  static class MixedSectionOffsets extends MixedSectionCollection {
 
     private static final int NOT_SET = -1;
     private static final int NOT_KNOWN = -2;
@@ -1078,12 +1069,14 @@
         = createObject2IntMap();
     private final Object2IntMap<DexAnnotationDirectory> annotationDirectories
         = createObject2IntMap();
-    private final Object2IntMap<DexProgramClass> classesWithData = createObject2IntMap();
+    private final Reference2IntMap<DexProgramClass> classesWithData = createReference2IntMap();
     private final Object2IntMap<DexEncodedArray> encodedArrays = createObject2IntMap();
-    private final Map<DexProgramClass, DexAnnotationDirectory> clazzToAnnotationDirectory
-        = new HashMap<>();
+    private final Map<DexProgramClass, DexAnnotationDirectory> classToAnnotationDirectory =
+        new IdentityHashMap<>();
+    private final Map<DexProgramClass, DexEncodedArray> classToStaticFieldValues =
+        new IdentityHashMap<>();
 
-    private final AndroidApiLevel minApiLevel;
+    private final InternalOptions options;
 
     private static <T> Object2IntMap<T> createObject2IntMap() {
       Object2IntMap<T> result = new Object2IntLinkedOpenHashMap<>();
@@ -1098,7 +1091,7 @@
     }
 
     private MixedSectionOffsets(InternalOptions options) {
-      this.minApiLevel = options.getMinApiLevel();
+      this.options = options;
     }
 
     private <T> boolean add(Object2IntMap<T> map, T item) {
@@ -1129,9 +1122,7 @@
 
     @Override
     public boolean add(DexAnnotationSet annotationSet) {
-      // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
-      // work around a DALVIK bug. See b/36951668.
-      if ((minApiLevel.isGreaterThanOrEqualTo(AndroidApiLevel.J_MR1)) && annotationSet.isEmpty()) {
+      if (!options.canHaveDalvikEmptyAnnotationSetBug() && annotationSet.isEmpty()) {
         return false;
       }
       return add(annotationSets, annotationSet);
@@ -1174,11 +1165,19 @@
     }
 
     @Override
-    public boolean setAnnotationsDirectoryForClass(DexProgramClass clazz,
-        DexAnnotationDirectory annotationDirectory) {
-      DexAnnotationDirectory previous = clazzToAnnotationDirectory.put(clazz, annotationDirectory);
+    public void setAnnotationsDirectoryForClass(
+        DexProgramClass clazz, DexAnnotationDirectory annotationDirectory) {
+      DexAnnotationDirectory previous = classToAnnotationDirectory.put(clazz, annotationDirectory);
       assert previous == null;
-      return add(annotationDirectories, annotationDirectory);
+      add(annotationDirectories, annotationDirectory);
+    }
+
+    @Override
+    public void setStaticFieldValuesForClass(
+        DexProgramClass clazz, DexEncodedArray staticFieldValues) {
+      DexEncodedArray previous = classToStaticFieldValues.put(clazz, staticFieldValues);
+      assert previous == null;
+      add(staticFieldValues);
     }
 
     public boolean add(DexString string) {
@@ -1266,12 +1265,11 @@
       return lookup(debugInfo, debugInfos);
     }
 
-
     public int getOffsetForAnnotationsDirectory(DexProgramClass clazz) {
       if (!clazz.hasClassOrMemberAnnotations()) {
         return Constants.NO_OFFSET;
       }
-      int offset = annotationDirectories.getInt(clazzToAnnotationDirectory.get(clazz));
+      int offset = annotationDirectories.getInt(getAnnotationDirectoryForClass(clazz));
       assert offset != NOT_KNOWN;
       return offset;
     }
@@ -1281,9 +1279,7 @@
     }
 
     public int getOffsetFor(DexAnnotationSet annotationSet) {
-      // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
-      // work around a DALVIK bug. See b/36951668.
-      if ((minApiLevel.isGreaterThanOrEqualTo(AndroidApiLevel.J_MR1)) && annotationSet.isEmpty()) {
+      if (!options.canHaveDalvikEmptyAnnotationSetBug() && annotationSet.isEmpty()) {
         return 0;
       }
       return lookup(annotationSet, annotationSets);
@@ -1332,9 +1328,7 @@
     }
 
     void setOffsetFor(DexAnnotationSet annotationSet, int offset) {
-      // Until we fully drop support for API levels < 17, we have to emit an empty annotation set to
-      // work around a DALVIK bug. See b/36951668.
-      assert (minApiLevel.isLessThan(AndroidApiLevel.J_MR1)) || !annotationSet.isEmpty();
+      assert options.canHaveDalvikEmptyAnnotationSetBug() || !annotationSet.isEmpty();
       setOffsetFor(annotationSet, offset, annotationSets);
     }
 
@@ -1354,29 +1348,31 @@
       assert offset != 0 && !annotationSetRefList.isEmpty();
       setOffsetFor(annotationSetRefList, offset, annotationSetRefLists);
     }
+
+    DexAnnotationDirectory getAnnotationDirectoryForClass(DexProgramClass clazz) {
+      return classToAnnotationDirectory.get(clazz);
+    }
+
+    DexEncodedArray getStaticFieldValuesForClass(DexProgramClass clazz) {
+      return classToStaticFieldValues.get(clazz);
+    }
   }
 
   private class ProgramClassDependencyCollector extends ProgramClassVisitor {
 
-    private final Set<DexClass> includedClasses = Sets.newIdentityHashSet();
+    private final Set<DexProgramClass> includedClasses = Sets.newIdentityHashSet();
 
-    ProgramClassDependencyCollector(DexApplication application, DexProgramClass[] includedClasses) {
-      super(application);
+    ProgramClassDependencyCollector(AppView<?> appView, DexProgramClass[] includedClasses) {
+      super(appView);
       Collections.addAll(this.includedClasses, includedClasses);
     }
 
     @Override
-    public void visit(DexType type) {
-      // Intentionally left empty.
-    }
-
-    @Override
-    public void visit(DexClass clazz) {
+    public void visit(DexProgramClass clazz) {
       // Only visit classes that are part of the current file.
-      if (!includedClasses.contains(clazz)) {
-        return;
+      if (includedClasses.contains(clazz)) {
+        clazz.addDependencies(mixedSectionOffsets);
       }
-      clazz.addDependencies(mixedSectionOffsets);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/dex/IndexedItemCollection.java b/src/main/java/com/android/tools/r8/dex/IndexedItemCollection.java
index 1de1144..393439d 100644
--- a/src/main/java/com/android/tools/r8/dex/IndexedItemCollection.java
+++ b/src/main/java/com/android/tools/r8/dex/IndexedItemCollection.java
@@ -12,9 +12,7 @@
 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.GraphLens;
 import com.android.tools.r8.graph.IndexedDexItem;
-import com.android.tools.r8.graph.InitClassLens;
 
 /**
  * Common interface for constant pools.
@@ -100,24 +98,4 @@
    * @return true if the method handle was not in the pool before.
    */
   boolean addMethodHandle(DexMethodHandle methodHandle);
-
-  default GraphLens getGraphLens() {
-    return GraphLens.getIdentityLens();
-  }
-
-  default InitClassLens getInitClassLens() {
-    return InitClassLens.getThrowingInstance();
-  }
-
-  default DexString getRenamedName(DexMethod method) {
-    return method.name;
-  }
-
-  default DexString getRenamedName(DexField field) {
-    return field.name;
-  }
-
-  default DexString getRenamedDescriptor(DexType type) {
-    return type.descriptor;
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java b/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
index 9978311..c78eaac 100644
--- a/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
+++ b/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
@@ -10,7 +10,6 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.IntBox;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.google.common.collect.Maps;
@@ -70,7 +69,7 @@
 
     public void updateNumbersOfIds() {
       // Use a temporary VirtualFile to evaluate the number of ids in the group.
-      VirtualFile virtualFile = new VirtualFile(0, appView, namingLens);
+      VirtualFile virtualFile = new VirtualFile(0, appView);
       // Note: sort not needed.
       for (DexProgramClass clazz : members) {
         virtualFile.addClass(clazz);
@@ -286,7 +285,6 @@
   private final Set<DexProgramClass> classes;
   private final AppView<?> appView;
   private final IntBox nextFileId;
-  private final NamingLens namingLens;
   private final DirectSubClassesInfo directSubClasses;
 
   public InheritanceClassInDexDistributor(
@@ -295,7 +293,6 @@
       List<VirtualFile> filesForDistribution,
       Set<DexProgramClass> classes,
       IntBox nextFileId,
-      NamingLens namingLens,
       AppView<?> appView,
       ExecutorService executorService) {
     this.mainDex = mainDex;
@@ -303,7 +300,6 @@
     this.filesForDistribution = filesForDistribution;
     this.classes = classes;
     this.nextFileId = nextFileId;
-    this.namingLens = namingLens;
     this.appView = appView;
     this.executorService = executorService;
 
@@ -320,7 +316,7 @@
     // Allocate member of groups depending on
     // the main dex members
     VirtualFileCycler cycler =
-        new VirtualFileCycler(files, filesForDistribution, appView, namingLens, nextFileId);
+        new VirtualFileCycler(files, filesForDistribution, appView, nextFileId);
     for (Iterator<ClassGroup> iter = remainingInheritanceGroups.iterator(); iter.hasNext();) {
       ClassGroup group = iter.next();
       if (group.dependsOnMainDexClasses) {
diff --git a/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java b/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
index fc3784f..785158d 100644
--- a/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
+++ b/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
@@ -6,29 +6,29 @@
 import static com.android.tools.r8.graph.DexCode.TryHandler.NO_HANDLER;
 import static com.android.tools.r8.graph.DexDebugEventBuilder.addDefaultEventWithAdvancePcIfNecessary;
 
-import com.android.tools.r8.code.ConstString;
-import com.android.tools.r8.code.ConstStringJumbo;
-import com.android.tools.r8.code.Format21t;
-import com.android.tools.r8.code.Format22t;
-import com.android.tools.r8.code.Format31t;
-import com.android.tools.r8.code.Goto;
-import com.android.tools.r8.code.Goto16;
-import com.android.tools.r8.code.Goto32;
-import com.android.tools.r8.code.IfEq;
-import com.android.tools.r8.code.IfEqz;
-import com.android.tools.r8.code.IfGe;
-import com.android.tools.r8.code.IfGez;
-import com.android.tools.r8.code.IfGt;
-import com.android.tools.r8.code.IfGtz;
-import com.android.tools.r8.code.IfLe;
-import com.android.tools.r8.code.IfLez;
-import com.android.tools.r8.code.IfLt;
-import com.android.tools.r8.code.IfLtz;
-import com.android.tools.r8.code.IfNe;
-import com.android.tools.r8.code.IfNez;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.code.Nop;
-import com.android.tools.r8.code.SwitchPayload;
+import com.android.tools.r8.dex.code.DexConstString;
+import com.android.tools.r8.dex.code.DexConstStringJumbo;
+import com.android.tools.r8.dex.code.DexFormat21t;
+import com.android.tools.r8.dex.code.DexFormat22t;
+import com.android.tools.r8.dex.code.DexFormat31t;
+import com.android.tools.r8.dex.code.DexGoto;
+import com.android.tools.r8.dex.code.DexGoto16;
+import com.android.tools.r8.dex.code.DexGoto32;
+import com.android.tools.r8.dex.code.DexIfEq;
+import com.android.tools.r8.dex.code.DexIfEqz;
+import com.android.tools.r8.dex.code.DexIfGe;
+import com.android.tools.r8.dex.code.DexIfGez;
+import com.android.tools.r8.dex.code.DexIfGt;
+import com.android.tools.r8.dex.code.DexIfGtz;
+import com.android.tools.r8.dex.code.DexIfLe;
+import com.android.tools.r8.dex.code.DexIfLez;
+import com.android.tools.r8.dex.code.DexIfLt;
+import com.android.tools.r8.dex.code.DexIfLtz;
+import com.android.tools.r8.dex.code.DexIfNe;
+import com.android.tools.r8.dex.code.DexIfNez;
+import com.android.tools.r8.dex.code.DexInstruction;
+import com.android.tools.r8.dex.code.DexNop;
+import com.android.tools.r8.dex.code.DexSwitchPayload;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexCode.Try;
 import com.android.tools.r8.graph.DexCode.TryHandler;
@@ -57,11 +57,11 @@
 public class JumboStringRewriter {
 
   private static class TryTargets {
-    private Instruction start;
-    private Instruction end;
+    private DexInstruction start;
+    private DexInstruction end;
     private final boolean endsAfterLastInstruction;
 
-    TryTargets(Instruction start, Instruction end, boolean endsAfterLastInstruction) {
+    TryTargets(DexInstruction start, DexInstruction end, boolean endsAfterLastInstruction) {
       assert start != null;
       assert end != null;
       this.start = start;
@@ -69,7 +69,7 @@
       this.endsAfterLastInstruction = endsAfterLastInstruction;
     }
 
-    void replaceTarget(Instruction target, Instruction newTarget) {
+    void replaceTarget(DexInstruction target, DexInstruction newTarget) {
       if (start == target) {
         start = newTarget;
       }
@@ -93,14 +93,16 @@
   private final DexEncodedMethod method;
   private final DexString firstJumboString;
   private final DexItemFactory factory;
-  private final Map<Instruction, List<Instruction>> instructionTargets = new IdentityHashMap<>();
+  private final Map<DexInstruction, List<DexInstruction>> instructionTargets =
+      new IdentityHashMap<>();
   private EventBasedDebugInfo debugEventBasedInfo = null;
-  private final Int2ReferenceMap<Instruction> debugEventTargets = new Int2ReferenceOpenHashMap<>();
-  private final Map<Instruction, Instruction> payloadToSwitch = new IdentityHashMap<>();
+  private final Int2ReferenceMap<DexInstruction> debugEventTargets =
+      new Int2ReferenceOpenHashMap<>();
+  private final Map<DexInstruction, DexInstruction> payloadToSwitch = new IdentityHashMap<>();
   private final Map<Try, TryTargets> tryTargets = new IdentityHashMap<>();
-  private final Int2ReferenceMap<Instruction> tryRangeStartAndEndTargets
-      = new Int2ReferenceOpenHashMap<>();
-  private final Map<TryHandler, List<Instruction>> handlerTargets = new IdentityHashMap<>();
+  private final Int2ReferenceMap<DexInstruction> tryRangeStartAndEndTargets =
+      new Int2ReferenceOpenHashMap<>();
+  private final Map<TryHandler, List<DexInstruction>> handlerTargets = new IdentityHashMap<>();
 
   public JumboStringRewriter(
       DexEncodedMethod method, DexString firstJumboString, DexItemFactory factory) {
@@ -114,7 +116,7 @@
     // instructions to the actual instruction referenced.
     recordTargets();
     // Expand the code by rewriting jumbo strings and branching instructions.
-    List<Instruction> newInstructions = expandCode();
+    List<DexInstruction> newInstructions = expandCode();
     // Commit to the new instruction offsets and update instructions, try-catch structures
     // and debug info with the new offsets.
     rewriteInstructionOffsets(newInstructions);
@@ -128,7 +130,7 @@
             oldCode.registerSize,
             oldCode.incomingRegisterSize,
             oldCode.outgoingRegisterSize,
-            newInstructions.toArray(Instruction.EMPTY_ARRAY),
+            newInstructions.toArray(DexInstruction.EMPTY_ARRAY),
             newTries,
             newHandlers,
             newDebugInfo);
@@ -138,44 +140,44 @@
     return newCode;
   }
 
-  private void rewriteInstructionOffsets(List<Instruction> instructions) {
-    for (Instruction instruction : instructions) {
-      if (instruction instanceof Format22t) {  // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
-        Format22t condition = (Format22t) instruction;
+  private void rewriteInstructionOffsets(List<DexInstruction> instructions) {
+    for (DexInstruction instruction : instructions) {
+      if (instruction instanceof DexFormat22t) { // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
+        DexFormat22t condition = (DexFormat22t) instruction;
         int offset = instructionTargets.get(condition).get(0).getOffset() - instruction.getOffset();
         assert Short.MIN_VALUE <= offset && offset <= Short.MAX_VALUE;
         condition.CCCC = (short) offset;
-      } else if (instruction instanceof Format21t) {  // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
-        Format21t condition = (Format21t) instruction;
+      } else if (instruction instanceof DexFormat21t) { // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
+        DexFormat21t condition = (DexFormat21t) instruction;
         int offset = instructionTargets.get(condition).get(0).getOffset() - instruction.getOffset();
         assert Short.MIN_VALUE <= offset && offset <= Short.MAX_VALUE;
         condition.BBBB = (short) offset;
-      } else if (instruction instanceof Goto) {
-        Goto jump = (Goto) instruction;
+      } else if (instruction instanceof DexGoto) {
+        DexGoto jump = (DexGoto) instruction;
         int offset = instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
         assert Byte.MIN_VALUE <= offset && offset <= Byte.MAX_VALUE;
         jump.AA = (byte) offset;
-      } else if (instruction instanceof Goto16) {
-        Goto16 jump = (Goto16) instruction;
+      } else if (instruction instanceof DexGoto16) {
+        DexGoto16 jump = (DexGoto16) instruction;
         int offset = instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
         assert Short.MIN_VALUE <= offset && offset <= Short.MAX_VALUE;
         jump.AAAA = (short) offset;
-      } else if (instruction instanceof Goto32) {
-        Goto32 jump = (Goto32) instruction;
+      } else if (instruction instanceof DexGoto32) {
+        DexGoto32 jump = (DexGoto32) instruction;
         int offset = instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
         jump.AAAAAAAA = offset;
-      } else if (instruction.hasPayload()) {  // FillArrayData, SparseSwitch, PackedSwitch
-        Format31t payloadUser = (Format31t) instruction;
+      } else if (instruction.hasPayload()) { // FillArrayData, SparseSwitch, PackedSwitch
+        DexFormat31t payloadUser = (DexFormat31t) instruction;
         int offset =
             instructionTargets.get(payloadUser).get(0).getOffset() - instruction.getOffset();
         payloadUser.setPayloadOffset(offset);
-      } else if (instruction instanceof SwitchPayload) {
-        SwitchPayload payload = (SwitchPayload) instruction;
-        Instruction switchInstruction = payloadToSwitch.get(payload);
-        List<Instruction> switchTargets = instructionTargets.get(payload);
+      } else if (instruction instanceof DexSwitchPayload) {
+        DexSwitchPayload payload = (DexSwitchPayload) instruction;
+        DexInstruction switchInstruction = payloadToSwitch.get(payload);
+        List<DexInstruction> switchTargets = instructionTargets.get(payload);
         int[] targets = payload.switchTargetOffsets();
         for (int i = 0; i < switchTargets.size(); i++) {
-          Instruction target = switchTargets.get(i);
+          DexInstruction target = switchTargets.get(i);
           targets[i] = target.getOffset() - switchInstruction.getOffset();
         }
       }
@@ -199,8 +201,8 @@
     TryHandler[] result = new TryHandler[code.handlers.length];
     for (int i = 0; i < code.handlers.length; i++) {
       TryHandler handler = code.handlers[i];
-      List<Instruction> targets = handlerTargets.get(handler);
-      Iterator<Instruction> it = targets.iterator();
+      List<DexInstruction> targets = handlerTargets.get(handler);
+      Iterator<DexInstruction> it = targets.iterator();
       int catchAllAddr = NO_HANDLER;
       if (handler.catchAllAddr != NO_HANDLER) {
         catchAllAddr = it.next().getOffset();
@@ -226,14 +228,14 @@
         if (event instanceof AdvancePC) {
           AdvancePC advance = (AdvancePC) event;
           lastOriginalOffset += advance.delta;
-          Instruction target = debugEventTargets.get(lastOriginalOffset);
+          DexInstruction target = debugEventTargets.get(lastOriginalOffset);
           int pcDelta = target.getOffset() - lastNewOffset;
           events.add(factory.createAdvancePC(pcDelta));
           lastNewOffset = target.getOffset();
         } else if (event instanceof Default) {
           Default defaultEvent = (Default) event;
           lastOriginalOffset += defaultEvent.getPCDelta();
-          Instruction target = debugEventTargets.get(lastOriginalOffset);
+          DexInstruction target = debugEventTargets.get(lastOriginalOffset);
           int lineDelta = defaultEvent.getLineDelta();
           int pcDelta = target.getOffset() - lastNewOffset;
           addDefaultEventWithAdvancePcIfNecessary(lineDelta, pcDelta, events, factory);
@@ -250,116 +252,116 @@
     return code.getDebugInfo();
   }
 
-  private List<Instruction> expandCode() {
-    LinkedList<Instruction> instructions = new LinkedList<>();
+  private List<DexInstruction> expandCode() {
+    LinkedList<DexInstruction> instructions = new LinkedList<>();
     Collections.addAll(instructions, method.getCode().asDexCode().instructions);
     int offsetDelta;
     do {
-      ListIterator<Instruction> it = instructions.listIterator();
+      ListIterator<DexInstruction> it = instructions.listIterator();
       offsetDelta = 0;
       while (it.hasNext()) {
-        Instruction instruction = it.next();
+        DexInstruction instruction = it.next();
         int orignalOffset = instruction.getOffset();
         instruction.setOffset(orignalOffset + offsetDelta);
-        if (instruction instanceof ConstString) {
-          ConstString string = (ConstString) instruction;
+        if (instruction instanceof DexConstString) {
+          DexConstString string = (DexConstString) instruction;
           if (string.getString().compareTo(firstJumboString) >= 0) {
-            ConstStringJumbo jumboString = new ConstStringJumbo(string.AA, string.getString());
+            DexConstStringJumbo jumboString =
+                new DexConstStringJumbo(string.AA, string.getString());
             jumboString.setOffset(string.getOffset());
             offsetDelta++;
             it.set(jumboString);
             replaceTarget(instruction, jumboString);
           }
-        } else if (instruction instanceof Format22t) {  // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
-          Format22t condition = (Format22t) instruction;
+        } else if (instruction instanceof DexFormat22t) { // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
+          DexFormat22t condition = (DexFormat22t) instruction;
           int offset =
               instructionTargets.get(condition).get(0).getOffset() - instruction.getOffset();
           if (Short.MIN_VALUE > offset || offset > Short.MAX_VALUE) {
-            Format22t newCondition = null;
+            DexFormat22t newCondition = null;
             switch (condition.getType().inverted()) {
               case EQ:
-                newCondition = new IfEq(condition.A, condition.B, 0);
+                newCondition = new DexIfEq(condition.A, condition.B, 0);
                 break;
               case GE:
-                newCondition = new IfGe(condition.A, condition.B, 0);
+                newCondition = new DexIfGe(condition.A, condition.B, 0);
                 break;
               case GT:
-                newCondition = new IfGt(condition.A, condition.B, 0);
+                newCondition = new DexIfGt(condition.A, condition.B, 0);
                 break;
               case LE:
-                newCondition = new IfLe(condition.A, condition.B, 0);
+                newCondition = new DexIfLe(condition.A, condition.B, 0);
                 break;
               case LT:
-                newCondition = new IfLt(condition.A, condition.B, 0);
+                newCondition = new DexIfLt(condition.A, condition.B, 0);
                 break;
               case NE:
-                newCondition = new IfNe(condition.A, condition.B, 0);
+                newCondition = new DexIfNe(condition.A, condition.B, 0);
                 break;
             }
             offsetDelta = rewriteIfToIfAndGoto(offsetDelta, it, condition, newCondition);
           }
-        } else if (instruction instanceof Format21t) {  // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
-          Format21t condition = (Format21t) instruction;
+        } else if (instruction
+            instanceof DexFormat21t) { // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
+          DexFormat21t condition = (DexFormat21t) instruction;
           int offset =
               instructionTargets.get(condition).get(0).getOffset() - instruction.getOffset();
           if (Short.MIN_VALUE > offset || offset > Short.MAX_VALUE) {
-            Format21t newCondition = null;
+            DexFormat21t newCondition = null;
             switch (condition.getType().inverted()) {
               case EQ:
-                newCondition = new IfEqz(condition.AA, 0);
+                newCondition = new DexIfEqz(condition.AA, 0);
                 break;
               case GE:
-                newCondition = new IfGez(condition.AA, 0);
+                newCondition = new DexIfGez(condition.AA, 0);
                 break;
               case GT:
-                newCondition = new IfGtz(condition.AA, 0);
+                newCondition = new DexIfGtz(condition.AA, 0);
                 break;
               case LE:
-                newCondition = new IfLez(condition.AA, 0);
+                newCondition = new DexIfLez(condition.AA, 0);
                 break;
               case LT:
-                newCondition = new IfLtz(condition.AA, 0);
+                newCondition = new DexIfLtz(condition.AA, 0);
                 break;
               case NE:
-                newCondition = new IfNez(condition.AA, 0);
+                newCondition = new DexIfNez(condition.AA, 0);
                 break;
             }
             offsetDelta = rewriteIfToIfAndGoto(offsetDelta, it, condition, newCondition);
           }
-        } else if (instruction instanceof Goto) {
-          Goto jump = (Goto) instruction;
-          int offset =
-              instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
+        } else if (instruction instanceof DexGoto) {
+          DexGoto jump = (DexGoto) instruction;
+          int offset = instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
           if (Byte.MIN_VALUE > offset || offset > Byte.MAX_VALUE) {
-            Instruction newJump;
+            DexInstruction newJump;
             if (Short.MIN_VALUE > offset || offset > Short.MAX_VALUE) {
-              newJump = new Goto32(offset);
+              newJump = new DexGoto32(offset);
             } else {
-              newJump = new Goto16(offset);
+              newJump = new DexGoto16(offset);
             }
             newJump.setOffset(jump.getOffset());
             it.set(newJump);
             offsetDelta += (newJump.getSize() - jump.getSize());
             replaceTarget(jump, newJump);
-            List<Instruction> targets = instructionTargets.remove(jump);
+            List<DexInstruction> targets = instructionTargets.remove(jump);
             instructionTargets.put(newJump, targets);
           }
-        } else if (instruction instanceof Goto16) {
-          Goto16 jump = (Goto16) instruction;
-          int offset =
-              instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
+        } else if (instruction instanceof DexGoto16) {
+          DexGoto16 jump = (DexGoto16) instruction;
+          int offset = instructionTargets.get(jump).get(0).getOffset() - instruction.getOffset();
           if (Short.MIN_VALUE > offset || offset > Short.MAX_VALUE) {
-            Instruction newJump = new Goto32(offset);
+            DexInstruction newJump = new DexGoto32(offset);
             newJump.setOffset(jump.getOffset());
             it.set(newJump);
             offsetDelta += (newJump.getSize() - jump.getSize());
             replaceTarget(jump, newJump);
-            List<Instruction> targets = instructionTargets.remove(jump);
+            List<DexInstruction> targets = instructionTargets.remove(jump);
             instructionTargets.put(newJump, targets);
           }
-        } else if (instruction instanceof Goto32) {
+        } else if (instruction instanceof DexGoto32) {
           // Instruction big enough for any offset.
-        } else if (instruction.hasPayload()) {  // FillArrayData, SparseSwitch, PackedSwitch
+        } else if (instruction.hasPayload()) { // FillArrayData, SparseSwitch, PackedSwitch
           // Instruction big enough for any offset.
         } else if (instruction.isPayload()) {
           // Payload instructions must be 4 byte aligned (instructions are 2 bytes).
@@ -368,7 +370,7 @@
             // Check if the previous instruction was a simple nop. If that is the case, remove it
             // to make the alignment instead of adding another one. Only allow removal if this
             // instruction is not targeted by anything. See b/78072750.
-            Instruction instructionBeforePayload = it.hasPrevious() ? it.previous() : null;
+            DexInstruction instructionBeforePayload = it.hasPrevious() ? it.previous() : null;
             if (instructionBeforePayload != null
                 && instructionBeforePayload.isSimpleNop()
                 && debugEventTargets.get(orignalOffset) == null
@@ -379,7 +381,7 @@
               if (instructionBeforePayload != null) {
                 it.next();
               }
-              Nop nop = new Nop();
+              DexNop nop = new DexNop();
               nop.setOffset(instruction.getOffset());
               it.add(nop);
               offsetDelta++;
@@ -396,11 +398,11 @@
 
   private int rewriteIfToIfAndGoto(
       int offsetDelta,
-      ListIterator<Instruction> it,
-      Instruction condition,
-      Instruction newCondition) {
+      ListIterator<DexInstruction> it,
+      DexInstruction condition,
+      DexInstruction newCondition) {
     int jumpOffset = condition.getOffset() + condition.getSize();
-    Goto32 jump = new Goto32(0);
+    DexGoto32 jump = new DexGoto32(0);
     jump.setOffset(jumpOffset);
     newCondition.setOffset(condition.getOffset());
     it.set(newCondition);
@@ -408,17 +410,17 @@
     it.add(jump);
     offsetDelta += jump.getSize();
     instructionTargets.put(jump, instructionTargets.remove(condition));
-    Instruction fallthroughInstruction = it.next();
+    DexInstruction fallthroughInstruction = it.next();
     instructionTargets.put(newCondition, Lists.newArrayList(fallthroughInstruction));
     it.previous();
     return offsetDelta;
   }
 
-  private void replaceTarget(Instruction target, Instruction newTarget) {
-    for (List<Instruction> instructions : instructionTargets.values()) {
+  private void replaceTarget(DexInstruction target, DexInstruction newTarget) {
+    for (List<DexInstruction> instructions : instructionTargets.values()) {
       instructions.replaceAll((i) -> i == target ? newTarget : i);
     }
-    for (Int2ReferenceMap.Entry<Instruction> entry : debugEventTargets.int2ReferenceEntrySet()) {
+    for (Int2ReferenceMap.Entry<DexInstruction> entry : debugEventTargets.int2ReferenceEntrySet()) {
       if (entry.getValue() == target) {
         entry.setValue(newTarget);
       }
@@ -426,52 +428,53 @@
     for (Entry<Try, TryTargets> entry : tryTargets.entrySet()) {
       entry.getValue().replaceTarget(target, newTarget);
     }
-    for (List<Instruction> instructions : handlerTargets.values()) {
+    for (List<DexInstruction> instructions : handlerTargets.values()) {
       instructions.replaceAll((i) -> i == target ? newTarget : i);
     }
   }
 
-  private void recordInstructionTargets(Int2ReferenceMap<Instruction> offsetToInstruction) {
-    Instruction[] instructions = method.getCode().asDexCode().instructions;
-    for (Instruction instruction : instructions) {
-      if (instruction instanceof Format22t) {  // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
-        Format22t condition = (Format22t) instruction;
-        Instruction target = offsetToInstruction.get(condition.getOffset() + condition.CCCC);
+  private void recordInstructionTargets(Int2ReferenceMap<DexInstruction> offsetToInstruction) {
+    DexInstruction[] instructions = method.getCode().asDexCode().instructions;
+    for (DexInstruction instruction : instructions) {
+      if (instruction instanceof DexFormat22t) { // IfEq, IfGe, IfGt, IfLe, IfLt, IfNe
+        DexFormat22t condition = (DexFormat22t) instruction;
+        DexInstruction target = offsetToInstruction.get(condition.getOffset() + condition.CCCC);
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction instanceof Format21t) {  // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
-        Format21t condition = (Format21t) instruction;
-        Instruction target = offsetToInstruction.get(condition.getOffset() + condition.BBBB);
+      } else if (instruction instanceof DexFormat21t) { // IfEqz, IfGez, IfGtz, IfLez, IfLtz, IfNez
+        DexFormat21t condition = (DexFormat21t) instruction;
+        DexInstruction target = offsetToInstruction.get(condition.getOffset() + condition.BBBB);
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction instanceof Goto) {
-        Goto jump = (Goto) instruction;
-        Instruction target = offsetToInstruction.get(jump.getOffset() + jump.AA);
+      } else if (instruction instanceof DexGoto) {
+        DexGoto jump = (DexGoto) instruction;
+        DexInstruction target = offsetToInstruction.get(jump.getOffset() + jump.AA);
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction instanceof Goto16) {
-        Goto16 jump = (Goto16) instruction;
-        Instruction target = offsetToInstruction.get(jump.getOffset() + jump.AAAA);
+      } else if (instruction instanceof DexGoto16) {
+        DexGoto16 jump = (DexGoto16) instruction;
+        DexInstruction target = offsetToInstruction.get(jump.getOffset() + jump.AAAA);
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction instanceof Goto32) {
-        Goto32 jump = (Goto32) instruction;
-        Instruction target = offsetToInstruction.get(jump.getOffset() + jump.AAAAAAAA);
+      } else if (instruction instanceof DexGoto32) {
+        DexGoto32 jump = (DexGoto32) instruction;
+        DexInstruction target = offsetToInstruction.get(jump.getOffset() + jump.AAAAAAAA);
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction.hasPayload()) {  // FillArrayData, SparseSwitch, PackedSwitch
-        Format31t offsetInstruction = (Format31t) instruction;
-        Instruction target = offsetToInstruction.get(
-            offsetInstruction.getOffset() + offsetInstruction.getPayloadOffset());
+      } else if (instruction.hasPayload()) { // FillArrayData, SparseSwitch, PackedSwitch
+        DexFormat31t offsetInstruction = (DexFormat31t) instruction;
+        DexInstruction target =
+            offsetToInstruction.get(
+                offsetInstruction.getOffset() + offsetInstruction.getPayloadOffset());
         assert target != null;
         instructionTargets.put(instruction, Lists.newArrayList(target));
-      } else if (instruction instanceof SwitchPayload) {
-        SwitchPayload payload = (SwitchPayload) instruction;
+      } else if (instruction instanceof DexSwitchPayload) {
+        DexSwitchPayload payload = (DexSwitchPayload) instruction;
         int[] targetOffsets = payload.switchTargetOffsets();
         int switchOffset = payloadToSwitch.get(instruction).getOffset();
-        List<Instruction> targets = new ArrayList<>();
+        List<DexInstruction> targets = new ArrayList<>();
         for (int i = 0; i < targetOffsets.length; i++) {
-          Instruction target = offsetToInstruction.get(switchOffset + targetOffsets[i]);
+          DexInstruction target = offsetToInstruction.get(switchOffset + targetOffsets[i]);
           assert target != null;
           targets.add(target);
         }
@@ -480,7 +483,7 @@
     }
   }
 
-  private void recordDebugEventTargets(Int2ReferenceMap<Instruction> offsetToInstruction) {
+  private void recordDebugEventTargets(Int2ReferenceMap<DexInstruction> offsetToInstruction) {
     // TODO(b/213411850): Merging pc based D8 builds will map out of PC for any jumbo processed
     //  method. Instead we should rather retain the PC encoding by bumping the max-pc and recording
     //  the line number translation. We actually need to do so to support merging with native PC
@@ -496,13 +499,13 @@
       if (event instanceof AdvancePC) {
         AdvancePC advance = (AdvancePC) event;
         address += advance.delta;
-        Instruction target = offsetToInstruction.get(address);
+        DexInstruction target = offsetToInstruction.get(address);
         assert target != null;
         debugEventTargets.put(address, target);
       } else if (event instanceof Default) {
         Default defaultEvent = (Default) event;
         address += defaultEvent.getPCDelta();
-        Instruction target = offsetToInstruction.get(address);
+        DexInstruction target = offsetToInstruction.get(address);
         assert target != null;
         debugEventTargets.put(address, target);
       }
@@ -510,12 +513,11 @@
   }
 
   private void recordTryAndHandlerTargets(
-      Int2ReferenceMap<Instruction> offsetToInstruction,
-      Instruction lastInstruction) {
+      Int2ReferenceMap<DexInstruction> offsetToInstruction, DexInstruction lastInstruction) {
     DexCode code = method.getCode().asDexCode();
     for (Try theTry : code.tries) {
-      Instruction start = offsetToInstruction.get(theTry.startAddress);
-      Instruction end = null;
+      DexInstruction start = offsetToInstruction.get(theTry.startAddress);
+      DexInstruction end = null;
       int endAddress = theTry.startAddress + theTry.instructionCount;
       TryTargets targets;
       if (endAddress > lastInstruction.getOffset()) {
@@ -532,14 +534,14 @@
       tryRangeStartAndEndTargets.put(end.getOffset(), end);
     }
     for (TryHandler handler : code.handlers) {
-      List<Instruction> targets = new ArrayList<>();
+      List<DexInstruction> targets = new ArrayList<>();
       if (handler.catchAllAddr != NO_HANDLER) {
-        Instruction target = offsetToInstruction.get(handler.catchAllAddr);
+        DexInstruction target = offsetToInstruction.get(handler.catchAllAddr);
         assert target != null;
         targets.add(target);
       }
       for (TypeAddrPair pair : handler.pairs) {
-        Instruction target = offsetToInstruction.get(pair.addr);
+        DexInstruction target = offsetToInstruction.get(pair.addr);
         assert target != null;
         targets.add(target);
       }
@@ -548,19 +550,19 @@
   }
 
   private void recordTargets() {
-    Int2ReferenceMap<Instruction> offsetToInstruction = new Int2ReferenceOpenHashMap<>();
-    Instruction[] instructions = method.getCode().asDexCode().instructions;
+    Int2ReferenceMap<DexInstruction> offsetToInstruction = new Int2ReferenceOpenHashMap<>();
+    DexInstruction[] instructions = method.getCode().asDexCode().instructions;
     boolean containsPayloads = false;
-    for (Instruction instruction : instructions) {
+    for (DexInstruction instruction : instructions) {
       offsetToInstruction.put(instruction.getOffset(), instruction);
-      if (instruction.hasPayload()) {  // FillArrayData, SparseSwitch, PackedSwitch
+      if (instruction.hasPayload()) { // FillArrayData, SparseSwitch, PackedSwitch
         containsPayloads = true;
       }
     }
     if (containsPayloads) {
-      for (Instruction instruction : instructions) {
-        if (instruction.hasPayload()) {  // FillArrayData, SparseSwitch, PackedSwitch
-          Instruction payload =
+      for (DexInstruction instruction : instructions) {
+        if (instruction.hasPayload()) { // FillArrayData, SparseSwitch, PackedSwitch
+          DexInstruction payload =
               offsetToInstruction.get(instruction.getOffset() + instruction.getPayloadOffset());
           assert payload != null;
           payloadToSwitch.put(payload, instruction);
@@ -569,7 +571,7 @@
     }
     recordInstructionTargets(offsetToInstruction);
     recordDebugEventTargets(offsetToInstruction);
-    Instruction lastInstruction = instructions[instructions.length - 1];
+    DexInstruction lastInstruction = instructions[instructions.length - 1];
     recordTryAndHandlerTargets(offsetToInstruction, lastInstruction);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/dex/MixedSectionCollection.java b/src/main/java/com/android/tools/r8/dex/MixedSectionCollection.java
index f0c4c06..d80b036 100644
--- a/src/main/java/com/android/tools/r8/dex/MixedSectionCollection.java
+++ b/src/main/java/com/android/tools/r8/dex/MixedSectionCollection.java
@@ -110,10 +110,16 @@
   /**
    * Adds the given annotation directory to the collection.
    *
-   * Add a dependency between the clazz and the annotation directory.
-   *
-   * @return true if the item was not added before
+   * <p>Adds a dependency between the clazz and the annotation directory.
    */
-  public abstract boolean setAnnotationsDirectoryForClass(DexProgramClass clazz,
-      DexAnnotationDirectory annotationDirectory);
+  public abstract void setAnnotationsDirectoryForClass(
+      DexProgramClass clazz, DexAnnotationDirectory annotationDirectory);
+
+  /**
+   * Adds the given static field values array to the collection.
+   *
+   * <p>Adds a dependency between the clazz and the static field values array.
+   */
+  public abstract void setStaticFieldValuesForClass(
+      DexProgramClass clazz, DexEncodedArray staticFieldValues);
 }
diff --git a/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java
new file mode 100644
index 0000000..5454b0f
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/dex/MixedSectionLayoutStrategy.java
@@ -0,0 +1,56 @@
+// Copyright (c) 2022, 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.dex;
+
+import com.android.tools.r8.dex.FileWriter.MixedSectionOffsets;
+import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexAnnotation;
+import com.android.tools.r8.graph.DexAnnotationDirectory;
+import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexEncodedArray;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.ProgramMethod;
+import java.util.Collection;
+
+public abstract class MixedSectionLayoutStrategy {
+
+  public static MixedSectionLayoutStrategy create(
+      AppView<?> appView, MixedSectionOffsets mixedSectionOffsets, VirtualFile virtualFile) {
+    StartupOrder startupOrderForWriting =
+        virtualFile.getId() == 0 && appView.hasClassHierarchy()
+            ? appView
+                .appInfoWithClassHierarchy()
+                .getStartupOrder()
+                .toStartupOrderForWriting(appView)
+            : StartupOrder.empty();
+    if (startupOrderForWriting.isEmpty()) {
+      return new DefaultMixedSectionLayoutStrategy(appView, mixedSectionOffsets);
+    }
+    return new StartupMixedSectionLayoutStrategy(
+        appView, mixedSectionOffsets, startupOrderForWriting, virtualFile);
+  }
+
+  public abstract Collection<DexAnnotation> getAnnotationLayout();
+
+  public abstract Collection<DexAnnotationDirectory> getAnnotationDirectoryLayout();
+
+  public abstract Collection<DexAnnotationSet> getAnnotationSetLayout();
+
+  public abstract Collection<ParameterAnnotationsList> getAnnotationSetRefListLayout();
+
+  public abstract Collection<DexProgramClass> getClassDataLayout();
+
+  public abstract Collection<ProgramMethod> getCodeLayout();
+
+  public abstract Collection<DexEncodedArray> getEncodedArrayLayout();
+
+  public abstract Collection<DexString> getStringDataLayout();
+
+  public abstract Collection<DexTypeList> getTypeListLayout();
+}
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 eaf736d..e249186 100644
--- a/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
+++ b/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
@@ -37,16 +37,12 @@
   private final NamingLens namingLens;
   private final InternalOptions options;
 
-  public ResourceAdapter(
-      AppView<?> appView,
-      DexItemFactory dexItemFactory,
-      NamingLens namingLens,
-      InternalOptions options) {
+  public ResourceAdapter(AppView<?> appView) {
     this.appView = appView;
-    this.dexItemFactory = dexItemFactory;
+    this.dexItemFactory = appView.dexItemFactory();
     this.graphLens = appView.graphLens();
-    this.namingLens = namingLens;
-    this.options = options;
+    this.namingLens = appView.getNamingLens();
+    this.options = appView.options();
   }
 
   public DataEntryResource adaptIfNeeded(DataEntryResource file) {
diff --git a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
new file mode 100644
index 0000000..b5ccc6b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
@@ -0,0 +1,226 @@
+// Copyright (c) 2022, 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.dex;
+
+import com.android.tools.r8.dex.FileWriter.MixedSectionOffsets;
+import com.android.tools.r8.experimental.startup.StartupOrder;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexAnnotation;
+import com.android.tools.r8.graph.DexAnnotationDirectory;
+import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexEncodedArray;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexMethodHandle;
+import com.android.tools.r8.graph.DexProgramClass;
+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.DexTypeList;
+import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
+import com.android.tools.r8.utils.MapUtils;
+import com.android.tools.r8.utils.collections.LinkedProgramMethodSet;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class StartupMixedSectionLayoutStrategy extends DefaultMixedSectionLayoutStrategy {
+
+  private final StartupOrder startupOrderForWriting;
+
+  private final LinkedHashSet<DexAnnotation> annotationLayout;
+  private final LinkedHashSet<DexAnnotationDirectory> annotationDirectoryLayout;
+  private final LinkedHashSet<DexAnnotationSet> annotationSetLayout;
+  private final LinkedHashSet<ParameterAnnotationsList> annotationSetRefListLayout;
+  private final LinkedHashSet<DexProgramClass> classDataLayout;
+  private final LinkedProgramMethodSet codeLayout;
+  private final LinkedHashSet<DexEncodedArray> encodedArrayLayout;
+  private final LinkedHashSet<DexString> stringDataLayout;
+  private final LinkedHashSet<DexTypeList> typeListLayout;
+
+  public StartupMixedSectionLayoutStrategy(
+      AppView<?> appView,
+      MixedSectionOffsets mixedSectionOffsets,
+      StartupOrder startupOrderForWriting,
+      VirtualFile virtualFile) {
+    super(appView, mixedSectionOffsets);
+    this.startupOrderForWriting = startupOrderForWriting;
+
+    // Initialize startup layouts.
+    this.annotationLayout = new LinkedHashSet<>(mixedSectionOffsets.getAnnotations().size());
+    this.annotationDirectoryLayout =
+        new LinkedHashSet<>(mixedSectionOffsets.getAnnotationDirectories().size());
+    this.annotationSetLayout = new LinkedHashSet<>(mixedSectionOffsets.getAnnotationSets().size());
+    this.annotationSetRefListLayout =
+        new LinkedHashSet<>(mixedSectionOffsets.getAnnotationSetRefLists().size());
+    this.classDataLayout = new LinkedHashSet<>(mixedSectionOffsets.getClassesWithData().size());
+    this.codeLayout = ProgramMethodSet.createLinked(mixedSectionOffsets.getCodes().size());
+    this.encodedArrayLayout = new LinkedHashSet<>(mixedSectionOffsets.getEncodedArrays().size());
+    this.stringDataLayout = new LinkedHashSet<>(mixedSectionOffsets.getStringData().size());
+    this.typeListLayout = new LinkedHashSet<>(mixedSectionOffsets.getTypeLists().size());
+
+    // Add startup items to startup layouts.
+    collectStartupItems(virtualFile);
+  }
+
+  private void collectStartupItems(VirtualFile virtualFile) {
+    Map<DexType, DexProgramClass> virtualFileDefinitions =
+        MapUtils.newIdentityHashMap(
+            builder ->
+                virtualFile.classes().forEach(clazz -> builder.accept(clazz.getType(), clazz)),
+            virtualFile.classes().size());
+    LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(appView, true);
+    StartupIndexedItemCollection indexedItemCollection = new StartupIndexedItemCollection();
+    for (DexType startupClass : startupOrderForWriting.getClasses()) {
+      DexProgramClass definition = virtualFileDefinitions.get(startupClass);
+      if (definition != null) {
+        definition.collectIndexedItems(appView, indexedItemCollection, rewriter);
+      }
+    }
+  }
+
+  private static <T> Collection<T> amendStartupLayout(
+      Collection<T> startupLayout, Collection<T> defaultLayout) {
+    startupLayout.addAll(defaultLayout);
+    return startupLayout;
+  }
+
+  @Override
+  public Collection<DexAnnotation> getAnnotationLayout() {
+    return amendStartupLayout(annotationLayout, super.getAnnotationLayout());
+  }
+
+  @Override
+  public Collection<DexAnnotationDirectory> getAnnotationDirectoryLayout() {
+    return amendStartupLayout(annotationDirectoryLayout, super.getAnnotationDirectoryLayout());
+  }
+
+  @Override
+  public Collection<DexAnnotationSet> getAnnotationSetLayout() {
+    return amendStartupLayout(annotationSetLayout, super.getAnnotationSetLayout());
+  }
+
+  @Override
+  public Collection<ParameterAnnotationsList> getAnnotationSetRefListLayout() {
+    return amendStartupLayout(annotationSetRefListLayout, super.getAnnotationSetRefListLayout());
+  }
+
+  @Override
+  public Collection<DexProgramClass> getClassDataLayout() {
+    return amendStartupLayout(classDataLayout, super.getClassDataLayout());
+  }
+
+  @Override
+  public Collection<ProgramMethod> getCodeLayout() {
+    Set<DexProgramClass> nonStartupClasses =
+        new LinkedHashSet<>(mixedSectionOffsets.getClassesWithData());
+    nonStartupClasses.removeIf(clazz -> startupOrderForWriting.contains(clazz.getType()));
+    return amendStartupLayout(codeLayout, super.getCodeLayoutForClasses(nonStartupClasses));
+  }
+
+  @Override
+  public Collection<DexEncodedArray> getEncodedArrayLayout() {
+    return amendStartupLayout(encodedArrayLayout, super.getEncodedArrayLayout());
+  }
+
+  @Override
+  public Collection<DexString> getStringDataLayout() {
+    return amendStartupLayout(stringDataLayout, super.getStringDataLayout());
+  }
+
+  @Override
+  public Collection<DexTypeList> getTypeListLayout() {
+    return amendStartupLayout(typeListLayout, super.getTypeListLayout());
+  }
+
+  private class StartupIndexedItemCollection implements IndexedItemCollection {
+
+    private void addAnnotation(DexAnnotation annotation) {
+      annotationLayout.add(annotation);
+    }
+
+    private void addAnnotationSet(DexAnnotationSet annotationSet) {
+      if (appView.options().canHaveDalvikEmptyAnnotationSetBug() || !annotationSet.isEmpty()) {
+        annotationSetLayout.add(annotationSet);
+      }
+    }
+
+    private void addAnnotationSetRefList(ParameterAnnotationsList annotationSetRefList) {
+      if (!annotationSetRefList.isEmpty()) {
+        annotationSetRefListLayout.add(annotationSetRefList);
+      }
+    }
+
+    @Override
+    public boolean addClass(DexProgramClass clazz) {
+      if (clazz.hasMethodsOrFields()) {
+        classDataLayout.add(clazz);
+      }
+      addTypeList(clazz.getInterfaces());
+      clazz.forEachProgramMethodMatching(DexEncodedMethod::hasCode, codeLayout::add);
+      DexAnnotationDirectory annotationDirectory =
+          mixedSectionOffsets.getAnnotationDirectoryForClass(clazz);
+      if (annotationDirectory != null) {
+        annotationDirectoryLayout.add(annotationDirectory);
+        annotationDirectory.visitAnnotations(
+            this::addAnnotation, this::addAnnotationSet, this::addAnnotationSetRefList);
+      }
+      DexEncodedArray staticFieldValues = mixedSectionOffsets.getStaticFieldValuesForClass(clazz);
+      if (staticFieldValues != null) {
+        encodedArrayLayout.add(staticFieldValues);
+      }
+      return true;
+    }
+
+    @Override
+    public boolean addField(DexField field) {
+      return true;
+    }
+
+    @Override
+    public boolean addMethod(DexMethod method) {
+      return true;
+    }
+
+    @Override
+    public boolean addString(DexString string) {
+      return stringDataLayout.add(string);
+    }
+
+    @Override
+    public boolean addProto(DexProto proto) {
+      addTypeList(proto.getParameters());
+      return true;
+    }
+
+    @Override
+    public boolean addType(DexType type) {
+      return true;
+    }
+
+    private void addTypeList(DexTypeList typeList) {
+      if (!typeList.isEmpty()) {
+        typeListLayout.add(typeList);
+      }
+    }
+
+    @Override
+    public boolean addCallSite(DexCallSite callSite) {
+      encodedArrayLayout.add(callSite.getEncodedArray());
+      return true;
+    }
+
+    @Override
+    public boolean addMethodHandle(DexMethodHandle methodHandle) {
+      return true;
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index d5995f4..80b9a6c 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -79,38 +79,32 @@
   private final DexProgramClass primaryClass;
   private DebugRepresentation debugRepresentation;
 
-  VirtualFile(
-      int id,
-      AppView<?> appView,
-      NamingLens namingLens) {
-    this(id, appView, namingLens, null, null);
+  VirtualFile(int id, AppView<?> appView) {
+    this(id, appView, null, null);
   }
 
   VirtualFile(
       int id,
       AppView<?> appView,
-      NamingLens namingLens,
       FeatureSplit featureSplit) {
-    this(id, appView, namingLens, null, featureSplit);
+    this(id, appView, null, featureSplit);
   }
 
   private VirtualFile(
       int id,
       AppView<?> appView,
-      NamingLens namingLens,
       DexProgramClass primaryClass) {
-    this(id, appView, namingLens, primaryClass, null);
+    this(id, appView, primaryClass, null);
   }
 
   private VirtualFile(
       int id,
       AppView<?> appView,
-      NamingLens namingLens,
       DexProgramClass primaryClass,
       FeatureSplit featureSplit) {
     this.id = id;
-    this.indexedItems = new VirtualFileIndexedItemCollection(appView, namingLens);
-    this.transaction = new IndexedItemTransaction(indexedItems, appView, namingLens);
+    this.indexedItems = new VirtualFileIndexedItemCollection(appView);
+    this.transaction = new IndexedItemTransaction(indexedItems, appView);
     this.primaryClass = primaryClass;
     this.featureSplit = featureSplit;
   }
@@ -199,7 +193,6 @@
 
   public void computeMapping(
       AppView<?> appView,
-      NamingLens namingLens,
       int lazyDexStringsCount,
       Timing timing) {
     assert transaction.isEmpty();
@@ -207,7 +200,6 @@
     objectMapping =
         new ObjectToOffsetMapping(
             appView,
-            namingLens,
             transaction.rewriter,
             indexedItems.classes,
             indexedItems.protos,
@@ -326,8 +318,7 @@
         //  duplicated.
         if (!combineSyntheticClassesWithPrimaryClass
             || !appView.getSyntheticItems().isSyntheticClass(clazz)) {
-          VirtualFile file =
-              new VirtualFile(virtualFiles.size(), appView, writer.namingLens, clazz);
+          VirtualFile file = new VirtualFile(virtualFiles.size(), appView, clazz);
           virtualFiles.add(file);
           file.addClass(clazz);
           files.put(clazz, file);
@@ -365,7 +356,7 @@
       this.classes = SetUtils.newIdentityHashSet(classes);
 
       // Create the primary dex file. The distribution will add more if needed.
-      mainDexFile = new VirtualFile(0, appView, writer.namingLens);
+      mainDexFile = new VirtualFile(0, appView);
       assert virtualFiles.isEmpty();
       virtualFiles.add(mainDexFile);
       addMarkers(mainDexFile);
@@ -446,7 +437,6 @@
             new VirtualFile(
                 nextFileId.getAndIncrement(),
                 appView,
-                writer.namingLens,
                 featureSplitSetEntry.getKey());
         virtualFiles.add(featureFile);
         addMarkers(featureFile);
@@ -458,8 +448,7 @@
                 appView,
                 featureSplitSetEntry.getValue(),
                 originalNames,
-                nextFileId,
-                writer.namingLens)
+                nextFileId)
             .run();
       }
     }
@@ -510,19 +499,12 @@
                 filesForDistribution,
                 classes,
                 nextFileId,
-                writer.namingLens,
                 appView,
                 executorService)
             .distribute();
       } else {
         new PackageSplitPopulator(
-                virtualFiles,
-                filesForDistribution,
-                appView,
-                classes,
-                originalNames,
-                nextFileId,
-                writer.namingLens)
+                virtualFiles, filesForDistribution, appView, classes, originalNames, nextFileId)
             .run();
       }
       addFeatureSplitFiles(featureSplitClasses);
@@ -573,10 +555,10 @@
     private final Set<DexCallSite> callSites = Sets.newIdentityHashSet();
     private final Set<DexMethodHandle> methodHandles = Sets.newIdentityHashSet();
 
-    public VirtualFileIndexedItemCollection(AppView<?> appView, NamingLens namingLens) {
+    public VirtualFileIndexedItemCollection(AppView<?> appView) {
       this.graphLens = appView.graphLens();
       this.initClassLens = appView.initClassLens();
-      this.namingLens = namingLens;
+      this.namingLens = appView.getNamingLens();
     }
 
     @Override
@@ -627,45 +609,12 @@
     int getNumberOfFields() {
       return fields.size();
     }
-
-    int getNumberOfStrings() {
-      return strings.size();
-    }
-
-    @Override
-    public GraphLens getGraphLens() {
-      return graphLens;
-    }
-
-    @Override
-    public InitClassLens getInitClassLens() {
-      return initClassLens;
-    }
-
-    @Override
-    public DexString getRenamedDescriptor(DexType type) {
-      return namingLens.lookupDescriptor(type);
-    }
-
-    @Override
-    public DexString getRenamedName(DexMethod method) {
-      DexMethod mappedMethod = graphLens.lookupMethod(method);
-      assert namingLens.verifyRenamingConsistentWithResolution(mappedMethod);
-      return namingLens.lookupName(mappedMethod);
-    }
-
-    @Override
-    public DexString getRenamedName(DexField field) {
-      return namingLens.lookupName(graphLens.lookupField(field));
-    }
   }
 
   public static class IndexedItemTransaction implements IndexedItemCollection {
 
     private final AppView<?> appView;
     private final VirtualFileIndexedItemCollection base;
-    private final InitClassLens initClassLens;
-    private final NamingLens namingLens;
     private final LensCodeRewriterUtils rewriter;
 
     private final Set<DexProgramClass> classes = new LinkedHashSet<>();
@@ -677,17 +626,16 @@
     private final Set<DexCallSite> callSites = new LinkedHashSet<>();
     private final Set<DexMethodHandle> methodHandles = new LinkedHashSet<>();
 
-    private IndexedItemTransaction(
-        VirtualFileIndexedItemCollection base,
-        AppView<?> appView,
-        NamingLens namingLens) {
+    private IndexedItemTransaction(VirtualFileIndexedItemCollection base, AppView<?> appView) {
       this.appView = appView;
       this.base = base;
-      this.initClassLens = appView.initClassLens();
-      this.namingLens = namingLens;
       this.rewriter = new LensCodeRewriterUtils(appView, true);
     }
 
+    private NamingLens getNamingLens() {
+      return appView.getNamingLens();
+    }
+
     private <T extends DexItem> boolean maybeInsert(T item, Set<T> set, Set<T> baseSet) {
       if (baseSet.contains(item) || set.contains(item)) {
         return false;
@@ -697,7 +645,7 @@
     }
 
     void addClassAndDependencies(DexProgramClass clazz) {
-      clazz.collectIndexedItems(this, getGraphLens(), rewriter);
+      clazz.collectIndexedItems(appView, this, rewriter);
     }
 
     @Override
@@ -741,32 +689,6 @@
       return maybeInsert(methodHandle, methodHandles, base.methodHandles);
     }
 
-    @Override
-    public GraphLens getGraphLens() {
-      return appView.graphLens();
-    }
-
-    @Override
-    public InitClassLens getInitClassLens() {
-      return initClassLens;
-    }
-
-    @Override
-    public DexString getRenamedDescriptor(DexType type) {
-      return namingLens.lookupDescriptor(type);
-    }
-
-    @Override
-    public DexString getRenamedName(DexMethod method) {
-      assert namingLens.verifyRenamingConsistentWithResolution(method);
-      return namingLens.lookupName(method);
-    }
-
-    @Override
-    public DexString getRenamedName(DexField field) {
-      return namingLens.lookupName(field);
-    }
-
     int getNumberOfMethods() {
       return methods.size() + base.getNumberOfMethods();
     }
@@ -830,7 +752,6 @@
     private final List<VirtualFile> files;
     private final List<VirtualFile> filesForDistribution;
     private final AppView<?> appView;
-    private final NamingLens namingLens;
 
     private final IntBox nextFileId;
     private Iterator<VirtualFile> allFilesCyclic;
@@ -841,12 +762,10 @@
         List<VirtualFile> files,
         List<VirtualFile> filesForDistribution,
         AppView<?> appView,
-        NamingLens namingLens,
         IntBox nextFileId) {
       this.files = files;
       this.filesForDistribution = new ArrayList<>(filesForDistribution);
       this.appView = appView;
-      this.namingLens = namingLens;
       this.nextFileId = nextFileId;
 
       if (filesForDistribution.size() > 0) {
@@ -917,8 +836,7 @@
     }
 
     private VirtualFile internalAddFile() {
-      VirtualFile newFile =
-          new VirtualFile(nextFileId.getAndIncrement(), appView, namingLens, featureSplit);
+      VirtualFile newFile = new VirtualFile(nextFileId.getAndIncrement(), appView, featureSplit);
       files.add(newFile);
       filesForDistribution.add(newFile);
       return newFile;
@@ -1061,14 +979,12 @@
         AppView<?> appView,
         Collection<DexProgramClass> classes,
         Map<DexProgramClass, String> originalNames,
-        IntBox nextFileId,
-        NamingLens namingLens) {
+        IntBox nextFileId) {
       this.classPartioning = PackageSplitClassPartioning.create(classes, appView, originalNames);
       this.originalNames = originalNames;
       this.dexItemFactory = appView.dexItemFactory();
       this.options = appView.options();
-      this.cycler =
-          new VirtualFileCycler(files, filesForDistribution, appView, namingLens, nextFileId);
+      this.cycler = new VirtualFileCycler(files, filesForDistribution, appView, nextFileId);
     }
 
     static boolean coveredByPrefix(String originalName, String currentPrefix) {
diff --git a/src/main/java/com/android/tools/r8/code/BytecodeStream.java b/src/main/java/com/android/tools/r8/dex/code/BytecodeStream.java
similarity index 87%
rename from src/main/java/com/android/tools/r8/code/BytecodeStream.java
rename to src/main/java/com/android/tools/r8/dex/code/BytecodeStream.java
index e928c3e..da1e31a 100644
--- a/src/main/java/com/android/tools/r8/code/BytecodeStream.java
+++ b/src/main/java/com/android/tools/r8/dex/code/BytecodeStream.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 public interface BytecodeStream {
 
@@ -23,7 +23,7 @@
    * Returns the next byte value from the stream, i.e., the high value of the next short followed by
    * the low value.
    *
-   * Both bytes need to be consumed before the next call to {@link #nextShort()}.
+   * <p>Both bytes need to be consumed before the next call to {@link #nextShort()}.
    *
    * @return next byte value in the stream.
    */
diff --git a/src/main/java/com/android/tools/r8/code/CfOrDexInstanceFieldRead.java b/src/main/java/com/android/tools/r8/dex/code/CfOrDexInstanceFieldRead.java
similarity index 89%
rename from src/main/java/com/android/tools/r8/code/CfOrDexInstanceFieldRead.java
rename to src/main/java/com/android/tools/r8/dex/code/CfOrDexInstanceFieldRead.java
index 3d560fc..4d4d9bc 100644
--- a/src/main/java/com/android/tools/r8/code/CfOrDexInstanceFieldRead.java
+++ b/src/main/java/com/android/tools/r8/dex/code/CfOrDexInstanceFieldRead.java
@@ -2,7 +2,7 @@
 // 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.DexField;
 
diff --git a/src/main/java/com/android/tools/r8/code/CfOrDexInstruction.java b/src/main/java/com/android/tools/r8/dex/code/CfOrDexInstruction.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/CfOrDexInstruction.java
rename to src/main/java/com/android/tools/r8/dex/code/CfOrDexInstruction.java
index e8ac111..7bd1e7a 100644
--- a/src/main/java/com/android/tools/r8/code/CfOrDexInstruction.java
+++ b/src/main/java/com/android/tools/r8/dex/code/CfOrDexInstruction.java
@@ -2,7 +2,7 @@
 // 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.cf.code.CfInstruction;
 
@@ -12,5 +12,5 @@
 
   boolean isCfInstruction();
 
-  Instruction asDexInstruction();
+  DexInstruction asDexInstruction();
 }
diff --git a/src/main/java/com/android/tools/r8/code/CfOrDexStaticFieldRead.java b/src/main/java/com/android/tools/r8/dex/code/CfOrDexStaticFieldRead.java
similarity index 89%
rename from src/main/java/com/android/tools/r8/code/CfOrDexStaticFieldRead.java
rename to src/main/java/com/android/tools/r8/dex/code/CfOrDexStaticFieldRead.java
index 121023a..513543c 100644
--- a/src/main/java/com/android/tools/r8/code/CfOrDexStaticFieldRead.java
+++ b/src/main/java/com/android/tools/r8/dex/code/CfOrDexStaticFieldRead.java
@@ -2,7 +2,7 @@
 // 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.DexField;
 
diff --git a/src/main/java/com/android/tools/r8/code/AddDouble.java b/src/main/java/com/android/tools/r8/dex/code/DexAddDouble.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddDouble.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddDouble.java
index ce962e2..d78dcbd 100644
--- a/src/main/java/com/android/tools/r8/code/AddDouble.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddDouble.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AddDouble extends Format23x {
+
+public class DexAddDouble extends DexFormat23x {
 
   public static final int OPCODE = 0xab;
   public static final String NAME = "AddDouble";
   public static final String SMALI_NAME = "add-double";
 
-  AddDouble(int high, BytecodeStream stream) {
+  DexAddDouble(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddDouble(int dest, int left, int right) {
+  public DexAddDouble(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddDouble2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAddDouble2Addr.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AddDouble2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddDouble2Addr.java
index a5a907b..c641b5f 100644
--- a/src/main/java/com/android/tools/r8/code/AddDouble2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddDouble2Addr.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AddDouble2Addr extends Format12x {
+
+public class DexAddDouble2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xcb;
   public static final String NAME = "AddDouble2Addr";
   public static final String SMALI_NAME = "add-double/2addr";
 
-  AddDouble2Addr(int high, BytecodeStream stream) {
+  DexAddDouble2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddDouble2Addr(int left, int right) {
+  public DexAddDouble2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddFloat.java b/src/main/java/com/android/tools/r8/dex/code/DexAddFloat.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddFloat.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddFloat.java
index 2d255ea..e745b30 100644
--- a/src/main/java/com/android/tools/r8/code/AddFloat.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddFloat.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddFloat extends Format23x {
+public class DexAddFloat extends DexFormat23x {
 
   public static final int OPCODE = 0xa6;
   public static final String NAME = "AddFloat";
   public static final String SMALI_NAME = "add-float";
 
-  AddFloat(int high, BytecodeStream stream) {
+  DexAddFloat(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddFloat(int dest, int left, int right) {
+  public DexAddFloat(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddFloat2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAddFloat2Addr.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AddFloat2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddFloat2Addr.java
index 0fb4691..e232cae 100644
--- a/src/main/java/com/android/tools/r8/code/AddFloat2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddFloat2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddFloat2Addr extends Format12x {
+public class DexAddFloat2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xc6;
   public static final String NAME = "AddFloat2Addr";
   public static final String SMALI_NAME = "add-float/2addr";
 
-  AddFloat2Addr(int high, BytecodeStream stream) {
+  DexAddFloat2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddFloat2Addr(int left, int right) {
+  public DexAddFloat2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddInt.java b/src/main/java/com/android/tools/r8/dex/code/DexAddInt.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddInt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddInt.java
index ba05bbf..b9e3d75 100644
--- a/src/main/java/com/android/tools/r8/code/AddInt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddInt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddInt extends Format23x {
+public class DexAddInt extends DexFormat23x {
 
   public static final int OPCODE = 0x90;
   public static final String NAME = "AddInt";
   public static final String SMALI_NAME = "add-int";
 
-  AddInt(int high, BytecodeStream stream) {
+  DexAddInt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddInt(int dest, int left, int right) {
+  public DexAddInt(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddInt2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAddInt2Addr.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddInt2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddInt2Addr.java
index 1d50caf..cc38583 100644
--- a/src/main/java/com/android/tools/r8/code/AddInt2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddInt2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddInt2Addr extends Format12x {
+public class DexAddInt2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xb0;
   public static final String NAME = "AddInt2Addr";
   public static final String SMALI_NAME = "add-int/2addr";
 
-  AddInt2Addr(int high, BytecodeStream stream) {
+  DexAddInt2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddInt2Addr(int left, int right) {
+  public DexAddInt2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddIntLit16.java b/src/main/java/com/android/tools/r8/dex/code/DexAddIntLit16.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AddIntLit16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddIntLit16.java
index c05f238..07e6e6a 100644
--- a/src/main/java/com/android/tools/r8/code/AddIntLit16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddIntLit16.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddIntLit16 extends Format22s {
+public class DexAddIntLit16 extends DexFormat22s {
 
   public static final int OPCODE = 0xd0;
   public static final String NAME = "AddIntLit16";
   public static final String SMALI_NAME = "add-int/lit16";
 
-  AddIntLit16(int high, BytecodeStream stream) {
+  DexAddIntLit16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddIntLit16(int dest, int register, int constant) {
+  public DexAddIntLit16(int dest, int register, int constant) {
     super(dest, register, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddIntLit8.java b/src/main/java/com/android/tools/r8/dex/code/DexAddIntLit8.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AddIntLit8.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddIntLit8.java
index 8715c06..8093253 100644
--- a/src/main/java/com/android/tools/r8/code/AddIntLit8.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddIntLit8.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AddIntLit8 extends Format22b {
+public class DexAddIntLit8 extends DexFormat22b {
 
   public static final int OPCODE = 0xd8;
   public static final String NAME = "AddIntLit8";
   public static final String SMALI_NAME = "add-int/lit8";
 
-  AddIntLit8(int high, BytecodeStream stream) {
+  DexAddIntLit8(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddIntLit8(int dest, int register, int constant) {
+  public DexAddIntLit8(int dest, int register, int constant) {
     super(dest, register, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddLong.java b/src/main/java/com/android/tools/r8/dex/code/DexAddLong.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddLong.java
index f3a6e3f..dbb0094 100644
--- a/src/main/java/com/android/tools/r8/code/AddLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddLong.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AddLong extends Format23x {
+
+public class DexAddLong extends DexFormat23x {
 
   public static final int OPCODE = 0x9b;
   public static final String NAME = "AddLong";
   public static final String SMALI_NAME = "add-long";
 
-  AddLong(int high, BytecodeStream stream) {
+  DexAddLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddLong(int dest, int left, int right) {
+  public DexAddLong(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AddLong2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAddLong2Addr.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AddLong2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAddLong2Addr.java
index 72cb8e6..0d93f58 100644
--- a/src/main/java/com/android/tools/r8/code/AddLong2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAddLong2Addr.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AddLong2Addr extends Format12x {
+
+public class DexAddLong2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xbb;
   public static final String NAME = "AddLong2Addr";
   public static final String SMALI_NAME = "add-long/2addr";
 
-  AddLong2Addr(int high, BytecodeStream stream) {
+  DexAddLong2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AddLong2Addr(int left, int right) {
+  public DexAddLong2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Aget.java b/src/main/java/com/android/tools/r8/dex/code/DexAget.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/Aget.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAget.java
index 063df5e..71f365b 100644
--- a/src/main/java/com/android/tools/r8/code/Aget.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAget.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Aget extends Format23x {
+public class DexAget extends DexFormat23x {
 
   public static final int OPCODE = 0x44;
   public static final String NAME = "Aget";
   public static final String SMALI_NAME = "aget";
 
-  /*package*/ Aget(int high, BytecodeStream stream) {
+  /*package*/ DexAget(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Aget(int AA, int BB, int CC) {
+  public DexAget(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetBoolean.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetBoolean.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AgetBoolean.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetBoolean.java
index fc05007..e969298 100644
--- a/src/main/java/com/android/tools/r8/code/AgetBoolean.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetBoolean.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AgetBoolean extends Format23x {
+public class DexAgetBoolean extends DexFormat23x {
 
   public static final int OPCODE = 0x47;
   public static final String NAME = "AgetBoolean";
   public static final String SMALI_NAME = "aget-boolean";
 
-  AgetBoolean(int high, BytecodeStream stream) {
+  DexAgetBoolean(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetBoolean(int AA, int BB, int CC) {
+  public DexAgetBoolean(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetByte.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetByte.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AgetByte.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetByte.java
index f7bc165..addb35e 100644
--- a/src/main/java/com/android/tools/r8/code/AgetByte.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetByte.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AgetByte extends Format23x {
+public class DexAgetByte extends DexFormat23x {
 
   public static final int OPCODE = 0x48;
   public static final String NAME = "AgetByte";
   public static final String SMALI_NAME = "aget-byte";
 
-  /*package*/ AgetByte(int high, BytecodeStream stream) {
+  /*package*/ DexAgetByte(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetByte(int AA, int BB, int CC) {
+  public DexAgetByte(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetChar.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetChar.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AgetChar.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetChar.java
index fc7804e..ed8ac21 100644
--- a/src/main/java/com/android/tools/r8/code/AgetChar.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetChar.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AgetChar extends Format23x {
+public class DexAgetChar extends DexFormat23x {
 
   public static final int OPCODE = 0x49;
   public static final String NAME = "AgetChar";
   public static final String SMALI_NAME = "aget-char";
 
-  /*package*/ AgetChar(int high, BytecodeStream stream) {
+  /*package*/ DexAgetChar(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetChar(int AA, int BB, int CC) {
+  public DexAgetChar(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetObject.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetObject.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AgetObject.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetObject.java
index 1574602..8cbedda 100644
--- a/src/main/java/com/android/tools/r8/code/AgetObject.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetObject.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AgetObject extends Format23x {
+
+public class DexAgetObject extends DexFormat23x {
 
   public static final int OPCODE = 0x46;
   public static final String NAME = "AgetObject";
   public static final String SMALI_NAME = "aget-object";
 
-  AgetObject(int high, BytecodeStream stream) {
+  DexAgetObject(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetObject(int AA, int BB, int CC) {
+  public DexAgetObject(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetShort.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetShort.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AgetShort.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetShort.java
index d7fb45a..fd887b1 100644
--- a/src/main/java/com/android/tools/r8/code/AgetShort.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetShort.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AgetShort extends Format23x {
+public class DexAgetShort extends DexFormat23x {
 
   public static final int OPCODE = 0x4a;
   public static final String NAME = "AgetShort";
   public static final String SMALI_NAME = "aget-short";
 
-  AgetShort(int high, BytecodeStream stream) {
+  DexAgetShort(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetShort(int AA, int BB, int CC) {
+  public DexAgetShort(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AgetWide.java b/src/main/java/com/android/tools/r8/dex/code/DexAgetWide.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AgetWide.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAgetWide.java
index 64c645d..59a0923 100644
--- a/src/main/java/com/android/tools/r8/code/AgetWide.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAgetWide.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AgetWide extends Format23x {
+public class DexAgetWide extends DexFormat23x {
 
   public static final int OPCODE = 0x45;
   public static final String NAME = "AgetWide";
   public static final String SMALI_NAME = "aget-wide";
 
-  /*package*/ AgetWide(int high, BytecodeStream stream) {
+  /*package*/ DexAgetWide(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AgetWide(int AA, int BB, int CC) {
+  public DexAgetWide(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndInt.java b/src/main/java/com/android/tools/r8/dex/code/DexAndInt.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AndInt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndInt.java
index 532e657..7050380 100644
--- a/src/main/java/com/android/tools/r8/code/AndInt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndInt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AndInt extends Format23x {
+public class DexAndInt extends DexFormat23x {
 
   public static final int OPCODE = 0x95;
   public static final String NAME = "AndInt";
   public static final String SMALI_NAME = "and-int";
 
-  AndInt(int high, BytecodeStream stream) {
+  DexAndInt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndInt(int dest, int left, int right) {
+  public DexAndInt(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndInt2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAndInt2Addr.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AndInt2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndInt2Addr.java
index ad29884..8eba630 100644
--- a/src/main/java/com/android/tools/r8/code/AndInt2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndInt2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AndInt2Addr extends Format12x {
+public class DexAndInt2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xb5;
   public static final String NAME = "AndInt2Addr";
   public static final String SMALI_NAME = "and-int/2addr";
 
-  AndInt2Addr(int high, BytecodeStream stream) {
+  DexAndInt2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndInt2Addr(int left, int right) {
+  public DexAndInt2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndIntLit16.java b/src/main/java/com/android/tools/r8/dex/code/DexAndIntLit16.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AndIntLit16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndIntLit16.java
index 8dc59d5..fd68e93 100644
--- a/src/main/java/com/android/tools/r8/code/AndIntLit16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndIntLit16.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AndIntLit16 extends Format22s {
+public class DexAndIntLit16 extends DexFormat22s {
 
   public static final int OPCODE = 0xd5;
   public static final String NAME = "AndIntLit16";
   public static final String SMALI_NAME = "and-int/lit16";
 
-  AndIntLit16(int high, BytecodeStream stream) {
+  DexAndIntLit16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndIntLit16(int dest, int left, int constant) {
+  public DexAndIntLit16(int dest, int left, int constant) {
     super(dest, left, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndIntLit8.java b/src/main/java/com/android/tools/r8/dex/code/DexAndIntLit8.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/AndIntLit8.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndIntLit8.java
index a347b70..18778c6 100644
--- a/src/main/java/com/android/tools/r8/code/AndIntLit8.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndIntLit8.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AndIntLit8 extends Format22b {
+
+public class DexAndIntLit8 extends DexFormat22b {
 
   public static final int OPCODE = 0xdd;
   public static final String NAME = "AndIntLit8";
   public static final String SMALI_NAME = "and-int/lit8";
 
-  AndIntLit8(int high, BytecodeStream stream) {
+  DexAndIntLit8(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndIntLit8(int dest, int left, int constant) {
+  public DexAndIntLit8(int dest, int left, int constant) {
     super(dest, left, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndLong.java b/src/main/java/com/android/tools/r8/dex/code/DexAndLong.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AndLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndLong.java
index 0bc3eaa..5458217 100644
--- a/src/main/java/com/android/tools/r8/code/AndLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndLong.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AndLong extends Format23x {
+public class DexAndLong extends DexFormat23x {
 
   public static final int OPCODE = 0xA0;
   public static final String NAME = "AndLong";
   public static final String SMALI_NAME = "and-long";
 
-  AndLong(int high, BytecodeStream stream) {
+  DexAndLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndLong(int dest, int left, int right) {
+  public DexAndLong(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AndLong2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexAndLong2Addr.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AndLong2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAndLong2Addr.java
index 276a814..73babe5 100644
--- a/src/main/java/com/android/tools/r8/code/AndLong2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAndLong2Addr.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class AndLong2Addr extends Format12x {
+
+public class DexAndLong2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xc0;
   public static final String NAME = "AndLong2Addr";
   public static final String SMALI_NAME = "and-long/2addr";
 
-  AndLong2Addr(int high, BytecodeStream stream) {
+  DexAndLong2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AndLong2Addr(int left, int right) {
+  public DexAndLong2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Aput.java b/src/main/java/com/android/tools/r8/dex/code/DexAput.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/Aput.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAput.java
index 65e0721..c5b1e1a 100644
--- a/src/main/java/com/android/tools/r8/code/Aput.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAput.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Aput extends Format23x {
+public class DexAput extends DexFormat23x {
 
   public static final int OPCODE = 0x4b;
   public static final String NAME = "Aput";
   public static final String SMALI_NAME = "aput";
 
-  /*package*/ Aput(int high, BytecodeStream stream) {
+  /*package*/ DexAput(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Aput(int AA, int BB, int CC) {
+  public DexAput(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputBoolean.java b/src/main/java/com/android/tools/r8/dex/code/DexAputBoolean.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AputBoolean.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputBoolean.java
index ac64012..78d70a2 100644
--- a/src/main/java/com/android/tools/r8/code/AputBoolean.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputBoolean.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputBoolean extends Format23x {
+public class DexAputBoolean extends DexFormat23x {
 
   public static final int OPCODE = 0x4e;
   public static final String NAME = "AputBoolean";
   public static final String SMALI_NAME = "aput-boolean";
 
-  /*package*/ AputBoolean(int high, BytecodeStream stream) {
+  /*package*/ DexAputBoolean(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputBoolean(int AA, int BB, int CC) {
+  public DexAputBoolean(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputByte.java b/src/main/java/com/android/tools/r8/dex/code/DexAputByte.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AputByte.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputByte.java
index 1d439c6..04def29 100644
--- a/src/main/java/com/android/tools/r8/code/AputByte.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputByte.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputByte extends Format23x {
+public class DexAputByte extends DexFormat23x {
 
   public static final int OPCODE = 0x4f;
   public static final String NAME = "AputByte";
   public static final String SMALI_NAME = "aput-byte";
 
-  /*package*/ AputByte(int high, BytecodeStream stream) {
+  /*package*/ DexAputByte(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputByte(int AA, int BB, int CC) {
+  public DexAputByte(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputChar.java b/src/main/java/com/android/tools/r8/dex/code/DexAputChar.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AputChar.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputChar.java
index 14e408c..0f66bfa 100644
--- a/src/main/java/com/android/tools/r8/code/AputChar.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputChar.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputChar extends Format23x {
+public class DexAputChar extends DexFormat23x {
 
   public static final int OPCODE = 0x50;
   public static final String NAME = "AputChar";
   public static final String SMALI_NAME = "aput-char";
 
-  /*package*/ AputChar(int high, BytecodeStream stream) {
+  /*package*/ DexAputChar(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputChar(int AA, int BB, int CC) {
+  public DexAputChar(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputObject.java b/src/main/java/com/android/tools/r8/dex/code/DexAputObject.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AputObject.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputObject.java
index bcfea78..3012172 100644
--- a/src/main/java/com/android/tools/r8/code/AputObject.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputObject.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputObject extends Format23x {
+public class DexAputObject extends DexFormat23x {
 
   public static final int OPCODE = 0x4d;
   public static final String NAME = "AputObject";
   public static final String SMALI_NAME = "aput-object";
 
-  /*package*/ AputObject(int high, BytecodeStream stream) {
+  /*package*/ DexAputObject(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputObject(int AA, int BB, int CC) {
+  public DexAputObject(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputShort.java b/src/main/java/com/android/tools/r8/dex/code/DexAputShort.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/AputShort.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputShort.java
index daf9b4a..6a3173e 100644
--- a/src/main/java/com/android/tools/r8/code/AputShort.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputShort.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputShort extends Format23x {
+public class DexAputShort extends DexFormat23x {
 
   public static final int OPCODE = 0x51;
   public static final String NAME = "AputShort";
   public static final String SMALI_NAME = "aput-short";
 
-  /*package*/ AputShort(int high, BytecodeStream stream) {
+  /*package*/ DexAputShort(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputShort(int AA, int BB, int CC) {
+  public DexAputShort(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/AputWide.java b/src/main/java/com/android/tools/r8/dex/code/DexAputWide.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/AputWide.java
rename to src/main/java/com/android/tools/r8/dex/code/DexAputWide.java
index 286dfff..adf0e40 100644
--- a/src/main/java/com/android/tools/r8/code/AputWide.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexAputWide.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class AputWide extends Format23x {
+public class DexAputWide extends DexFormat23x {
 
   public static final int OPCODE = 0x4c;
   public static final String NAME = "AputWide";
   public static final String SMALI_NAME = "aput-wide";
 
-  /*package*/ AputWide(int high, BytecodeStream stream) {
+  /*package*/ DexAputWide(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public AputWide(int AA, int BB, int CC) {
+  public DexAputWide(int AA, int BB, int CC) {
     super(AA, BB, CC);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/ArrayLength.java b/src/main/java/com/android/tools/r8/dex/code/DexArrayLength.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/ArrayLength.java
rename to src/main/java/com/android/tools/r8/dex/code/DexArrayLength.java
index 156df49..543ab01 100644
--- a/src/main/java/com/android/tools/r8/code/ArrayLength.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexArrayLength.java
@@ -1,21 +1,21 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class ArrayLength extends Format12x {
+public class DexArrayLength extends DexFormat12x {
 
   public static final int OPCODE = 0x21;
   public static final String NAME = "ArrayLength";
   public static final String SMALI_NAME = "array-length";
 
-  ArrayLength(int high, BytecodeStream stream) {
+  DexArrayLength(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ArrayLength(int dest, int array) {
+  public DexArrayLength(int dest, int array) {
     super(dest, array);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Base1Format.java b/src/main/java/com/android/tools/r8/dex/code/DexBase1Format.java
similarity index 64%
rename from src/main/java/com/android/tools/r8/code/Base1Format.java
rename to src/main/java/com/android/tools/r8/dex/code/DexBase1Format.java
index 09c4bc8..eaea826 100644
--- a/src/main/java/com/android/tools/r8/code/Base1Format.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBase1Format.java
@@ -1,17 +1,17 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
-public abstract class Base1Format extends Instruction {
+public abstract class DexBase1Format extends DexInstruction {
 
   public static final int SIZE = 1;
 
-  public Base1Format(BytecodeStream stream) {
+  public DexBase1Format(BytecodeStream stream) {
     super(stream);
   }
 
-  protected Base1Format() {}
+  protected DexBase1Format() {}
 
   @Override
   public int getSize() {
diff --git a/src/main/java/com/android/tools/r8/code/Base2Format.java b/src/main/java/com/android/tools/r8/dex/code/DexBase2Format.java
similarity index 64%
rename from src/main/java/com/android/tools/r8/code/Base2Format.java
rename to src/main/java/com/android/tools/r8/dex/code/DexBase2Format.java
index 7d8e51e..abc2ee2 100644
--- a/src/main/java/com/android/tools/r8/code/Base2Format.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBase2Format.java
@@ -1,15 +1,15 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
-public abstract class Base2Format extends Instruction {
+public abstract class DexBase2Format extends DexInstruction {
 
   public static final int SIZE = 2;
 
-  protected Base2Format() {}
+  protected DexBase2Format() {}
 
-  public Base2Format(BytecodeStream stream) {
+  public DexBase2Format(BytecodeStream stream) {
     super(stream);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Base3Format.java b/src/main/java/com/android/tools/r8/dex/code/DexBase3Format.java
similarity index 64%
rename from src/main/java/com/android/tools/r8/code/Base3Format.java
rename to src/main/java/com/android/tools/r8/dex/code/DexBase3Format.java
index 62d6824..e78d48d 100644
--- a/src/main/java/com/android/tools/r8/code/Base3Format.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBase3Format.java
@@ -1,15 +1,15 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
-public abstract class Base3Format extends Instruction {
+public abstract class DexBase3Format extends DexInstruction {
 
   public static final int SIZE = 3;
 
-  protected Base3Format() {}
+  protected DexBase3Format() {}
 
-  public Base3Format(BytecodeStream stream) {
+  public DexBase3Format(BytecodeStream stream) {
     super(stream);
   }
 
@@ -17,4 +17,4 @@
   public int getSize() {
     return SIZE;
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/android/tools/r8/code/Base4Format.java b/src/main/java/com/android/tools/r8/dex/code/DexBase4Format.java
similarity index 64%
rename from src/main/java/com/android/tools/r8/code/Base4Format.java
rename to src/main/java/com/android/tools/r8/dex/code/DexBase4Format.java
index a08411f..ea206fe 100644
--- a/src/main/java/com/android/tools/r8/code/Base4Format.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBase4Format.java
@@ -1,15 +1,15 @@
 // Copyright (c) 2017, 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.code;
+package com.android.tools.r8.dex.code;
 
-public abstract class Base4Format extends Instruction {
+public abstract class DexBase4Format extends DexInstruction {
 
   public static final int SIZE = 4;
 
-  protected Base4Format() {}
+  protected DexBase4Format() {}
 
-  public Base4Format(BytecodeStream stream) {
+  public DexBase4Format(BytecodeStream stream) {
     super(stream);
   }
 
@@ -17,4 +17,4 @@
   public int getSize() {
     return SIZE;
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/android/tools/r8/code/Base5Format.java b/src/main/java/com/android/tools/r8/dex/code/DexBase5Format.java
similarity index 64%
rename from src/main/java/com/android/tools/r8/code/Base5Format.java
rename to src/main/java/com/android/tools/r8/dex/code/DexBase5Format.java
index 093e932..207129d 100644
--- a/src/main/java/com/android/tools/r8/code/Base5Format.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBase5Format.java
@@ -1,15 +1,15 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
-public abstract class Base5Format extends Instruction {
+public abstract class DexBase5Format extends DexInstruction {
 
   public static final int SIZE = 5;
 
-  protected Base5Format() {}
+  protected DexBase5Format() {}
 
-  public Base5Format(BytecodeStream stream) {
+  public DexBase5Format(BytecodeStream stream) {
     super(stream);
   }
 
@@ -17,4 +17,4 @@
   public int getSize() {
     return SIZE;
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/android/tools/r8/dex/code/DexBaseInstructionFactory.java b/src/main/java/com/android/tools/r8/dex/code/DexBaseInstructionFactory.java
new file mode 100644
index 0000000..fdd4b40
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/dex/code/DexBaseInstructionFactory.java
@@ -0,0 +1,465 @@
+// Copyright (c) 2016, 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.dex.code;
+
+import com.android.tools.r8.graph.OffsetToObjectMapping;
+
+abstract class DexBaseInstructionFactory {
+
+  static DexInstruction create(
+      int high, int opcode, BytecodeStream stream, OffsetToObjectMapping mapping) {
+    switch (opcode) {
+      case 0x0:
+        return DexNop.create(high, stream);
+      case DexMove.OPCODE:
+        return new DexMove(high, stream);
+      case DexMoveFrom16.OPCODE:
+        return new DexMoveFrom16(high, stream);
+      case DexMove16.OPCODE:
+        return new DexMove16(high, stream);
+      case DexMoveWide.OPCODE:
+        return new DexMoveWide(high, stream);
+      case DexMoveWideFrom16.OPCODE:
+        return new DexMoveWideFrom16(high, stream);
+      case DexMoveWide16.OPCODE:
+        return new DexMoveWide16(high, stream);
+      case DexMoveObject.OPCODE:
+        return new DexMoveObject(high, stream);
+      case DexMoveObjectFrom16.OPCODE:
+        return new DexMoveObjectFrom16(high, stream);
+      case DexMoveObject16.OPCODE:
+        return new DexMoveObject16(high, stream);
+      case DexMoveResult.OPCODE:
+        return new DexMoveResult(high, stream);
+      case DexMoveResultWide.OPCODE:
+        return new DexMoveResultWide(high, stream);
+      case DexMoveResultObject.OPCODE:
+        return new DexMoveResultObject(high, stream);
+      case DexMoveException.OPCODE:
+        return new DexMoveException(high, stream);
+      case DexReturnVoid.OPCODE:
+        return new DexReturnVoid(high, stream);
+      case DexReturn.OPCODE:
+        return new DexReturn(high, stream);
+      case DexReturnWide.OPCODE:
+        return new DexReturnWide(high, stream);
+      case DexReturnObject.OPCODE:
+        return new DexReturnObject(high, stream);
+      case DexConst4.OPCODE:
+        return new DexConst4(high, stream);
+      case DexConst16.OPCODE:
+        return new DexConst16(high, stream);
+      case DexConst.OPCODE:
+        return new DexConst(high, stream);
+      case DexConstHigh16.OPCODE:
+        return new DexConstHigh16(high, stream);
+      case DexConstWide16.OPCODE:
+        return new DexConstWide16(high, stream);
+      case DexConstWide32.OPCODE:
+        return new DexConstWide32(high, stream);
+      case DexConstWide.OPCODE:
+        return new DexConstWide(high, stream);
+      case DexConstWideHigh16.OPCODE:
+        return new DexConstWideHigh16(high, stream);
+      case DexConstString.OPCODE:
+        return new DexConstString(high, stream, mapping);
+      case DexConstStringJumbo.OPCODE:
+        return new DexConstStringJumbo(high, stream, mapping);
+      case DexConstClass.OPCODE:
+        return new DexConstClass(high, stream, mapping);
+      case DexMonitorEnter.OPCODE:
+        return new DexMonitorEnter(high, stream);
+      case DexMonitorExit.OPCODE:
+        return new DexMonitorExit(high, stream);
+      case DexCheckCast.OPCODE:
+        return new DexCheckCast(high, stream, mapping);
+      case DexInstanceOf.OPCODE:
+        return new DexInstanceOf(high, stream, mapping);
+      case DexArrayLength.OPCODE:
+        return new DexArrayLength(high, stream);
+      case DexNewInstance.OPCODE:
+        return new DexNewInstance(high, stream, mapping);
+      case DexNewArray.OPCODE:
+        return new DexNewArray(high, stream, mapping);
+      case DexFilledNewArray.OPCODE:
+        return new DexFilledNewArray(high, stream, mapping);
+      case DexFilledNewArrayRange.OPCODE:
+        return new DexFilledNewArrayRange(high, stream, mapping);
+      case DexFillArrayData.OPCODE:
+        return new DexFillArrayData(high, stream);
+      case DexThrow.OPCODE:
+        return new DexThrow(high, stream);
+      case DexGoto.OPCODE:
+        return new DexGoto(high, stream);
+      case DexGoto16.OPCODE:
+        return new DexGoto16(high, stream);
+      case DexGoto32.OPCODE:
+        return new DexGoto32(high, stream);
+      case DexPackedSwitch.OPCODE:
+        return new DexPackedSwitch(high, stream);
+      case DexSparseSwitch.OPCODE:
+        return new DexSparseSwitch(high, stream);
+      case DexCmplFloat.OPCODE:
+        return new DexCmplFloat(high, stream);
+      case DexCmpgFloat.OPCODE:
+        return new DexCmpgFloat(high, stream);
+      case DexCmplDouble.OPCODE:
+        return new DexCmplDouble(high, stream);
+      case DexCmpgDouble.OPCODE:
+        return new DexCmpgDouble(high, stream);
+      case DexCmpLong.OPCODE:
+        return new DexCmpLong(high, stream);
+      case DexIfEq.OPCODE:
+        return new DexIfEq(high, stream);
+      case DexIfNe.OPCODE:
+        return new DexIfNe(high, stream);
+      case DexIfLt.OPCODE:
+        return new DexIfLt(high, stream);
+      case DexIfGe.OPCODE:
+        return new DexIfGe(high, stream);
+      case DexIfGt.OPCODE:
+        return new DexIfGt(high, stream);
+      case DexIfLe.OPCODE:
+        return new DexIfLe(high, stream);
+      case DexIfEqz.OPCODE:
+        return new DexIfEqz(high, stream);
+      case DexIfNez.OPCODE:
+        return new DexIfNez(high, stream);
+      case DexIfLtz.OPCODE:
+        return new DexIfLtz(high, stream);
+      case DexIfGez.OPCODE:
+        return new DexIfGez(high, stream);
+      case DexIfGtz.OPCODE:
+        return new DexIfGtz(high, stream);
+      case DexIfLez.OPCODE:
+        return new DexIfLez(high, stream);
+      case DexAget.OPCODE:
+        return new DexAget(high, stream);
+      case DexAgetWide.OPCODE:
+        return new DexAgetWide(high, stream);
+      case DexAgetObject.OPCODE:
+        return new DexAgetObject(high, stream);
+      case DexAgetBoolean.OPCODE:
+        return new DexAgetBoolean(high, stream);
+      case DexAgetByte.OPCODE:
+        return new DexAgetByte(high, stream);
+      case DexAgetChar.OPCODE:
+        return new DexAgetChar(high, stream);
+      case DexAgetShort.OPCODE:
+        return new DexAgetShort(high, stream);
+      case DexAput.OPCODE:
+        return new DexAput(high, stream);
+      case DexAputWide.OPCODE:
+        return new DexAputWide(high, stream);
+      case DexAputObject.OPCODE:
+        return new DexAputObject(high, stream);
+      case DexAputBoolean.OPCODE:
+        return new DexAputBoolean(high, stream);
+      case DexAputByte.OPCODE:
+        return new DexAputByte(high, stream);
+      case DexAputChar.OPCODE:
+        return new DexAputChar(high, stream);
+      case DexAputShort.OPCODE:
+        return new DexAputShort(high, stream);
+      case DexIget.OPCODE:
+        return new DexIget(high, stream, mapping);
+      case DexIgetWide.OPCODE:
+        return new DexIgetWide(high, stream, mapping);
+      case DexIgetObject.OPCODE:
+        return new DexIgetObject(high, stream, mapping);
+      case DexIgetBoolean.OPCODE:
+        return new DexIgetBoolean(high, stream, mapping);
+      case DexIgetByte.OPCODE:
+        return new DexIgetByte(high, stream, mapping);
+      case DexIgetChar.OPCODE:
+        return new DexIgetChar(high, stream, mapping);
+      case DexIgetShort.OPCODE:
+        return new DexIgetShort(high, stream, mapping);
+      case DexIput.OPCODE:
+        return new DexIput(high, stream, mapping);
+      case DexIputWide.OPCODE:
+        return new DexIputWide(high, stream, mapping);
+      case DexIputObject.OPCODE:
+        return new DexIputObject(high, stream, mapping);
+      case DexIputBoolean.OPCODE:
+        return new DexIputBoolean(high, stream, mapping);
+      case DexIputByte.OPCODE:
+        return new DexIputByte(high, stream, mapping);
+      case DexIputChar.OPCODE:
+        return new DexIputChar(high, stream, mapping);
+      case DexIputShort.OPCODE:
+        return new DexIputShort(high, stream, mapping);
+      case DexSget.OPCODE:
+        return new DexSget(high, stream, mapping);
+      case DexSgetWide.OPCODE:
+        return new DexSgetWide(high, stream, mapping);
+      case DexSgetObject.OPCODE:
+        return new DexSgetObject(high, stream, mapping);
+      case DexSgetBoolean.OPCODE:
+        return new DexSgetBoolean(high, stream, mapping);
+      case DexSgetByte.OPCODE:
+        return new DexSgetByte(high, stream, mapping);
+      case DexSgetChar.OPCODE:
+        return new DexSgetChar(high, stream, mapping);
+      case DexSgetShort.OPCODE:
+        return new DexSgetShort(high, stream, mapping);
+      case DexSput.OPCODE:
+        return new DexSput(high, stream, mapping);
+      case DexSputWide.OPCODE:
+        return new DexSputWide(high, stream, mapping);
+      case DexSputObject.OPCODE:
+        return new DexSputObject(high, stream, mapping);
+      case DexSputBoolean.OPCODE:
+        return new DexSputBoolean(high, stream, mapping);
+      case DexSputByte.OPCODE:
+        return new DexSputByte(high, stream, mapping);
+      case DexSputChar.OPCODE:
+        return new DexSputChar(high, stream, mapping);
+      case DexSputShort.OPCODE:
+        return new DexSputShort(high, stream, mapping);
+      case DexInvokeVirtual.OPCODE:
+        return new DexInvokeVirtual(high, stream, mapping);
+      case DexInvokeSuper.OPCODE:
+        return new DexInvokeSuper(high, stream, mapping);
+      case DexInvokeDirect.OPCODE:
+        return new DexInvokeDirect(high, stream, mapping);
+      case DexInvokeStatic.OPCODE:
+        return new DexInvokeStatic(high, stream, mapping);
+      case DexInvokeInterface.OPCODE:
+        return new DexInvokeInterface(high, stream, mapping);
+      case DexInvokeVirtualRange.OPCODE:
+        return new DexInvokeVirtualRange(high, stream, mapping);
+      case DexInvokeSuperRange.OPCODE:
+        return new DexInvokeSuperRange(high, stream, mapping);
+      case DexInvokeDirectRange.OPCODE:
+        return new DexInvokeDirectRange(high, stream, mapping);
+      case DexInvokeStaticRange.OPCODE:
+        return new DexInvokeStaticRange(high, stream, mapping);
+      case DexInvokeInterfaceRange.OPCODE:
+        return new DexInvokeInterfaceRange(high, stream, mapping);
+      case DexNegInt.OPCODE:
+        return new DexNegInt(high, stream);
+      case DexNotInt.OPCODE:
+        return new DexNotInt(high, stream);
+      case DexNegLong.OPCODE:
+        return new DexNegLong(high, stream);
+      case DexNotLong.OPCODE:
+        return new DexNotLong(high, stream);
+      case DexNegFloat.OPCODE:
+        return new DexNegFloat(high, stream);
+      case DexNegDouble.OPCODE:
+        return new DexNegDouble(high, stream);
+      case DexIntToLong.OPCODE:
+        return new DexIntToLong(high, stream);
+      case DexIntToFloat.OPCODE:
+        return new DexIntToFloat(high, stream);
+      case DexIntToDouble.OPCODE:
+        return new DexIntToDouble(high, stream);
+      case DexLongToInt.OPCODE:
+        return new DexLongToInt(high, stream);
+      case DexLongToFloat.OPCODE:
+        return new DexLongToFloat(high, stream);
+      case DexLongToDouble.OPCODE:
+        return new DexLongToDouble(high, stream);
+      case DexFloatToInt.OPCODE:
+        return new DexFloatToInt(high, stream);
+      case DexFloatToLong.OPCODE:
+        return new DexFloatToLong(high, stream);
+      case DexFloatToDouble.OPCODE:
+        return new DexFloatToDouble(high, stream);
+      case DexDoubleToInt.OPCODE:
+        return new DexDoubleToInt(high, stream);
+      case DexDoubleToLong.OPCODE:
+        return new DexDoubleToLong(high, stream);
+      case DexDoubleToFloat.OPCODE:
+        return new DexDoubleToFloat(high, stream);
+      case DexIntToByte.OPCODE:
+        return new DexIntToByte(high, stream);
+      case DexIntToChar.OPCODE:
+        return new DexIntToChar(high, stream);
+      case DexIntToShort.OPCODE:
+        return new DexIntToShort(high, stream);
+      case DexAddInt.OPCODE:
+        return new DexAddInt(high, stream);
+      case DexSubInt.OPCODE:
+        return new DexSubInt(high, stream);
+      case DexMulInt.OPCODE:
+        return new DexMulInt(high, stream);
+      case DexDivInt.OPCODE:
+        return new DexDivInt(high, stream);
+      case DexRemInt.OPCODE:
+        return new DexRemInt(high, stream);
+      case DexAndInt.OPCODE:
+        return new DexAndInt(high, stream);
+      case DexOrInt.OPCODE:
+        return new DexOrInt(high, stream);
+      case DexXorInt.OPCODE:
+        return new DexXorInt(high, stream);
+      case DexShlInt.OPCODE:
+        return new DexShlInt(high, stream);
+      case DexShrInt.OPCODE:
+        return new DexShrInt(high, stream);
+      case DexUshrInt.OPCODE:
+        return new DexUshrInt(high, stream);
+      case DexAddLong.OPCODE:
+        return new DexAddLong(high, stream);
+      case DexSubLong.OPCODE:
+        return new DexSubLong(high, stream);
+      case DexMulLong.OPCODE:
+        return new DexMulLong(high, stream);
+      case DexDivLong.OPCODE:
+        return new DexDivLong(high, stream);
+      case DexRemLong.OPCODE:
+        return new DexRemLong(high, stream);
+      case DexAndLong.OPCODE:
+        return new DexAndLong(high, stream);
+      case DexOrLong.OPCODE:
+        return new DexOrLong(high, stream);
+      case DexXorLong.OPCODE:
+        return new DexXorLong(high, stream);
+      case DexShlLong.OPCODE:
+        return new DexShlLong(high, stream);
+      case DexShrLong.OPCODE:
+        return new DexShrLong(high, stream);
+      case DexUshrLong.OPCODE:
+        return new DexUshrLong(high, stream);
+      case DexAddFloat.OPCODE:
+        return new DexAddFloat(high, stream);
+      case DexSubFloat.OPCODE:
+        return new DexSubFloat(high, stream);
+      case DexMulFloat.OPCODE:
+        return new DexMulFloat(high, stream);
+      case DexDivFloat.OPCODE:
+        return new DexDivFloat(high, stream);
+      case DexRemFloat.OPCODE:
+        return new DexRemFloat(high, stream);
+      case DexAddDouble.OPCODE:
+        return new DexAddDouble(high, stream);
+      case DexSubDouble.OPCODE:
+        return new DexSubDouble(high, stream);
+      case DexMulDouble.OPCODE:
+        return new DexMulDouble(high, stream);
+      case DexDivDouble.OPCODE:
+        return new DexDivDouble(high, stream);
+      case DexRemDouble.OPCODE:
+        return new DexRemDouble(high, stream);
+      case DexAddInt2Addr.OPCODE:
+        return new DexAddInt2Addr(high, stream);
+      case DexSubInt2Addr.OPCODE:
+        return new DexSubInt2Addr(high, stream);
+      case DexMulInt2Addr.OPCODE:
+        return new DexMulInt2Addr(high, stream);
+      case DexDivInt2Addr.OPCODE:
+        return new DexDivInt2Addr(high, stream);
+      case DexRemInt2Addr.OPCODE:
+        return new DexRemInt2Addr(high, stream);
+      case DexAndInt2Addr.OPCODE:
+        return new DexAndInt2Addr(high, stream);
+      case DexOrInt2Addr.OPCODE:
+        return new DexOrInt2Addr(high, stream);
+      case DexXorInt2Addr.OPCODE:
+        return new DexXorInt2Addr(high, stream);
+      case DexShlInt2Addr.OPCODE:
+        return new DexShlInt2Addr(high, stream);
+      case DexShrInt2Addr.OPCODE:
+        return new DexShrInt2Addr(high, stream);
+      case DexUshrInt2Addr.OPCODE:
+        return new DexUshrInt2Addr(high, stream);
+      case DexAddLong2Addr.OPCODE:
+        return new DexAddLong2Addr(high, stream);
+      case DexSubLong2Addr.OPCODE:
+        return new DexSubLong2Addr(high, stream);
+      case DexMulLong2Addr.OPCODE:
+        return new DexMulLong2Addr(high, stream);
+      case DexDivLong2Addr.OPCODE:
+        return new DexDivLong2Addr(high, stream);
+      case DexRemLong2Addr.OPCODE:
+        return new DexRemLong2Addr(high, stream);
+      case DexAndLong2Addr.OPCODE:
+        return new DexAndLong2Addr(high, stream);
+      case DexOrLong2Addr.OPCODE:
+        return new DexOrLong2Addr(high, stream);
+      case DexXorLong2Addr.OPCODE:
+        return new DexXorLong2Addr(high, stream);
+      case DexShlLong2Addr.OPCODE:
+        return new DexShlLong2Addr(high, stream);
+      case DexShrLong2Addr.OPCODE:
+        return new DexShrLong2Addr(high, stream);
+      case DexUshrLong2Addr.OPCODE:
+        return new DexUshrLong2Addr(high, stream);
+      case DexAddFloat2Addr.OPCODE:
+        return new DexAddFloat2Addr(high, stream);
+      case DexSubFloat2Addr.OPCODE:
+        return new DexSubFloat2Addr(high, stream);
+      case DexMulFloat2Addr.OPCODE:
+        return new DexMulFloat2Addr(high, stream);
+      case DexDivFloat2Addr.OPCODE:
+        return new DexDivFloat2Addr(high, stream);
+      case DexRemFloat2Addr.OPCODE:
+        return new DexRemFloat2Addr(high, stream);
+      case DexAddDouble2Addr.OPCODE:
+        return new DexAddDouble2Addr(high, stream);
+      case DexSubDouble2Addr.OPCODE:
+        return new DexSubDouble2Addr(high, stream);
+      case DexMulDouble2Addr.OPCODE:
+        return new DexMulDouble2Addr(high, stream);
+      case DexDivDouble2Addr.OPCODE:
+        return new DexDivDouble2Addr(high, stream);
+      case DexRemDouble2Addr.OPCODE:
+        return new DexRemDouble2Addr(high, stream);
+      case DexAddIntLit16.OPCODE:
+        return new DexAddIntLit16(high, stream);
+      case DexRsubInt.OPCODE:
+        return new DexRsubInt(high, stream);
+      case DexMulIntLit16.OPCODE:
+        return new DexMulIntLit16(high, stream);
+      case DexDivIntLit16.OPCODE:
+        return new DexDivIntLit16(high, stream);
+      case DexRemIntLit16.OPCODE:
+        return new DexRemIntLit16(high, stream);
+      case DexAndIntLit16.OPCODE:
+        return new DexAndIntLit16(high, stream);
+      case DexOrIntLit16.OPCODE:
+        return new DexOrIntLit16(high, stream);
+      case DexXorIntLit16.OPCODE:
+        return new DexXorIntLit16(high, stream);
+      case DexAddIntLit8.OPCODE:
+        return new DexAddIntLit8(high, stream);
+      case DexRsubIntLit8.OPCODE:
+        return new DexRsubIntLit8(high, stream);
+      case DexMulIntLit8.OPCODE:
+        return new DexMulIntLit8(high, stream);
+      case DexDivIntLit8.OPCODE:
+        return new DexDivIntLit8(high, stream);
+      case DexRemIntLit8.OPCODE:
+        return new DexRemIntLit8(high, stream);
+      case DexAndIntLit8.OPCODE:
+        return new DexAndIntLit8(high, stream);
+      case DexOrIntLit8.OPCODE:
+        return new DexOrIntLit8(high, stream);
+      case DexXorIntLit8.OPCODE:
+        return new DexXorIntLit8(high, stream);
+      case DexShlIntLit8.OPCODE:
+        return new DexShlIntLit8(high, stream);
+      case DexShrIntLit8.OPCODE:
+        return new DexShrIntLit8(high, stream);
+      case DexUshrIntLit8.OPCODE:
+        return new DexUshrIntLit8(high, stream);
+      case DexInvokePolymorphic.OPCODE:
+        return new DexInvokePolymorphic(high, stream, mapping);
+      case DexInvokePolymorphicRange.OPCODE:
+        return new DexInvokePolymorphicRange(high, stream, mapping);
+      case DexInvokeCustom.OPCODE:
+        return new DexInvokeCustom(high, stream, mapping);
+      case DexInvokeCustomRange.OPCODE:
+        return new DexInvokeCustomRange(high, stream, mapping);
+      case DexConstMethodHandle.OPCODE:
+        return new DexConstMethodHandle(high, stream, mapping);
+      case DexConstMethodType.OPCODE:
+        return new DexConstMethodType(high, stream, mapping);
+      default:
+        throw new IllegalArgumentException("Illegal Opcode: 0x" + Integer.toString(opcode, 16));
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/code/CheckCast.java b/src/main/java/com/android/tools/r8/dex/code/DexCheckCast.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/CheckCast.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCheckCast.java
index 74a5f91..650655a 100644
--- a/src/main/java/com/android/tools/r8/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCheckCast.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -15,7 +16,7 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public class CheckCast extends Format21c<DexType> {
+public class DexCheckCast extends DexFormat21c<DexType> {
 
   public static final int OPCODE = 0x1f;
   public static final String NAME = "CheckCast";
@@ -23,12 +24,12 @@
 
   private final boolean ignoreCompatRules;
 
-  CheckCast(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexCheckCast(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getTypeMap());
     this.ignoreCompatRules = false;
   }
 
-  public CheckCast(int valueRegister, DexType type, boolean ignoreCompatRules) {
+  public DexCheckCast(int valueRegister, DexType type, boolean ignoreCompatRules) {
     super(valueRegister, type);
     this.ignoreCompatRules = ignoreCompatRules;
   }
@@ -49,7 +50,7 @@
   }
 
   @Override
-  void internalSubSpecify(StructuralSpecification<Format21c<DexType>, ?> spec) {
+  void internalSubSpecify(StructuralSpecification<DexFormat21c<DexType>, ?> spec) {
     spec.withItem(i -> i.BBBB);
   }
 
@@ -60,12 +61,12 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
-    DexType rewritten = graphLens.lookupType(getType());
-    rewritten.collectIndexedItems(indexedItems);
+    DexType rewritten = appView.graphLens().lookupType(getType());
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
@@ -81,7 +82,7 @@
   }
 
   @Override
-  public CheckCast asCheckCast() {
+  public DexCheckCast asCheckCast() {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/CmpLong.java b/src/main/java/com/android/tools/r8/dex/code/DexCmpLong.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/CmpLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCmpLong.java
index 38f1bc9..57f1807 100644
--- a/src/main/java/com/android/tools/r8/code/CmpLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCmpLong.java
@@ -1,23 +1,23 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class CmpLong extends Format23x {
+public class DexCmpLong extends DexFormat23x {
 
   public static final int OPCODE = 0x31;
   public static final String NAME = "CmpLong";
   public static final String SMALI_NAME = "cmp-long";
 
-  CmpLong(int high, BytecodeStream stream) {
+  DexCmpLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public CmpLong(int dest, int left, int right) {
+  public DexCmpLong(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/CmpgDouble.java b/src/main/java/com/android/tools/r8/dex/code/DexCmpgDouble.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/CmpgDouble.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCmpgDouble.java
index f4cfef4..4414ec7 100644
--- a/src/main/java/com/android/tools/r8/code/CmpgDouble.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCmpgDouble.java
@@ -1,23 +1,23 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class CmpgDouble extends Format23x {
+public class DexCmpgDouble extends DexFormat23x {
 
   public static final int OPCODE = 0x30;
   public static final String NAME = "CmpgDouble";
   public static final String SMALI_NAME = "cmpg-double";
 
-  CmpgDouble(int high, BytecodeStream stream) {
+  DexCmpgDouble(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public CmpgDouble(int dest, int left, int right) {
+  public DexCmpgDouble(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/CmpgFloat.java b/src/main/java/com/android/tools/r8/dex/code/DexCmpgFloat.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/CmpgFloat.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCmpgFloat.java
index 299e2fe..ac387ed 100644
--- a/src/main/java/com/android/tools/r8/code/CmpgFloat.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCmpgFloat.java
@@ -1,23 +1,23 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class CmpgFloat extends Format23x {
+public class DexCmpgFloat extends DexFormat23x {
 
   public static final int OPCODE = 0x2e;
   public static final String NAME = "CmpgFloat";
   public static final String SMALI_NAME = "cmpg-float";
 
-  CmpgFloat(int high, BytecodeStream stream) {
+  DexCmpgFloat(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public CmpgFloat(int dest, int left, int right) {
+  public DexCmpgFloat(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/CmplDouble.java b/src/main/java/com/android/tools/r8/dex/code/DexCmplDouble.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/CmplDouble.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCmplDouble.java
index a65ef74..b28bf82 100644
--- a/src/main/java/com/android/tools/r8/code/CmplDouble.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCmplDouble.java
@@ -1,23 +1,23 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class CmplDouble extends Format23x {
+public class DexCmplDouble extends DexFormat23x {
 
   public static final int OPCODE = 0x2f;
   public static final String NAME = "CmplDouble";
   public static final String SMALI_NAME = "cmpl-double";
 
-  CmplDouble(int high, BytecodeStream stream) {
+  DexCmplDouble(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public CmplDouble(int dest, int left, int right) {
+  public DexCmplDouble(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/CmplFloat.java b/src/main/java/com/android/tools/r8/dex/code/DexCmplFloat.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/CmplFloat.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCmplFloat.java
index 892d0de..76becd7 100644
--- a/src/main/java/com/android/tools/r8/code/CmplFloat.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCmplFloat.java
@@ -1,23 +1,23 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class CmplFloat extends Format23x {
+public class DexCmplFloat extends DexFormat23x {
 
   public static final int OPCODE = 0x2d;
   public static final String NAME = "CmplFloat";
   public static final String SMALI_NAME = "cmpl-float";
 
-  CmplFloat(int high, BytecodeStream stream) {
+  DexCmplFloat(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public CmplFloat(int dest, int left, int right) {
+  public DexCmplFloat(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DexCompareHelper.java b/src/main/java/com/android/tools/r8/dex/code/DexCompareHelper.java
similarity index 91%
rename from src/main/java/com/android/tools/r8/code/DexCompareHelper.java
rename to src/main/java/com/android/tools/r8/dex/code/DexCompareHelper.java
index 130e69b..93c2501 100644
--- a/src/main/java/com/android/tools/r8/code/DexCompareHelper.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexCompareHelper.java
@@ -1,7 +1,7 @@
 // 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.code;
+package com.android.tools.r8.dex.code;
 
 public class DexCompareHelper {
 
@@ -22,7 +22,7 @@
 
   // Helper to signal that the concrete instruction is uniquely determined by its ID/opcode.
   public static int compareIdUniquelyDeterminesEquality(
-      Instruction instruction1, Instruction instruction2) {
+      DexInstruction instruction1, DexInstruction instruction2) {
     assert instruction1.getClass() == instruction2.getClass();
     assert instruction1.getCompareToId() == instruction2.getCompareToId();
     assert instruction1.toString().equals(instruction2.toString());
diff --git a/src/main/java/com/android/tools/r8/code/Const.java b/src/main/java/com/android/tools/r8/dex/code/DexConst.java
similarity index 74%
rename from src/main/java/com/android/tools/r8/code/Const.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConst.java
index 498f747..33fdff4 100644
--- a/src/main/java/com/android/tools/r8/code/Const.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConst.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.SingleConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class Const extends Format31i implements SingleConstant {
+public class DexConst extends DexFormat31i implements SingleConstant {
 
   public static final int OPCODE = 0x14;
   public static final String NAME = "Const";
   public static final String SMALI_NAME = "const";
 
-  Const(int high, BytecodeStream stream) {
+  DexConst(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Const(int register, int constant) {
+  public DexConst(int register, int constant) {
     super(register, constant);
   }
 
@@ -45,14 +45,14 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) + " (" + decodedValue() + ")");
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) +
-        "  # " + decodedValue());
+    return formatSmaliString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) + "  # " + decodedValue());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/Const16.java b/src/main/java/com/android/tools/r8/dex/code/DexConst16.java
similarity index 78%
rename from src/main/java/com/android/tools/r8/code/Const16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConst16.java
index 9d69f25..1188df2 100644
--- a/src/main/java/com/android/tools/r8/code/Const16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConst16.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.SingleConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class Const16 extends Format21s implements SingleConstant {
+public class DexConst16 extends DexFormat21s implements SingleConstant {
 
   public static final int OPCODE = 0x13;
   public static final String NAME = "Const16";
   public static final String SMALI_NAME = "const/16";
 
-  /*package*/ Const16(int high, BytecodeStream stream) {
+  /*package*/ DexConst16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Const16(int dest, int constant) {
+  public DexConst16(int dest, int constant) {
     super(dest, constant);
   }
 
@@ -45,8 +45,8 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 4) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 4) + " (" + decodedValue() + ")");
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/Const4.java b/src/main/java/com/android/tools/r8/dex/code/DexConst4.java
similarity index 74%
rename from src/main/java/com/android/tools/r8/code/Const4.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConst4.java
index b9fd59c..09ecd15 100644
--- a/src/main/java/com/android/tools/r8/code/Const4.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConst4.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.SingleConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class Const4 extends Format11n implements SingleConstant {
+public class DexConst4 extends DexFormat11n implements SingleConstant {
 
   public static final int OPCODE = 0x12;
   public static final String NAME = "Const4";
   public static final String SMALI_NAME = "const/4";
 
-  Const4(int high, BytecodeStream stream) {
+  DexConst4(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Const4(int dest, int constant) {
+  public DexConst4(int dest, int constant) {
     super(dest, constant);
   }
 
@@ -45,14 +45,14 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + A + ", " + StringUtils.hexString(decodedValue(), 1) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + A + ", " + StringUtils.hexString(decodedValue(), 1) + " (" + decodedValue() + ")");
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + A + ", " + StringUtils.hexString(decodedValue(), 2) +
-        "  # " + decodedValue());
+    return formatSmaliString(
+        "v" + A + ", " + StringUtils.hexString(decodedValue(), 2) + "  # " + decodedValue());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstClass.java b/src/main/java/com/android/tools/r8/dex/code/DexConstClass.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/ConstClass.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstClass.java
index 88b35e1..bc476c1 100644
--- a/src/main/java/com/android/tools/r8/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstClass.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -15,7 +16,7 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public class ConstClass extends Format21c<DexType> {
+public class DexConstClass extends DexFormat21c<DexType> {
 
   public static final int OPCODE = 0x1c;
   public static final String NAME = "ConstClass";
@@ -23,18 +24,18 @@
 
   private final boolean ignoreCompatRules;
 
-  ConstClass(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexConstClass(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getTypeMap());
     this.ignoreCompatRules = false;
   }
 
-  public ConstClass(int dest, DexType type, boolean ignoreCompatRules) {
+  public DexConstClass(int dest, DexType type, boolean ignoreCompatRules) {
     super(dest, type);
     this.ignoreCompatRules = ignoreCompatRules;
   }
 
   @Override
-  void internalSubSpecify(StructuralSpecification<Format21c<DexType>, ?> spec) {
+  void internalSubSpecify(StructuralSpecification<DexFormat21c<DexType>, ?> spec) {
     spec.withItem(i -> i.BBBB);
   }
 
@@ -60,12 +61,12 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
-    DexType rewritten = graphLens.lookupType(getType());
-    rewritten.collectIndexedItems(indexedItems);
+    DexType rewritten = appView.graphLens().lookupType(getType());
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
@@ -100,7 +101,7 @@
   }
 
   @Override
-  public ConstClass asConstClass() {
+  public DexConstClass asConstClass() {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/ConstHigh16.java b/src/main/java/com/android/tools/r8/dex/code/DexConstHigh16.java
similarity index 72%
rename from src/main/java/com/android/tools/r8/code/ConstHigh16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstHigh16.java
index b16e45d..2e732ed 100644
--- a/src/main/java/com/android/tools/r8/code/ConstHigh16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstHigh16.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.SingleConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class ConstHigh16 extends Format21h implements SingleConstant {
+public class DexConstHigh16 extends DexFormat21h implements SingleConstant {
 
   public static final int OPCODE = 0x15;
   public static final String NAME = "ConstHigh16";
   public static final String SMALI_NAME = "const/high16";
 
-  /*package*/ ConstHigh16(int high, BytecodeStream stream) {
+  /*package*/ DexConstHigh16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ConstHigh16(int register, int constantHighBits) {
+  public DexConstHigh16(int register, int constantHighBits) {
     super(register, constantHighBits);
   }
 
@@ -45,14 +45,14 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) + " (" + decodedValue() + ")");
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) +
-        "  # " + decodedValue());
+    return formatSmaliString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 8) + "  # " + decodedValue());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstMethodHandle.java b/src/main/java/com/android/tools/r8/dex/code/DexConstMethodHandle.java
similarity index 86%
rename from src/main/java/com/android/tools/r8/code/ConstMethodHandle.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstMethodHandle.java
index 0df963f..87964c8 100644
--- a/src/main/java/com/android/tools/r8/code/ConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstMethodHandle.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2017, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.errors.InternalCompilerError;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethodHandle;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -18,17 +19,17 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public class ConstMethodHandle extends Format21c<DexMethodHandle> {
+public class DexConstMethodHandle extends DexFormat21c<DexMethodHandle> {
 
   public static final int OPCODE = 0xfe;
   public static final String NAME = "ConstMethodHandle";
   public static final String SMALI_NAME = "const-method-handle";
 
-  ConstMethodHandle(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexConstMethodHandle(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getMethodHandleMap());
   }
 
-  public ConstMethodHandle(int register, DexMethodHandle methodHandle) {
+  public DexConstMethodHandle(int register, DexMethodHandle methodHandle) {
     super(register, methodHandle);
   }
 
@@ -52,7 +53,7 @@
   }
 
   @Override
-  void internalSubSpecify(StructuralSpecification<Format21c<DexMethodHandle>, ?> spec) {
+  void internalSubSpecify(StructuralSpecification<DexFormat21c<DexMethodHandle>, ?> spec) {
     spec.withItem(i -> i.BBBB);
   }
 
@@ -92,14 +93,14 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     DexMethodHandle rewritten =
         rewriter.rewriteDexMethodHandle(
             getMethodHandle(), MethodHandleUse.NOT_ARGUMENT_TO_LAMBDA_METAFACTORY, context);
-    rewritten.collectIndexedItems(indexedItems);
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstMethodType.java b/src/main/java/com/android/tools/r8/dex/code/DexConstMethodType.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/code/ConstMethodType.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstMethodType.java
index 478d3b5..68f49fb 100644
--- a/src/main/java/com/android/tools/r8/code/ConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstMethodType.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2017, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.errors.InternalCompilerError;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -17,17 +18,17 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public class ConstMethodType extends Format21c<DexProto> {
+public class DexConstMethodType extends DexFormat21c<DexProto> {
 
   public static final int OPCODE = 0xff;
   public static final String NAME = "ConstMethodType";
   public static final String SMALI_NAME = "const-method-type";
 
-  ConstMethodType(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexConstMethodType(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getProtosMap());
   }
 
-  public ConstMethodType(int register, DexProto methodType) {
+  public DexConstMethodType(int register, DexProto methodType) {
     super(register, methodType);
   }
 
@@ -51,7 +52,7 @@
   }
 
   @Override
-  void internalSubSpecify(StructuralSpecification<Format21c<DexProto>, ?> spec) {
+  void internalSubSpecify(StructuralSpecification<DexFormat21c<DexProto>, ?> spec) {
     spec.withItem(i -> i.BBBB);
   }
 
@@ -88,12 +89,12 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     DexProto rewritten = rewriter.rewriteProto(getMethodType());
-    rewritten.collectIndexedItems(indexedItems);
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstString.java b/src/main/java/com/android/tools/r8/dex/code/DexConstString.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/code/ConstString.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstString.java
index 5fd55e4..0117785 100644
--- a/src/main/java/com/android/tools/r8/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstString.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.errors.InternalCompilerError;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -16,17 +17,17 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public class ConstString extends Format21c<DexString> {
+public class DexConstString extends DexFormat21c<DexString> {
 
   public static final int OPCODE = 0x1a;
   public static final String NAME = "ConstString";
   public static final String SMALI_NAME = "const-string";
 
-  ConstString(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexConstString(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getStringMap());
   }
 
-  public ConstString(int register, DexString string) {
+  public DexConstString(int register, DexString string) {
     super(register, string);
   }
 
@@ -35,15 +36,15 @@
   }
 
   @Override
-  void internalSubSpecify(StructuralSpecification<Format21c<DexString>, ?> spec) {
+  void internalSubSpecify(StructuralSpecification<DexFormat21c<DexString>, ?> spec) {
     spec.withItem(i -> i.BBBB);
   }
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     getString().collectIndexedItems(indexedItems);
   }
@@ -64,7 +65,7 @@
   }
 
   @Override
-  public ConstString asConstString() {
+  public DexConstString asConstString() {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/ConstStringJumbo.java b/src/main/java/com/android/tools/r8/dex/code/DexConstStringJumbo.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/ConstStringJumbo.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstStringJumbo.java
index b24f86f..725ef8a 100644
--- a/src/main/java/com/android/tools/r8/code/ConstStringJumbo.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstStringJumbo.java
@@ -1,24 +1,24 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.OffsetToObjectMapping;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.naming.ClassNameMapper;
 
-public class ConstStringJumbo extends Format31c {
+public class DexConstStringJumbo extends DexFormat31c {
 
   public static final int OPCODE = 0x1b;
   public static final String NAME = "ConstStringJumbo";
   public static final String SMALI_NAME = "const-string/jumbo";
 
-  ConstStringJumbo(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexConstStringJumbo(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getStringMap());
   }
 
-  public ConstStringJumbo(int register, DexString string) {
+  public DexConstStringJumbo(int register, DexString string) {
     super(register, string);
   }
 
@@ -42,7 +42,7 @@
   }
 
   @Override
-  public ConstStringJumbo asConstStringJumbo() {
+  public DexConstStringJumbo asConstStringJumbo() {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/ConstWide.java b/src/main/java/com/android/tools/r8/dex/code/DexConstWide.java
similarity index 72%
rename from src/main/java/com/android/tools/r8/code/ConstWide.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstWide.java
index dd2e6e6..6fbd6f2 100644
--- a/src/main/java/com/android/tools/r8/code/ConstWide.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstWide.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.WideConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class ConstWide extends Format51l implements WideConstant {
+public class DexConstWide extends DexFormat51l implements WideConstant {
 
   public static final int OPCODE = 0x18;
   public static final String NAME = "ConstWide";
   public static final String SMALI_NAME = "const-wide";
 
-  ConstWide(int high, BytecodeStream stream) {
+  DexConstWide(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ConstWide(int dest, long constant) {
+  public DexConstWide(int dest, long constant) {
     super(dest, constant);
   }
 
@@ -45,14 +45,14 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + " (" + decodedValue() + ")");
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        "L  # " + decodedValue());
+    return formatSmaliString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + "L  # " + decodedValue());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstWide16.java b/src/main/java/com/android/tools/r8/dex/code/DexConstWide16.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/ConstWide16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstWide16.java
index 99c1810..e30b886 100644
--- a/src/main/java/com/android/tools/r8/code/ConstWide16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstWide16.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.WideConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class ConstWide16 extends Format21s implements WideConstant {
+public class DexConstWide16 extends DexFormat21s implements WideConstant {
 
   public static final int OPCODE = 0x16;
   public static final String NAME = "ConstWide16";
   public static final String SMALI_NAME = "const-wide/16";
 
-  ConstWide16(int high, BytecodeStream stream) {
+  DexConstWide16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ConstWide16(int dest, int constant) {
+  public DexConstWide16(int dest, int constant) {
     super(dest, constant);
   }
 
@@ -45,8 +45,8 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + " (" + decodedValue() + ")");
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstWide32.java b/src/main/java/com/android/tools/r8/dex/code/DexConstWide32.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/ConstWide32.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstWide32.java
index 1e2c274..b315cb9 100644
--- a/src/main/java/com/android/tools/r8/code/ConstWide32.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstWide32.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.WideConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class ConstWide32 extends Format31i implements WideConstant {
+public class DexConstWide32 extends DexFormat31i implements WideConstant {
 
   public static final int OPCODE = 0x17;
   public static final String NAME = "ConstWide32";
   public static final String SMALI_NAME = "const-wide/32";
 
-  ConstWide32(int high, BytecodeStream stream) {
+  DexConstWide32(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ConstWide32(int dest, int constant) {
+  public DexConstWide32(int dest, int constant) {
     super(dest, constant);
   }
 
@@ -45,8 +45,8 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + " (" + decodedValue() + ")");
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/ConstWideHigh16.java b/src/main/java/com/android/tools/r8/dex/code/DexConstWideHigh16.java
similarity index 71%
rename from src/main/java/com/android/tools/r8/code/ConstWideHigh16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexConstWideHigh16.java
index 26d5ea0..0eeca93 100644
--- a/src/main/java/com/android/tools/r8/code/ConstWideHigh16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexConstWideHigh16.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.WideConstant;
@@ -9,17 +9,17 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.StringUtils;
 
-public class ConstWideHigh16 extends Format21h implements WideConstant {
+public class DexConstWideHigh16 extends DexFormat21h implements WideConstant {
 
   public static final int OPCODE = 0x19;
   public static final String NAME = "ConstWideHigh16";
   public static final String SMALI_NAME = "const-wide/high16";
 
-  ConstWideHigh16(int high, BytecodeStream stream) {
+  DexConstWideHigh16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public ConstWideHigh16(int dest, int constantHighBits) {
+  public DexConstWideHigh16(int dest, int constantHighBits) {
     super(dest, constantHighBits);
   }
 
@@ -45,14 +45,14 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        " (" + decodedValue() + ")");
+    return formatString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + " (" + decodedValue() + ")");
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) +
-        "L  # " + decodedValue());
+    return formatSmaliString(
+        "v" + AA + ", " + StringUtils.hexString(decodedValue(), 16) + "L  # " + decodedValue());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/DivDouble.java b/src/main/java/com/android/tools/r8/dex/code/DexDivDouble.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DivDouble.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivDouble.java
index 1be9ee9..19ad41f 100644
--- a/src/main/java/com/android/tools/r8/code/DivDouble.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivDouble.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DivDouble extends Format23x {
+
+public class DexDivDouble extends DexFormat23x {
 
   public static final int OPCODE = 0xae;
   public static final String NAME = "DivDouble";
   public static final String SMALI_NAME = "div-double";
 
-  DivDouble(int high, BytecodeStream stream) {
+  DexDivDouble(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivDouble(int dest, int left, int right) {
+  public DexDivDouble(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivDouble2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexDivDouble2Addr.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/DivDouble2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivDouble2Addr.java
index a8070d2..9481f04 100644
--- a/src/main/java/com/android/tools/r8/code/DivDouble2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivDouble2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivDouble2Addr extends Format12x {
+public class DexDivDouble2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xce;
   public static final String NAME = "DivDouble2Addr";
   public static final String SMALI_NAME = "div-double/2addr";
 
-  DivDouble2Addr(int high, BytecodeStream stream) {
+  DexDivDouble2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivDouble2Addr(int left, int right) {
+  public DexDivDouble2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivFloat.java b/src/main/java/com/android/tools/r8/dex/code/DexDivFloat.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DivFloat.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivFloat.java
index 4069d40..2791142 100644
--- a/src/main/java/com/android/tools/r8/code/DivFloat.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivFloat.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DivFloat extends Format23x {
+
+public class DexDivFloat extends DexFormat23x {
 
   public static final int OPCODE = 0xa9;
   public static final String NAME = "DivFloat";
   public static final String SMALI_NAME = "div-float";
 
-  DivFloat(int high, BytecodeStream stream) {
+  DexDivFloat(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivFloat(int dest, int left, int right) {
+  public DexDivFloat(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivFloat2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexDivFloat2Addr.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/DivFloat2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivFloat2Addr.java
index a51af26..56fb846 100644
--- a/src/main/java/com/android/tools/r8/code/DivFloat2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivFloat2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivFloat2Addr extends Format12x {
+public class DexDivFloat2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xc9;
   public static final String NAME = "DivFloat2Addr";
   public static final String SMALI_NAME = "div-float/2addr";
 
-  DivFloat2Addr(int high, BytecodeStream stream) {
+  DexDivFloat2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivFloat2Addr(int left, int right) {
+  public DexDivFloat2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivInt.java b/src/main/java/com/android/tools/r8/dex/code/DexDivInt.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DivInt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivInt.java
index 90e1459..7f5dc8a 100644
--- a/src/main/java/com/android/tools/r8/code/DivInt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivInt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivInt extends Format23x {
+public class DexDivInt extends DexFormat23x {
 
   public static final int OPCODE = 0x93;
   public static final String NAME = "DivInt";
   public static final String SMALI_NAME = "div-int";
 
-  /*package*/ DivInt(int high, BytecodeStream stream) {
+  /*package*/ DexDivInt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivInt(int dest, int left, int right) {
+  public DexDivInt(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivInt2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexDivInt2Addr.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DivInt2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivInt2Addr.java
index a92d24f..f321ff2 100644
--- a/src/main/java/com/android/tools/r8/code/DivInt2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivInt2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivInt2Addr extends Format12x {
+public class DexDivInt2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xb3;
   public static final String NAME = "DivInt2Addr";
   public static final String SMALI_NAME = "div-int/2addr";
 
-  /*package*/ DivInt2Addr(int high, BytecodeStream stream) {
+  /*package*/ DexDivInt2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivInt2Addr(int left, int right) {
+  public DexDivInt2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivIntLit16.java b/src/main/java/com/android/tools/r8/dex/code/DexDivIntLit16.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/DivIntLit16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivIntLit16.java
index 1a62f6e..10931d3 100644
--- a/src/main/java/com/android/tools/r8/code/DivIntLit16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivIntLit16.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DivIntLit16 extends Format22s {
+
+public class DexDivIntLit16 extends DexFormat22s {
 
   public static final int OPCODE = 0xd3;
   public static final String NAME = "DivIntLit16";
   public static final String SMALI_NAME = "div-int/lit16";
 
-  /*package*/ DivIntLit16(int high, BytecodeStream stream) {
+  /*package*/ DexDivIntLit16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivIntLit16(int dest, int register, int constant) {
+  public DexDivIntLit16(int dest, int register, int constant) {
     super(dest, register, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivIntLit8.java b/src/main/java/com/android/tools/r8/dex/code/DexDivIntLit8.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DivIntLit8.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivIntLit8.java
index 31fd0e60..0626aa4 100644
--- a/src/main/java/com/android/tools/r8/code/DivIntLit8.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivIntLit8.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivIntLit8 extends Format22b {
+public class DexDivIntLit8 extends DexFormat22b {
 
   public static final int OPCODE = 0xdb;
   public static final String NAME = "DivIntLit8";
   public static final String SMALI_NAME = "div-int/lit8";
 
-  DivIntLit8(int high, BytecodeStream stream) {
+  DexDivIntLit8(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivIntLit8(int dest, int left, int constant) {
+  public DexDivIntLit8(int dest, int left, int constant) {
     super(dest, left, constant);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivLong.java b/src/main/java/com/android/tools/r8/dex/code/DexDivLong.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/DivLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivLong.java
index 271dd04..260be18 100644
--- a/src/main/java/com/android/tools/r8/code/DivLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivLong.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DivLong extends Format23x {
+
+public class DexDivLong extends DexFormat23x {
 
   public static final int OPCODE = 0x9e;
   public static final String NAME = "DivLong";
   public static final String SMALI_NAME = "div-long";
 
-  DivLong(int high, BytecodeStream stream) {
+  DexDivLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivLong(int dest, int left, int right) {
+  public DexDivLong(int dest, int left, int right) {
     super(dest, left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DivLong2Addr.java b/src/main/java/com/android/tools/r8/dex/code/DexDivLong2Addr.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/DivLong2Addr.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDivLong2Addr.java
index 40f0946..b36326d 100644
--- a/src/main/java/com/android/tools/r8/code/DivLong2Addr.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDivLong2Addr.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DivLong2Addr extends Format12x {
+public class DexDivLong2Addr extends DexFormat12x {
 
   public static final int OPCODE = 0xbe;
   public static final String NAME = "DivLong2Addr";
   public static final String SMALI_NAME = "div-long/2addr";
 
-  DivLong2Addr(int high, BytecodeStream stream) {
+  DexDivLong2Addr(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DivLong2Addr(int left, int right) {
+  public DexDivLong2Addr(int left, int right) {
     super(left, right);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DoubleToFloat.java b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToFloat.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DoubleToFloat.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDoubleToFloat.java
index 07b8ab6..008c565 100644
--- a/src/main/java/com/android/tools/r8/code/DoubleToFloat.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToFloat.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class DoubleToFloat extends Format12x {
+public class DexDoubleToFloat extends DexFormat12x {
 
   public static final int OPCODE = 0x8c;
   public static final String NAME = "DoubleToFloat";
   public static final String SMALI_NAME = "double-to-float";
 
-  DoubleToFloat(int high, BytecodeStream stream) {
+  DexDoubleToFloat(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DoubleToFloat(int dest, int source) {
+  public DexDoubleToFloat(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DoubleToInt.java b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToInt.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DoubleToInt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDoubleToInt.java
index 6d8f506..99debd4 100644
--- a/src/main/java/com/android/tools/r8/code/DoubleToInt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToInt.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DoubleToInt extends Format12x {
+
+public class DexDoubleToInt extends DexFormat12x {
 
   public static final int OPCODE = 0x8a;
   public static final String NAME = "DoubleToInt";
   public static final String SMALI_NAME = "doubleto-int";
 
-  DoubleToInt(int high, BytecodeStream stream) {
+  DexDoubleToInt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DoubleToInt(int dest, int source) {
+  public DexDoubleToInt(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/DoubleToLong.java b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToLong.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/DoubleToLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexDoubleToLong.java
index d9fa0c5..0ea8942 100644
--- a/src/main/java/com/android/tools/r8/code/DoubleToLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexDoubleToLong.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class DoubleToLong extends Format12x {
+
+public class DexDoubleToLong extends DexFormat12x {
 
   public static final int OPCODE = 0x8b;
   public static final String NAME = "DoubleToLong";
   public static final String SMALI_NAME = "double-to-long";
 
-  DoubleToLong(int high, BytecodeStream stream) {
+  DexDoubleToLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public DoubleToLong(int dest, int source) {
+  public DexDoubleToLong(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/FillArrayData.java b/src/main/java/com/android/tools/r8/dex/code/DexFillArrayData.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/code/FillArrayData.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFillArrayData.java
index a49a31d..de478d7 100644
--- a/src/main/java/com/android/tools/r8/code/FillArrayData.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFillArrayData.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.conversion.IRBuilder;
 import com.android.tools.r8.naming.ClassNameMapper;
 
-public class FillArrayData extends Format31t {
+public class DexFillArrayData extends DexFormat31t {
 
   public static final int OPCODE = 0x26;
   public static final String NAME = "FillArrayData";
   public static final String SMALI_NAME = "fill-array-data";
 
-  FillArrayData(int high, BytecodeStream stream) {
+  DexFillArrayData(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public FillArrayData(int value) {
+  public DexFillArrayData(int value) {
     super(value, -1);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/FillArrayDataPayload.java b/src/main/java/com/android/tools/r8/dex/code/DexFillArrayDataPayload.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/code/FillArrayDataPayload.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFillArrayDataPayload.java
index cab0270..11b34be 100644
--- a/src/main/java/com/android/tools/r8/code/FillArrayDataPayload.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFillArrayDataPayload.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -15,17 +15,17 @@
 import java.nio.ShortBuffer;
 import java.util.Arrays;
 
-public class FillArrayDataPayload extends Nop {
+public class DexFillArrayDataPayload extends DexNop {
 
   public final int element_width;
   public final long size;
   public final short[] data;
 
-  private static void specify(StructuralSpecification<FillArrayDataPayload, ?> spec) {
+  private static void specify(StructuralSpecification<DexFillArrayDataPayload, ?> spec) {
     spec.withInt(i -> i.element_width).withLong(i -> i.size).withShortArray(i -> i.data);
   }
 
-  FillArrayDataPayload(int high, BytecodeStream stream) {
+  DexFillArrayDataPayload(int high, BytecodeStream stream) {
     super(high, stream);
     element_width = read16BitValue(stream);
     size = read32BitValue(stream);
@@ -39,7 +39,7 @@
     }
   }
 
-  public FillArrayDataPayload(int element_width, long size, short[] data) {
+  public DexFillArrayDataPayload(int element_width, long size, short[] data) {
     this.element_width = element_width;
     this.size = size;
     this.data = data;
@@ -57,7 +57,7 @@
       GraphLens graphLens,
       ObjectToOffsetMapping mapping,
       LensCodeRewriterUtils rewriter) {
-    writeFirst(3, dest);  // Pseudo-opcode = 0x0300
+    writeFirst(3, dest); // Pseudo-opcode = 0x0300
     write16BitValue(element_width, dest);
     write32BitValue(size, dest);
     for (short datum : data) {
@@ -66,8 +66,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (FillArrayDataPayload) other, FillArrayDataPayload::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFillArrayDataPayload) other, DexFillArrayDataPayload::specify);
   }
 
   @Override
@@ -86,8 +86,12 @@
 
   @Override
   public String toString(ClassNameMapper naming) {
-    return super.toString(naming) + "[FillArrayPayload], " +
-        "width: " + element_width + ", size:  " + size;
+    return super.toString(naming)
+        + "[FillArrayPayload], "
+        + "width: "
+        + element_width
+        + ", size:  "
+        + size;
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/FilledNewArray.java b/src/main/java/com/android/tools/r8/dex/code/DexFilledNewArray.java
similarity index 77%
rename from src/main/java/com/android/tools/r8/code/FilledNewArray.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFilledNewArray.java
index 5198876..ab52b2b 100644
--- a/src/main/java/com/android/tools/r8/code/FilledNewArray.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFilledNewArray.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -13,17 +14,17 @@
 import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
 import java.nio.ShortBuffer;
 
-public class FilledNewArray extends Format35c<DexType> {
+public class DexFilledNewArray extends DexFormat35c<DexType> {
 
   public static final int OPCODE = 0x24;
   public static final String NAME = "FilledNewArray";
   public static final String SMALI_NAME = "filled-new-array";
 
-  FilledNewArray(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexFilledNewArray(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getTypeMap());
   }
 
-  public FilledNewArray(int size, DexType type, int v0, int v1, int v2, int v3, int v4) {
+  public DexFilledNewArray(int size, DexType type, int v0, int v1, int v2, int v3, int v4) {
     super(size, type, v0, v1, v2, v3, v4);
   }
 
@@ -44,12 +45,12 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
-    DexType rewritten = graphLens.lookupType(getType());
-    rewritten.collectIndexedItems(indexedItems);
+    DexType rewritten = appView.graphLens().lookupType(getType());
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   public DexType getType() {
@@ -58,7 +59,7 @@
 
   @Override
   public void buildIR(IRBuilder builder) {
-    builder.addInvokeNewArray(getType(), A, new int[]{C, D, E, F, G});
+    builder.addInvokeNewArray(getType(), A, new int[] {C, D, E, F, G});
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/FilledNewArrayRange.java b/src/main/java/com/android/tools/r8/dex/code/DexFilledNewArrayRange.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/FilledNewArrayRange.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFilledNewArrayRange.java
index de651f5..5e473dc 100644
--- a/src/main/java/com/android/tools/r8/code/FilledNewArrayRange.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFilledNewArrayRange.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
@@ -13,17 +14,17 @@
 import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
 import java.nio.ShortBuffer;
 
-public class FilledNewArrayRange extends Format3rc<DexType> {
+public class DexFilledNewArrayRange extends DexFormat3rc<DexType> {
 
   public static final int OPCODE = 0x25;
   public static final String NAME = "FilledNewArrayRange";
   public static final String SMALI_NAME = "filled-new-array/range";
 
-  FilledNewArrayRange(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  DexFilledNewArrayRange(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getTypeMap());
   }
 
-  public FilledNewArrayRange(int firstContentRegister, int size, DexType type) {
+  public DexFilledNewArrayRange(int firstContentRegister, int size, DexType type) {
     super(firstContentRegister, size, type);
   }
 
@@ -44,12 +45,12 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
-    DexType rewritten = graphLens.lookupType(getType());
-    rewritten.collectIndexedItems(indexedItems);
+    DexType rewritten = appView.graphLens().lookupType(getType());
+    rewritten.collectIndexedItems(appView, indexedItems);
   }
 
   public DexType getType() {
diff --git a/src/main/java/com/android/tools/r8/code/FloatToDouble.java b/src/main/java/com/android/tools/r8/dex/code/DexFloatToDouble.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/FloatToDouble.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFloatToDouble.java
index 5b11258..8536b7e 100644
--- a/src/main/java/com/android/tools/r8/code/FloatToDouble.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFloatToDouble.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class FloatToDouble extends Format12x {
+public class DexFloatToDouble extends DexFormat12x {
 
   public static final int OPCODE = 0x89;
   public static final String NAME = "FloatToDouble";
   public static final String SMALI_NAME = "float-to-double";
 
-  FloatToDouble(int high, BytecodeStream stream) {
+  DexFloatToDouble(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public FloatToDouble(int dest, int source) {
+  public DexFloatToDouble(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/FloatToInt.java b/src/main/java/com/android/tools/r8/dex/code/DexFloatToInt.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/FloatToInt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFloatToInt.java
index d0d706f..cf95583 100644
--- a/src/main/java/com/android/tools/r8/code/FloatToInt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFloatToInt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class FloatToInt extends Format12x {
+public class DexFloatToInt extends DexFormat12x {
 
   public static final int OPCODE = 0x87;
   public static final String NAME = "FloatToInt";
   public static final String SMALI_NAME = "float-to-int";
 
-  FloatToInt(int high, BytecodeStream stream) {
+  DexFloatToInt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public FloatToInt(int dest, int source) {
+  public DexFloatToInt(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/FloatToLong.java b/src/main/java/com/android/tools/r8/dex/code/DexFloatToLong.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/FloatToLong.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFloatToLong.java
index 82346b0..3c7d3b4 100644
--- a/src/main/java/com/android/tools/r8/code/FloatToLong.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFloatToLong.java
@@ -1,21 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.conversion.IRBuilder;
-public class FloatToLong extends Format12x {
+
+public class DexFloatToLong extends DexFormat12x {
 
   public static final int OPCODE = 0x88;
   public static final String NAME = "FloatToLong";
   public static final String SMALI_NAME = "float-to-long";
 
-  FloatToLong(int high, BytecodeStream stream) {
+  DexFloatToLong(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public FloatToLong(int dest, int source) {
+  public DexFloatToLong(int dest, int source) {
     super(dest, source);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Format10t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat10t.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format10t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat10t.java
index 9b2b11c..5ccccb9 100644
--- a/src/main/java/com/android/tools/r8/code/Format10t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat10t.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -12,18 +13,18 @@
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.nio.ShortBuffer;
 
-abstract class Format10t extends Base1Format {
+abstract class DexFormat10t extends DexBase1Format {
 
   public /* offset */ byte AA;
 
   // +AA | op
-  Format10t(int high, BytecodeStream stream) {
+  DexFormat10t(int high, BytecodeStream stream) {
     super(stream);
     // AA is an offset, so convert to signed.
     AA = (byte) high;
   }
 
-  protected Format10t(int AA) {
+  protected DexFormat10t(int AA) {
     assert Byte.MIN_VALUE <= AA && AA <= Byte.MAX_VALUE;
     this.AA = (byte) AA;
   }
@@ -44,8 +45,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visitInt(AA, ((Format10t) other).AA);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visitInt(AA, ((DexFormat10t) other).AA);
   }
 
   @Override
@@ -60,9 +61,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format10x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat10x.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/Format10x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat10x.java
index bc8feed..3cb41fb 100644
--- a/src/main/java/com/android/tools/r8/code/Format10x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat10x.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -11,16 +12,15 @@
 import com.android.tools.r8.naming.ClassNameMapper;
 import java.nio.ShortBuffer;
 
-abstract class Format10x extends Base1Format {
+abstract class DexFormat10x extends DexBase1Format {
 
   // øø | op
-  Format10x(int high, BytecodeStream stream) {
+  DexFormat10x(int high, BytecodeStream stream) {
     // Intentionally left empty.
     super(stream);
   }
 
-  protected Format10x() {
-  }
+  protected DexFormat10x() {}
 
   @Override
   public void write(
@@ -44,9 +44,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format11n.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat11n.java
similarity index 78%
rename from src/main/java/com/android/tools/r8/code/Format11n.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat11n.java
index 27c0d27..20bec92 100644
--- a/src/main/java/com/android/tools/r8/code/Format11n.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat11n.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,16 +15,16 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format11n extends Base1Format {
+abstract class DexFormat11n extends DexBase1Format {
 
   public final byte A, B;
 
-  private static void specify(StructuralSpecification<Format11n, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat11n, ?> spec) {
     spec.withInt(i -> i.A).withInt(i -> i.B);
   }
 
   // #+B | vA | op
-  /*package*/ Format11n(int high, BytecodeStream stream) {
+  /*package*/ DexFormat11n(int high, BytecodeStream stream) {
     super(stream);
     A = (byte) (high & 0xf);
     // Sign extend 4bit value.
@@ -35,7 +36,7 @@
     }
   }
 
-  /*package*/ Format11n(int A, int B) {
+  /*package*/ DexFormat11n(int A, int B) {
     assert 0 <= A && A <= Constants.U4BIT_MAX;
     assert Constants.S4BIT_MIN <= B && B <= Constants.S4BIT_MAX;
     this.A = (byte) A;
@@ -58,8 +59,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format11n) other, Format11n::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat11n) other, DexFormat11n::specify);
   }
 
   @Override
@@ -69,9 +70,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format11x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat11x.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/Format11x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat11x.java
index 3cc3b73..46d615b 100644
--- a/src/main/java/com/android/tools/r8/code/Format11x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat11x.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -13,17 +14,17 @@
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.nio.ShortBuffer;
 
-abstract class Format11x extends Base1Format {
+abstract class DexFormat11x extends DexBase1Format {
 
   public final short AA;
 
   // vAA | op
-  Format11x(int high, BytecodeStream stream) {
+  DexFormat11x(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
   }
 
-  protected Format11x(int AA) {
+  protected DexFormat11x(int AA) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     this.AA = (short) AA;
   }
@@ -44,8 +45,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visitInt(AA, ((Format11x) other).AA);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visitInt(AA, ((DexFormat11x) other).AA);
   }
 
   @Override
@@ -60,9 +61,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format12x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat12x.java
similarity index 78%
rename from src/main/java/com/android/tools/r8/code/Format12x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat12x.java
index f3b80aa..29c2224 100644
--- a/src/main/java/com/android/tools/r8/code/Format12x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat12x.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,22 +15,22 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format12x extends Base1Format {
+abstract class DexFormat12x extends DexBase1Format {
 
   public final byte A, B;
 
-  private static void specify(StructuralSpecification<Format12x, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat12x, ?> spec) {
     spec.withInt(i -> i.A).withInt(i -> i.B);
   }
 
   // vB | vA | op
-  Format12x(int high, BytecodeStream stream) {
+  DexFormat12x(int high, BytecodeStream stream) {
     super(stream);
     A = (byte) (high & 0xF);
     B = (byte) ((high >> 4) & 0xF);
   }
 
-  Format12x(int A, int B) {
+  DexFormat12x(int A, int B) {
     assert 0 <= A && A <= Constants.U4BIT_MAX;
     assert 0 <= B && B <= Constants.U4BIT_MAX;
     this.A = (byte) A;
@@ -52,11 +53,10 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format12x) other, Format12x::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat12x) other, DexFormat12x::specify);
   }
 
-
   @Override
   public String toString(ClassNameMapper naming) {
     return formatString("v" + A + ", v" + B);
@@ -69,9 +69,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format20t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat20t.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format20t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat20t.java
index c9cd18b..c63962f 100644
--- a/src/main/java/com/android/tools/r8/code/Format20t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat20t.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -12,17 +13,17 @@
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.nio.ShortBuffer;
 
-abstract class Format20t extends Base2Format {
+abstract class DexFormat20t extends DexBase2Format {
 
   public /* offset */ short AAAA;
 
   // øø | op | +AAAA
-  Format20t(int high, BytecodeStream stream) {
+  DexFormat20t(int high, BytecodeStream stream) {
     super(stream);
     AAAA = readSigned16BitValue(stream);
   }
 
-  protected Format20t(int AAAA) {
+  protected DexFormat20t(int AAAA) {
     assert Short.MIN_VALUE <= AAAA && AAAA <= Short.MAX_VALUE;
     this.AAAA = (short) AAAA;
   }
@@ -44,8 +45,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visitInt(AAAA, ((Format20t) other).AAAA);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visitInt(AAAA, ((DexFormat20t) other).AAAA);
   }
 
   @Override
@@ -60,9 +61,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format21c.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat21c.java
similarity index 73%
rename from src/main/java/com/android/tools/r8/code/Format21c.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat21c.java
index 9416be7..d942119 100644
--- a/src/main/java/com/android/tools/r8/code/Format21c.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat21c.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.IndexedDexItem;
@@ -10,19 +10,19 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.util.function.BiPredicate;
 
-abstract class Format21c<T extends IndexedDexItem> extends Base2Format {
+abstract class DexFormat21c<T extends IndexedDexItem> extends DexBase2Format {
 
   public final short AA;
   public T BBBB;
 
   // AA | op | [type|field|string]@BBBB
-  Format21c(int high, BytecodeStream stream, T[] map) {
+  DexFormat21c(int high, BytecodeStream stream, T[] map) {
     super(stream);
     AA = (short) high;
     BBBB = map[read16BitValue(stream)];
   }
 
-  protected Format21c(int AA, T BBBB) {
+  protected DexFormat21c(int AA, T BBBB) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     this.AA = (short) AA;
     this.BBBB = BBBB;
@@ -35,14 +35,14 @@
 
   @SuppressWarnings("unchecked")
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
     return visitor.visit(
         this,
-        (Format21c<T>) other,
+        (DexFormat21c<T>) other,
         spec -> spec.withInt(i -> i.AA).withSpec(this::internalSubSpecify));
   }
 
-  abstract void internalSubSpecify(StructuralSpecification<Format21c<T>, ?> spec);
+  abstract void internalSubSpecify(StructuralSpecification<DexFormat21c<T>, ?> spec);
 
   @Override
   public String toString(ClassNameMapper naming) {
@@ -57,11 +57,12 @@
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || this.getClass() != other.getClass()) {
       return false;
     }
-    Format21c<?> o = (Format21c<?>) other;
+    DexFormat21c<?> o = (DexFormat21c<?>) other;
     return o.AA == AA && equality.test(BBBB, o.BBBB);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/code/Format21h.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat21h.java
similarity index 76%
rename from src/main/java/com/android/tools/r8/code/Format21h.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat21h.java
index 36b9174..ae07163 100644
--- a/src/main/java/com/android/tools/r8/code/Format21h.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat21h.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -13,23 +14,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format21h extends Base2Format {
+abstract class DexFormat21h extends DexBase2Format {
 
   public final short AA;
   public final char BBBB;
 
-  private static void specify(StructuralSpecification<Format21h, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat21h, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBB);
   }
 
   // AA | op | BBBB0000[00000000]
-  /*package*/ Format21h(int high, BytecodeStream stream) {
+  /*package*/ DexFormat21h(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBB = read16BitValue(stream);
   }
 
-  /*package*/ Format21h(int AA, int BBBB) {
+  /*package*/ DexFormat21h(int AA, int BBBB) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     assert 0 <= BBBB && BBBB <= Constants.U16BIT_MAX;
     this.AA = (short) AA;
@@ -53,15 +54,15 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format21h) other, Format21h::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat21h) other, DexFormat21h::specify);
   }
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format21s.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat21s.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/Format21s.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat21s.java
index 550fdd4..1194963 100644
--- a/src/main/java/com/android/tools/r8/code/Format21s.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat21s.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -15,23 +16,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format21s extends Base2Format {
+abstract class DexFormat21s extends DexBase2Format {
 
   public final short AA;
   public final short BBBB;
 
-  private static void specify(StructuralSpecification<Format21s, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat21s, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBB);
   }
 
   // AA | op | #+BBBB
-  /*package*/ Format21s(int high, BytecodeStream stream) {
+  /*package*/ DexFormat21s(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBB = readSigned16BitValue(stream);
   }
 
-  /*package*/ Format21s(int AA, int BBBB) {
+  /*package*/ DexFormat21s(int AA, int BBBB) {
     assert Short.MIN_VALUE <= BBBB && BBBB <= Short.MAX_VALUE;
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     this.AA = (short) AA;
@@ -55,8 +56,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format21s) other, Format21s::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat21s) other, DexFormat21s::specify);
   }
 
   @Override
@@ -71,9 +72,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format21t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat21t.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/Format21t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat21t.java
index bde930d..21061c3 100644
--- a/src/main/java/com/android/tools/r8/code/Format21t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat21t.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -17,23 +18,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public abstract class Format21t extends Base2Format {
+public abstract class DexFormat21t extends DexBase2Format {
 
   public final short AA;
   public /* offset */ short BBBB;
 
-  private static void specify(StructuralSpecification<Format21t, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat21t, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBB);
   }
 
   // AA | op | +BBBB
-  Format21t(int high, BytecodeStream stream) {
+  DexFormat21t(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBB = readSigned16BitValue(stream);
   }
 
-  Format21t(int register, int offset) {
+  DexFormat21t(int register, int offset) {
     assert Short.MIN_VALUE <= offset && offset <= Short.MAX_VALUE;
     assert 0 <= register && register <= Constants.U8BIT_MAX;
     AA = (short) register;
@@ -57,8 +58,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format21t) other, Format21t::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat21t) other, DexFormat21t::specify);
   }
 
   public abstract Type getType();
@@ -67,7 +68,7 @@
 
   @Override
   public int[] getTargets() {
-    return new int[]{BBBB, getSize()};
+    return new int[] {BBBB, getSize()};
   }
 
   @Override
@@ -89,9 +90,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format22b.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat22b.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format22b.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat22b.java
index 6f79b50..5f3213e 100644
--- a/src/main/java/com/android/tools/r8/code/Format22b.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat22b.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -15,25 +16,25 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public abstract class Format22b extends Base2Format {
+public abstract class DexFormat22b extends DexBase2Format {
 
   public final short AA;
   public final short BB;
   public final byte CC;
 
-  private static void specify(StructuralSpecification<Format22b, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat22b, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BB).withInt(i -> i.CC);
   }
 
   // vAA | op | #+CC | VBB
-  /*package*/ Format22b(int high, BytecodeStream stream) {
+  /*package*/ DexFormat22b(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     CC = readSigned8BitValue(stream);
     BB = read8BitValue(stream);
   }
 
-  /*package*/ Format22b(int AA, int BB, int CC) {
+  /*package*/ DexFormat22b(int AA, int BB, int CC) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     assert 0 <= BB && BB <= Constants.U8BIT_MAX;
     assert Byte.MIN_VALUE <= CC && CC <= Byte.MAX_VALUE;
@@ -59,8 +60,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format22b) other, Format22b::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat22b) other, DexFormat22b::specify);
   }
 
   @Override
@@ -76,9 +77,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format22c.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat22c.java
similarity index 71%
rename from src/main/java/com/android/tools/r8/code/Format22c.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat22c.java
index 536ec65..d406aad 100644
--- a/src/main/java/com/android/tools/r8/code/Format22c.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat22c.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.DexReference;
@@ -11,25 +11,26 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.util.function.BiPredicate;
 
-public abstract class Format22c<T extends DexReference> extends Base2Format {
+public abstract class DexFormat22c<T extends DexReference> extends DexBase2Format {
 
   public final byte A;
   public final byte B;
   public T CCCC;
 
-  private static void specify(StructuralSpecification<Format22c<? extends DexReference>, ?> spec) {
+  private static void specify(
+      StructuralSpecification<DexFormat22c<? extends DexReference>, ?> spec) {
     spec.withInt(i -> i.A).withInt(i -> i.B).withDexReference(i -> i.CCCC);
   }
 
   // vB | vA | op | [type|field]@CCCC
-  /*package*/ Format22c(int high, BytecodeStream stream, T[] map) {
+  /*package*/ DexFormat22c(int high, BytecodeStream stream, T[] map) {
     super(stream);
     A = (byte) (high & 0xf);
     B = (byte) ((high >> 4) & 0xf);
     CCCC = map[read16BitValue(stream)];
   }
 
-  /*package*/ Format22c(int A, int B, T CCCC) {
+  /*package*/ DexFormat22c(int A, int B, T CCCC) {
     assert 0 <= A && A <= Constants.U4BIT_MAX;
     assert 0 <= B && B <= Constants.U4BIT_MAX;
     this.A = (byte) A;
@@ -43,8 +44,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format22c<? extends DexReference>) other, Format22c::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat22c<? extends DexReference>) other, DexFormat22c::specify);
   }
 
   @Override
@@ -60,11 +61,12 @@
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || this.getClass() != other.getClass()) {
       return false;
     }
-    Format22c<?> o = (Format22c<?>) other;
+    DexFormat22c<?> o = (DexFormat22c<?>) other;
     return o.A == A && o.B == B && equality.test(CCCC, o.CCCC);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/code/Format22s.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat22s.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format22s.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat22s.java
index efa14d2..84921eb 100644
--- a/src/main/java/com/android/tools/r8/code/Format22s.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat22s.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -15,25 +16,25 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public abstract class Format22s extends Base2Format {
+public abstract class DexFormat22s extends DexBase2Format {
 
   public final byte A;
   public final byte B;
   public final short CCCC;
 
-  private static void specify(StructuralSpecification<Format22s, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat22s, ?> spec) {
     spec.withInt(i -> i.A).withInt(i -> i.B).withInt(i -> i.CCCC);
   }
 
   // vB | vA | op | #+CCCC
-  /*package*/ Format22s(int high, BytecodeStream stream) {
+  /*package*/ DexFormat22s(int high, BytecodeStream stream) {
     super(stream);
     A = (byte) (high & 0xf);
     B = (byte) ((high >> 4) & 0xf);
     CCCC = readSigned16BitValue(stream);
   }
 
-  /*package*/ Format22s(int A, int B, int CCCC) {
+  /*package*/ DexFormat22s(int A, int B, int CCCC) {
     assert 0 <= A && A <= Constants.U4BIT_MAX;
     assert 0 <= B && B <= Constants.U4BIT_MAX;
     assert Short.MIN_VALUE <= CCCC && CCCC <= Short.MAX_VALUE;
@@ -59,8 +60,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format22s) other, Format22s::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat22s) other, DexFormat22s::specify);
   }
 
   @Override
@@ -76,9 +77,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format22t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat22t.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/Format22t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat22t.java
index 9688b4e..395ac6e 100644
--- a/src/main/java/com/android/tools/r8/code/Format22t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat22t.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -17,25 +18,25 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public abstract class Format22t extends Base2Format {
+public abstract class DexFormat22t extends DexBase2Format {
 
   public final byte A;
   public final byte B;
   public /* offset */ short CCCC;
 
-  private static void specify(StructuralSpecification<Format22t, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat22t, ?> spec) {
     spec.withInt(i -> i.A).withInt(i -> i.B).withInt(i -> i.CCCC);
   }
 
   // vB | vA | op | +CCCC
-  Format22t(int high, BytecodeStream stream) {
+  DexFormat22t(int high, BytecodeStream stream) {
     super(stream);
     A = (byte) (high & 0xf);
     B = (byte) ((high >> 4) & 0xf);
     CCCC = readSigned16BitValue(stream);
   }
 
-  Format22t(int register1, int register2, int offset) {
+  DexFormat22t(int register1, int register2, int offset) {
     assert 0 <= register1 && register1 <= Constants.U4BIT_MAX;
     assert 0 <= register2 && register2 <= Constants.U4BIT_MAX;
     assert Short.MIN_VALUE <= offset && offset <= Short.MAX_VALUE;
@@ -61,8 +62,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format22t) other, Format22t::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat22t) other, DexFormat22t::specify);
   }
 
   public abstract Type getType();
@@ -71,7 +72,7 @@
 
   @Override
   public int[] getTargets() {
-    return new int[]{CCCC, getSize()};
+    return new int[] {CCCC, getSize()};
   }
 
   @Override
@@ -93,9 +94,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format22x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat22x.java
similarity index 74%
rename from src/main/java/com/android/tools/r8/code/Format22x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat22x.java
index 1d9d8ba..e7d6f0c 100644
--- a/src/main/java/com/android/tools/r8/code/Format22x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat22x.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,23 +15,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format22x extends Base2Format {
+abstract class DexFormat22x extends DexBase2Format {
 
   public final short AA;
   public final char BBBB;
 
-  private static void specify(StructuralSpecification<Format22x, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat22x, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBB);
   }
 
   // AA | op | vBBBB
-  Format22x(int high, BytecodeStream stream) {
+  DexFormat22x(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBB = read16BitValue(stream);
   }
 
-  Format22x(int dest, int src) {
+  DexFormat22x(int dest, int src) {
     assert 0 <= dest && dest <= Constants.U8BIT_MAX;
     assert 0 <= src && src <= Constants.U16BIT_MAX;
     AA = (short) dest;
@@ -54,26 +55,25 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format22x) other, Format22x::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat22x) other, DexFormat22x::specify);
   }
 
-
   @Override
   public String toString(ClassNameMapper naming) {
-    return formatString("v" + AA + ", v" + (int)BBBB);
+    return formatString("v" + AA + ", v" + (int) BBBB);
   }
 
   @Override
   public String toSmaliString(ClassNameMapper naming) {
-    return formatSmaliString("v" + AA + ", v" + (int)BBBB);
+    return formatSmaliString("v" + AA + ", v" + (int) BBBB);
   }
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format23x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat23x.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format23x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat23x.java
index ca3ef80..ee90cf8 100644
--- a/src/main/java/com/android/tools/r8/code/Format23x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat23x.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,25 +15,25 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format23x extends Base2Format {
+abstract class DexFormat23x extends DexBase2Format {
 
   public final short AA;
   public final short BB;
   public final short CC;
 
-  private static void specify(StructuralSpecification<Format23x, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat23x, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BB).withInt(i -> i.CC);
   }
 
   // vAA | op | vCC | vBB
-  Format23x(int high, BytecodeStream stream) {
+  DexFormat23x(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     CC = read8BitValue(stream);
     BB = read8BitValue(stream);
   }
 
-  Format23x(int AA, int BB, int CC) {
+  DexFormat23x(int AA, int BB, int CC) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     assert 0 <= BB && BB <= Constants.U8BIT_MAX;
     assert 0 <= CC && CC <= Constants.U8BIT_MAX;
@@ -58,8 +59,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format23x) other, Format23x::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat23x) other, DexFormat23x::specify);
   }
 
   @Override
@@ -74,9 +75,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format30t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat30t.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/Format30t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat30t.java
index ba986cc..878cc7b 100644
--- a/src/main/java/com/android/tools/r8/code/Format30t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat30t.java
@@ -1,9 +1,10 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -12,17 +13,17 @@
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import java.nio.ShortBuffer;
 
-abstract class Format30t extends Base3Format {
+abstract class DexFormat30t extends DexBase3Format {
 
   public /* offset */ int AAAAAAAA;
 
   // øø | op | AAAAlo | AAAAhi
-  Format30t(int high, BytecodeStream stream) {
+  DexFormat30t(int high, BytecodeStream stream) {
     super(stream);
     AAAAAAAA = readSigned32BitValue(stream);
   }
 
-  protected Format30t(int AAAAAAAA) {
+  protected DexFormat30t(int AAAAAAAA) {
     this.AAAAAAAA = AAAAAAAA;
   }
 
@@ -43,8 +44,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visitInt(AAAAAAAA, ((Format30t) other).AAAAAAAA);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visitInt(AAAAAAAA, ((DexFormat30t) other).AAAAAAAA);
   }
 
   @Override
@@ -59,9 +60,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format31c.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat31c.java
similarity index 76%
rename from src/main/java/com/android/tools/r8/code/Format31c.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat31c.java
index 6664662..82e033a 100644
--- a/src/main/java/com/android/tools/r8/code/Format31c.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat31c.java
@@ -1,11 +1,12 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import static com.android.tools.r8.dex.Constants.U8BIT_MAX;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.IndexedDexItem;
@@ -18,23 +19,23 @@
 import java.nio.ShortBuffer;
 import java.util.function.BiPredicate;
 
-abstract class Format31c extends Base3Format {
+abstract class DexFormat31c extends DexBase3Format {
 
   public final short AA;
   public DexString BBBBBBBB;
 
-  private static void specify(StructuralSpecification<Format31c, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat31c, ?> spec) {
     spec.withInt(i -> i.AA).withItem(i -> i.BBBBBBBB);
   }
 
   // vAA | op | string@BBBBlo | string@#+BBBBhi
-  Format31c(int high, BytecodeStream stream, DexString[] map) {
+  DexFormat31c(int high, BytecodeStream stream, DexString[] map) {
     super(stream);
     AA = (short) high;
     BBBBBBBB = map[(int) read32BitValue(stream)];
   }
 
-  Format31c(int AA, DexString BBBBBBBB) {
+  DexFormat31c(int AA, DexString BBBBBBBB) {
     assert 0 <= AA && AA <= U8BIT_MAX;
     this.AA = (short) AA;
     this.BBBBBBBB = BBBBBBBB;
@@ -57,8 +58,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format31c) other, Format31c::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat31c) other, DexFormat31c::specify);
   }
 
   @Override
@@ -69,19 +70,20 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     BBBBBBBB.collectIndexedItems(indexedItems);
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || (this.getClass() != other.getClass())) {
       return false;
     }
-    Format31c o = (Format31c) other;
+    DexFormat31c o = (DexFormat31c) other;
     return o.AA == AA && equality.test(BBBBBBBB, o.BBBBBBBB);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/code/Format31i.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat31i.java
similarity index 77%
rename from src/main/java/com/android/tools/r8/code/Format31i.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat31i.java
index c2fa1b1..04e57f1 100644
--- a/src/main/java/com/android/tools/r8/code/Format31i.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat31i.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,23 +15,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format31i extends Base3Format {
+abstract class DexFormat31i extends DexBase3Format {
 
   public final short AA;
   public final int BBBBBBBB;
 
-  private static void specify(StructuralSpecification<Format31i, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat31i, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBBBBBB);
   }
 
   // vAA | op | #+BBBBlo | #+BBBBhi
-  /*package*/ Format31i(int high, BytecodeStream stream) {
+  /*package*/ DexFormat31i(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBBBBBB = readSigned32BitValue(stream);
   }
 
-  /*package*/ Format31i(int AA, int BBBBBBBB) {
+  /*package*/ DexFormat31i(int AA, int BBBBBBBB) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     this.AA = (short) AA;
     this.BBBBBBBB = BBBBBBBB;
@@ -53,8 +54,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format31i) other, Format31i::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat31i) other, DexFormat31i::specify);
   }
 
   @Override
@@ -64,9 +65,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format31t.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat31t.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Format31t.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat31t.java
index f85aca6..cc57a14 100644
--- a/src/main/java/com/android/tools/r8/code/Format31t.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat31t.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,23 +15,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-public abstract class Format31t extends Base3Format {
+public abstract class DexFormat31t extends DexBase3Format {
 
   public final short AA;
   protected /* offset */ int BBBBBBBB;
 
-  private static void specify(StructuralSpecification<Format31t, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat31t, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.BBBBBBBB);
   }
 
   // vAA | op | +BBBBlo | +BBBBhi
-  Format31t(int high, BytecodeStream stream) {
+  DexFormat31t(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBBBBBB = readSigned32BitValue(stream);
   }
 
-  Format31t(int register, int payloadOffset) {
+  DexFormat31t(int register, int payloadOffset) {
     assert 0 <= register && register <= Constants.U8BIT_MAX;
     AA = (short) register;
     BBBBBBBB = payloadOffset;
@@ -68,8 +69,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format31t) other, Format31t::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat31t) other, DexFormat31t::specify);
   }
 
   @Override
@@ -79,9 +80,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format32x.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat32x.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/Format32x.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat32x.java
index c637383..f9a7792 100644
--- a/src/main/java/com/android/tools/r8/code/Format32x.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat32x.java
@@ -1,11 +1,12 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import static com.android.tools.r8.dex.Constants.U16BIT_MAX;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -15,23 +16,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format32x extends Base3Format {
+abstract class DexFormat32x extends DexBase3Format {
 
   public final int AAAA;
   public final int BBBB;
 
-  private static void specify(StructuralSpecification<Format32x, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat32x, ?> spec) {
     spec.withInt(i -> i.AAAA).withInt(i -> i.BBBB);
   }
 
   // øø | op | AAAA | BBBB
-  Format32x(int high, BytecodeStream stream) {
+  DexFormat32x(int high, BytecodeStream stream) {
     super(stream);
     AAAA = read16BitValue(stream);
     BBBB = read16BitValue(stream);
   }
 
-  Format32x(int dest, int src) {
+  DexFormat32x(int dest, int src) {
     assert 0 <= dest && dest <= U16BIT_MAX;
     assert 0 <= src && src <= U16BIT_MAX;
     AAAA = dest;
@@ -56,8 +57,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format32x) other, Format32x::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat32x) other, DexFormat32x::specify);
   }
 
   @Override
@@ -72,9 +73,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Format35c.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat35c.java
similarity index 77%
rename from src/main/java/com/android/tools/r8/code/Format35c.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat35c.java
index e5d2489..78a5323 100644
--- a/src/main/java/com/android/tools/r8/code/Format35c.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat35c.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.IndexedDexItem;
@@ -11,7 +11,8 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.util.function.BiPredicate;
 
-public abstract class Format35c<T extends IndexedDexItem & StructuralItem<T>> extends Base3Format {
+public abstract class DexFormat35c<T extends IndexedDexItem & StructuralItem<T>>
+    extends DexBase3Format {
 
   public final byte A;
   public final byte C;
@@ -22,7 +23,7 @@
   public T BBBB;
 
   private static <T extends IndexedDexItem & StructuralItem<T>> void specify(
-      StructuralSpecification<Format35c<T>, ?> spec) {
+      StructuralSpecification<DexFormat35c<T>, ?> spec) {
     spec.withInt(i -> i.A)
         .withInt(i -> i.C)
         .withInt(i -> i.D)
@@ -33,7 +34,7 @@
   }
 
   // A | G | op | BBBB | F | E | D | C
-  Format35c(int high, BytecodeStream stream, T[] map) {
+  DexFormat35c(int high, BytecodeStream stream, T[] map) {
     super(stream);
     G = (byte) (high & 0xf);
     A = (byte) ((high >> 4) & 0xf);
@@ -46,7 +47,7 @@
     D = (byte) ((next >> 4) & 0xf);
   }
 
-  Format35c(int A, T BBBB, int C, int D, int E, int F, int G) {
+  DexFormat35c(int A, T BBBB, int C, int D, int E, int F, int G) {
     assert 0 <= A && A <= Constants.U4BIT_MAX;
     assert 0 <= C && C <= Constants.U4BIT_MAX;
     assert 0 <= D && D <= Constants.U4BIT_MAX;
@@ -64,19 +65,19 @@
 
   @Override
   public final int hashCode() {
-    return ((BBBB.hashCode() << 24) | (A << 20) | (C << 16) | (D << 12) | (E << 8) | (F << 4)
-        | G) ^ getClass().hashCode();
+    return ((BBBB.hashCode() << 24) | (A << 20) | (C << 16) | (D << 12) | (E << 8) | (F << 4) | G)
+        ^ getClass().hashCode();
   }
 
   @SuppressWarnings("unchecked")
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format35c<T>) other, Format35c::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat35c<T>) other, DexFormat35c::specify);
   }
 
   private void appendRegisterArguments(StringBuilder builder, String separator) {
     builder.append("{ ");
-    int[] values = new int[]{C, D, E, F, G};
+    int[] values = new int[] {C, D, E, F, G};
     for (int i = 0; i < A; i++) {
       if (i != 0) {
         builder.append(separator);
@@ -110,12 +111,18 @@
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || (this.getClass() != other.getClass())) {
       return false;
     }
-    Format35c o = (Format35c) other;
-    return o.A == A && o.C == C && o.D == D && o.E == E && o.F == F && o.G == G
+    DexFormat35c o = (DexFormat35c) other;
+    return o.A == A
+        && o.C == C
+        && o.D == D
+        && o.E == E
+        && o.F == F
+        && o.G == G
         && equality.test(BBBB, o.BBBB);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/code/Format3rc.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat3rc.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/Format3rc.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat3rc.java
index 0ceeb4a..01fff36b 100644
--- a/src/main/java/com/android/tools/r8/code/Format3rc.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat3rc.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.IndexedDexItem;
@@ -11,26 +11,27 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.util.function.BiPredicate;
 
-public abstract class Format3rc<T extends IndexedDexItem & StructuralItem<T>> extends Base3Format {
+public abstract class DexFormat3rc<T extends IndexedDexItem & StructuralItem<T>>
+    extends DexBase3Format {
 
   public final short AA;
   public final char CCCC;
   public T BBBB;
 
   private static <T extends IndexedDexItem & StructuralItem<T>> void specify(
-      StructuralSpecification<Format3rc<T>, ?> spec) {
+      StructuralSpecification<DexFormat3rc<T>, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.CCCC).withItem(i -> i.BBBB);
   }
 
   // AA | op | [meth|type]@BBBBB | CCCC
-  Format3rc(int high, BytecodeStream stream, T[] map) {
+  DexFormat3rc(int high, BytecodeStream stream, T[] map) {
     super(stream);
     this.AA = (short) high;
     this.BBBB = map[read16BitValue(stream)];
     this.CCCC = read16BitValue(stream);
   }
 
-  Format3rc(int firstArgumentRegister, int argumentCount, T dexItem) {
+  DexFormat3rc(int firstArgumentRegister, int argumentCount, T dexItem) {
     assert 0 <= firstArgumentRegister && firstArgumentRegister <= Constants.U16BIT_MAX;
     assert 0 <= argumentCount && argumentCount <= Constants.U8BIT_MAX;
     this.CCCC = (char) firstArgumentRegister;
@@ -49,8 +50,8 @@
 
   @SuppressWarnings("unchecked")
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format3rc<T>) other, Format3rc::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat3rc<T>) other, DexFormat3rc::specify);
   }
 
   private void appendRegisterRange(StringBuilder builder) {
@@ -87,11 +88,12 @@
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || (this.getClass() != other.getClass())) {
       return false;
     }
-    Format3rc<?> o = (Format3rc<?>) other;
+    DexFormat3rc<?> o = (DexFormat3rc<?>) other;
     return o.AA == AA && o.CCCC == CCCC && equality.test(BBBB, o.BBBB);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/code/Format45cc.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat45cc.java
similarity index 85%
rename from src/main/java/com/android/tools/r8/code/Format45cc.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat45cc.java
index 1542015..bdc0a15 100644
--- a/src/main/java/com/android/tools/r8/code/Format45cc.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat45cc.java
@@ -1,11 +1,12 @@
 // Copyright (c) 2017, 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.code;
+package com.android.tools.r8.dex.code;
 
 import static com.android.tools.r8.dex.Constants.U4BIT_MAX;
 
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.GraphLens;
@@ -21,7 +22,7 @@
 import java.nio.ShortBuffer;
 
 /** Format45cc for instructions of size 4, with 5 registers and 2 constant pool index. */
-public abstract class Format45cc extends Base4Format {
+public abstract class DexFormat45cc extends DexBase4Format {
 
   public final byte A;
   public final byte C;
@@ -32,7 +33,7 @@
   public DexMethod BBBB;
   public DexProto HHHH;
 
-  private static void specify(StructuralSpecification<Format45cc, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat45cc, ?> spec) {
     spec.withInt(i -> i.A)
         .withInt(i -> i.C)
         .withInt(i -> i.D)
@@ -43,7 +44,7 @@
         .withItem(i -> i.HHHH);
   }
 
-  Format45cc(int high, BytecodeStream stream, DexMethod[] methodMap, DexProto[] protoMap) {
+  DexFormat45cc(int high, BytecodeStream stream, DexMethod[] methodMap, DexProto[] protoMap) {
     super(stream);
     G = (byte) (high & 0xf);
     A = (byte) ((high >> 4) & 0xf);
@@ -58,7 +59,7 @@
   }
 
   // A | G | op | [meth]@BBBB | F | E | D | C | [proto]@HHHH
-  protected Format45cc(int A, DexMethod BBBB, DexProto HHHH, int C, int D, int E, int F, int G) {
+  protected DexFormat45cc(int A, DexMethod BBBB, DexProto HHHH, int C, int D, int E, int F, int G) {
     assert 0 <= A && A <= U4BIT_MAX;
     assert 0 <= C && C <= U4BIT_MAX;
     assert 0 <= D && D <= U4BIT_MAX;
@@ -89,23 +90,23 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format45cc) other, Format45cc::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat45cc) other, DexFormat45cc::specify);
   }
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     MethodLookupResult lookup =
-        graphLens.lookupMethod(getMethod(), context.getReference(), Type.POLYMORPHIC);
+        appView.graphLens().lookupMethod(getMethod(), context.getReference(), Type.POLYMORPHIC);
     assert lookup.getType() == Type.POLYMORPHIC;
-    lookup.getReference().collectIndexedItems(indexedItems);
+    lookup.getReference().collectIndexedItems(appView, indexedItems);
 
     DexProto rewrittenProto = rewriter.rewriteProto(getProto());
-    rewrittenProto.collectIndexedItems(indexedItems);
+    rewrittenProto.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/Format4rcc.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat4rcc.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/Format4rcc.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat4rcc.java
index 4da5b40..a96b70b 100644
--- a/src/main/java/com/android/tools/r8/code/Format4rcc.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat4rcc.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2017, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.GraphLens;
@@ -21,19 +22,19 @@
 import java.util.function.BiPredicate;
 
 /** Format4rcc for instructions of size 4, with a range of registers and 2 constant pool index. */
-public abstract class Format4rcc extends Base4Format {
+public abstract class DexFormat4rcc extends DexBase4Format {
 
   public final short AA;
   public final char CCCC;
   public DexMethod BBBB;
   public DexProto HHHH;
 
-  private static void specify(StructuralSpecification<Format4rcc, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat4rcc, ?> spec) {
     spec.withInt(i -> i.AA).withInt(i -> i.CCCC).withItem(i -> i.BBBB).withItem(i -> i.HHHH);
   }
 
   // AA | op | [meth]@BBBB | CCCC | [proto]@HHHH
-  Format4rcc(int high, BytecodeStream stream, DexMethod[] methodMap, DexProto[] protoMap) {
+  DexFormat4rcc(int high, BytecodeStream stream, DexMethod[] methodMap, DexProto[] protoMap) {
     super(stream);
     this.AA = (short) high;
     this.BBBB = methodMap[read16BitValue(stream)];
@@ -41,7 +42,7 @@
     this.HHHH = protoMap[read16BitValue(stream)];
   }
 
-  Format4rcc(int firstArgumentRegister, int argumentCount, DexMethod method, DexProto proto) {
+  DexFormat4rcc(int firstArgumentRegister, int argumentCount, DexMethod method, DexProto proto) {
     assert 0 <= firstArgumentRegister && firstArgumentRegister <= Constants.U16BIT_MAX;
     assert 0 <= argumentCount && argumentCount <= Constants.U8BIT_MAX;
     this.CCCC = (char) firstArgumentRegister;
@@ -75,8 +76,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format4rcc) other, Format4rcc::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat4rcc) other, DexFormat4rcc::specify);
   }
 
   @Override
@@ -111,25 +112,26 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     MethodLookupResult lookup =
-        graphLens.lookupMethod(getMethod(), context.getReference(), Type.POLYMORPHIC);
+        appView.graphLens().lookupMethod(getMethod(), context.getReference(), Type.POLYMORPHIC);
     assert lookup.getType() == Type.POLYMORPHIC;
-    lookup.getReference().collectIndexedItems(indexedItems);
+    lookup.getReference().collectIndexedItems(appView, indexedItems);
 
     DexProto rewrittenProto = rewriter.rewriteProto(getProto());
-    rewrittenProto.collectIndexedItems(indexedItems);
+    rewrittenProto.collectIndexedItems(appView, indexedItems);
   }
 
   @Override
-  public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
+  public boolean equals(
+      DexInstruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
     if (other == null || (this.getClass() != other.getClass())) {
       return false;
     }
-    Format4rcc o = (Format4rcc) other;
+    DexFormat4rcc o = (DexFormat4rcc) other;
     return o.AA == AA
         && o.CCCC == CCCC
         && equality.test(BBBB, o.BBBB)
diff --git a/src/main/java/com/android/tools/r8/code/Format51l.java b/src/main/java/com/android/tools/r8/dex/code/DexFormat51l.java
similarity index 78%
rename from src/main/java/com/android/tools/r8/code/Format51l.java
rename to src/main/java/com/android/tools/r8/dex/code/DexFormat51l.java
index 1417bf8..fa88721 100644
--- a/src/main/java/com/android/tools/r8/code/Format51l.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexFormat51l.java
@@ -1,10 +1,11 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.dex.IndexedItemCollection;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.ObjectToOffsetMapping;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -14,23 +15,23 @@
 import com.android.tools.r8.utils.structural.StructuralSpecification;
 import java.nio.ShortBuffer;
 
-abstract class Format51l extends Base5Format {
+abstract class DexFormat51l extends DexBase5Format {
 
   public final short AA;
   public final long BBBBBBBBBBBBBBBB;
 
-  private static void specify(StructuralSpecification<Format51l, ?> spec) {
+  private static void specify(StructuralSpecification<DexFormat51l, ?> spec) {
     spec.withInt(i -> i.AA).withLong(i -> i.BBBBBBBBBBBBBBBB);
   }
 
   // AA | op | BBBB | BBBB | BBBB | BBBB
-  Format51l(int high, BytecodeStream stream) {
+  DexFormat51l(int high, BytecodeStream stream) {
     super(stream);
     AA = (short) high;
     BBBBBBBBBBBBBBBB = read64BitValue(stream);
   }
 
-  public Format51l(int AA, long BBBBBBBBBBBBBBBB) {
+  public DexFormat51l(int AA, long BBBBBBBBBBBBBBBB) {
     assert 0 <= AA && AA <= Constants.U8BIT_MAX;
     this.AA = (short) AA;
     this.BBBBBBBBBBBBBBBB = BBBBBBBBBBBBBBBB;
@@ -53,8 +54,8 @@
   }
 
   @Override
-  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
-    return visitor.visit(this, (Format51l) other, Format51l::specify);
+  final int internalAcceptCompareTo(DexInstruction other, CompareToVisitor visitor) {
+    return visitor.visit(this, (DexFormat51l) other, DexFormat51l::specify);
   }
 
   @Override
@@ -64,9 +65,9 @@
 
   @Override
   public void collectIndexedItems(
+      AppView<?> appView,
       IndexedItemCollection indexedItems,
       ProgramMethod context,
-      GraphLens graphLens,
       LensCodeRewriterUtils rewriter) {
     // No references.
   }
diff --git a/src/main/java/com/android/tools/r8/code/Goto.java b/src/main/java/com/android/tools/r8/dex/code/DexGoto.java
similarity index 81%
rename from src/main/java/com/android/tools/r8/code/Goto.java
rename to src/main/java/com/android/tools/r8/dex/code/DexGoto.java
index fc911ee..6b7c0b2 100644
--- a/src/main/java/com/android/tools/r8/code/Goto.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexGoto.java
@@ -1,21 +1,21 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Goto extends Format10t {
+public class DexGoto extends DexFormat10t {
 
   public static final int OPCODE = 0x28;
   public static final String NAME = "Goto";
   public static final String SMALI_NAME = "goto";
 
-  Goto(int high, BytecodeStream stream) {
+  DexGoto(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Goto(int AA) {
+  public DexGoto(int AA) {
     super(AA);
   }
 
@@ -36,7 +36,7 @@
 
   @Override
   public int[] getTargets() {
-    return new int[] { AA };
+    return new int[] {AA};
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/Goto16.java b/src/main/java/com/android/tools/r8/dex/code/DexGoto16.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Goto16.java
rename to src/main/java/com/android/tools/r8/dex/code/DexGoto16.java
index c4cec89..0a41ab6 100644
--- a/src/main/java/com/android/tools/r8/code/Goto16.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexGoto16.java
@@ -1,21 +1,21 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Goto16 extends Format20t {
+public class DexGoto16 extends DexFormat20t {
 
   public static final int OPCODE = 0x29;
   public static final String NAME = "Goto16";
   public static final String SMALI_NAME = "goto/16";
 
-  Goto16(int high, BytecodeStream stream) {
+  DexGoto16(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Goto16(int AAAA) {
+  public DexGoto16(int AAAA) {
     super(AAAA);
   }
 
@@ -36,7 +36,7 @@
 
   @Override
   public int[] getTargets() {
-    return new int[]{AAAA};
+    return new int[] {AAAA};
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/Goto32.java b/src/main/java/com/android/tools/r8/dex/code/DexGoto32.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Goto32.java
rename to src/main/java/com/android/tools/r8/dex/code/DexGoto32.java
index 3a4c6b8..bfa83cc 100644
--- a/src/main/java/com/android/tools/r8/code/Goto32.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexGoto32.java
@@ -1,21 +1,21 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Goto32 extends Format30t {
+public class DexGoto32 extends DexFormat30t {
 
   public static final int OPCODE = 0x2a;
   public static final String NAME = "Goto32";
   public static final String SMALI_NAME = "goto/32";
 
-  Goto32(int high, BytecodeStream stream) {
+  DexGoto32(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public Goto32(int AAAAAAAA) {
+  public DexGoto32(int AAAAAAAA) {
     super(AAAAAAAA);
   }
 
@@ -36,7 +36,7 @@
 
   @Override
   public int[] getTargets() {
-    return new int[]{AAAAAAAA};
+    return new int[] {AAAAAAAA};
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/code/IfEq.java b/src/main/java/com/android/tools/r8/dex/code/DexIfEq.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfEq.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfEq.java
index abd77ee..345328f 100644
--- a/src/main/java/com/android/tools/r8/code/IfEq.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfEq.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfEq extends Format22t {
+public class DexIfEq extends DexFormat22t {
 
   public static final int OPCODE = 0x32;
   public static final String NAME = "IfEq";
   public static final String SMALI_NAME = "if-eq";
 
-  IfEq(int high, BytecodeStream stream) {
+  DexIfEq(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfEq(int register1, int register2, int offset) {
+  public DexIfEq(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfEqz.java b/src/main/java/com/android/tools/r8/dex/code/DexIfEqz.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfEqz.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfEqz.java
index 8bfed6d..517576c 100644
--- a/src/main/java/com/android/tools/r8/code/IfEqz.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfEqz.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfEqz extends Format21t {
+public class DexIfEqz extends DexFormat21t {
 
   public static final int OPCODE = 0x38;
   public static final String NAME = "IfEqz";
   public static final String SMALI_NAME = "if-eqz";
 
-  IfEqz(int high, BytecodeStream stream) {
+  DexIfEqz(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfEqz(int register, int offset) {
+  public DexIfEqz(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfGe.java b/src/main/java/com/android/tools/r8/dex/code/DexIfGe.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfGe.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfGe.java
index dd123f2..4c49892 100644
--- a/src/main/java/com/android/tools/r8/code/IfGe.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfGe.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfGe extends Format22t {
+public class DexIfGe extends DexFormat22t {
 
   public static final int OPCODE = 0x35;
   public static final String NAME = "IfGe";
   public static final String SMALI_NAME = "if-ge";
 
-  IfGe(int high, BytecodeStream stream) {
+  DexIfGe(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfGe(int register1, int register2, int offset) {
+  public DexIfGe(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfGez.java b/src/main/java/com/android/tools/r8/dex/code/DexIfGez.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfGez.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfGez.java
index 9ca69c0..6a9b49e 100644
--- a/src/main/java/com/android/tools/r8/code/IfGez.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfGez.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfGez extends Format21t {
+public class DexIfGez extends DexFormat21t {
 
   public static final int OPCODE = 0x3b;
   public static final String NAME = "IfGez";
   public static final String SMALI_NAME = "if-gez";
 
-  IfGez(int high, BytecodeStream stream) {
+  DexIfGez(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfGez(int register, int offset) {
+  public DexIfGez(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfGt.java b/src/main/java/com/android/tools/r8/dex/code/DexIfGt.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfGt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfGt.java
index 84a8fcb..20abfdc 100644
--- a/src/main/java/com/android/tools/r8/code/IfGt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfGt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfGt extends Format22t {
+public class DexIfGt extends DexFormat22t {
 
   public static final int OPCODE = 0x36;
   public static final String NAME = "IfGt";
   public static final String SMALI_NAME = "if-gt";
 
-  IfGt(int high, BytecodeStream stream) {
+  DexIfGt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfGt(int register1, int register2, int offset) {
+  public DexIfGt(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfGtz.java b/src/main/java/com/android/tools/r8/dex/code/DexIfGtz.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfGtz.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfGtz.java
index 8567a11..c3a8348 100644
--- a/src/main/java/com/android/tools/r8/code/IfGtz.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfGtz.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfGtz extends Format21t {
+public class DexIfGtz extends DexFormat21t {
 
   public static final int OPCODE = 0x3c;
   public static final String NAME = "IfGtz";
   public static final String SMALI_NAME = "if-gtz";
 
-  IfGtz(int high, BytecodeStream stream) {
+  DexIfGtz(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfGtz(int register, int offset) {
+  public DexIfGtz(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfLe.java b/src/main/java/com/android/tools/r8/dex/code/DexIfLe.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfLe.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfLe.java
index c313a4f..9fde6a5 100644
--- a/src/main/java/com/android/tools/r8/code/IfLe.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfLe.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfLe extends Format22t {
+public class DexIfLe extends DexFormat22t {
 
   public static final int OPCODE = 0x37;
   public static final String NAME = "IfLe";
   public static final String SMALI_NAME = "if-le";
 
-  IfLe(int high, BytecodeStream stream) {
+  DexIfLe(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfLe(int register1, int register2, int offset) {
+  public DexIfLe(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfLez.java b/src/main/java/com/android/tools/r8/dex/code/DexIfLez.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfLez.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfLez.java
index 9024a98..04ebeff 100644
--- a/src/main/java/com/android/tools/r8/code/IfLez.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfLez.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfLez extends Format21t {
+public class DexIfLez extends DexFormat21t {
 
   public static final int OPCODE = 0x3d;
   public static final String NAME = "IfLez";
   public static final String SMALI_NAME = "if-lez";
 
-  IfLez(int high, BytecodeStream stream) {
+  DexIfLez(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfLez(int register, int offset) {
+  public DexIfLez(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfLt.java b/src/main/java/com/android/tools/r8/dex/code/DexIfLt.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfLt.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfLt.java
index 556de31..728ba10 100644
--- a/src/main/java/com/android/tools/r8/code/IfLt.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfLt.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfLt extends Format22t {
+public class DexIfLt extends DexFormat22t {
 
   public static final int OPCODE = 0x34;
   public static final String NAME = "IfLt";
   public static final String SMALI_NAME = "if-lt";
 
-  IfLt(int high, BytecodeStream stream) {
+  DexIfLt(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfLt(int register1, int register2, int offset) {
+  public DexIfLt(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfLtz.java b/src/main/java/com/android/tools/r8/dex/code/DexIfLtz.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfLtz.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfLtz.java
index c19b0d9..0aba44f 100644
--- a/src/main/java/com/android/tools/r8/code/IfLtz.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfLtz.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfLtz extends Format21t {
+public class DexIfLtz extends DexFormat21t {
 
   public static final int OPCODE = 0x3a;
   public static final String NAME = "IfLtz";
   public static final String SMALI_NAME = "if-ltz";
 
-  IfLtz(int high, BytecodeStream stream) {
+  DexIfLtz(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfLtz(int register, int offset) {
+  public DexIfLtz(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfNe.java b/src/main/java/com/android/tools/r8/dex/code/DexIfNe.java
similarity index 82%
rename from src/main/java/com/android/tools/r8/code/IfNe.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfNe.java
index 24e45d9..9919538 100644
--- a/src/main/java/com/android/tools/r8/code/IfNe.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfNe.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfNe extends Format22t {
+public class DexIfNe extends DexFormat22t {
 
   public static final int OPCODE = 0x33;
   public static final String NAME = "IfNe";
   public static final String SMALI_NAME = "if-ne";
 
-  IfNe(int high, BytecodeStream stream) {
+  DexIfNe(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfNe(int register1, int register2, int offset) {
+  public DexIfNe(int register1, int register2, int offset) {
     super(register1, register2, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IfNez.java b/src/main/java/com/android/tools/r8/dex/code/DexIfNez.java
similarity index 83%
rename from src/main/java/com/android/tools/r8/code/IfNez.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIfNez.java
index f9057e6..cb74246 100644
--- a/src/main/java/com/android/tools/r8/code/IfNez.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIfNez.java
@@ -1,22 +1,22 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.ir.code.If.Type;
 import com.android.tools.r8.ir.code.ValueTypeConstraint;
 
-public class IfNez extends Format21t {
+public class DexIfNez extends DexFormat21t {
 
   public static final int OPCODE = 0x39;
   public static final String NAME = "IfNez";
   public static final String SMALI_NAME = "if-nez";
 
-  IfNez(int high, BytecodeStream stream) {
+  DexIfNez(int high, BytecodeStream stream) {
     super(high, stream);
   }
 
-  public IfNez(int register, int offset) {
+  public DexIfNez(int register, int offset) {
     super(register, offset);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/Iget.java b/src/main/java/com/android/tools/r8/dex/code/DexIget.java
similarity index 80%
rename from src/main/java/com/android/tools/r8/code/Iget.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIget.java
index ee8e7a0..0329505 100644
--- a/src/main/java/com/android/tools/r8/code/Iget.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIget.java
@@ -1,24 +1,24 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.OffsetToObjectMapping;
 import com.android.tools.r8.graph.UseRegistry;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class Iget extends IgetOrIput implements CfOrDexInstanceFieldRead {
+public class DexIget extends DexIgetOrIput implements CfOrDexInstanceFieldRead {
 
   public static final int OPCODE = 0x52;
   public static final String NAME = "Iget";
   public static final String SMALI_NAME = "iget";
 
-  /*package*/ Iget(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  /*package*/ DexIget(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getFieldMap());
   }
 
-  public Iget(int destRegister, int objectRegister, DexField field) {
+  public DexIget(int destRegister, int objectRegister, DexField field) {
     super(destRegister, objectRegister, field);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IgetBoolean.java b/src/main/java/com/android/tools/r8/dex/code/DexIgetBoolean.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/IgetBoolean.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIgetBoolean.java
index 3212878..16bfd6d 100644
--- a/src/main/java/com/android/tools/r8/code/IgetBoolean.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIgetBoolean.java
@@ -1,24 +1,24 @@
 // Copyright (c) 2016, 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.code;
+package com.android.tools.r8.dex.code;
 
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.OffsetToObjectMapping;
 import com.android.tools.r8.graph.UseRegistry;
 import com.android.tools.r8.ir.conversion.IRBuilder;
 
-public class IgetBoolean extends IgetOrIput implements CfOrDexInstanceFieldRead {
+public class DexIgetBoolean extends DexIgetOrIput implements CfOrDexInstanceFieldRead {
 
   public static final int OPCODE = 0x55;
   public static final String NAME = "IgetBoolean";
   public static final String SMALI_NAME = "iget-boolean";
 
-  /*package*/ IgetBoolean(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
+  /*package*/ DexIgetBoolean(int high, BytecodeStream stream, OffsetToObjectMapping mapping) {
     super(high, stream, mapping.getFieldMap());
   }
 
-  public IgetBoolean(int destRegister, int objectRegister, DexField field) {
+  public DexIgetBoolean(int destRegister, int objectRegister, DexField field) {
     super(destRegister, objectRegister, field);
   }
 
diff --git a/src/main/java/com/android/tools/r8/code/IgetByte.java b/src/main/java/com/android/tools/r8/dex/code/DexIgetByte.java
similarity index 79%
rename from src/main/java/com/android/tools/r8/code/IgetByte.java
rename to src/main/java/com/android/tools/r8/dex/code/DexIgetByte.java
index a876d70..a1a04db 100644
--- a/src/main/java/com/android/tools/r8/code/IgetByte.java
+++ b/src/main/java/com/android/tools/r8/dex/code/DexIgetByte.java
@@ -1