diff --git a/tools/dexdeps/src/com/android/dexdeps/DexData.java b/tools/dexdeps/src/com/android/dexdeps/DexData.java
index 1b6cc98..e7f9a53 100644
--- a/tools/dexdeps/src/com/android/dexdeps/DexData.java
+++ b/tools/dexdeps/src/com/android/dexdeps/DexData.java
@@ -23,13 +23,11 @@
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
-/**
- * Data extracted from a DEX file.
- */
+/** Data extracted from a DEX file. */
 public class DexData {
     private RandomAccessFile mDexFile;
     private HeaderItem mHeaderItem;
-    private String[] mStrings;              // strings from string_data_*
+    private String[] mStrings; // strings from string_data_*
     private TypeIdItem[] mTypeIds;
     private ProtoIdItem[] mProtoIds;
     private FieldIdItem[] mFieldIds;
@@ -39,9 +37,7 @@
     private byte tmpBuf[] = new byte[4];
     private ByteOrder mByteOrder = ByteOrder.LITTLE_ENDIAN;
 
-    /**
-     * Constructs a new DexData for this file.
-     */
+    /** Constructs a new DexData for this file. */
     public DexData(RandomAccessFile raf) {
         mDexFile = raf;
     }
@@ -65,19 +61,16 @@
         markInternalClasses();
     }
 
-    /**
-     * Verifies the given magic number.
-     */
+    /** Verifies the given magic number. */
     private static boolean verifyMagic(byte[] magic) {
-        return Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v035) ||
-            Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v037) ||
-            Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v038) ||
-            Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v039);
+        return Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v035)
+                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v037)
+                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v038)
+                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v039)
+                || Arrays.equals(magic, HeaderItem.DEX_FILE_MAGIC_v041);
     }
 
