Clean up how api levels are handled in various places

Now that dex files store an associated Opcodes instance, we don't need to
pass the api level around as much.
diff --git a/baksmali/src/main/java/org/jf/baksmali/AnalysisArguments.java b/baksmali/src/main/java/org/jf/baksmali/AnalysisArguments.java
index fa3bb85..20bc45b 100644
--- a/baksmali/src/main/java/org/jf/baksmali/AnalysisArguments.java
+++ b/baksmali/src/main/java/org/jf/baksmali/AnalysisArguments.java
@@ -49,11 +49,6 @@
 import static org.jf.dexlib2.analysis.ClassPath.NOT_ART;
 
 public class AnalysisArguments {
-    @Parameter(names = {"-a", "--api"},
-            description = "The numeric api level of the file being disassembled.")
-    @ExtendedParameter(argumentNames = "api")
-    public int apiLevel = 15;
-
     @Parameter(names = {"-b", "--bootclasspath", "--bcp"},
             description = "A colon separated list of the files to include in the bootclasspath when analyzing the " +
                     "dex file. If not specified, baksmali will attempt to choose an " +
@@ -131,7 +126,7 @@
         if (bootClassPath == null) {
             // TODO: we should be able to get the api from the Opcodes object associated with the dexFile..
             // except that the oat version -> api mapping doesn't fully work yet
-            resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile, apiLevel);
+            resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile);
         }  else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) {
             // --bootclasspath "" is a special case, denoting that no bootclasspath should be used
             resolver = new ClassPathResolver(
diff --git a/baksmali/src/main/java/org/jf/baksmali/DexInputCommand.java b/baksmali/src/main/java/org/jf/baksmali/DexInputCommand.java
index 7117bb2..c7660cb 100644
--- a/baksmali/src/main/java/org/jf/baksmali/DexInputCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/DexInputCommand.java
@@ -52,6 +52,11 @@
  */
 public abstract class DexInputCommand extends Command {
 
+    @Parameter(names = {"-a", "--api"},
+            description = "The numeric api level of the file being disassembled.")
+    @ExtendedParameter(argumentNames = "api")
+    public int apiLevel = 15;
+
     @Parameter(description = "A dex/apk/oat/odex file. For apk or oat files that contain multiple dex " +
             "files, you can specify the specific entry to use as if the apk/oat file was a directory. " +
             "e.g. \"app.apk/classes2.dex\". For more information, see \"baksmali help input\".")
@@ -100,9 +105,8 @@
      * framework/arm/framework.oat/"system/framework/framework.jar:classes2.dex"
      *
      * @param input The name of a dex, apk, odex or oat file/entry.
-     * @param opcodes The set of opcodes to load the dex file with.
      */
-    protected void loadDexFile(@Nonnull String input, Opcodes opcodes) {
+    protected void loadDexFile(@Nonnull String input) {
         File file = new File(input);
 
         while (file != null && !file.exists()) {
@@ -131,13 +135,13 @@
             inputEntry = dexEntry;
 
             try {
-                dexFile = DexFileFactory.loadDexEntry(file, dexEntry, exactMatch, opcodes);
+                dexFile = DexFileFactory.loadDexEntry(file, dexEntry, exactMatch, Opcodes.forApi(apiLevel));
             } catch (IOException ex) {
                 throw new RuntimeException(ex);
             }
         } else {
             try {
-                dexFile = DexFileFactory.loadDexFile(file, opcodes);
+                dexFile = DexFileFactory.loadDexFile(file, Opcodes.forApi(apiLevel));
             } catch (IOException ex) {
                 throw new RuntimeException(ex);
             }
diff --git a/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java b/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
index 06d7c96..2e3eb79 100644
--- a/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
@@ -38,7 +38,6 @@
 import com.beust.jcommander.validators.PositiveInteger;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.util.SyntheticAccessorResolver;
 import org.jf.util.StringWrapper;
 import org.jf.util.jcommander.ExtendedParameter;
@@ -155,7 +154,7 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
 
         if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
             StringWrapper.printWrappedString(System.err,
diff --git a/baksmali/src/main/java/org/jf/baksmali/DumpCommand.java b/baksmali/src/main/java/org/jf/baksmali/DumpCommand.java
index 94c7bb3..433be12 100644
--- a/baksmali/src/main/java/org/jf/baksmali/DumpCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/DumpCommand.java
@@ -34,12 +34,10 @@
 import com.beust.jcommander.JCommander;
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.dexbacked.DexBackedDexFile;
 import org.jf.dexlib2.dexbacked.raw.RawDexFile;
 import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
 import org.jf.util.ConsoleUtil;
-import org.jf.util.jcommander.ExtendedParameter;
 import org.jf.util.jcommander.ExtendedParameters;
 
 import javax.annotation.Nonnull;
@@ -56,11 +54,6 @@
             description = "Show usage information for this command.")
     private boolean help;
 
-    @Parameter(names = {"-a", "--api"},
-            description = "The numeric api level of the file being disassembled.")
-    @ExtendedParameter(argumentNames = "api")
-    private int apiLevel = 15;
-
     public DumpCommand(@Nonnull List<JCommander> commandAncestors) {
         super(commandAncestors);
     }
@@ -78,10 +71,10 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
 
         try {
-            dump(dexFile, System.out, apiLevel);
+            dump(dexFile, System.out);
         } catch (IOException ex) {
             System.err.println("There was an error while dumping the dex file");
             ex.printStackTrace(System.err);
@@ -94,11 +87,10 @@
      * @param dexFile The dex file to dump
      * @param output An OutputStream to write the annotated hex dump to. The caller is responsible for closing this
      *               when needed.
-     * @param apiLevel The api level to use when dumping the dex file
      *
      * @throws IOException
      */
-    public static void dump(@Nonnull DexBackedDexFile dexFile, @Nonnull OutputStream output, int apiLevel)
+    public static void dump(@Nonnull DexBackedDexFile dexFile, @Nonnull OutputStream output)
             throws IOException {
         Writer writer = new BufferedWriter(new OutputStreamWriter(output));
 
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListClassesCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListClassesCommand.java
index 6c6ca64..fb172bd 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListClassesCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListClassesCommand.java
@@ -34,7 +34,6 @@
 import com.beust.jcommander.JCommander;
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.iface.ClassDef;
 import org.jf.util.jcommander.ExtendedParameters;
 
@@ -68,7 +67,7 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
 
         for (ClassDef classDef: dexFile.getClasses()) {
             System.out.println(classDef.getType());
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListFieldOffsetsCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListFieldOffsetsCommand.java
index 68e2050..d6dd6e2 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListFieldOffsetsCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListFieldOffsetsCommand.java
@@ -35,7 +35,6 @@
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 import com.beust.jcommander.ParametersDelegate;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.analysis.ClassProto;
 import org.jf.dexlib2.iface.ClassDef;
 import org.jf.dexlib2.iface.reference.FieldReference;
@@ -76,7 +75,7 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
         BaksmaliOptions options = getOptions();
 
         try {
@@ -105,7 +104,7 @@
 
         final BaksmaliOptions options = new BaksmaliOptions();
 
-        options.apiLevel = analysisArguments.apiLevel;
+        options.apiLevel = apiLevel;
 
         try {
             options.classPath = analysisArguments.loadClassPathForDexFile(
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListReferencesCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListReferencesCommand.java
index 3403bbf..da9c3e3 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListReferencesCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListReferencesCommand.java
@@ -33,7 +33,6 @@
 
 import com.beust.jcommander.JCommander;
 import com.beust.jcommander.Parameter;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.iface.reference.Reference;
 import org.jf.dexlib2.util.ReferenceUtil;
 
@@ -66,7 +65,7 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
 
         for (Reference reference: dexFile.getReferences(referenceType)) {
             System.out.println(ReferenceUtil.getReferenceString(reference));
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
index ed88c12..74435b3 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
@@ -37,7 +37,6 @@
 import com.beust.jcommander.ParametersDelegate;
 import org.jf.baksmali.AnalysisArguments.CheckPackagePrivateArgument;
 import org.jf.dexlib2.AccessFlags;
-import org.jf.dexlib2.Opcodes;
 import org.jf.dexlib2.analysis.ClassProto;
 import org.jf.dexlib2.iface.ClassDef;
 import org.jf.dexlib2.iface.Method;
@@ -92,7 +91,7 @@
         }
 
         String input = inputList.get(0);
-        loadDexFile(input, Opcodes.getDefault());
+        loadDexFile(input);
 
         BaksmaliOptions options = getOptions();
         if (options == null) {
@@ -142,7 +141,7 @@
 
         final BaksmaliOptions options = new BaksmaliOptions();
 
-        options.apiLevel = analysisArguments.apiLevel;
+        options.apiLevel = apiLevel;
 
         try {
             options.classPath = analysisArguments.loadClassPathForDexFile(inputFile.getAbsoluteFile().getParentFile(),
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
index 5a700d8..bc11f12 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
@@ -81,7 +81,6 @@
             throw new DexFileNotFoundException("%s does not exist", file.getName());
         }
 
-
         try {
             ZipDexContainer container = new ZipDexContainer(file, opcodes);
             return new DexEntryFinder(file.getPath(), container).findEntry("classes.dex", true);
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPathResolver.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPathResolver.java
index c9f4713..da2dbea 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPathResolver.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPathResolver.java
@@ -82,7 +82,7 @@
     public ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nonnull List<String> bootClassPathEntries,
                              @Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile)
             throws IOException {
-        this(bootClassPathDirs, bootClassPathEntries, extraClassPathEntries, dexFile, dexFile.getOpcodes().api);
+        this(bootClassPathDirs, bootClassPathEntries, extraClassPathEntries, dexFile, true);
     }
 
     /**
@@ -92,7 +92,6 @@
      * @param extraClassPathEntries A list of additional classpath entries to load. Can be empty. All entries must be
      *                              local paths. Device paths are not supported.
      * @param dexFile The dex file that the classpath will be used to analyze
-     * @param apiLevel The api level of the device. This is used to select an appropriate set of boot classpath entries.
      * @throws IOException If any IOException occurs
      * @throws ResolveException If any classpath entries cannot be loaded for some reason
      *
@@ -101,19 +100,19 @@
      *                             classpath entries will be loaded
      */
     public ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nonnull List<String> extraClassPathEntries,
-                             @Nonnull DexFile dexFile, int apiLevel)
+                             @Nonnull DexFile dexFile)
             throws IOException {
-        this(bootClassPathDirs, null, extraClassPathEntries, dexFile, apiLevel);
+        this(bootClassPathDirs, null, extraClassPathEntries, dexFile, true);
     }
 
     private ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nullable List<String> bootClassPathEntries,
-                              @Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile, int apiLevel)
+                              @Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile, boolean unused)
             throws IOException {
         this.classPathDirs = bootClassPathDirs;
         opcodes = dexFile.getOpcodes();
 
         if (bootClassPathEntries == null) {
-            bootClassPathEntries = getDefaultBootClassPath(dexFile, apiLevel);
+            bootClassPathEntries = getDefaultBootClassPath(dexFile, opcodes.api);
         }
 
         for (String entry : bootClassPathEntries) {