-    /**
-     * Parses the interesting bits out of the header.
-     */
+    /** Parses the interesting bits out of the header. */
     void parseHeaderItem() throws IOException {
         mHeaderItem = new HeaderItem();
 
@@ -86,8 +79,7 @@
         byte[] magic = new byte[8];
         readBytes(magic);
         if (!verifyMagic(magic)) {
-            System.err.println("Magic number is wrong -- are you sure " +
-                "this is a DEX file?");
+            System.err.println("Magic number is wrong -- are you sure " + "this is a DEX file?");
             throw new DexDataException();
         }
 
@@ -95,20 +87,21 @@
          * Read the endian tag, so we properly swap things as we read
          * them from here on.
          */
-        seek(8+4+20+4+4);
+        seek(8 + 4 + 20 + 4 + 4);
         mHeaderItem.endianTag = readInt();
         if (mHeaderItem.endianTag == HeaderItem.ENDIAN_CONSTANT) {
             /* do nothing */
-        } else if (mHeaderItem.endianTag == HeaderItem.REVERSE_ENDIAN_CONSTANT){
+        } else if (mHeaderItem.endianTag == HeaderItem.REVERSE_ENDIAN_CONSTANT) {
             /* file is big-endian (!), reverse future reads */
             mByteOrder = ByteOrder.BIG_ENDIAN;
         } else {
-            System.err.println("Endian constant has unexpected value " +
-                Integer.toHexString(mHeaderItem.endianTag));
+            System.err.println(
+                    "Endian constant has unexpected value "
+                            + Integer.toHexString(mHeaderItem.endianTag));
             throw new DexDataException();
         }
 
-        seek(8+4+20);  // magic, checksum, signature
+        seek(8 + 4 + 20); // magic, checksum, signature
         ByteBuffer buffer = readByteBuffer(Integer.BYTES * 20);
         mHeaderItem.fileSize = buffer.getInt();
         mHeaderItem.headerSize = buffer.getInt();
@@ -135,15 +128,14 @@
     /**
      * Loads the string table out of the DEX.
      *
-     * First we read all of the string_id_items, then we read all of the
-     * string_data_item.  Doing it this way should allow us to avoid
-     * seeking around in the file.
+     * <p>First we read all of the string_id_items, then we read all of the string_data_item. Doing
+     * it this way should allow us to avoid seeking around in the file.
      */
     void loadStrings() throws IOException {
         int count = mHeaderItem.stringIdsSize;
         int stringOffsets[] = new int[count];
 
-        //System.out.println("reading " + count + " strings");
+        // System.out.println("reading " + count + " strings");
 
         seek(mHeaderItem.stringIdsOff);
         readByteBuffer(Integer.BYTES * count).asIntBuffer().get(stringOffsets);
@@ -152,39 +144,35 @@
 
         seek(stringOffsets[0]);
         for (int i = 0; i < count; i++) {
-            seek(stringOffsets[i]);         // should be a no-op
+            seek(stringOffsets[i]); // should be a no-op
             mStrings[i] = readString();
-            //System.out.println("STR: " + i + ": " + mStrings[i]);
+            // System.out.println("STR: " + i + ": " + mStrings[i]);
         }
     }
 
-    /**
-     * Loads the type ID list.
-     */
+    /** Loads the type ID list. */
     void loadTypeIds() throws IOException {
         int count = mHeaderItem.typeIdsSize;
         mTypeIds = new TypeIdItem[count];
 
-        //System.out.println("reading " + count + " typeIds");
+        // System.out.println("reading " + count + " typeIds");
         seek(mHeaderItem.typeIdsOff);
         ByteBuffer buffer = readByteBuffer(Integer.BYTES * count);
         for (int i = 0; i < count; i++) {
             mTypeIds[i] = new TypeIdItem();
             mTypeIds[i].descriptorIdx = buffer.getInt();
 
-            //System.out.println(i + ": " + mTypeIds[i].descriptorIdx +
+            // System.out.println(i + ": " + mTypeIds[i].descriptorIdx +
             //    " " + mStrings[mTypeIds[i].descriptorIdx]);
         }
     }
 
-    /**
-     * Loads the proto ID list.
-     */
+    /** Loads the proto ID list. */
     void loadProtoIds() throws IOException {
         int count = mHeaderItem.protoIdsSize;
         mProtoIds = new ProtoIdItem[count];
 
-        //System.out.println("reading " + count + " protoIds");
+        // System.out.println("reading " + count + " protoIds");
         seek(mHeaderItem.protoIdsOff);
         ByteBuffer buffer = readByteBuffer(Integer.BYTES * 3 * count);
 
@@ -197,7 +185,7 @@
             mProtoIds[i].returnTypeIdx = buffer.getInt();
             mProtoIds[i].parametersOff = buffer.getInt();
 
-            //System.out.println(i + ": " + mProtoIds[i].shortyIdx +
+            // System.out.println(i + ": " + mProtoIds[i].shortyIdx +
             //    " " + mStrings[mProtoIds[i].shortyIdx]);
         }
 
@@ -214,7 +202,7 @@
                 continue;
             } else {
                 seek(offset);
-                int size = readInt();       // #of entries in list
+                int size = readInt(); // #of entries in list
                 buffer = readByteBuffer(Short.BYTES * size);
                 protoId.types = new int[size];
 
@@ -225,14 +213,12 @@
         }
     }
 
-    /**
-     * Loads the field ID list.
-     */
+    /** Loads the field ID list. */
     void loadFieldIds() throws IOException {
         int count = mHeaderItem.fieldIdsSize;
         mFieldIds = new FieldIdItem[count];
 
-        //System.out.println("reading " + count + " fieldIds");
+        // System.out.println("reading " + count + " fieldIds");
         seek(mHeaderItem.fieldIdsOff);
         ByteBuffer buffer = readByteBuffer((Integer.BYTES + Short.BYTES * 2) * count);
         for (int i = 0; i < count; i++) {
@@ -241,19 +227,17 @@
             mFieldIds[i].typeIdx = buffer.getShort() & 0xffff;
             mFieldIds[i].nameIdx = buffer.getInt();
 
-            //System.out.println(i + ": " + mFieldIds[i].nameIdx +
+            // System.out.println(i + ": " + mFieldIds[i].nameIdx +
             //    " " + mStrings[mFieldIds[i].nameIdx]);
         }
     }
 
-    /**
-     * Loads the method ID list.
-     */
+    /** Loads the method ID list. */
     void loadMethodIds() throws IOException {
         int count = mHeaderItem.methodIdsSize;
         mMethodIds = new MethodIdItem[count];
 
-        //System.out.println("reading " + count + " methodIds");
+        // System.out.println("reading " + count + " methodIds");
         seek(mHeaderItem.methodIdsOff);
         ByteBuffer buffer = readByteBuffer((Integer.BYTES + Short.BYTES * 2) * count);
         for (int i = 0; i < count; i++) {
@@ -262,44 +246,42 @@
             mMethodIds[i].protoIdx = buffer.getShort() & 0xffff;
             mMethodIds[i].nameIdx = buffer.getInt();
 
-            //System.out.println(i + ": " + mMethodIds[i].nameIdx +
+            // System.out.println(i + ": " + mMethodIds[i].nameIdx +
             //    " " + mStrings[mMethodIds[i].nameIdx]);
         }
     }
 
-    /**
-     * Loads the class defs list.
-     */
+    /** Loads the class defs list. */
     void loadClassDefs() throws IOException {
         int count = mHeaderItem.classDefsSize;
         mClassDefs = new ClassDefItem[count];
 
-        //System.out.println("reading " + count + " classDefs");
+        // System.out.println("reading " + count + " classDefs");
         seek(mHeaderItem.classDefsOff);
         ByteBuffer buffer = readByteBuffer(Integer.BYTES * 8 * count);
         for (int i = 0; i < count; i++) {
             mClassDefs[i] = new ClassDefItem();
             mClassDefs[i].classIdx = buffer.getInt();
 
-            /* access_flags = */ buffer.getInt();
-            /* superclass_idx = */ buffer.getInt();
-            /* interfaces_off = */ buffer.getInt();
-            /* source_file_idx = */ buffer.getInt();
-            /* annotations_off = */ buffer.getInt();
-            /* class_data_off = */ buffer.getInt();
-            /* static_values_off = */ buffer.getInt();
+            /* access_flags= */ buffer.getInt();
+            /* superclass_idx= */ buffer.getInt();
+            /* interfaces_off= */ buffer.getInt();
+            /* source_file_idx= */ buffer.getInt();
+            /* annotations_off= */ buffer.getInt();
+            /* class_data_off= */ buffer.getInt();
+            /* static_values_off= */ buffer.getInt();
 
-            //System.out.println(i + ": " + mClassDefs[i].classIdx + " " +
+            // System.out.println(i + ": " + mClassDefs[i].classIdx + " " +
             //    mStrings[mTypeIds[mClassDefs[i].classIdx].descriptorIdx]);
         }
     }
 
     /**
-     * Sets the "internal" flag on type IDs which are defined in the
-     * DEX file or within the VM (e.g. primitive classes and arrays).
+     * Sets the "internal" flag on type IDs which are defined in the DEX file or within the VM (e.g.
+     * primitive classes and arrays).
      */
     void markInternalClasses() {
-        for (int i = mClassDefs.length -1; i >= 0; i--) {
+        for (int i = mClassDefs.length - 1; i >= 0; i--) {
             mTypeIds[mClassDefs[i].classIdx].internal = true;
         }
 
@@ -313,29 +295,25 @@
                 mTypeIds[i].internal = true;
             }
 
-            //System.out.println(i + " " +
+            // System.out.println(i + " " +
             //    (mTypeIds[i].internal ? "INTERNAL" : "external") + " - " +
             //    mStrings[mTypeIds[i].descriptorIdx]);
         }
     }
 
-
     /*
      * =======================================================================
      *      Queries
      * =======================================================================
      */
 
-    /**
-     * Returns the class name, given an index into the type_ids table.
-     */
+    /** Returns the class name, given an index into the type_ids table. */
     private String classNameFromTypeIndex(int idx) {
         return mStrings[mTypeIds[idx].descriptorIdx];
     }
 
     /**
-     * Returns an array of method argument type strings, given an index
-     * into the proto_ids table.
+     * Returns an array of method argument type strings, given an index into the proto_ids table.
      */
     private String[] argArrayFromProtoIndex(int idx) {
         ProtoIdItem protoId = mProtoIds[idx];
@@ -349,8 +327,8 @@
     }
 
     /**
-     * Returns a string representing the method's return type, given an
-     * index into the proto_ids table.
+     * Returns a string representing the method's return type, given an index into the proto_ids
+     * table.
      */
     private String returnTypeFromProtoIndex(int idx) {
         ProtoIdItem protoId = mProtoIds[idx];
@@ -358,9 +336,8 @@
     }
 
     /**
-     * Returns an array with all of the class references that don't
-     * correspond to classes in the DEX file.  Each class reference has
-     * a list of the referenced fields and methods associated with
+     * Returns an array with all of the class references that don't correspond to classes in the DEX
+     * file. Each class reference has a list of the referenced fields and methods associated with
      * that class.
      */
     public ClassRef[] getExternalReferences() {
@@ -371,8 +348,7 @@
         int count = 0;
         for (int i = 0; i < mTypeIds.length; i++) {
             if (!mTypeIds[i].internal) {
-                sparseRefs[i] =
-                    new ClassRef(mStrings[mTypeIds[i].descriptorIdx]);
+                sparseRefs[i] = new ClassRef(mStrings[mTypeIds[i].descriptorIdx]);
                 count++;
             }
         }
@@ -385,8 +361,7 @@
         ClassRef[] classRefs = new ClassRef[count];
         int idx = 0;
         for (int i = 0; i < mTypeIds.length; i++) {
-            if (sparseRefs[i] != null)
-                classRefs[idx++] = sparseRefs[i];
+            if (sparseRefs[i] != null) classRefs[idx++] = sparseRefs[i];
         }
 
         assert idx == count;
@@ -395,87 +370,84 @@
     }
 
     /**
-     * Runs through the list of field references, inserting external
-     * references into the appropriate ClassRef.
+     * Runs through the list of field references, inserting external references into the appropriate
+     * ClassRef.
      */
     private void addExternalFieldReferences(ClassRef[] sparseRefs) {
         for (int i = 0; i < mFieldIds.length; i++) {
             if (!mTypeIds[mFieldIds[i].classIdx].internal) {
                 FieldIdItem fieldId = mFieldIds[i];
-                FieldRef newFieldRef = new FieldRef(
-                        classNameFromTypeIndex(fieldId.classIdx),
-                        classNameFromTypeIndex(fieldId.typeIdx),
-                        mStrings[fieldId.nameIdx]);
+                FieldRef newFieldRef =
+                        new FieldRef(
+                                classNameFromTypeIndex(fieldId.classIdx),
+                                classNameFromTypeIndex(fieldId.typeIdx),
+                                mStrings[fieldId.nameIdx]);
                 sparseRefs[mFieldIds[i].classIdx].addField(newFieldRef);
             }
         }
     }
 
     /**
-     * Runs through the list of method references, inserting external
-     * references into the appropriate ClassRef.
+     * Runs through the list of method references, inserting external references into the
+     * appropriate ClassRef.
      */
     private void addExternalMethodReferences(ClassRef[] sparseRefs) {
         for (int i = 0; i < mMethodIds.length; i++) {
             if (!mTypeIds[mMethodIds[i].classIdx].internal) {
                 MethodIdItem methodId = mMethodIds[i];
-                MethodRef newMethodRef = new MethodRef(
-                        classNameFromTypeIndex(methodId.classIdx),
-                        argArrayFromProtoIndex(methodId.protoIdx),
-                        returnTypeFromProtoIndex(methodId.protoIdx),
-                        mStrings[methodId.nameIdx]);
+                MethodRef newMethodRef =
+                        new MethodRef(
+                                classNameFromTypeIndex(methodId.classIdx),
+                                argArrayFromProtoIndex(methodId.protoIdx),
+                                returnTypeFromProtoIndex(methodId.protoIdx),
+                                mStrings[methodId.nameIdx]);
                 sparseRefs[mMethodIds[i].classIdx].addMethod(newMethodRef);
             }
         }
     }
 
-
     /*
      * =======================================================================
      *      Basic I/O functions
      * =======================================================================
      */
 
-    /**
-     * Seeks the DEX file to the specified absolute position.
-     */
+    /** Seeks the DEX file to the specified absolute position. */
     void seek(int position) throws IOException {
         mDexFile.seek(position);
     }
 
-    /**
-     * Fills the buffer by reading bytes from the DEX file.
-     */
+    /** Fills the buffer by reading bytes from the DEX file. */
     void readBytes(byte[] buffer) throws IOException {
         mDexFile.readFully(buffer);
     }
 
-    /**
-     * Reads a single signed byte value.
-     */
+    /** Reads a single signed byte value. */
     byte readByte() throws IOException {
         mDexFile.readFully(tmpBuf, 0, 1);
         return tmpBuf[0];
     }
 
-    /**
-     * Reads a signed 32-bit integer, byte-swapping if necessary.
-     */
+    /** Reads a signed 32-bit integer, byte-swapping if necessary. */
     int readInt() throws IOException {
         mDexFile.readFully(tmpBuf, 0, 4);
 
         if (mByteOrder == ByteOrder.BIG_ENDIAN) {
-            return (tmpBuf[3] & 0xff) | ((tmpBuf[2] & 0xff) << 8) |
-                   ((tmpBuf[1] & 0xff) << 16) | ((tmpBuf[0] & 0xff) << 24);
+            return (tmpBuf[3] & 0xff)
+                    | ((tmpBuf[2] & 0xff) << 8)
+                    | ((tmpBuf[1] & 0xff) << 16)
+                    | ((tmpBuf[0] & 0xff) << 24);
         } else {
-            return (tmpBuf[0] & 0xff) | ((tmpBuf[1] & 0xff) << 8) |
-                   ((tmpBuf[2] & 0xff) << 16) | ((tmpBuf[3] & 0xff) << 24);
+            return (tmpBuf[0] & 0xff)
+                    | ((tmpBuf[1] & 0xff) << 8)
+                    | ((tmpBuf[2] & 0xff) << 16)
+                    | ((tmpBuf[3] & 0xff) << 24);
         }
     }
 
     /**
-     * Reads a variable-length unsigned LEB128 value.  Does not attempt to
-     * verify that the value is valid.
+     * Reads a variable-length unsigned LEB128 value. Does not attempt to verify that the value is
+     * valid.
      *
      * @throws EOFException if we run off the end of the file
      */
@@ -504,14 +476,15 @@
     /**
      * Reads a UTF-8 string.
      *
-     * We don't know how long the UTF-8 string is, so we try to read the worst case amount of bytes.
+     * <p>We don't know how long the UTF-8 string is, so we try to read the worst case amount of
+     * bytes.
      *
-     * Note that the dex file pointer will likely be at a wrong location after this operation, which
-     * means it can't be used in the middle of sequential reads.
+     * <p>Note that the dex file pointer will likely be at a wrong location after this operation,
+     * which means it can't be used in the middle of sequential reads.
      */
     String readString() throws IOException {
         int utf16len = readUnsignedLeb128();
-        byte inBuf[] = new byte[utf16len * 3];      // worst case
+        byte inBuf[] = new byte[utf16len * 3]; // worst case
 
         int bytesRead = mDexFile.read(inBuf);
         for (int i = 0; i < bytesRead; i++) {
@@ -530,9 +503,7 @@
      * =======================================================================
      */
 
-    /**
-     * Holds the contents of a header_item.
-     */
+    /** Holds the contents of a header_item. */
     static class HeaderItem {
         public int fileSize;
         public int headerSize;
@@ -546,7 +517,7 @@
 
         /* expected magic values */
         public static final byte[] DEX_FILE_MAGIC_v035 =
-            "dex\n035\0".getBytes(StandardCharsets.US_ASCII);
+                "dex\n035\0".getBytes(StandardCharsets.US_ASCII);
 
         // Dex version 036 skipped because of an old dalvik bug on some versions
         // of android where dex files with that version number would erroneously
@@ -554,15 +525,19 @@
 
         // V037 was introduced in API LEVEL 24
         public static final byte[] DEX_FILE_MAGIC_v037 =
-            "dex\n037\0".getBytes(StandardCharsets.US_ASCII);
+                "dex\n037\0".getBytes(StandardCharsets.US_ASCII);
 
         // V038 was introduced in API LEVEL 26
         public static final byte[] DEX_FILE_MAGIC_v038 =
-            "dex\n038\0".getBytes(StandardCharsets.US_ASCII);
+                "dex\n038\0".getBytes(StandardCharsets.US_ASCII);
 
         // V039 was introduced in API LEVEL 28
         public static final byte[] DEX_FILE_MAGIC_v039 =
-            "dex\n039\0".getBytes(StandardCharsets.US_ASCII);
+                "dex\n039\0".getBytes(StandardCharsets.US_ASCII);
+
+        // V041 will be introduced in API LEVEL 35
+        public static final byte[] DEX_FILE_MAGIC_v041 =
+                "dex\n041\0".getBytes(StandardCharsets.US_ASCII);
 
         public static final int ENDIAN_CONSTANT = 0x12345678;
         public static final int REVERSE_ENDIAN_CONSTANT = 0x78563412;
@@ -571,54 +546,47 @@
     /**
      * Holds the contents of a type_id_item.
      *
-     * This is chiefly a list of indices into the string table.  We need
-     * some additional bits of data, such as whether or not the type ID
-     * represents a class defined in this DEX, so we use an object for
-     * each instead of a simple integer.  (Could use a parallel array, but
-     * since this is a desktop app it's not essential.)
+     * <p>This is chiefly a list of indices into the string table. We need some additional bits of
+     * data, such as whether or not the type ID represents a class defined in this DEX, so we use an
+     * object for each instead of a simple integer. (Could use a parallel array, but since this is a
+     * desktop app it's not essential.)
      */
     static class TypeIdItem {
-        public int descriptorIdx;       // index into string_ids
+        public int descriptorIdx; // index into string_ids
 
-        public boolean internal;        // defined within this DEX file?
+        public boolean internal; // defined within this DEX file?
     }
 
-    /**
-     * Holds the contents of a proto_id_item.
-     */
+    /** Holds the contents of a proto_id_item. */
     static class ProtoIdItem {
-        public int shortyIdx;           // index into string_ids
-        public int returnTypeIdx;       // index into type_ids
-        public int parametersOff;       // file offset to a type_list
+        public int shortyIdx; // index into string_ids
+        public int returnTypeIdx; // index into type_ids
+        public int parametersOff; // file offset to a type_list
 
-        public int types[];             // contents of type list
+        public int types[]; // contents of type list
     }
 
-    /**
-     * Holds the contents of a field_id_item.
-     */
+    /** Holds the contents of a field_id_item. */
     static class FieldIdItem {
-        public int classIdx;            // index into type_ids (defining class)
-        public int typeIdx;             // index into type_ids (field type)
-        public int nameIdx;             // index into string_ids
+        public int classIdx; // index into type_ids (defining class)
+        public int typeIdx; // index into type_ids (field type)
+        public int nameIdx; // index into string_ids
     }
 
-    /**
-     * Holds the contents of a method_id_item.
-     */
+    /** Holds the contents of a method_id_item. */
     static class MethodIdItem {
-        public int classIdx;            // index into type_ids
-        public int protoIdx;            // index into proto_ids
-        public int nameIdx;             // index into string_ids
+        public int classIdx; // index into type_ids
+        public int protoIdx; // index into proto_ids
+        public int nameIdx; // index into string_ids
     }
 
     /**
      * Holds the contents of a class_def_item.
      *
-     * We don't really need a class for this, but there's some stuff in
-     * the class_def_item that we might want later.
+     * <p>We don't really need a class for this, but there's some stuff in the class_def_item that
+     * we might want later.
      */
     static class ClassDefItem {
-        public int classIdx;            // index into type_ids
+        public int classIdx; // index into type_ids
     }
 }
