changeset 17:fe828e968662

Reformatted code and removed author tags.
author Roman Kennke <roman.kennke@sun.com>
date Tue, 15 Mar 2011 23:25:43 +0100
parents 445506caa0c7
children 3a79fec307ae
files src/main/java/org/icedrobot/daneel/ClassTransformer.java src/main/java/org/icedrobot/daneel/dex/ClassData.java src/main/java/org/icedrobot/daneel/dex/ClassDef.java src/main/java/org/icedrobot/daneel/dex/Code.java src/main/java/org/icedrobot/daneel/dex/DexClassVisitor.java src/main/java/org/icedrobot/daneel/dex/DexFieldVisitor.java src/main/java/org/icedrobot/daneel/dex/DexFile.java src/main/java/org/icedrobot/daneel/dex/DexFileVisitor.java src/main/java/org/icedrobot/daneel/dex/DexMethodVisitor.java src/main/java/org/icedrobot/daneel/dex/DexReader.java src/main/java/org/icedrobot/daneel/dex/EncodedValue.java src/main/java/org/icedrobot/daneel/dex/FieldId.java src/main/java/org/icedrobot/daneel/dex/Header.java src/main/java/org/icedrobot/daneel/dex/Label.java src/main/java/org/icedrobot/daneel/dex/Main.java src/main/java/org/icedrobot/daneel/dex/MethodId.java src/main/java/org/icedrobot/daneel/dex/Opcode.java src/main/java/org/icedrobot/daneel/dex/ProtoId.java src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java src/main/java/org/icedrobot/daneel/dex/dexlib/OpcodesEncoder.java src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java src/main/java/org/icedrobot/daneel/rewriter/Main.java src/main/java/org/icedrobot/daneel/rewriter/PatchMethodVisitor.java src/main/java/org/icedrobot/daneel/rewriter/Patchable.java src/main/java/org/icedrobot/daneel/rewriter/Register.java src/main/java/org/icedrobot/daneel/rewriter/Registers.java src/main/java/org/icedrobot/daneel/util/BufferUtil.java
diffstat 28 files changed, 1387 insertions(+), 1498 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/ClassTransformer.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/ClassTransformer.java	Tue Mar 15 23:25:43 2011 +0100
@@ -29,14 +29,15 @@
     /**
      * Transforms a given class from Dalvik representation into its equivalent
      * Java bytecode representation.
+     * 
      * @param classDef The given class definition as Dalvik representation.
      * @return The generated Java bytecode representation.
      */
     public static byte[] transformClass(ClassDef classDef) {
-      ClassTransformer transformer = new ClassTransformer(classDef);
-      transformer.visitClass();
-      transformer.visitFields();
-      return transformer.visitEnd();
+        ClassTransformer transformer = new ClassTransformer(classDef);
+        transformer.visitClass();
+        transformer.visitFields();
+        return transformer.visitEnd();
     }
 
     private ClassWriter writer;
@@ -61,7 +62,8 @@
         for (int i = 0; i < classData.getStaticFieldsSize(); i++) {
             int access = classData.getStaticFieldsFlag(i);
             FieldId field = classData.getStaticFieldsId(i);
-            writer.visitField(access, field.getName(), field.getTypeDescriptor(), null, null);
+            writer.visitField(access, field.getName(),
+                    field.getTypeDescriptor(), null, null);
         }
     }
 
@@ -72,8 +74,9 @@
 
     /**
      * Converts a type descriptor for a class type into an internal class name
-     * as the ASM library expects it. For details about those type names see
-     * the "ASM 3.0 User Guide, Section 2.1.2 and 2.1.3".
+     * as the ASM library expects it. For details about those type names see the
+     * "ASM 3.0 User Guide, Section 2.1.2 and 2.1.3".
+     * 
      * @param desc The given type descriptor.
      * @return The internal class name.
      */
--- a/src/main/java/org/icedrobot/daneel/dex/ClassData.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/ClassData.java	Tue Mar 15 23:25:43 2011 +0100
@@ -27,10 +27,12 @@
     /**
      * Parses a {@code class_data_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @param staticValuesOff Offset to the list of initial values for static
-     * fields as stored in {@code class_def_item}, or 0 in case there are none.
+     *            fields as stored in {@code class_def_item}, or 0 in case there
+     *            are none.
      * @return An object representing the parsed data.
      */
     public static ClassData parse(ByteBuffer buffer, DexFile dex,
@@ -101,7 +103,8 @@
             directMethodsFlags[i] = BufferUtil.getULEB128(buffer);
             int codeOff = BufferUtil.getULEB128(buffer);
             if (codeOff != 0)
-                directMethodsCode[i] = Code.parse(dex.getDataBuffer(codeOff), dex);
+                directMethodsCode[i] = Code.parse(dex.getDataBuffer(codeOff),
+                        dex);
         }
 
         // Parse encoded_method structures in virtual_methods array.
@@ -115,7 +118,8 @@
             virtualMethodsFlags[i] = BufferUtil.getULEB128(buffer);
             int codeOff = BufferUtil.getULEB128(buffer);
             if (codeOff != 0)
-                virtualMethodsCode[i] = Code.parse(dex.getDataBuffer(codeOff), dex);
+                virtualMethodsCode[i] = Code.parse(dex.getDataBuffer(codeOff),
+                        dex);
         }
 
         // Parse encoded_array_item and contained encoded_value structures.
@@ -171,6 +175,7 @@
 
     /**
      * Allows the given visitor to visit this class data object.
+     * 
      * @param visitor The given DEX class visitor object.
      */
     public void accept(DexClassVisitor visitor) {
@@ -224,9 +229,9 @@
     private static void acceptMethod(DexClassVisitor visitor, int access,
             MethodId method, Code code) {
         ProtoId proto = method.getProtoId();
-        DexMethodVisitor dmv = visitor.visitMethod(access,
-                method.getName(), proto.getShorty(), proto.getReturnType(),
-                proto.getParameters());
+        DexMethodVisitor dmv = visitor
+                .visitMethod(access, method.getName(), proto.getShorty(),
+                        proto.getReturnType(), proto.getParameters());
         if (dmv == null)
             return;
         if (code != null)
--- a/src/main/java/org/icedrobot/daneel/dex/ClassDef.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/ClassDef.java	Tue Mar 15 23:25:43 2011 +0100
@@ -25,6 +25,7 @@
     /**
      * Parses a {@code class_def_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
@@ -102,6 +103,7 @@
 
     /**
      * Allows the given visitor to visit this class definition.
+     * 
      * @param visitor The given DEX class visitor object.
      */
     public void accept(DexClassVisitor visitor) {
--- a/src/main/java/org/icedrobot/daneel/dex/Code.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/Code.java	Tue Mar 15 23:25:43 2011 +0100
@@ -28,15 +28,15 @@
 import org.icedrobot.daneel.util.BufferUtil;
 
 /**
- * A parser class capable of parsing {@code code_item} structures as part
- * of DEX files. Keep package-private to hide internal API.
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ * A parser class capable of parsing {@code code_item} structures as part of DEX
+ * files. Keep package-private to hide internal API.
  */
 class Code {
 
     /**
      * Parses a {@code code_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
@@ -67,7 +67,7 @@
         insSize = buffer.getShort();
         outsSize = buffer.getShort();
         triesSize = buffer.getShort();
-        /*debugInfoOff =*/ buffer.getInt();
+        /* debugInfoOff = */buffer.getInt();
         insnsSize = buffer.getInt();
 
         // Keep a separate buffer for the instructions array.
@@ -121,6 +121,7 @@
 
     /**
      * Allows the given visitor to visit this code object.
+     * 
      * @param visitor The given DEX method visitor object.
      */
     public void accept(DexMethodVisitor visitor) {
@@ -134,6 +135,7 @@
     /**
      * Allows the given visitor to visit all instructions and labels contained
      * within this code object.
+     * 
      * @param v The given DEX method visitor object.
      * @throws DexParseException In case any instruction cannot be decoded.
      */
@@ -142,19 +144,19 @@
 
         // Iterate over all 16-bit code units.
         while (insns.hasRemaining()) {
-            int pos = insns.position();                   // bytecode address
-            int s1 = insns.get();                         // signed 1st short
+            int pos = insns.position(); // bytecode address
+            int s1 = insns.get(); // signed 1st short
 
             // Read and decode further code units.
-            Opcode op = Opcode.getOpcode(s1 & 0xff);      // current opcode
+            Opcode op = Opcode.getOpcode(s1 & 0xff); // current opcode
             int codeLength = OP_LENGTH[op.ordinal()];
             int s2 = (codeLength >= 2) ? insns.get() : 0; // signed 2nd short
             int s3 = (codeLength >= 3) ? insns.get() : 0; // signed 3rd short
-            int b1 = ((s1 >> 8) & 0xff);                  // unsig. 1st byte
-            int n1 = ((s1 >> 12) & 0x0f);                 // unsig. 1st nibble
-            int n2 = ((s1 >> 8) & 0x0f);                  // unsig. 2nd nibble
-            int u2 = (s2 & 0xffff);                       // unsig. 2nd short
-            int u3 = (s3 & 0xffff);                       // unsig. 3rd short
+            int b1 = ((s1 >> 8) & 0xff); // unsig. 1st byte
+            int n1 = ((s1 >> 12) & 0x0f); // unsig. 1st nibble
+            int n2 = ((s1 >> 8) & 0x0f); // unsig. 2nd nibble
+            int u2 = (s2 & 0xffff); // unsig. 2nd short
+            int u3 = (s3 & 0xffff); // unsig. 3rd short
             int b3, b4;
 
             // Local variables used within the big switch.
@@ -356,7 +358,7 @@
                 if (!(label instanceof FillArrayDataLabel))
                     throw new DexParseException("Mistyped branch target.");
                 // XXX Use fill-array-data structure once the interface
-                //     specifies how to do that.
+                // specifies how to do that.
                 v.visitInstrFillArrayData(op, b1, null);
                 break;
 
@@ -461,8 +463,8 @@
                 // Format 22c: B|A|op CCCC
                 // Syntax: op vA, vB, field@CCCC
                 field = dex.getFieldId(u2);
-                v.visitInstrField(op, n2, n1, field.getClassName(), field
-                        .getName(), field.getTypeDescriptor());
+                v.visitInstrField(op, n2, n1, field.getClassName(),
+                        field.getName(), field.getTypeDescriptor());
                 break;
 
             case SGET:
@@ -482,8 +484,8 @@
                 // Format 21c: AA|op BBBB
                 // Syntax: op vAA, field@BBBB
                 field = dex.getFieldId(u2);
-                v.visitInstrField(op, b1, 0, field.getClassName(), field
-                        .getName(), field.getTypeDescriptor());
+                v.visitInstrField(op, b1, 0, field.getClassName(),
+                        field.getName(), field.getTypeDescriptor());
                 break;
 
             case INVOKE_VIRTUAL:
@@ -508,8 +510,8 @@
                 // Syntax: op {vCCCC .. vNNNN}, meth@BBBB
                 method = dex.getMethodId(u2);
                 // XXX Don't use the shorty as type descriptor.
-                v.visitInstrMethod(op, b1, u3, 0, method.getClassName(), method
-                        .getName(), method.getProtoId().getShorty());
+                v.visitInstrMethod(op, b1, u3, 0, method.getClassName(),
+                        method.getName(), method.getProtoId().getShorty());
                 break;
 
             case CMPL_FLOAT:
@@ -631,28 +633,29 @@
     }
 
     /** The array associating bytecode instructions to their lengths. */
-    private static final int[] OP_LENGTH = new int[] {
-        1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3,
-        5, 2, 2, 3, 2, 1, 1, 2, 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3,
-        3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
-        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-    };
+    private static final int[] OP_LENGTH = new int[] { 1, 1, 2, 3, 1, 2, 3, 1,
+            2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 5, 2, 2, 3, 2, 1,
+            1, 2, 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 3, 3,
+            3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1 };
 
     /**
      * Adds a new try-catch-block information structure to our internal list.
+     * 
      * @param startLabel The start of the try block.
      * @param endLabel The end (exclusive) of the try block.
-     * @param type The type descriptor of the exception to catch or
-     * {@code null} for a catch-all handler.
+     * @param type The type descriptor of the exception to catch or {@code null}
+     *            for a catch-all handler.
      * @param handlerAddr The bytecode address of the associated exception
-     * handler, a label will be added for this address.
+     *            handler, a label will be added for this address.
      */
     private void addTryCatch(Label startLabel, Label endLabel, String type,
             int handlerAddr) {
@@ -667,6 +670,7 @@
 
     /**
      * Returns the label associated with the given bytecode position.
+     * 
      * @param pos The given bytecode position in 16-bit code units.
      * @return The associated label, never returns {@code null}.
      * @throws DexParseException In case no label can be found.
@@ -684,6 +688,7 @@
      * Adds a new label to the given bytecode position. Keep this method
      * package-private in favor of private as long as there are inner classes
      * which call it, to avoid trampoline code.
+     * 
      * @param pos The given bytecode position in 16-bit code units.
      * @return The associated label, never returns {@code null}.
      */
@@ -700,6 +705,7 @@
 
     /**
      * Adds a given label to the given bytecode position.
+     * 
      * @param pos The given bytecode position in 16-bit code units.
      * @param label The label to be associated with that position.
      * @throws DexParseException In case there already is a label.
@@ -716,8 +722,9 @@
     /**
      * Finds all branch targets by iterating over the bytecode instructions.
      * This method also parses all encountered in-code data structures.
+     * 
      * @param buffer The original buffer needed for decoding of in-code data
-     * structures.
+     *            structures.
      */
     private void findLabels(ByteBuffer buffer) {
         ShortBuffer insns = this.insns.duplicate();
@@ -815,8 +822,9 @@
     }
 
     /**
-     * Skips possible in-code data structures inside the instructions array.
-     * The given buffer will be positioned after the in-code data.
+     * Skips possible in-code data structures inside the instructions array. The
+     * given buffer will be positioned after the in-code data.
+     * 
      * @param insns The buffer for the instructions array.
      * @param pos The position at which in-code data is suspeced.
      * @return True if skipping was sucessfull, false otherwise.
@@ -832,7 +840,7 @@
             return true;
         }
         if (label instanceof FillArrayDataLabel) {
-            insns.position(pos + ((FillArrayDataLabel)label).length());
+            insns.position(pos + ((FillArrayDataLabel) label).length());
             return true;
         }
         return false;
@@ -849,6 +857,7 @@
         protected final Label endLabel;
         protected final Label handlerLabel;
         protected final String type;
+
         public TryCatchInfo(Label startLabel, Label endLabel,
                 Label handlerLabel, String type) {
             this.startLabel = startLabel;
@@ -864,6 +873,7 @@
     private class PackedSwitchLabel extends Label {
         private final int size;
         protected final Map<Integer, Label> map;
+
         public PackedSwitchLabel(ByteBuffer buffer, int pos) {
             if (buffer.getShort() != 0x0100)
                 throw new DexParseException("Unidentified in-code data.");
@@ -874,6 +884,7 @@
             for (int i = 0; i < size; i++)
                 map.put(firstKey + i, putLabel(pos + targets[i]));
         }
+
         public int length() {
             return (size * 2) + 4;
         }
@@ -885,6 +896,7 @@
     private class SparseSwitchLabel extends Label {
         private final int size;
         protected final Map<Integer, Label> map;
+
         public SparseSwitchLabel(ByteBuffer buffer, int pos) {
             if (buffer.getShort() != 0x0200)
                 throw new DexParseException("Unidentified in-code data.");
@@ -895,6 +907,7 @@
             for (int i = 0; i < size; i++)
                 map.put(keys[i], putLabel(pos + targets[i]));
         }
+
         public int length() {
             return (size * 4) + 2;
         }
@@ -907,6 +920,7 @@
         private final int elementWidth;
         private final int size;
         private final byte[] data;
+
         public FillArrayDataLabel(ByteBuffer buffer) {
             if (buffer.getShort() != 0x0300)
                 throw new DexParseException("Unidentified in-code data.");
@@ -915,6 +929,7 @@
             data = new byte[size];
             buffer.get(data, 0, size);
         }
+
         public int length() {
             return (size * elementWidth + 1) / 2 + 4;
         }
@@ -926,9 +941,11 @@
      */
     private static class DebugLabel extends Label {
         private final int pos;
+
         public DebugLabel(int pos) {
             this.pos = pos;
         }
+
         public String toString() {
             return String.format("L%03d", pos);
         }
--- a/src/main/java/org/icedrobot/daneel/dex/DexClassVisitor.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexClassVisitor.java	Tue Mar 15 23:25:43 2011 +0100
@@ -20,43 +20,44 @@
 
 /**
  * A visitor for classes contained in DEX files.
- * @author RĂ©mi Forax
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 public interface DexClassVisitor {
 
     /**
      * Visits the header of the class.
+     * 
      * @param access The access flags of the class.
      * @param name The name of the class as a type descriptor.
      * @param supername The name of the superclass as a type descriptor or
-     * {@code null} if the class has no superclass (i.e. only for definition of
-     * {@code java.lang.Object}).
+     *            {@code null} if the class has no superclass (i.e. only for
+     *            definition of {@code java.lang.Object}).
      * @param interfaces The names of implemented interfaces as type
-     * descriptors.
+     *            descriptors.
      */
     void visit(int access, String name, String supername, String[] interfaces);
 
     /**
      * Visits the source of the class.
-     * @param source The name of the file containing the original source for
-     * (at least most of) this class.
+     * 
+     * @param source The name of the file containing the original source for (at
+     *            least most of) this class.
      */
     void visitSource(String source);
 
     /**
      * Visits a field of the class. In case this visitor is interested in
-     * further details about the field (i.e. annotations) it should return a
-     * new visitor object, otherwise it should return {@code null}.
+     * further details about the field (i.e. annotations) it should return a new
+     * visitor object, otherwise it should return {@code null}.
+     * 
      * @param access The field's access flags.
      * @param name The field's name.
      * @param type The field's type as a type descriptor.
      * @param value The field's initial value. This parameter can be a boxed
-     * primitive value, a {@code String} object or {@code null} if the field
-     * does not have an initial value. Is always {@code null} for instance
-     * fields.
-     * @return A visitor object for the field or {@code null} if this visitor
-     * is not interested in details about the field.
+     *            primitive value, a {@code String} object or {@code null} if
+     *            the field does not have an initial value. Is always
+     *            {@code null} for instance fields.
+     * @return A visitor object for the field or {@code null} if this visitor is
+     *         not interested in details about the field.
      */
     DexFieldVisitor visitField(int access, String name, String type,
             Object value);
@@ -65,13 +66,14 @@
      * Visits a method of the class. In case this visitor is interested in
      * further details about the method it should return a new visitor object,
      * otherwise it should return {@code null}.
+     * 
      * @param access The method's access flags.
      * @param name The method's name.
      * @param shorty The method's prototype as a short form descriptor.
      * @param returnType The method's return type as a type descriptor.
      * @param parameterTypes The method's parameter types as type descriptors.
      * @return A visitor object for the method or {@code null} if this visitor
-     * is not interested in details about the method.
+     *         is not interested in details about the method.
      */
     DexMethodVisitor visitMethod(int access, String name, String shorty,
             String returnType, String[] parameterTypes);
--- a/src/main/java/org/icedrobot/daneel/dex/DexFieldVisitor.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFieldVisitor.java	Tue Mar 15 23:25:43 2011 +0100
@@ -20,8 +20,6 @@
 
 /**
  * A visitor for fields contained in DEX files.
- * @author RĂ©mi Forax
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 public interface DexFieldVisitor {
 
--- a/src/main/java/org/icedrobot/daneel/dex/DexFile.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFile.java	Tue Mar 15 23:25:43 2011 +0100
@@ -101,6 +101,7 @@
     /**
      * Resolves the given index value to a prototype id object. The index is
      * implicitly range-checked. Keep package-private to hide internal API.
+     * 
      * @param idx The index referring to a prototype id inside this DEX file.
      * @return The resolved prototype id object.
      */
@@ -115,6 +116,7 @@
     /**
      * Resolves the given index value to a method id object. The index is
      * implicitly range-checked. Keep package-private to hide internal API.
+     * 
      * @param idx The index referring to a method id inside this DEX file.
      * @return The resolved method id object.
      */
@@ -128,9 +130,10 @@
 
     /**
      * Provides a buffer for the data area of this DEX file. The buffer is
-     * positioned at the given offset and limited to the data area, all
-     * attempts to read outside that area will fail. Keep package-private to
-     * hide internal API.
+     * positioned at the given offset and limited to the data area, all attempts
+     * to read outside that area will fail. Keep package-private to hide
+     * internal API.
+     * 
      * @param off The offset from the start of the file into the data area.
      * @return The positioned and limited byte buffer.
      * @throws DexParseException In case the offset is outside of data area.
@@ -150,6 +153,7 @@
 
     /**
      * Allows the given visitor to visit this DEX file.
+     * 
      * @param visitor The given DEX file visitor object.
      */
     public void accept(DexFileVisitor visitor) {
--- a/src/main/java/org/icedrobot/daneel/dex/DexFileVisitor.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFileVisitor.java	Tue Mar 15 23:25:43 2011 +0100
@@ -20,8 +20,6 @@
 
 /**
  * A visitor for DEX files.
- * @author RĂ©mi Forax
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 public interface DexFileVisitor {
 
@@ -29,9 +27,10 @@
      * Visits a class of the DEX file. In case this visitor is interested in
      * further details about the class it should return a new visitor object,
      * otherwise it should return {@code null}.
+     * 
      * @param name The name of the class as a type descriptor.
-     * @return A visitor object for the class or {@code null} if this visitor
-     * is not interested in details about the class.
+     * @return A visitor object for the class or {@code null} if this visitor is
+     *         not interested in details about the class.
      */
     DexClassVisitor visitClass(String name);
 
--- a/src/main/java/org/icedrobot/daneel/dex/DexMethodVisitor.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexMethodVisitor.java	Tue Mar 15 23:25:43 2011 +0100
@@ -22,17 +22,16 @@
 
 /**
  * A visitor for methods contained in DEX files.
- * @author RĂ©mi Forax
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 public interface DexMethodVisitor {
     /**
      * Starts visiting the method's code. The code is visited by subsequent
      * calls to {@code visitLabel()} and {@code visitInstr*()} methods.
+     * 
      * @param registers The number of registers used by the code.
      * @param ins The number of words of incoming arguments to the code.
      * @param outs The number of words of outgoing argument space required by
-     * the code for method invocation.
+     *            the code for method invocation.
      */
     void visitCode(int registers, int ins, int outs);
 
@@ -40,34 +39,39 @@
      * Visits a label. The given label refers to the instruction immediately
      * following it. Labels can be used as branch targets or in try-catch
      * blocks.
+     * 
      * @param label The target of a branch.
      */
     void visitLabel(Label label);
 
     /**
      * Visits an instruction with a {@code 10x} format id.
+     * 
      * @param opcode An opcode among NOP, RETURN_VOID.
      */
     void visitInstr(Opcode opcode);
 
     /**
      * Visits an instruction with a {@code 11x} format id.
+     * 
      * @param opcode An opcode among MOVE_RESULT, MOVE_RESULT_WIDE,
-     * MOVE_RESULT_OBJECT, MOVE_EXCEPTION, RETURN, MONITOR_ENTER, MONITOR_EXIT,
-     * RETURN_WIDE, RETURN_OBJECT, THROW.
+     *            MOVE_RESULT_OBJECT, MOVE_EXCEPTION, RETURN, MONITOR_ENTER,
+     *            MONITOR_EXIT, RETURN_WIDE, RETURN_OBJECT, THROW.
      * @param srcOrDst Source or destination register or register pair.
      */
     void visitInstrOp(Opcode opcode, int srcOrDst);
 
     /**
      * Visits an instruction with a {@code 12x|22x|32x} format id.
+     * 
      * @param opcode An opcode among MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE,
-     * MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT, MOVE_OBJECT_FROM16,
-     * MOVE_OBJECT_16, NEG_INT, NOT_INT, NEG_LONG, NOT_LONG, NEG_FLOAT,
-     * NEG_DOUBLE, INT_TO_LONG, INT_TO_FLOAT, INT_TO_DOUBLE, LONG_TO_INT,
-     * LONG_TO_FLOAT, LONG_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG,
-     * DOUBLE_TO_INT, DOUBLE_TO_LONG, DOUBLE_TO_FLOAT, INT_TO_BYTE, INT_TO_CHAR,
-     * INT_TO_SHORT, ARRAY_LENGTH.
+     *            MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT,
+     *            MOVE_OBJECT_FROM16, MOVE_OBJECT_16, NEG_INT, NOT_INT,
+     *            NEG_LONG, NOT_LONG, NEG_FLOAT, NEG_DOUBLE, INT_TO_LONG,
+     *            INT_TO_FLOAT, INT_TO_DOUBLE, LONG_TO_INT, LONG_TO_FLOAT,
+     *            LONG_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG, DOUBLE_TO_INT,
+     *            DOUBLE_TO_LONG, DOUBLE_TO_FLOAT, INT_TO_BYTE, INT_TO_CHAR,
+     *            INT_TO_SHORT, ARRAY_LENGTH.
      * @param vdest Destination register or register pair.
      * @param vsrc Source register or register pair.
      */
@@ -75,20 +79,23 @@
 
     /**
      * Visits an instruction with a {@code 23x} format id.
+     * 
      * @param opcode An opcode among CMPL_FLOAT, CMPG_FLOAT, CMPL_DOUBLE,
-     * CMPG_DOUBLE, CMP_LONG, ADD_INT, SUB_INT, MUL_INT, DIV_INT, REM_INT,
-     * AND_INT, OR_INT, XOR_INT, SHL_INT, SHR_INT, USHR_INT, ADD_LONG, SUB_LONG,
-     * MUL_LONG, DIV_LONG, REM_LONG, AND_LONG, OR_LONG, XOR_LONG, SHL_LONG,
-     * SHR_LONG, USHR_LONG, ADD_FLOAT, SUB_FLOAT, MUL_FLOAT, DIV_FLOAT,
-     * REM_FLOAT, ADD_DOUBLE, SUB_DOUBLE, MUL_DOUBLE, DIV_DOUBLE, REM_DOUBLE,
-     * ADD_INT_2ADDR, SUB_INT_2ADDR, MUL_INT_2ADDR, DIV_INT_2ADDR,
-     * REM_INT_2ADDR, AND_INT_2ADDR, OR_INT_2ADDR, XOR_INT_2ADDR, SHL_INT_2ADDR,
-     * SHR_INT_2ADDR, USHR_INT_2ADDR, ADD_LONG_2ADDR, SUB_LONG_2ADDR,
-     * MUL_LONG_2ADDR, DIV_LONG_2ADDR, REM_LONG_2ADDR, AND_LONG_2ADDR,
-     * OR_LONG_2ADDR, XOR_LONG_2ADDR, SHL_LONG_2ADDR, SHR_LONG_2ADDR,
-     * USHR_LONG_2ADDR, ADD_FLOAT_2ADDR, SUB_FLOAT_2ADDR, MUL_FLOAT_2ADDR,
-     * DIV_FLOAT_2ADDR, REM_FLOAT_2ADDR, ADD_DOUBLE_2ADDR, SUB_DOUBLE_2ADDR,
-     * MUL_DOUBLE_2ADDR, DIV_DOUBLE_2ADDR, REM_DOUBLE_2ADDR.
+     *            CMPG_DOUBLE, CMP_LONG, ADD_INT, SUB_INT, MUL_INT, DIV_INT,
+     *            REM_INT, AND_INT, OR_INT, XOR_INT, SHL_INT, SHR_INT, USHR_INT,
+     *            ADD_LONG, SUB_LONG, MUL_LONG, DIV_LONG, REM_LONG, AND_LONG,
+     *            OR_LONG, XOR_LONG, SHL_LONG, SHR_LONG, USHR_LONG, ADD_FLOAT,
+     *            SUB_FLOAT, MUL_FLOAT, DIV_FLOAT, REM_FLOAT, ADD_DOUBLE,
+     *            SUB_DOUBLE, MUL_DOUBLE, DIV_DOUBLE, REM_DOUBLE, ADD_INT_2ADDR,
+     *            SUB_INT_2ADDR, MUL_INT_2ADDR, DIV_INT_2ADDR, REM_INT_2ADDR,
+     *            AND_INT_2ADDR, OR_INT_2ADDR, XOR_INT_2ADDR, SHL_INT_2ADDR,
+     *            SHR_INT_2ADDR, USHR_INT_2ADDR, ADD_LONG_2ADDR, SUB_LONG_2ADDR,
+     *            MUL_LONG_2ADDR, DIV_LONG_2ADDR, REM_LONG_2ADDR,
+     *            AND_LONG_2ADDR, OR_LONG_2ADDR, XOR_LONG_2ADDR, SHL_LONG_2ADDR,
+     *            SHR_LONG_2ADDR, USHR_LONG_2ADDR, ADD_FLOAT_2ADDR,
+     *            SUB_FLOAT_2ADDR, MUL_FLOAT_2ADDR, DIV_FLOAT_2ADDR,
+     *            REM_FLOAT_2ADDR, ADD_DOUBLE_2ADDR, SUB_DOUBLE_2ADDR,
+     *            MUL_DOUBLE_2ADDR, DIV_DOUBLE_2ADDR, REM_DOUBLE_2ADDR.
      * @param vdest Destination register or register pair.
      * @param vsrc1 First source register or register pair.
      * @param vsrc2 Second source register or register pair.
@@ -97,11 +104,13 @@
 
     /**
      * Visits an instruction with a {@code 22b|22s} format id.
+     * 
      * @param opcode An opcode among ADD_INT_LIT16, RSUB_INT_LIT16,
-     * MUL_INT_LIT16, DIV_INT_LIT16, REM_INT_LIT16, AND_INT_LIT16, OR_INT_LIT16,
-     * XOR_INT_LIT16, ADD_INT_LIT8, RSUB_INT_LIT8, MUL_INT_LIT8, DIV_INT_LIT8,
-     * REM_INT_LIT8, AND_INT_LIT8, OR_INT_LIT8, XOR_INT_LIT8, SHL_INT_LIT8,
-     * SHR_INT_LIT8, USHR_INT_LIT8.
+     *            MUL_INT_LIT16, DIV_INT_LIT16, REM_INT_LIT16, AND_INT_LIT16,
+     *            OR_INT_LIT16, XOR_INT_LIT16, ADD_INT_LIT8, RSUB_INT_LIT8,
+     *            MUL_INT_LIT8, DIV_INT_LIT8, REM_INT_LIT8, AND_INT_LIT8,
+     *            OR_INT_LIT8, XOR_INT_LIT8, SHL_INT_LIT8, SHR_INT_LIT8,
+     *            USHR_INT_LIT8.
      * @param vdest Destination register or register pair.
      * @param vsrc Source register or register pair.
      * @param value Constant literal value.
@@ -110,6 +119,7 @@
 
     /**
      * Visits an instruction with a {@code 21c|31c} format id.
+     * 
      * @param opcode An opcode among CONST_STRING, CONST_STRING_JUMBO.
      * @param vdest Destination register (no register pair).
      * @param value Constant string literal value.
@@ -118,6 +128,7 @@
 
     /**
      * Visits an instruction with a {@code 11n|21h|21s|31i} format id.
+     * 
      * @param opcode An opcode among CONST_4, CONST_16, CONST, CONST_HIGH16.
      * @param vdest Destination register (no register pair).
      * @param value Constant literal value.
@@ -126,8 +137,9 @@
 
     /**
      * Visits an instruction with a {@code 21h|21s|31i|51l} format id.
+     * 
      * @param opcode An opcode among CONST_WIDE_16, CONST_WIDE_32, CONST_WIDE,
-     * CONST_WIDE_HIGH16.
+     *            CONST_WIDE_HIGH16.
      * @param vdest Destination register pair (no single register).
      * @param value Constant literal value.
      */
@@ -135,6 +147,7 @@
 
     /**
      * Visits an instruction with a {@code 21c} format id.
+     * 
      * @param opcode An opcode among CONST_CLASS, CHECK_CAST, NEW_INSTANCE.
      * @param vdest Destination register (no register pair).
      * @param type Constant type descriptor value.
@@ -143,6 +156,7 @@
 
     /**
      * Visits an instruction with a {@code 22c} format id.
+     * 
      * @param opcode The opcode INSTANCE_OF.
      * @param vdest Destination register (no register pair).
      * @param vsrc Source register (no register pair).
@@ -152,6 +166,7 @@
 
     /**
      * Visits an instruction with a {@code 10t|20t|30t} format id.
+     * 
      * @param opcode An opcode among GOTO_32, GOTO, GOTO_16.
      * @param label The target of the branch.
      */
@@ -159,8 +174,9 @@
 
     /**
      * Visits an instruction with a {@code 21t} format id.
+     * 
      * @param opcode An opcode among IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ,
-     * IF_LEZ.
+     *            IF_LEZ.
      * @param vsrc Source register (no register pair).
      * @param label The target of the branch.
      */
@@ -168,6 +184,7 @@
 
     /**
      * Visits an instruction with a {@code 22t} format id.
+     * 
      * @param opcode An opcode among IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE.
      * @param vsrc1 First source register (no register pair).
      * @param vsrc2 Second source register (no register pair).
@@ -177,6 +194,7 @@
 
     /**
      * Visits an instruction with a {@code 31t} format id.
+     * 
      * @param opcode An opcode among PACKED_SWITCH, SPARSE_SWITCH.
      * @param vsrc Source register (no register pair).
      * @param labels The target of the branch.
@@ -185,9 +203,10 @@
 
     /**
      * Visits an instruction with a {@code 23x} format id.
+     * 
      * @param opcode An opcode among APUT, APUT_WIDE, APUT_OBJECT, APUT_BOOLEAN,
-     * APUT_BYTE, APUT_CHAR, APUT_SHORT, AGET, AGET_WIDE, AGET_OBJECT,
-     * AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT.
+     *            APUT_BYTE, APUT_CHAR, APUT_SHORT, AGET, AGET_WIDE,
+     *            AGET_OBJECT, AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT.
      * @param vsrcOrDest Source or destination register or register pair.
      * @param varray The array register.
      * @param vindex The index register.
@@ -196,11 +215,13 @@
 
     /**
      * Visits an instruction with a {@code 21c|22c} format id.
+     * 
      * @param opcode opcode among IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN,
-     * IGET_BYTE, IGET_CHAR, IGET_SHORT, IPUT, IPUT_WIDE, IPUT_OBJECT,
-     * IPUT_BOOLEAN, IPUT_BYTE, IPUT_CHAR, IPUT_SHORT, SGET, SGET_WIDE,
-     * SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT, SPUT,
-     * SPUT_WIDE, SPUT_OBJECT, SPUT_BOOLEAN, SPUT_BYTE, SPUT_CHAR, SPUT_SHORT.
+     *            IGET_BYTE, IGET_CHAR, IGET_SHORT, IPUT, IPUT_WIDE,
+     *            IPUT_OBJECT, IPUT_BOOLEAN, IPUT_BYTE, IPUT_CHAR, IPUT_SHORT,
+     *            SGET, SGET_WIDE, SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE,
+     *            SGET_CHAR, SGET_SHORT, SPUT, SPUT_WIDE, SPUT_OBJECT,
+     *            SPUT_BOOLEAN, SPUT_BYTE, SPUT_CHAR, SPUT_SHORT.
      * @param vsrcOrDest Source or destination register or register pair.
      * @param vref The object register in instance mode or 0 in static mode.
      * @param owner The field's owner as type descriptor.
@@ -212,14 +233,15 @@
 
     /**
      * Visits an instruction with a {@code 35c|3rc} format id.
+     * 
      * @param opcode An opcode among INVOKE_VIRTUAL, INVOKE_SUPER,
-     * INVOKE_DIRECT, INVOKE_STATIC, INVOKE_INTERFACE, INVOKE_VIRTUAL_RANGE,
-     * INVOKE_SUPER_RANGE, INVOKE_DIRECT_RANGE, INVOKE_STATIC_RANGE,
-     * INVOKE_INTERFACE_RANGE.
+     *            INVOKE_DIRECT, INVOKE_STATIC, INVOKE_INTERFACE,
+     *            INVOKE_VIRTUAL_RANGE, INVOKE_SUPER_RANGE, INVOKE_DIRECT_RANGE,
+     *            INVOKE_STATIC_RANGE, INVOKE_INTERFACE_RANGE.
      * @param num The number of registers involved.
      * @param va Register A in normal mode or first register in range mode.
      * @param vpacked Register D,E,F,G (4 bits each) in normal mode or 0 in
-     * range mode.
+     *            range mode.
      * @param owner The method's owner as type descriptor.
      * @param name The method's name.
      * @param desc The method's type descriptor.
@@ -229,11 +251,12 @@
 
     /**
      * Visits an instruction with a {@code 35c|3rc} format id.
+     * 
      * @param opcode An opcode among FILLED_NEW_ARRAY, FILLED_NEW_ARRAY_RANGE.
      * @param num The number of registers involved.
      * @param va Register A in normal mode or first register in range mode.
      * @param vpacked Register D,E,F,G (4 bits each) in normal mode or 0 in
-     * range mode.
+     *            range mode.
      * @param type Constant type descriptor value.
      */
     void visitInstrFilledNewArray(Opcode opcode, int num, int va, int vpacked,
@@ -241,6 +264,7 @@
 
     /**
      * Visits an instruction with a {@code 22c} format id.
+     * 
      * @param opcode The opcode NEW_ARRAY.
      * @param vdest Destination register (no register pair).
      * @param vsize The size register.
@@ -250,6 +274,7 @@
 
     /**
      * Visits an instruction with a {@code 31t} format id.
+     * 
      * @param opcode The opcode FILL_ARRAY_DATA.
      * @param vsrc The array register.
      * @param arrayData XXX Specify me!
@@ -258,11 +283,12 @@
 
     /**
      * Visits a try-catch block for the method's code.
+     * 
      * @param start The label of the handler's scope start.
      * @param end The label of the handler's scope end (exclusive).
      * @param handler The label for the actual handler code.
      * @param type The type descriptor of the exceptions this block handles or
-     * {@code null} in case it is a catch-all handler.
+     *            {@code null} in case it is a catch-all handler.
      */
     void visitTryCatch(Label start, Label end, Label handler, String type);
 
--- a/src/main/java/org/icedrobot/daneel/dex/DexReader.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexReader.java	Tue Mar 15 23:25:43 2011 +0100
@@ -1,13 +1,11 @@
 package org.icedrobot.daneel.dex;
 
-/** 
+/**
  * Common interface of DEX file reader.
- * 
- * @author Remi Forax
  */
 public interface DexReader {
-  public void accept(DexFileVisitor dv);
+    public void accept(DexFileVisitor dv);
 
-  public void accept(String className, DexClassVisitor cv)
-      throws ClassNotFoundException;
+    public void accept(String className, DexClassVisitor cv)
+            throws ClassNotFoundException;
 }
\ No newline at end of file
--- a/src/main/java/org/icedrobot/daneel/dex/EncodedValue.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/EncodedValue.java	Tue Mar 15 23:25:43 2011 +0100
@@ -21,32 +21,32 @@
 import java.nio.ByteBuffer;
 
 /**
- * A parser class capable of parsing {@code encoded_value} structures as part
- * of DEX files. Keep package-private to hide internal API.
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ * A parser class capable of parsing {@code encoded_value} structures as part of
+ * DEX files. Keep package-private to hide internal API.
  */
 class EncodedValue {
 
-    public static final int VALUE_BYTE       = 0x00;
-    public static final int VALUE_SHORT      = 0x02;
-    public static final int VALUE_CHAR       = 0x03;
-    public static final int VALUE_INT        = 0x04;
-    public static final int VALUE_LONG       = 0x06;
-    public static final int VALUE_FLOAT      = 0x10;
-    public static final int VALUE_DOUBLE     = 0x11;
-    public static final int VALUE_STRING     = 0x17;
-    public static final int VALUE_TYPE       = 0x18;
-    public static final int VALUE_FIELD      = 0x19;
-    public static final int VALUE_METHOD     = 0x1a;
-    public static final int VALUE_ENUM       = 0x1b;
-    public static final int VALUE_ARRAY      = 0x1c;
+    public static final int VALUE_BYTE = 0x00;
+    public static final int VALUE_SHORT = 0x02;
+    public static final int VALUE_CHAR = 0x03;
+    public static final int VALUE_INT = 0x04;
+    public static final int VALUE_LONG = 0x06;
+    public static final int VALUE_FLOAT = 0x10;
+    public static final int VALUE_DOUBLE = 0x11;
+    public static final int VALUE_STRING = 0x17;
+    public static final int VALUE_TYPE = 0x18;
+    public static final int VALUE_FIELD = 0x19;
+    public static final int VALUE_METHOD = 0x1a;
+    public static final int VALUE_ENUM = 0x1b;
+    public static final int VALUE_ARRAY = 0x1c;
     public static final int VALUE_ANNOTATION = 0x1d;
-    public static final int VALUE_NULL       = 0x1e;
-    public static final int VALUE_BOOLEAN    = 0x1f;
+    public static final int VALUE_NULL = 0x1e;
+    public static final int VALUE_BOOLEAN = 0x1f;
 
     /**
      * Parses a {@code encoded_value} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
@@ -90,6 +90,7 @@
 
     /**
      * Helper method for sanity checking the {@code value_arg} value.
+     * 
      * @param arg The given {@code value_arg} value.
      * @param max The maximum value allowed in this instance.
      * @throws DexParseException In case the value exceeds its boundaries.
@@ -102,6 +103,7 @@
 
     /**
      * Helper method decoding a signed (sign-extended) {@code value} array.
+     * 
      * @param buffer The buffer positioned at the array.
      * @param size The number of bytes in the array minus 1.
      * @return The decoded value.
@@ -116,6 +118,7 @@
 
     /**
      * Helper method decoding an unsigned (zero-extended) {@code value} array.
+     * 
      * @param buffer The buffer positioned at the {@code value} array.
      * @param size The number of bytes in the array minus 1.
      * @return The decoded value.
--- a/src/main/java/org/icedrobot/daneel/dex/FieldId.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/FieldId.java	Tue Mar 15 23:25:43 2011 +0100
@@ -25,6 +25,7 @@
     /**
      * Parses a {@code field_id_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
--- a/src/main/java/org/icedrobot/daneel/dex/Header.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/Header.java	Tue Mar 15 23:25:43 2011 +0100
@@ -247,8 +247,8 @@
         string.append(getChecksum());
         string.append("\n  signature: ");
         for (byte sigByte : getSignature()) {
-          string.append(Integer.toHexString(sigByte));
-          string.append(' ');
+            string.append(Integer.toHexString(sigByte));
+            string.append(' ');
         }
         string.append("\n  file size: ");
         string.append(getFileLength());
--- a/src/main/java/org/icedrobot/daneel/dex/Label.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/Label.java	Tue Mar 15 23:25:43 2011 +0100
@@ -20,7 +20,6 @@
 
 /**
  * A label referencing a certain position in Dalvik VM bytecode.
- * @author RĂ©mi Forax
  */
 public class Label {
 
--- a/src/main/java/org/icedrobot/daneel/dex/Main.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/Main.java	Tue Mar 15 23:25:43 2011 +0100
@@ -12,7 +12,8 @@
         File dexFile = new File(dexFileName);
         RandomAccessFile dexFileAccess = new RandomAccessFile(dexFile, "r");
         FileChannel dexFileChannel = dexFileAccess.getChannel();
-        ByteBuffer dexFileBuffer = dexFileChannel.map(FileChannel.MapMode.READ_ONLY, 0, dexFile.length());
+        ByteBuffer dexFileBuffer = dexFileChannel.map(
+                FileChannel.MapMode.READ_ONLY, 0, dexFile.length());
         DexFile parsedDexFile = DexFile.parse(dexFileBuffer);
         System.out.println(parsedDexFile);
     }
--- a/src/main/java/org/icedrobot/daneel/dex/MethodId.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/MethodId.java	Tue Mar 15 23:25:43 2011 +0100
@@ -23,13 +23,13 @@
 /**
  * A parser class capable of parsing {@code method_id_item} structures as part
  * of DEX files. Keep package-private to hide internal API.
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 class MethodId {
 
     /**
      * Parses a {@code method_id_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
--- a/src/main/java/org/icedrobot/daneel/dex/Opcode.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/Opcode.java	Tue Mar 15 23:25:43 2011 +0100
@@ -20,264 +20,77 @@
 
 /**
  * Enumeration of all opcodes available in Dalvik VM bytecode.
- * @author RĂ©mi Forax
  */
 public enum Opcode {
-    NOP(0x00),
-    MOVE(0x01),
-    MOVE_FROM16(0x02),
-    MOVE_16(0x03),
-    MOVE_WIDE(0x04),
-    MOVE_WIDE_FROM16(0x05),
-    MOVE_WIDE_16(0x06),
-    MOVE_OBJECT(0x07),
-    MOVE_OBJECT_FROM16(0x08),
-    MOVE_OBJECT_16(0x09),
-    MOVE_RESULT(0x0a),
-    MOVE_RESULT_WIDE(0x0b),
-    MOVE_RESULT_OBJECT(0x0c),
-    MOVE_EXCEPTION(0x0d),
-    RETURN_VOID(0x0e),
-    RETURN(0x0f),
-    RETURN_WIDE(0x10),
-    RETURN_OBJECT(0x11),
-    CONST_4(0x12),
-    CONST_16(0x13),
-    CONST(0x14),
-    CONST_HIGH16(0x15),
-    CONST_WIDE_16(0x16),
-    CONST_WIDE_32(0x17),
-    CONST_WIDE(0x18),
-    CONST_WIDE_HIGH16(0x19),
-    CONST_STRING(0x1a),
-    CONST_STRING_JUMBO(0x1b),
-    CONST_CLASS(0x1c),
-    MONITOR_ENTER(0x1d),
-    MONITOR_EXIT(0x1e),
-    CHECK_CAST(0x1f),
-    INSTANCE_OF(0x20),
-    ARRAY_LENGTH(0x21),
-    NEW_INSTANCE(0x22),
-    NEW_ARRAY(0x23),
-    FILLED_NEW_ARRAY(0x24),
-    FILLED_NEW_ARRAY_RANGE(0x25),
-    FILL_ARRAY_DATA(0x26),
-    THROW(0x27),
-    GOTO(0x28),
-    GOTO_16(0x29),
-    GOTO_32(0x2a),
-    PACKED_SWITCH(0x2b),
-    SPARSE_SWITCH(0x2c),
-    CMPL_FLOAT(0x2d),
-    CMPG_FLOAT(0x2e),
-    CMPL_DOUBLE(0x2f),
-    CMPG_DOUBLE(0x30),
-    CMP_LONG(0x31),
-    IF_EQ(0x32),
-    IF_NE(0x33),
-    IF_LT(0x34),
-    IF_GE(0x35),
-    IF_GT(0x36),
-    IF_LE(0x37),
-    IF_EQZ(0x38),
-    IF_NEZ(0x39),
-    IF_LTZ(0x3a),
-    IF_GEZ(0x3b),
-    IF_GTZ(0x3c),
-    IF_LEZ(0x3d),
-    UNUSED_3E(0x3e),
-    UNUSED_3F(0x3f),
-    UNUSED_40(0x40),
-    UNUSED_41(0x41),
-    UNUSED_42(0x42),
-    UNUSED_43(0x43),
-    AGET(0x44),
-    AGET_WIDE(0x45),
-    AGET_OBJECT(0x46),
-    AGET_BOOLEAN(0x47),
-    AGET_BYTE(0x48),
-    AGET_CHAR(0x49),
-    AGET_SHORT(0x4a),
-    APUT(0x4b),
-    APUT_WIDE(0x4c),
-    APUT_OBJECT(0x4d),
-    APUT_BOOLEAN(0x4e),
-    APUT_BYTE(0x4f),
-    APUT_CHAR(0x50),
-    APUT_SHORT(0x51),
-    IGET(0x52),
-    IGET_WIDE(0x53),
-    IGET_OBJECT(0x54),
-    IGET_BOOLEAN(0x55),
-    IGET_BYTE(0x56),
-    IGET_CHAR(0x57),
-    IGET_SHORT(0x58),
-    IPUT(0x59),
-    IPUT_WIDE(0x5a),
-    IPUT_OBJECT(0x5b),
-    IPUT_BOOLEAN(0x5c),
-    IPUT_BYTE(0x5d),
-    IPUT_CHAR(0x5e),
-    IPUT_SHORT(0x5f),
-    SGET(0x60),
-    SGET_WIDE(0x61),
-    SGET_OBJECT(0x62),
-    SGET_BOOLEAN(0x63),
-    SGET_BYTE(0x64),
-    SGET_CHAR(0x65),
-    SGET_SHORT(0x66),
-    SPUT(0x67),
-    SPUT_WIDE(0x68),
-    SPUT_OBJECT(0x69),
-    SPUT_BOOLEAN(0x6a),
-    SPUT_BYTE(0x6b),
-    SPUT_CHAR(0x6c),
-    SPUT_SHORT(0x6d),
-    INVOKE_VIRTUAL(0x6e),
-    INVOKE_SUPER(0x6f),
-    INVOKE_DIRECT(0x70),
-    INVOKE_STATIC(0x71),
-    INVOKE_INTERFACE(0x72),
-    UNUSED_73(0x73),
-    INVOKE_VIRTUAL_RANGE(0x74),
-    INVOKE_SUPER_RANGE(0x75),
-    INVOKE_DIRECT_RANGE(0x76),
-    INVOKE_STATIC_RANGE(0x77),
-    INVOKE_INTERFACE_RANGE(0x78),
-    UNUSED_79(0x79),
-    UNUSED_7A(0x7a),
-    NEG_INT(0x7b),
-    NOT_INT(0x7c),
-    NEG_LONG(0x7d),
-    NOT_LONG(0x7e),
-    NEG_FLOAT(0x7f),
-    NEG_DOUBLE(0x80),
-    INT_TO_LONG(0x81),
-    INT_TO_FLOAT(0x82),
-    INT_TO_DOUBLE(0x83),
-    LONG_TO_INT(0x84),
-    LONG_TO_FLOAT(0x85),
-    LONG_TO_DOUBLE(0x86),
-    FLOAT_TO_INT(0x87),
-    FLOAT_TO_LONG(0x88),
-    FLOAT_TO_DOUBLE(0x89),
-    DOUBLE_TO_INT(0x8a),
-    DOUBLE_TO_LONG(0x8b),
-    DOUBLE_TO_FLOAT(0x8c),
-    INT_TO_BYTE(0x8d),
-    INT_TO_CHAR(0x8e),
-    INT_TO_SHORT(0x8f),
-    ADD_INT(0x90),
-    SUB_INT(0x91),
-    MUL_INT(0x92),
-    DIV_INT(0x93),
-    REM_INT(0x94),
-    AND_INT(0x95),
-    OR_INT(0x96),
-    XOR_INT(0x97),
-    SHL_INT(0x98),
-    SHR_INT(0x99),
-    USHR_INT(0x9a),
-    ADD_LONG(0x9b),
-    SUB_LONG(0x9c),
-    MUL_LONG(0x9d),
-    DIV_LONG(0x9e),
-    REM_LONG(0x9f),
-    AND_LONG(0xa0),
-    OR_LONG(0xa1),
-    XOR_LONG(0xa2),
-    SHL_LONG(0xa3),
-    SHR_LONG(0xa4),
-    USHR_LONG(0xa5),
-    ADD_FLOAT(0xa6),
-    SUB_FLOAT(0xa7),
-    MUL_FLOAT(0xa8),
-    DIV_FLOAT(0xa9),
-    REM_FLOAT(0xaa),
-    ADD_DOUBLE(0xab),
-    SUB_DOUBLE(0xac),
-    MUL_DOUBLE(0xad),
-    DIV_DOUBLE(0xae),
-    REM_DOUBLE(0xaf),
-    ADD_INT_2ADDR(0xb0),
-    SUB_INT_2ADDR(0xb1),
-    MUL_INT_2ADDR(0xb2),
-    DIV_INT_2ADDR(0xb3),
-    REM_INT_2ADDR(0xb4),
-    AND_INT_2ADDR(0xb5),
-    OR_INT_2ADDR(0xb6),
-    XOR_INT_2ADDR(0xb7),
-    SHL_INT_2ADDR(0xb8),
-    SHR_INT_2ADDR(0xb9),
-    USHR_INT_2ADDR(0xba),
-    ADD_LONG_2ADDR(0xbb),
-    SUB_LONG_2ADDR(0xbc),
-    MUL_LONG_2ADDR(0xbd),
-    DIV_LONG_2ADDR(0xbe),
-    REM_LONG_2ADDR(0xbf),
-    AND_LONG_2ADDR(0xc0),
-    OR_LONG_2ADDR(0xc1),
-    XOR_LONG_2ADDR(0xc2),
-    SHL_LONG_2ADDR(0xc3),
-    SHR_LONG_2ADDR(0xc4),
-    USHR_LONG_2ADDR(0xc5),
-    ADD_FLOAT_2ADDR(0xc6),
-    SUB_FLOAT_2ADDR(0xc7),
-    MUL_FLOAT_2ADDR(0xc8),
-    DIV_FLOAT_2ADDR(0xc9),
-    REM_FLOAT_2ADDR(0xca),
-    ADD_DOUBLE_2ADDR(0xcb),
-    SUB_DOUBLE_2ADDR(0xcc),
-    MUL_DOUBLE_2ADDR(0xcd),
-    DIV_DOUBLE_2ADDR(0xce),
-    REM_DOUBLE_2ADDR(0xcf),
-    ADD_INT_LIT16(0xd0),
-    RSUB_INT_LIT16(0xd1),
-    MUL_INT_LIT16(0xd2),
-    DIV_INT_LIT16(0xd3),
-    REM_INT_LIT16(0xd4),
-    AND_INT_LIT16(0xd5),
-    OR_INT_LIT16(0xd6),
-    XOR_INT_LIT16(0xd7),
-    ADD_INT_LIT8(0xd8),
-    RSUB_INT_LIT8(0xd9),
-    MUL_INT_LIT8(0xda),
-    DIV_INT_LIT8(0xdb),
-    REM_INT_LIT8(0xdc),
-    AND_INT_LIT8(0xdd),
-    OR_INT_LIT8(0xde),
-    XOR_INT_LIT8(0xdf),
-    SHL_INT_LIT8(0xe0),
-    SHR_INT_LIT8(0xe1),
-    USHR_INT_LIT8(0xe2),
-    IGET_VOLATILE(0xe3),
-    IPUT_VOLATILE(0xe4),
-    SGET_VOLATILE(0xe5),
-    SPUT_VOLATILE(0xe6),
-    IGET_OBJECT_VOLATILE(0xe7),
-    IGET_WIDE_VOLATILE(0xe8),
-    IPUT_WIDE_VOLATILE(0xe9),
-    SGET_WIDE_VOLATILE(0xea),
-    SPUT_WIDE_VOLATILE(0xeb),
-    UNUSED_EC(0xec),
-    UNUSED_ED(0xed),
-    EXECUTE_INLINE(0xee),
-    EXECUTE_INLINE_RANGE(0xef),
-    INVOKE_DIRECT_EMPTY(0xf0),
-    IGET_QUICK(0xf2),
-    IGET_WIDE_QUICK(0xf3),
-    IGET_OBJECT_QUICK(0xf4),
-    IPUT_QUICK(0xf5),
-    IPUT_WIDE_QUICK(0xf6),
-    IPUT_OBJECT_QUICK(0xf7),
-    INVOKE_VIRTUAL_QUICK(0xf8),
-    INVOKE_VIRTUAL_QUICK_RANGE(0xf9),
-    INVOKE_SUPER_QUICK(0xfa),
-    INVOKE_SUPER_QUICK_RANGE(0xfb),
-    IPUT_OBJECT_VOLATILE(0xfc),
-    SGET_OBJECT_VOLATILE(0xfd),
-    SPUT_OBJECT_VOLATILE(0xfe),
-    UNUSED_FF(0xff);
+    NOP(0x00), MOVE(0x01), MOVE_FROM16(0x02), MOVE_16(0x03), MOVE_WIDE(0x04), MOVE_WIDE_FROM16(
+            0x05), MOVE_WIDE_16(0x06), MOVE_OBJECT(0x07), MOVE_OBJECT_FROM16(
+            0x08), MOVE_OBJECT_16(0x09), MOVE_RESULT(0x0a), MOVE_RESULT_WIDE(
+            0x0b), MOVE_RESULT_OBJECT(0x0c), MOVE_EXCEPTION(0x0d), RETURN_VOID(
+            0x0e), RETURN(0x0f), RETURN_WIDE(0x10), RETURN_OBJECT(0x11), CONST_4(
+            0x12), CONST_16(0x13), CONST(0x14), CONST_HIGH16(0x15), CONST_WIDE_16(
+            0x16), CONST_WIDE_32(0x17), CONST_WIDE(0x18), CONST_WIDE_HIGH16(
+            0x19), CONST_STRING(0x1a), CONST_STRING_JUMBO(0x1b), CONST_CLASS(
+            0x1c), MONITOR_ENTER(0x1d), MONITOR_EXIT(0x1e), CHECK_CAST(0x1f), INSTANCE_OF(
+            0x20), ARRAY_LENGTH(0x21), NEW_INSTANCE(0x22), NEW_ARRAY(0x23), FILLED_NEW_ARRAY(
+            0x24), FILLED_NEW_ARRAY_RANGE(0x25), FILL_ARRAY_DATA(0x26), THROW(
+            0x27), GOTO(0x28), GOTO_16(0x29), GOTO_32(0x2a), PACKED_SWITCH(0x2b), SPARSE_SWITCH(
+            0x2c), CMPL_FLOAT(0x2d), CMPG_FLOAT(0x2e), CMPL_DOUBLE(0x2f), CMPG_DOUBLE(
+            0x30), CMP_LONG(0x31), IF_EQ(0x32), IF_NE(0x33), IF_LT(0x34), IF_GE(
+            0x35), IF_GT(0x36), IF_LE(0x37), IF_EQZ(0x38), IF_NEZ(0x39), IF_LTZ(
+            0x3a), IF_GEZ(0x3b), IF_GTZ(0x3c), IF_LEZ(0x3d), UNUSED_3E(0x3e), UNUSED_3F(
+            0x3f), UNUSED_40(0x40), UNUSED_41(0x41), UNUSED_42(0x42), UNUSED_43(
+            0x43), AGET(0x44), AGET_WIDE(0x45), AGET_OBJECT(0x46), AGET_BOOLEAN(
+            0x47), AGET_BYTE(0x48), AGET_CHAR(0x49), AGET_SHORT(0x4a), APUT(
+            0x4b), APUT_WIDE(0x4c), APUT_OBJECT(0x4d), APUT_BOOLEAN(0x4e), APUT_BYTE(
+            0x4f), APUT_CHAR(0x50), APUT_SHORT(0x51), IGET(0x52), IGET_WIDE(
+            0x53), IGET_OBJECT(0x54), IGET_BOOLEAN(0x55), IGET_BYTE(0x56), IGET_CHAR(
+            0x57), IGET_SHORT(0x58), IPUT(0x59), IPUT_WIDE(0x5a), IPUT_OBJECT(
+            0x5b), IPUT_BOOLEAN(0x5c), IPUT_BYTE(0x5d), IPUT_CHAR(0x5e), IPUT_SHORT(
+            0x5f), SGET(0x60), SGET_WIDE(0x61), SGET_OBJECT(0x62), SGET_BOOLEAN(
+            0x63), SGET_BYTE(0x64), SGET_CHAR(0x65), SGET_SHORT(0x66), SPUT(
+            0x67), SPUT_WIDE(0x68), SPUT_OBJECT(0x69), SPUT_BOOLEAN(0x6a), SPUT_BYTE(
+            0x6b), SPUT_CHAR(0x6c), SPUT_SHORT(0x6d), INVOKE_VIRTUAL(0x6e), INVOKE_SUPER(
+            0x6f), INVOKE_DIRECT(0x70), INVOKE_STATIC(0x71), INVOKE_INTERFACE(
+            0x72), UNUSED_73(0x73), INVOKE_VIRTUAL_RANGE(0x74), INVOKE_SUPER_RANGE(
+            0x75), INVOKE_DIRECT_RANGE(0x76), INVOKE_STATIC_RANGE(0x77), INVOKE_INTERFACE_RANGE(
+            0x78), UNUSED_79(0x79), UNUSED_7A(0x7a), NEG_INT(0x7b), NOT_INT(
+            0x7c), NEG_LONG(0x7d), NOT_LONG(0x7e), NEG_FLOAT(0x7f), NEG_DOUBLE(
+            0x80), INT_TO_LONG(0x81), INT_TO_FLOAT(0x82), INT_TO_DOUBLE(0x83), LONG_TO_INT(
+            0x84), LONG_TO_FLOAT(0x85), LONG_TO_DOUBLE(0x86), FLOAT_TO_INT(0x87), FLOAT_TO_LONG(
+            0x88), FLOAT_TO_DOUBLE(0x89), DOUBLE_TO_INT(0x8a), DOUBLE_TO_LONG(
+            0x8b), DOUBLE_TO_FLOAT(0x8c), INT_TO_BYTE(0x8d), INT_TO_CHAR(0x8e), INT_TO_SHORT(
+            0x8f), ADD_INT(0x90), SUB_INT(0x91), MUL_INT(0x92), DIV_INT(0x93), REM_INT(
+            0x94), AND_INT(0x95), OR_INT(0x96), XOR_INT(0x97), SHL_INT(0x98), SHR_INT(
+            0x99), USHR_INT(0x9a), ADD_LONG(0x9b), SUB_LONG(0x9c), MUL_LONG(
+            0x9d), DIV_LONG(0x9e), REM_LONG(0x9f), AND_LONG(0xa0), OR_LONG(0xa1), XOR_LONG(
+            0xa2), SHL_LONG(0xa3), SHR_LONG(0xa4), USHR_LONG(0xa5), ADD_FLOAT(
+            0xa6), SUB_FLOAT(0xa7), MUL_FLOAT(0xa8), DIV_FLOAT(0xa9), REM_FLOAT(
+            0xaa), ADD_DOUBLE(0xab), SUB_DOUBLE(0xac), MUL_DOUBLE(0xad), DIV_DOUBLE(
+            0xae), REM_DOUBLE(0xaf), ADD_INT_2ADDR(0xb0), SUB_INT_2ADDR(0xb1), MUL_INT_2ADDR(
+            0xb2), DIV_INT_2ADDR(0xb3), REM_INT_2ADDR(0xb4), AND_INT_2ADDR(0xb5), OR_INT_2ADDR(
+            0xb6), XOR_INT_2ADDR(0xb7), SHL_INT_2ADDR(0xb8), SHR_INT_2ADDR(0xb9), USHR_INT_2ADDR(
+            0xba), ADD_LONG_2ADDR(0xbb), SUB_LONG_2ADDR(0xbc), MUL_LONG_2ADDR(
+            0xbd), DIV_LONG_2ADDR(0xbe), REM_LONG_2ADDR(0xbf), AND_LONG_2ADDR(
+            0xc0), OR_LONG_2ADDR(0xc1), XOR_LONG_2ADDR(0xc2), SHL_LONG_2ADDR(
+            0xc3), SHR_LONG_2ADDR(0xc4), USHR_LONG_2ADDR(0xc5), ADD_FLOAT_2ADDR(
+            0xc6), SUB_FLOAT_2ADDR(0xc7), MUL_FLOAT_2ADDR(0xc8), DIV_FLOAT_2ADDR(
+            0xc9), REM_FLOAT_2ADDR(0xca), ADD_DOUBLE_2ADDR(0xcb), SUB_DOUBLE_2ADDR(
+            0xcc), MUL_DOUBLE_2ADDR(0xcd), DIV_DOUBLE_2ADDR(0xce), REM_DOUBLE_2ADDR(
+            0xcf), ADD_INT_LIT16(0xd0), RSUB_INT_LIT16(0xd1), MUL_INT_LIT16(
+            0xd2), DIV_INT_LIT16(0xd3), REM_INT_LIT16(0xd4), AND_INT_LIT16(0xd5), OR_INT_LIT16(
+            0xd6), XOR_INT_LIT16(0xd7), ADD_INT_LIT8(0xd8), RSUB_INT_LIT8(0xd9), MUL_INT_LIT8(
+            0xda), DIV_INT_LIT8(0xdb), REM_INT_LIT8(0xdc), AND_INT_LIT8(0xdd), OR_INT_LIT8(
+            0xde), XOR_INT_LIT8(0xdf), SHL_INT_LIT8(0xe0), SHR_INT_LIT8(0xe1), USHR_INT_LIT8(
+            0xe2), IGET_VOLATILE(0xe3), IPUT_VOLATILE(0xe4), SGET_VOLATILE(0xe5), SPUT_VOLATILE(
+            0xe6), IGET_OBJECT_VOLATILE(0xe7), IGET_WIDE_VOLATILE(0xe8), IPUT_WIDE_VOLATILE(
+            0xe9), SGET_WIDE_VOLATILE(0xea), SPUT_WIDE_VOLATILE(0xeb), UNUSED_EC(
+            0xec), UNUSED_ED(0xed), EXECUTE_INLINE(0xee), EXECUTE_INLINE_RANGE(
+            0xef), INVOKE_DIRECT_EMPTY(0xf0), IGET_QUICK(0xf2), IGET_WIDE_QUICK(
+            0xf3), IGET_OBJECT_QUICK(0xf4), IPUT_QUICK(0xf5), IPUT_WIDE_QUICK(
+            0xf6), IPUT_OBJECT_QUICK(0xf7), INVOKE_VIRTUAL_QUICK(0xf8), INVOKE_VIRTUAL_QUICK_RANGE(
+            0xf9), INVOKE_SUPER_QUICK(0xfa), INVOKE_SUPER_QUICK_RANGE(0xfb), IPUT_OBJECT_VOLATILE(
+            0xfc), SGET_OBJECT_VOLATILE(0xfd), SPUT_OBJECT_VOLATILE(0xfe), UNUSED_FF(
+            0xff);
 
     private final static Opcode[] OPCODES = Opcode.values();
 
--- a/src/main/java/org/icedrobot/daneel/dex/ProtoId.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/ProtoId.java	Tue Mar 15 23:25:43 2011 +0100
@@ -21,15 +21,15 @@
 import java.nio.ByteBuffer;
 
 /**
- * A parser class capable of parsing {@code proto_id_item} structures as part
- * of DEX files. Keep package-private to hide internal API.
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ * A parser class capable of parsing {@code proto_id_item} structures as part of
+ * DEX files. Keep package-private to hide internal API.
  */
 class ProtoId {
 
     /**
      * Parses a {@code proto_id_item} structure in a DEX file at the buffer's
      * current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param dex The DEX file currently being parsed.
      * @return An object representing the parsed data.
--- a/src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/dexlib/DexLibDexReader.java	Tue Mar 15 23:25:43 2011 +0100
@@ -49,284 +49,288 @@
 import org.objectweb.asm.Type;
 
 public class DexLibDexReader implements DexReader {
-  private final DexFile dex;
-  private HashMap<String,Integer> classIndexMap;
-  
-  public DexLibDexReader(File file) throws IOException {
-    dex = new DexFile(file);
-  }
-  
-  @Override
-  public void accept(DexFileVisitor dv) {
-    List<ClassDefItem> classItems = dex.ClassDefsSection.getItems();
-    for(ClassDefItem classItem: classItems) {
-      DexClassVisitor cv = dv.visitClass(asInternalName(classItem.getClassType()));
-      if (cv != null) {
-        accept(classItem, cv);
-      }
+    private final DexFile dex;
+    private HashMap<String, Integer> classIndexMap;
+
+    public DexLibDexReader(File file) throws IOException {
+        dex = new DexFile(file);
+    }
+
+    @Override
+    public void accept(DexFileVisitor dv) {
+        List<ClassDefItem> classItems = dex.ClassDefsSection.getItems();
+        for (ClassDefItem classItem : classItems) {
+            DexClassVisitor cv = dv.visitClass(asInternalName(classItem
+                    .getClassType()));
+            if (cv != null) {
+                accept(classItem, cv);
+            }
+        }
+        dv.visitEnd();
     }
-    dv.visitEnd();
-  }
-  
-  @Override
-  public void accept(String className, DexClassVisitor cv) throws ClassNotFoundException {
-    if (classIndexMap == null) {
-      HashMap<String, Integer> map = new HashMap<String,Integer>();
-      int index = 0;
-      List<ClassDefItem> classItems = dex.ClassDefsSection.getItems();
-      for(ClassDefItem classItem: classItems) {
-        map.put(asInternalName(classItem.getClassType()).replace('/', '.'), index++);
-      }
-      classIndexMap = map;
-    }
-    
-    Integer index = classIndexMap.get(className);
-    if (index == null) {
-      throw new ClassNotFoundException(className);
-    }
-    accept(dex.ClassDefsSection.getItemByIndex(index), cv);
-  }
 
-  private static void accept(ClassDefItem classItem, DexClassVisitor cv) {
-    TypeListItem interfaceListItem = classItem.getInterfaces();
-    String[] interfaces = null;
-    if (interfaceListItem != null) {
-      interfaces = new String[interfaceListItem.getTypeCount()];
-      for(int i=0; i<interfaces.length; i++) {
-        interfaces[i] = asInternalName(interfaceListItem.getTypeIdItem(i));
-      }
-    }
-    
-    cv.visit(classItem.getAccessFlags(),
-        asInternalName(classItem.getClassType()),
-        asInternalName(classItem.getSuperclass()),
-        interfaces);
-    
-    StringIdItem sourceFile = classItem.getSourceFile();
-    if (sourceFile != null) {
-      cv.visitSource(sourceFile.getStringValue());
+    @Override
+    public void accept(String className, DexClassVisitor cv)
+            throws ClassNotFoundException {
+        if (classIndexMap == null) {
+            HashMap<String, Integer> map = new HashMap<String, Integer>();
+            int index = 0;
+            List<ClassDefItem> classItems = dex.ClassDefsSection.getItems();
+            for (ClassDefItem classItem : classItems) {
+                map.put(asInternalName(classItem.getClassType()).replace('/',
+                        '.'), index++);
+            }
+            classIndexMap = map;
+        }
+
+        Integer index = classIndexMap.get(className);
+        if (index == null) {
+            throw new ClassNotFoundException(className);
+        }
+        accept(dex.ClassDefsSection.getItemByIndex(index), cv);
     }
-    
-    // outer-class
-    
-    // annotations
-    
-    // attributes
-    
-    // inner classes
-    
-    // fields
-    ClassDataItem classData = classItem.getClassData();
-    acceptField(classData.getStaticFields(), classItem.getStaticFieldInitializers(), cv);
-    acceptField(classData.getInstanceFields(), null, cv);
-    
-    // methods
-    acceptMethod(classData.getDirectMethods(), cv);
-    acceptMethod(classData.getVirtualMethods(), cv);
-    
-    cv.visitEnd();
-  }
+
+    private static void accept(ClassDefItem classItem, DexClassVisitor cv) {
+        TypeListItem interfaceListItem = classItem.getInterfaces();
+        String[] interfaces = null;
+        if (interfaceListItem != null) {
+            interfaces = new String[interfaceListItem.getTypeCount()];
+            for (int i = 0; i < interfaces.length; i++) {
+                interfaces[i] = asInternalName(interfaceListItem
+                        .getTypeIdItem(i));
+            }
+        }
+
+        cv.visit(classItem.getAccessFlags(),
+                asInternalName(classItem.getClassType()),
+                asInternalName(classItem.getSuperclass()), interfaces);
+
+        StringIdItem sourceFile = classItem.getSourceFile();
+        if (sourceFile != null) {
+            cv.visitSource(sourceFile.getStringValue());
+        }
+
+        // outer-class
+
+        // annotations
+
+        // attributes
+
+        // inner classes
+
+        // fields
+        ClassDataItem classData = classItem.getClassData();
+        acceptField(classData.getStaticFields(),
+                classItem.getStaticFieldInitializers(), cv);
+        acceptField(classData.getInstanceFields(), null, cv);
+
+        // methods
+        acceptMethod(classData.getDirectMethods(), cv);
+        acceptMethod(classData.getVirtualMethods(), cv);
+
+        cv.visitEnd();
+    }
+
+    private static String asInternalName(TypeIdItem typeIdItem) {
+        return Type.getType(typeIdItem.getTypeDescriptor()).getInternalName();
+    }
 
-  private static String asInternalName(TypeIdItem typeIdItem) {
-    return Type.getType(typeIdItem.getTypeDescriptor()).getInternalName();
-  }
-  
-  private static void acceptField(EncodedField[] fields, EncodedArrayItem staticInitItem, DexClassVisitor cv) {
-    EncodedValue[] constants = (staticInitItem == null)? null: staticInitItem.getEncodedArray().values;
-    
-    for(int i=0; i<fields.length; i++) {
-      EncodedField field = fields[i];
-      FieldIdItem fieldIdItem = field.field;
-      
-      DexFieldVisitor fv = cv.visitField(field.accessFlags, fieldIdItem.getFieldName().getStringValue(),
-          asInternalName(fieldIdItem.getFieldType()),
-          (constants == null? null: getConstant(constants[i])));
-      if (fv != null) {
-        // visit annotation
-        
-        // visit attribute
-        
-        fv.visitEnd();
-      }
+    private static void acceptField(EncodedField[] fields,
+            EncodedArrayItem staticInitItem, DexClassVisitor cv) {
+        EncodedValue[] constants = (staticInitItem == null) ? null
+                : staticInitItem.getEncodedArray().values;
+
+        for (int i = 0; i < fields.length; i++) {
+            EncodedField field = fields[i];
+            FieldIdItem fieldIdItem = field.field;
+
+            DexFieldVisitor fv = cv.visitField(field.accessFlags, fieldIdItem
+                    .getFieldName().getStringValue(),
+                    asInternalName(fieldIdItem.getFieldType()),
+                    (constants == null ? null : getConstant(constants[i])));
+            if (fv != null) {
+                // visit annotation
+
+                // visit attribute
+
+                fv.visitEnd();
+            }
+        }
     }
-  }
-  
-  private static Object getConstant(EncodedValue value) {
-    switch(value.getValueType()) {
-    case VALUE_BOOLEAN:
-      return ((BooleanEncodedValue)value).value;
-    case VALUE_BYTE:
-      return ((ByteEncodedValue)value).value;
-    case VALUE_SHORT:
-      return ((ShortEncodedValue)value).value;
-    case VALUE_CHAR:
-      return ((CharEncodedValue)value).value;
-    case VALUE_INT:
-      return ((IntEncodedValue)value).value;
-    case VALUE_LONG:
-      return ((LongEncodedValue)value).value;
-    case VALUE_FLOAT:
-      return ((FloatEncodedValue)value).value;
-    case VALUE_DOUBLE:
-      return ((DoubleEncodedValue)value).value;
-    default:
-      throw new AssertionError("invalid type "+value.getValueType());
+
+    private static Object getConstant(EncodedValue value) {
+        switch (value.getValueType()) {
+        case VALUE_BOOLEAN:
+            return ((BooleanEncodedValue) value).value;
+        case VALUE_BYTE:
+            return ((ByteEncodedValue) value).value;
+        case VALUE_SHORT:
+            return ((ShortEncodedValue) value).value;
+        case VALUE_CHAR:
+            return ((CharEncodedValue) value).value;
+        case VALUE_INT:
+            return ((IntEncodedValue) value).value;
+        case VALUE_LONG:
+            return ((LongEncodedValue) value).value;
+        case VALUE_FLOAT:
+            return ((FloatEncodedValue) value).value;
+        case VALUE_DOUBLE:
+            return ((DoubleEncodedValue) value).value;
+        default:
+            throw new AssertionError("invalid type " + value.getValueType());
+        }
     }
-  }
+
+    private static void acceptMethod(EncodedMethod[] methods, DexClassVisitor cv) {
+        for (EncodedMethod method : methods) {
+            MethodIdItem methodIdItem = method.method;
+            ProtoIdItem protoIdItem = methodIdItem.getPrototype();
 
-  private static void acceptMethod(EncodedMethod[] methods, DexClassVisitor cv) {
-    for(EncodedMethod method: methods) {
-      MethodIdItem methodIdItem = method.method;
-      ProtoIdItem protoIdItem = methodIdItem.getPrototype();
-      
-      DexMethodVisitor mv = cv.visitMethod(method.accessFlags, methodIdItem.getMethodName().getStringValue(),
-          protoIdItem.getConciseIdentity(),
-          protoIdItem.getReturnType().getTypeDescriptor(),
-          asDescriptorArray(protoIdItem));
-      if (mv != null) {
-        CodeItem codeItem = method.codeItem;
-        
-        // visit annotation default
-        
-        // visit annotation
-        
-        // visit parameter annotation
-        
-        // visit attribute
-        
-        mv.visitCode(codeItem.getRegisterCount(), -1, -1); //FIXME insSize/outSize 
-        acceptCode(codeItem, mv);
-        mv.visitEnd();
-      }
-    }
-  }
+            DexMethodVisitor mv = cv.visitMethod(method.accessFlags,
+                    methodIdItem.getMethodName().getStringValue(), protoIdItem
+                            .getConciseIdentity(), protoIdItem.getReturnType()
+                            .getTypeDescriptor(),
+                    asDescriptorArray(protoIdItem));
+            if (mv != null) {
+                CodeItem codeItem = method.codeItem;
+
+                // visit annotation default
 
-  private static String[] asDescriptorArray(ProtoIdItem protoIdItem) {
-    TypeListItem parameters = protoIdItem.getParameters();
-    if (parameters == null) {
-      return new String[0];
-    }
-    int length = parameters.getTypeCount();
-    String[] types = new String[length];
-    for(int i=0; i<length; i++) {
-      types[i] = parameters.getTypeIdItem(i).getTypeDescriptor();
+                // visit annotation
+
+                // visit parameter annotation
+
+                // visit attribute
+
+                mv.visitCode(codeItem.getRegisterCount(), -1, -1); // FIXME
+                                                                   // insSize/outSize
+                acceptCode(codeItem, mv);
+                mv.visitEnd();
+            }
+        }
     }
-    return types;
-  }
 
-  // opcode categories
-  private static final int INSTR = 0;
-  private static final int INSTR_OP = 1;
-  private static final int INSTR_UNARY_OP = 2;
-  private static final int INSTR_BIN_OP = 3;
-  private static final int INSTR_BIN_AND_LITERAL = 4;
-  private static final int INSTR_CONST_STRING = 5;
-  private static final int INSTR_CONST_U32 = 6;
-  private static final int INSTR_CONST_U64 = 7;
-  private static final int INSTR_CLASS = 8;
-  private static final int INSTR_INSTANCEOF = 9;
-  private static final int INSTR_GOTO = 10;
-  private static final int INSTR_IF_TESTZ = 11;
-  private static final int INSTR_IF_TEST = 12;
-  private static final int INSTR_SWITCH = 13;
-  private static final int INSTR_ARRAY = 14;
-  private static final int INSTR_FIELD = 15;
-  private static final int INSTR_METHOD = 16;
-  private static final int INSTR_FILLED_NEW_ARRAY = 17;
-  private static final int INSTR_NEW_ARRAY = 18;
-  private static final int INSTR_FILL_ARRAY_DATA = 19;
-  
-  private static final int[] OPCODE_CATEGORY;
-  static {  // see OpcodesEncoder
-    int[] categories = new int[256];
-    String text = "ACCCCCCCCCBBBBABBBGGGGHHHHFFIBBI"+ 
-                  "JCISRRTBKKKNNDDDDDMMMMMMLLLLLL@@"+
-                  "@@@@OOOOOOOOOOOOOOPPPPPPPPPPPPPP"+
-                  "PPPPPPPPPPPPPPQQQQQ@QQQQQ@@CCCCC"+
-                  "CCCCCCCCC@CCCCCCDDDDDDDDDDDDDDDD"+
-                  "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"+
-                  "DDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEE"+
-                  "EEE@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
-    for(int i=0; i<text.length(); i++) {
-      categories[i] = text.charAt(i) - 'A';
+    private static String[] asDescriptorArray(ProtoIdItem protoIdItem) {
+        TypeListItem parameters = protoIdItem.getParameters();
+        if (parameters == null) {
+            return new String[0];
+        }
+        int length = parameters.getTypeCount();
+        String[] types = new String[length];
+        for (int i = 0; i < length; i++) {
+            types[i] = parameters.getTypeIdItem(i).getTypeDescriptor();
+        }
+        return types;
     }
-    OPCODE_CATEGORY = categories;
-  }
-  
-  private static void acceptCode(CodeItem codeItem, DexMethodVisitor mv) {
-    Instruction[] instrs = codeItem.getInstructions();
-    for(int i=0; i<instrs.length; i++) {
-      Instruction instr = instrs[i];
-      acceptInstr(instr, mv);
-    }
-  }
+
+    // opcode categories
+    private static final int INSTR = 0;
+    private static final int INSTR_OP = 1;
+    private static final int INSTR_UNARY_OP = 2;
+    private static final int INSTR_BIN_OP = 3;
+    private static final int INSTR_BIN_AND_LITERAL = 4;
+    private static final int INSTR_CONST_STRING = 5;
+    private static final int INSTR_CONST_U32 = 6;
+    private static final int INSTR_CONST_U64 = 7;
+    private static final int INSTR_CLASS = 8;
+    private static final int INSTR_INSTANCEOF = 9;
+    private static final int INSTR_GOTO = 10;
+    private static final int INSTR_IF_TESTZ = 11;
+    private static final int INSTR_IF_TEST = 12;
+    private static final int INSTR_SWITCH = 13;
+    private static final int INSTR_ARRAY = 14;
+    private static final int INSTR_FIELD = 15;
+    private static final int INSTR_METHOD = 16;
+    private static final int INSTR_FILLED_NEW_ARRAY = 17;
+    private static final int INSTR_NEW_ARRAY = 18;
+    private static final int INSTR_FILL_ARRAY_DATA = 19;
 
-  private static void acceptInstr(Instruction instr, DexMethodVisitor mv) {
-    org.jf.dexlib.Code.Opcode dexOpcode = instr.opcode;
-    Opcode opcode = Opcode.getOpcode(dexOpcode.value);
-    switch(OPCODE_CATEGORY[dexOpcode.value]) {
-    
-    case INSTR:
-      mv.visitInstr(opcode);
-      break;
-      
-    case INSTR_FIELD: {
-        FieldIdItem field;
-        int vsrcOrDest;
-        int vref;
-        if (instr instanceof Instruction21c) {
-          Instruction21c i21c = (Instruction21c)instr;
-          field = (FieldIdItem)i21c.getReferencedItem(); 
-          vsrcOrDest = i21c.getRegisterA();
-          vref = 0; // no instance
-        } else {
-          Instruction22c i22c = (Instruction22c)instr;
-          field = (FieldIdItem)i22c.getReferencedItem(); 
-          vsrcOrDest = i22c.getRegisterA();
-          vref = i22c.getRegisterB();
+    private static final int[] OPCODE_CATEGORY;
+    static { // see OpcodesEncoder
+        int[] categories = new int[256];
+        String text = "ACCCCCCCCCBBBBABBBGGGGHHHHFFIBBI"
+                + "JCISRRTBKKKNNDDDDDMMMMMMLLLLLL@@"
+                + "@@@@OOOOOOOOOOOOOOPPPPPPPPPPPPPP"
+                + "PPPPPPPPPPPPPPQQQQQ@QQQQQ@@CCCCC"
+                + "CCCCCCCCC@CCCCCCDDDDDDDDDDDDDDDD"
+                + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+                + "DDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEE"
+                + "EEE@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
+        for (int i = 0; i < text.length(); i++) {
+            categories[i] = text.charAt(i) - 'A';
+        }
+        OPCODE_CATEGORY = categories;
+    }
+
+    private static void acceptCode(CodeItem codeItem, DexMethodVisitor mv) {
+        Instruction[] instrs = codeItem.getInstructions();
+        for (int i = 0; i < instrs.length; i++) {
+            Instruction instr = instrs[i];
+            acceptInstr(instr, mv);
         }
-        mv.visitInstrField(opcode, vsrcOrDest,
-            vref,  
-            asInternalName(field.getContainingClass()),
-            field.getFieldName().getStringValue(),
-            field.getFieldType().getTypeDescriptor());
-        break;
-      }
-    
-    case INSTR_CONST_U64: {
-        int vdest = ((SingleRegisterInstruction)instr).getRegisterA();
-        long value = ((LiteralInstruction)instr).getLiteral();
-        mv.visitInstrConstU64(opcode, vdest, value);
-        break;
     }
-    
-    case INSTR_CONST_STRING: {
-        Item<?> item = ((InstructionWithReference)instr).getReferencedItem();
-        int registerA = ((SingleRegisterInstruction)instr).getRegisterA();
-        mv.visitInstrConstString(opcode, registerA, ((StringIdItem)item).getStringValue());
-        break;
-      }
-    
-    case INSTR_METHOD: {   //TODO implement range !!!
-        Instruction35c i35c = (Instruction35c)instr;
-        MethodIdItem methodIdItem = (MethodIdItem)i35c.getReferencedItem();
-        String desc = methodIdItem.getPrototype().getPrototypeString();
-        int vpacked = i35c.getRegisterG() << 12 |
-                      i35c.getRegisterF() << 8 |
-                      i35c.getRegisterE() << 4 |
-                      i35c.getRegisterD();
-        mv.visitInstrMethod(opcode,
-            i35c.getRegCount(),
-            i35c.getRegisterA(),
-            vpacked,
-            asInternalName(methodIdItem.getContainingClass()),
-            methodIdItem.getMethodName().getStringValue(),
-            desc);
-        break;
-      }
-      
-    default:
-      throw new AssertionError("unknown category for "+dexOpcode);
+
+    private static void acceptInstr(Instruction instr, DexMethodVisitor mv) {
+        org.jf.dexlib.Code.Opcode dexOpcode = instr.opcode;
+        Opcode opcode = Opcode.getOpcode(dexOpcode.value);
+        switch (OPCODE_CATEGORY[dexOpcode.value]) {
+
+        case INSTR:
+            mv.visitInstr(opcode);
+            break;
+
+        case INSTR_FIELD: {
+            FieldIdItem field;
+            int vsrcOrDest;
+            int vref;
+            if (instr instanceof Instruction21c) {
+                Instruction21c i21c = (Instruction21c) instr;
+                field = (FieldIdItem) i21c.getReferencedItem();
+                vsrcOrDest = i21c.getRegisterA();
+                vref = 0; // no instance
+            } else {
+                Instruction22c i22c = (Instruction22c) instr;
+                field = (FieldIdItem) i22c.getReferencedItem();
+                vsrcOrDest = i22c.getRegisterA();
+                vref = i22c.getRegisterB();
+            }
+            mv.visitInstrField(opcode, vsrcOrDest, vref, asInternalName(field
+                    .getContainingClass()), field.getFieldName()
+                    .getStringValue(), field.getFieldType().getTypeDescriptor());
+            break;
+        }
+
+        case INSTR_CONST_U64: {
+            int vdest = ((SingleRegisterInstruction) instr).getRegisterA();
+            long value = ((LiteralInstruction) instr).getLiteral();
+            mv.visitInstrConstU64(opcode, vdest, value);
+            break;
+        }
+
+        case INSTR_CONST_STRING: {
+            Item<?> item = ((InstructionWithReference) instr)
+                    .getReferencedItem();
+            int registerA = ((SingleRegisterInstruction) instr).getRegisterA();
+            mv.visitInstrConstString(opcode, registerA,
+                    ((StringIdItem) item).getStringValue());
+            break;
+        }
+
+        case INSTR_METHOD: { // TODO implement range !!!
+            Instruction35c i35c = (Instruction35c) instr;
+            MethodIdItem methodIdItem = (MethodIdItem) i35c.getReferencedItem();
+            String desc = methodIdItem.getPrototype().getPrototypeString();
+            int vpacked = i35c.getRegisterG() << 12 | i35c.getRegisterF() << 8
+                    | i35c.getRegisterE() << 4 | i35c.getRegisterD();
+            mv.visitInstrMethod(opcode, i35c.getRegCount(),
+                    i35c.getRegisterA(), vpacked,
+                    asInternalName(methodIdItem.getContainingClass()),
+                    methodIdItem.getMethodName().getStringValue(), desc);
+            break;
+        }
+
+        default:
+            throw new AssertionError("unknown category for " + dexOpcode);
+        }
     }
-  }
 }
--- a/src/main/java/org/icedrobot/daneel/dex/dexlib/OpcodesEncoder.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/dexlib/OpcodesEncoder.java	Tue Mar 15 23:25:43 2011 +0100
@@ -7,135 +7,125 @@
 import static org.icedrobot.daneel.dex.Opcode.*;
 
 class OpcodesEncoder {
-  //opcode categories
-  private static final int INSTR = 0;
-  private static final int INSTR_OP = 1;
-  private static final int INSTR_UNARY_OP = 2;
-  private static final int INSTR_BIN_OP = 3;
-  private static final int INSTR_BIN_AND_LITERAL = 4;
-  private static final int INSTR_CONST_STRING = 5;
-  private static final int INSTR_CONST_U32 = 6;
-  private static final int INSTR_CONST_U64 = 7;
-  private static final int INSTR_CLASS = 8;
-  private static final int INSTR_INSTANCEOF = 9;
-  private static final int INSTR_GOTO = 10;
-  private static final int INSTR_IF_TESTZ = 11;
-  private static final int INSTR_IF_TEST = 12;
-  private static final int INSTR_SWITCH = 13;
-  private static final int INSTR_ARRAY = 14;
-  private static final int INSTR_FIELD = 15;
-  private static final int INSTR_METHOD = 16;
-  private static final int INSTR_FILLED_NEW_ARRAY = 17;
-  private static final int INSTR_NEW_ARRAY = 18;
-  private static final int INSTR_FILL_ARRAY_DATA = 19;
-  
-  public static void main(String[] args) {
-    Object[] assoc = {
-      INSTR, new Opcode[] {
-          NOP, RETURN_VOID
-      },
-      INSTR_OP, new Opcode[] {
-          MOVE_RESULT, MOVE_RESULT_WIDE,
-          MOVE_RESULT_OBJECT, MOVE_EXCEPTION, RETURN, MONITOR_ENTER, MONITOR_EXIT,
-          RETURN_WIDE, RETURN_OBJECT, THROW
-      },
-      INSTR_UNARY_OP, new Opcode[] {
-          MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE,
-          MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT, MOVE_OBJECT_FROM16,
-          MOVE_OBJECT_16, NEG_INT, NOT_INT, NEG_LONG, NOT_LONG, NEG_FLOAT,
-          NEG_DOUBLE, INT_TO_LONG, INT_TO_FLOAT, INT_TO_DOUBLE, LONG_TO_INT,
-          LONG_TO_FLOAT, LONG_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG,
-          DOUBLE_TO_INT, DOUBLE_TO_LONG, DOUBLE_TO_FLOAT, INT_TO_BYTE, INT_TO_CHAR,
-          INT_TO_SHORT, ARRAY_LENGTH
-      },
-      INSTR_BIN_OP, new Opcode[] {
-          CMPL_FLOAT, CMPG_FLOAT, CMPL_DOUBLE,
-          CMPG_DOUBLE, CMP_LONG, ADD_INT, SUB_INT, MUL_INT, DIV_INT, REM_INT,
-          AND_INT, OR_INT, XOR_INT, SHL_INT, SHR_INT, USHR_INT, ADD_LONG, SUB_LONG,
-          MUL_LONG, DIV_LONG, REM_LONG, AND_LONG, OR_LONG, XOR_LONG, SHL_LONG,
-          SHR_LONG, USHR_LONG, ADD_FLOAT, SUB_FLOAT, MUL_FLOAT, DIV_FLOAT,
-          REM_FLOAT, ADD_DOUBLE, SUB_DOUBLE, MUL_DOUBLE, DIV_DOUBLE, REM_DOUBLE,
-          ADD_INT_2ADDR, SUB_INT_2ADDR, MUL_INT_2ADDR, DIV_INT_2ADDR,
-          REM_INT_2ADDR, AND_INT_2ADDR, OR_INT_2ADDR, XOR_INT_2ADDR, SHL_INT_2ADDR,
-          SHR_INT_2ADDR, USHR_INT_2ADDR, ADD_LONG_2ADDR, SUB_LONG_2ADDR,
-          MUL_LONG_2ADDR, DIV_LONG_2ADDR, REM_LONG_2ADDR, AND_LONG_2ADDR,
-          OR_LONG_2ADDR, XOR_LONG_2ADDR, SHL_LONG_2ADDR, SHR_LONG_2ADDR,
-          USHR_LONG_2ADDR, ADD_FLOAT_2ADDR, SUB_FLOAT_2ADDR, MUL_FLOAT_2ADDR,
-          DIV_FLOAT_2ADDR, REM_FLOAT_2ADDR, ADD_DOUBLE_2ADDR, SUB_DOUBLE_2ADDR,
-          MUL_DOUBLE_2ADDR, DIV_DOUBLE_2ADDR, REM_DOUBLE_2ADDR
-      },
-      INSTR_BIN_AND_LITERAL, new Opcode[] {
-          ADD_INT_LIT16, RSUB_INT_LIT16,
-          MUL_INT_LIT16, DIV_INT_LIT16, REM_INT_LIT16, AND_INT_LIT16, OR_INT_LIT16,
-          XOR_INT_LIT16, ADD_INT_LIT8, RSUB_INT_LIT8, MUL_INT_LIT8, DIV_INT_LIT8,
-          REM_INT_LIT8, AND_INT_LIT8, OR_INT_LIT8, XOR_INT_LIT8, SHL_INT_LIT8,
-          SHR_INT_LIT8, USHR_INT_LIT8
-      },
-      INSTR_CONST_STRING, new Opcode[] {
-          CONST_STRING, CONST_STRING_JUMBO
-      },
-      INSTR_CONST_U32, new Opcode[] {
-          CONST_4, CONST_16, CONST, CONST_HIGH16
-      },
-      INSTR_CONST_U64, new Opcode[] {
-          CONST_WIDE_16, CONST_WIDE_32, CONST_WIDE, CONST_WIDE_HIGH16
-      },
-      INSTR_CLASS, new Opcode[] {
-          CONST_CLASS, CHECK_CAST, NEW_INSTANCE
-      },
-      INSTR_INSTANCEOF, new Opcode[] {
-          INSTANCE_OF
-      },
-      INSTR_GOTO, new Opcode[] {
-        GOTO_32, GOTO, GOTO_16
-      },
-      INSTR_IF_TESTZ, new Opcode[] {
-          IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ, IF_LEZ
-      },
-      INSTR_IF_TEST, new Opcode[] {
-          IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE
-      },
-      INSTR_SWITCH, new Opcode[] {
-          PACKED_SWITCH, SPARSE_SWITCH
-      },
-      INSTR_ARRAY, new Opcode[] {
-          APUT, APUT_WIDE, APUT_OBJECT, APUT_BOOLEAN,
-          APUT_BYTE, APUT_CHAR, APUT_SHORT, AGET, AGET_WIDE, AGET_OBJECT,
-          AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT
-      },
-      INSTR_FIELD, new Opcode[] {
-          IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN,
-          IGET_BYTE, IGET_CHAR, IGET_SHORT, IPUT, IPUT_WIDE, IPUT_OBJECT,
-          IPUT_BOOLEAN, IPUT_BYTE, IPUT_CHAR, IPUT_SHORT, SGET, SGET_WIDE,
-          SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT, SPUT,
-          SPUT_WIDE, SPUT_OBJECT, SPUT_BOOLEAN, SPUT_BYTE, SPUT_CHAR, SPUT_SHORT
-      },
-      INSTR_METHOD, new Opcode[] {
-          INVOKE_VIRTUAL, INVOKE_SUPER,
-          INVOKE_DIRECT, INVOKE_STATIC, INVOKE_INTERFACE, INVOKE_VIRTUAL_RANGE,
-          INVOKE_SUPER_RANGE, INVOKE_DIRECT_RANGE, INVOKE_STATIC_RANGE,
-          INVOKE_INTERFACE_RANGE
-      },
-      INSTR_FILLED_NEW_ARRAY, new Opcode[] {
-          FILLED_NEW_ARRAY, FILLED_NEW_ARRAY_RANGE
-      },
-      INSTR_NEW_ARRAY, new Opcode[] {
-          NEW_ARRAY
-      },
-      INSTR_FILL_ARRAY_DATA, new Opcode[] {
-          FILL_ARRAY_DATA
-      },
-    };
-    
-    char[] text = new char[256];
-    Arrays.fill(text, '@');
-    for(int i=0; i<assoc.length; i+=2) {
-      int category = (Integer)assoc[i];
-      Opcode[] opcodes  = (Opcode[])assoc[i+1];
-      for(Opcode opcode: opcodes) {
-        text[opcode.ordinal()] = (char)('A' + category);
-      }
+    // opcode categories
+    private static final int INSTR = 0;
+    private static final int INSTR_OP = 1;
+    private static final int INSTR_UNARY_OP = 2;
+    private static final int INSTR_BIN_OP = 3;
+    private static final int INSTR_BIN_AND_LITERAL = 4;
+    private static final int INSTR_CONST_STRING = 5;
+    private static final int INSTR_CONST_U32 = 6;
+    private static final int INSTR_CONST_U64 = 7;
+    private static final int INSTR_CLASS = 8;
+    private static final int INSTR_INSTANCEOF = 9;
+    private static final int INSTR_GOTO = 10;
+    private static final int INSTR_IF_TESTZ = 11;
+    private static final int INSTR_IF_TEST = 12;
+    private static final int INSTR_SWITCH = 13;
+    private static final int INSTR_ARRAY = 14;
+    private static final int INSTR_FIELD = 15;
+    private static final int INSTR_METHOD = 16;
+    private static final int INSTR_FILLED_NEW_ARRAY = 17;
+    private static final int INSTR_NEW_ARRAY = 18;
+    private static final int INSTR_FILL_ARRAY_DATA = 19;
+
+    public static void main(String[] args) {
+        Object[] assoc = {
+                INSTR,
+                new Opcode[] { NOP, RETURN_VOID },
+                INSTR_OP,
+                new Opcode[] { MOVE_RESULT, MOVE_RESULT_WIDE,
+                        MOVE_RESULT_OBJECT, MOVE_EXCEPTION, RETURN,
+                        MONITOR_ENTER, MONITOR_EXIT, RETURN_WIDE,
+                        RETURN_OBJECT, THROW },
+                INSTR_UNARY_OP,
+                new Opcode[] { MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE,
+                        MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT,
+                        MOVE_OBJECT_FROM16, MOVE_OBJECT_16, NEG_INT, NOT_INT,
+                        NEG_LONG, NOT_LONG, NEG_FLOAT, NEG_DOUBLE, INT_TO_LONG,
+                        INT_TO_FLOAT, INT_TO_DOUBLE, LONG_TO_INT,
+                        LONG_TO_FLOAT, LONG_TO_DOUBLE, FLOAT_TO_INT,
+                        FLOAT_TO_LONG, DOUBLE_TO_INT, DOUBLE_TO_LONG,
+                        DOUBLE_TO_FLOAT, INT_TO_BYTE, INT_TO_CHAR,
+                        INT_TO_SHORT, ARRAY_LENGTH },
+                INSTR_BIN_OP,
+                new Opcode[] { CMPL_FLOAT, CMPG_FLOAT, CMPL_DOUBLE,
+                        CMPG_DOUBLE, CMP_LONG, ADD_INT, SUB_INT, MUL_INT,
+                        DIV_INT, REM_INT, AND_INT, OR_INT, XOR_INT, SHL_INT,
+                        SHR_INT, USHR_INT, ADD_LONG, SUB_LONG, MUL_LONG,
+                        DIV_LONG, REM_LONG, AND_LONG, OR_LONG, XOR_LONG,
+                        SHL_LONG, SHR_LONG, USHR_LONG, ADD_FLOAT, SUB_FLOAT,
+                        MUL_FLOAT, DIV_FLOAT, REM_FLOAT, ADD_DOUBLE,
+                        SUB_DOUBLE, MUL_DOUBLE, DIV_DOUBLE, REM_DOUBLE,
+                        ADD_INT_2ADDR, SUB_INT_2ADDR, MUL_INT_2ADDR,
+                        DIV_INT_2ADDR, REM_INT_2ADDR, AND_INT_2ADDR,
+                        OR_INT_2ADDR, XOR_INT_2ADDR, SHL_INT_2ADDR,
+                        SHR_INT_2ADDR, USHR_INT_2ADDR, ADD_LONG_2ADDR,
+                        SUB_LONG_2ADDR, MUL_LONG_2ADDR, DIV_LONG_2ADDR,
+                        REM_LONG_2ADDR, AND_LONG_2ADDR, OR_LONG_2ADDR,
+                        XOR_LONG_2ADDR, SHL_LONG_2ADDR, SHR_LONG_2ADDR,
+                        USHR_LONG_2ADDR, ADD_FLOAT_2ADDR, SUB_FLOAT_2ADDR,
+                        MUL_FLOAT_2ADDR, DIV_FLOAT_2ADDR, REM_FLOAT_2ADDR,
+                        ADD_DOUBLE_2ADDR, SUB_DOUBLE_2ADDR, MUL_DOUBLE_2ADDR,
+                        DIV_DOUBLE_2ADDR, REM_DOUBLE_2ADDR },
+                INSTR_BIN_AND_LITERAL,
+                new Opcode[] { ADD_INT_LIT16, RSUB_INT_LIT16, MUL_INT_LIT16,
+                        DIV_INT_LIT16, REM_INT_LIT16, AND_INT_LIT16,
+                        OR_INT_LIT16, XOR_INT_LIT16, ADD_INT_LIT8,
+                        RSUB_INT_LIT8, MUL_INT_LIT8, DIV_INT_LIT8,
+                        REM_INT_LIT8, AND_INT_LIT8, OR_INT_LIT8, XOR_INT_LIT8,
+                        SHL_INT_LIT8, SHR_INT_LIT8, USHR_INT_LIT8 },
+                INSTR_CONST_STRING,
+                new Opcode[] { CONST_STRING, CONST_STRING_JUMBO },
+                INSTR_CONST_U32,
+                new Opcode[] { CONST_4, CONST_16, CONST, CONST_HIGH16 },
+                INSTR_CONST_U64,
+                new Opcode[] { CONST_WIDE_16, CONST_WIDE_32, CONST_WIDE,
+                        CONST_WIDE_HIGH16 },
+                INSTR_CLASS,
+                new Opcode[] { CONST_CLASS, CHECK_CAST, NEW_INSTANCE },
+                INSTR_INSTANCEOF,
+                new Opcode[] { INSTANCE_OF },
+                INSTR_GOTO,
+                new Opcode[] { GOTO_32, GOTO, GOTO_16 },
+                INSTR_IF_TESTZ,
+                new Opcode[] { IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ, IF_LEZ },
+                INSTR_IF_TEST,
+                new Opcode[] { IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE },
+                INSTR_SWITCH,
+                new Opcode[] { PACKED_SWITCH, SPARSE_SWITCH },
+                INSTR_ARRAY,
+                new Opcode[] { APUT, APUT_WIDE, APUT_OBJECT, APUT_BOOLEAN,
+                        APUT_BYTE, APUT_CHAR, APUT_SHORT, AGET, AGET_WIDE,
+                        AGET_OBJECT, AGET_BOOLEAN, AGET_BYTE, AGET_CHAR,
+                        AGET_SHORT },
+                INSTR_FIELD,
+                new Opcode[] { IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN,
+                        IGET_BYTE, IGET_CHAR, IGET_SHORT, IPUT, IPUT_WIDE,
+                        IPUT_OBJECT, IPUT_BOOLEAN, IPUT_BYTE, IPUT_CHAR,
+                        IPUT_SHORT, SGET, SGET_WIDE, SGET_OBJECT, SGET_BOOLEAN,
+                        SGET_BYTE, SGET_CHAR, SGET_SHORT, SPUT, SPUT_WIDE,
+                        SPUT_OBJECT, SPUT_BOOLEAN, SPUT_BYTE, SPUT_CHAR,
+                        SPUT_SHORT },
+                INSTR_METHOD,
+                new Opcode[] { INVOKE_VIRTUAL, INVOKE_SUPER, INVOKE_DIRECT,
+                        INVOKE_STATIC, INVOKE_INTERFACE, INVOKE_VIRTUAL_RANGE,
+                        INVOKE_SUPER_RANGE, INVOKE_DIRECT_RANGE,
+                        INVOKE_STATIC_RANGE, INVOKE_INTERFACE_RANGE },
+                INSTR_FILLED_NEW_ARRAY,
+                new Opcode[] { FILLED_NEW_ARRAY, FILLED_NEW_ARRAY_RANGE },
+                INSTR_NEW_ARRAY, new Opcode[] { NEW_ARRAY },
+                INSTR_FILL_ARRAY_DATA, new Opcode[] { FILL_ARRAY_DATA }, };
+
+        char[] text = new char[256];
+        Arrays.fill(text, '@');
+        for (int i = 0; i < assoc.length; i += 2) {
+            int category = (Integer) assoc[i];
+            Opcode[] opcodes = (Opcode[]) assoc[i + 1];
+            for (Opcode opcode : opcodes) {
+                text[opcode.ordinal()] = (char) ('A' + category);
+            }
+        }
+        System.out.println(new String(text));
     }
-    System.out.println(new String(text));
-  }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Tue Mar 15 23:25:43 2011 +0100
@@ -21,308 +21,341 @@
 import org.objectweb.asm.tree.VarInsnNode;
 
 public class DexRewriter implements DexClassVisitor {
-  private final ClassVisitor cv;
-  
-  public DexRewriter(ClassVisitor cv) {
-    this.cv = cv;
-  }
+    private final ClassVisitor cv;
 
-  @Override
-  public void visit(int access, String name, String supername, String[] interfaces) {
-    cv.visit(V1_6, access,
-        name,
-        null,
-        supername,
-        interfaces);
-  }
-  
-  @Override
-  public void visitSource(String source) {
-    cv.visitSource(source, null);
-  }
-  
-  @Override
-  public DexFieldVisitor visitField(int access, String name, String type, Object value) {
-    final FieldVisitor fv = cv.visitField(access, name, type, null, value);
-    if (fv == null) {
-      return null;
-    }
-    
-    return new DexFieldVisitor() {
-      @Override
-      public void visitEnd() {
-        fv.visitEnd();
-      }
-    };
-  }
-  
-  @Override
-  public DexMethodVisitor visitMethod(int access, String name, String shorty, String returnType, String[] parameterTypes) {
-    StringBuilder desc = new StringBuilder();
-    desc.append('(');
-    for(String parameterType: parameterTypes) {
-      desc.append(parameterType);
+    public DexRewriter(ClassVisitor cv) {
+        this.cv = cv;
     }
-    desc.append(')');
-    desc.append(returnType);
-    
-    MethodVisitor mv = cv.visitMethod(access, name,
-        desc.toString(),
-        null,
-        null);
-    if (mv == null) {
-      return null;
-    }
-    
-    return new MethodRewriter(mv);
-  }
-  
-  @Override
-  public void visitEnd() {
-    cv.visitEnd();
-  }
 
-  static class MethodRewriter implements DexMethodVisitor {    
-    final PatchMethodVisitor mv;
-    
-    private Interpreter interpreter;
-    private int returnRegisterType;  // type of the register used to stored the return value
-    
-    public MethodRewriter(MethodVisitor mv) {
-      this.mv = new PatchMethodVisitor(mv);
+    @Override
+    public void visit(int access, String name, String supername,
+            String[] interfaces) {
+        cv.visit(V1_6, access, name, null, supername, interfaces);
     }
-    
-    private static int getTypeFromASMType(Type type) {
-      switch(type.getSort()) {
-      case Type.BOOLEAN:
-        return BOOLEAN_TYPE;
-      case Type.BYTE:
-        return BYTE_TYPE;
-      case Type.CHAR:
-        return CHAR_TYPE;
-      case Type.SHORT:
-        return SHORT_TYPE;
-      case Type.INT:
-        return INT_TYPE;
-      case Type.LONG:
-        return LONG_TYPE;
-      case Type.FLOAT:
-        return FLOAT_TYPE;
-      case Type.DOUBLE:
-        return DOUBLE_TYPE;
-      case Type.VOID:
-        return VOID_TYPE;
-      default:
-        return OBJECT_TYPE;
-      }
-    }
-    
-    private static int getTypeFromFieldDescriptor(String descriptor) {
-      return getTypeFromASMType(Type.getType(descriptor));
-    }
-    
-    private static int getReturnTypeFromMethodDescriptor(String descriptor) {
-      return getTypeFromASMType(Type.getReturnType(descriptor));
+
+    @Override
+    public void visitSource(String source) {
+        cv.visitSource(source, null);
     }
-    
-    private static void throwNewAssertionError(Opcode opcode) {
-      throw new AssertionError("invalid opcode "+opcode);
-    }
-    
-    @Override
-    public void visitCode(int registerSize, int insSize, int outSize) {
-      mv.visitCode();
-      interpreter = new Interpreter(registerSize);
-    }
-    
+
     @Override
-    public void visitInstr(Opcode opcode) {
-      if (opcode == Opcode.RETURN_VOID) {
-        mv.visitInsn(RETURN);
-        interpreter.setDead();
-        return;
-      }
-      if (opcode == Opcode.NOP) {
-        mv.visitInsn(NOP);
-        return;
-      }
-      throwNewAssertionError(opcode);
+    public DexFieldVisitor visitField(int access, String name, String type,
+            Object value) {
+        final FieldVisitor fv = cv.visitField(access, name, type, null, value);
+        if (fv == null) {
+            return null;
+        }
+
+        return new DexFieldVisitor() {
+            @Override
+            public void visitEnd() {
+                fv.visitEnd();
+            }
+        };
     }
-    
+
     @Override
-    public void visitInstrField(Opcode opcode, int vsrcOrDest, int vref, String owner, String name, String desc) {
-      if (opcode.compareTo(Opcode.IGET)>=0 && opcode.compareTo(Opcode.IGET_SHORT)<=0) {
-        mv.visitVarInsn(ALOAD, vref);
-        mv.visitFieldInsn(GETFIELD, owner, name, desc);
-        int type = getTypeFromFieldDescriptor(desc);
-        interpreter.store(vsrcOrDest, type);
-        mv.visitVarInsn(Register.getJavaOpcode(type, ISTORE), vsrcOrDest);
-      } else
-        if (opcode.compareTo(Opcode.SGET)>=0 && opcode.compareTo(Opcode.SGET_SHORT)<=0) {
-          mv.visitFieldInsn(GETSTATIC, owner, name, desc);
-          int type = getTypeFromFieldDescriptor(desc);
-          interpreter.store(vsrcOrDest, type);
-          mv.visitVarInsn(Register.getJavaOpcode(type, ISTORE), vsrcOrDest);
-        } else
-          if (opcode.compareTo(Opcode.IPUT)>=0 && opcode.compareTo(Opcode.IPUT_SHORT)<=0) {
-            mv.visitVarInsn(ALOAD, vref);
-            int type = getTypeFromFieldDescriptor(desc);
-            mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), vsrcOrDest);
-            mv.visitFieldInsn(PUTFIELD, owner, name, desc);
-            interpreter.load(vsrcOrDest, type);
-          } else
-            if (opcode.compareTo(Opcode.SPUT)>=0 && opcode.compareTo(Opcode.SPUT_SHORT)<=0) {
-              int type = getTypeFromFieldDescriptor(desc);
-              mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), vsrcOrDest);
-              mv.visitFieldInsn(PUTSTATIC, owner, name, desc);
-              interpreter.load(vsrcOrDest, type);
-            } else {
-              throwNewAssertionError(opcode);
-            }
-    }
-    
-    @Override
-    public void visitInstrConstString(Opcode opcode, int vdest, String value) {
-      mv.visitLdcInsn(value);
-      mv.visitVarInsn(ASTORE, vdest);
-      interpreter.store(vdest, OBJECT_TYPE);
-    }
-    
-    
-    @Override
-    public void visitInstrMethod(Opcode opcode, int num, int va, int vpacked, String owner, String name, String desc) {
-      switch(opcode) {
-      case INVOKE_VIRTUAL:
-      case INVOKE_STATIC:
-      case INVOKE_SUPER:
-      case INVOKE_DIRECT:
-        int javaOpcode;
-        int[] registers = { getRegisterD(vpacked), getRegisterE(vpacked), getRegisterF(vpacked), getRegisterG(vpacked), va};
-        int r;
-        if (opcode == Opcode.INVOKE_STATIC) {
-          r = 0;
-          javaOpcode = INVOKESTATIC;
-        } else {
-          r = 1;
-          javaOpcode = (opcode == Opcode.INVOKE_SUPER)? INVOKESPECIAL:
-              (opcode == Opcode.INVOKE_DIRECT && "<init>".equals(name))? INVOKESPECIAL: INVOKEVIRTUAL;
-          int register = registers[0];
-          mv.visitVarInsn(ALOAD, register);
-          interpreter.load(register, OBJECT_TYPE);
+    public DexMethodVisitor visitMethod(int access, String name, String shorty,
+            String returnType, String[] parameterTypes) {
+        StringBuilder desc = new StringBuilder();
+        desc.append('(');
+        for (String parameterType : parameterTypes) {
+            desc.append(parameterType);
         }
-        
-        Type[] types = Type.getArgumentTypes(desc);
-        for(int i=0; i<types.length; i++) {
-          Type asmType = types[i];
-          int type = getTypeFromASMType(asmType);
-          int register = registers[r];
-          mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), register);
-          interpreter.load(register, type);
-          r += asmType.getSize();
+        desc.append(')');
+        desc.append(returnType);
+
+        MethodVisitor mv = cv.visitMethod(access, name, desc.toString(), null,
+                null);
+        if (mv == null) {
+            return null;
         }
-        mv.visitMethodInsn(javaOpcode, owner, name, desc);
-        returnRegisterType = getReturnTypeFromMethodDescriptor(desc);
-        return;
-      default:
-        throwNewAssertionError(opcode);
-      }
+
+        return new MethodRewriter(mv);
     }
 
     @Override
-    public void visitInstrConstU64(Opcode opcode, final int vdest, final long value) {
-      mv.setPatchMode();
-      mv.visitLdcInsn(value);
-      final AbstractInsnNode ldc = mv.getLastInsnNode();
-      mv.visitVarInsn(LSTORE, vdest);
-      final AbstractInsnNode lstore = mv.getLastInsnNode();
-      interpreter.storeArbitraryType(vdest, U64_TYPE, new Patchable() {
-        @Override
-        protected void patch(int registerType) {
-          if (registerType == DOUBLE_TYPE) {
-            mv.patch(ldc, new LdcInsnNode(Double.longBitsToDouble(value)));
-            mv.patch(lstore, new VarInsnNode(DSTORE, vdest));
-          }
-        }
-      });
-    }
-    
-    // unimplemented
-    @Override
-    public void visitLabel(Label label) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrArray(Opcode opcode, int vsrcOrDest, int varray, int vindex) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrBinOp(Opcode opcode, int vdest, int vsrc, int vsrc2) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrBinOpAndLiteral(Opcode opcode, int vdest, int vsrc, int value) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrClass(Opcode opcode, int vdest, String type) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrConstU32(Opcode opcode, int vdest, int value) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrFillArrayData(Opcode opcode, int vsrc, Object arrayData) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrFilledNewArray(Opcode opcode, int num, int va, int vpacked, String type) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrGoto(Opcode opcode, Label label) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrIfTest(Opcode opcode, int vsrc1, int vsrc2, Label label) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrIfTestZ(Opcode opcode, int vsrc, Label label) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrInstanceof(Opcode opcode, int vdest, int vsrc, String type) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrNewArray(Opcode opcode, int vdest, int vsize, String type) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrOp(Opcode opcode, int srcOrDst) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrSwitch(Opcode opcode, int vsrc, Map<Integer, Label> labels) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    @Override
-    public void visitInstrUnaryOp(Opcode opcode, int vdest, int vsrc) {
-      throw new UnsupportedOperationException("NYI");
-    }
-    
-    
-    @Override
     public void visitEnd() {
-      mv.visitMaxs(-1, -1);
-      mv.visitEnd();
+        cv.visitEnd();
     }
 
-    @Override
-    public void visitTryCatch(Label start, Label end, Label handler, String type) {
-        // TODO Auto-generated method stub
-        
+    static class MethodRewriter implements DexMethodVisitor {
+        final PatchMethodVisitor mv;
+
+        private Interpreter interpreter;
+        private int returnRegisterType; // type of the register used to stored
+                                        // the return value
+
+        public MethodRewriter(MethodVisitor mv) {
+            this.mv = new PatchMethodVisitor(mv);
+        }
+
+        private static int getTypeFromASMType(Type type) {
+            switch (type.getSort()) {
+            case Type.BOOLEAN:
+                return BOOLEAN_TYPE;
+            case Type.BYTE:
+                return BYTE_TYPE;
+            case Type.CHAR:
+                return CHAR_TYPE;
+            case Type.SHORT:
+                return SHORT_TYPE;
+            case Type.INT:
+                return INT_TYPE;
+            case Type.LONG:
+                return LONG_TYPE;
+            case Type.FLOAT:
+                return FLOAT_TYPE;
+            case Type.DOUBLE:
+                return DOUBLE_TYPE;
+            case Type.VOID:
+                return VOID_TYPE;
+            default:
+                return OBJECT_TYPE;
+            }
+        }
+
+        private static int getTypeFromFieldDescriptor(String descriptor) {
+            return getTypeFromASMType(Type.getType(descriptor));
+        }
+
+        private static int getReturnTypeFromMethodDescriptor(String descriptor) {
+            return getTypeFromASMType(Type.getReturnType(descriptor));
+        }
+
+        private static void throwNewAssertionError(Opcode opcode) {
+            throw new AssertionError("invalid opcode " + opcode);
+        }
+
+        @Override
+        public void visitCode(int registerSize, int insSize, int outSize) {
+            mv.visitCode();
+            interpreter = new Interpreter(registerSize);
+        }
+
+        @Override
+        public void visitInstr(Opcode opcode) {
+            if (opcode == Opcode.RETURN_VOID) {
+                mv.visitInsn(RETURN);
+                interpreter.setDead();
+                return;
+            }
+            if (opcode == Opcode.NOP) {
+                mv.visitInsn(NOP);
+                return;
+            }
+            throwNewAssertionError(opcode);
+        }
+
+        @Override
+        public void visitInstrField(Opcode opcode, int vsrcOrDest, int vref,
+                String owner, String name, String desc) {
+            if (opcode.compareTo(Opcode.IGET) >= 0
+                    && opcode.compareTo(Opcode.IGET_SHORT) <= 0) {
+                mv.visitVarInsn(ALOAD, vref);
+                mv.visitFieldInsn(GETFIELD, owner, name, desc);
+                int type = getTypeFromFieldDescriptor(desc);
+                interpreter.store(vsrcOrDest, type);
+                mv.visitVarInsn(Register.getJavaOpcode(type, ISTORE),
+                        vsrcOrDest);
+            } else if (opcode.compareTo(Opcode.SGET) >= 0
+                    && opcode.compareTo(Opcode.SGET_SHORT) <= 0) {
+                mv.visitFieldInsn(GETSTATIC, owner, name, desc);
+                int type = getTypeFromFieldDescriptor(desc);
+                interpreter.store(vsrcOrDest, type);
+                mv.visitVarInsn(Register.getJavaOpcode(type, ISTORE),
+                        vsrcOrDest);
+            } else if (opcode.compareTo(Opcode.IPUT) >= 0
+                    && opcode.compareTo(Opcode.IPUT_SHORT) <= 0) {
+                mv.visitVarInsn(ALOAD, vref);
+                int type = getTypeFromFieldDescriptor(desc);
+                mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), vsrcOrDest);
+                mv.visitFieldInsn(PUTFIELD, owner, name, desc);
+                interpreter.load(vsrcOrDest, type);
+            } else if (opcode.compareTo(Opcode.SPUT) >= 0
+                    && opcode.compareTo(Opcode.SPUT_SHORT) <= 0) {
+                int type = getTypeFromFieldDescriptor(desc);
+                mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), vsrcOrDest);
+                mv.visitFieldInsn(PUTSTATIC, owner, name, desc);
+                interpreter.load(vsrcOrDest, type);
+            } else {
+                throwNewAssertionError(opcode);
+            }
+        }
+
+        @Override
+        public void visitInstrConstString(Opcode opcode, int vdest, String value) {
+            mv.visitLdcInsn(value);
+            mv.visitVarInsn(ASTORE, vdest);
+            interpreter.store(vdest, OBJECT_TYPE);
+        }
+
+        @Override
+        public void visitInstrMethod(Opcode opcode, int num, int va,
+                int vpacked, String owner, String name, String desc) {
+            switch (opcode) {
+            case INVOKE_VIRTUAL:
+            case INVOKE_STATIC:
+            case INVOKE_SUPER:
+            case INVOKE_DIRECT:
+                int javaOpcode;
+                int[] registers = { getRegisterD(vpacked),
+                        getRegisterE(vpacked), getRegisterF(vpacked),
+                        getRegisterG(vpacked), va };
+                int r;
+                if (opcode == Opcode.INVOKE_STATIC) {
+                    r = 0;
+                    javaOpcode = INVOKESTATIC;
+                } else {
+                    r = 1;
+                    javaOpcode = (opcode == Opcode.INVOKE_SUPER) ? INVOKESPECIAL
+                            : (opcode == Opcode.INVOKE_DIRECT && "<init>"
+                                    .equals(name)) ? INVOKESPECIAL
+                                    : INVOKEVIRTUAL;
+                    int register = registers[0];
+                    mv.visitVarInsn(ALOAD, register);
+                    interpreter.load(register, OBJECT_TYPE);
+                }
+
+                Type[] types = Type.getArgumentTypes(desc);
+                for (int i = 0; i < types.length; i++) {
+                    Type asmType = types[i];
+                    int type = getTypeFromASMType(asmType);
+                    int register = registers[r];
+                    mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD),
+                            register);
+                    interpreter.load(register, type);
+                    r += asmType.getSize();
+                }
+                mv.visitMethodInsn(javaOpcode, owner, name, desc);
+                returnRegisterType = getReturnTypeFromMethodDescriptor(desc);
+                return;
+            default:
+                throwNewAssertionError(opcode);
+            }
+        }
+
+        @Override
+        public void visitInstrConstU64(Opcode opcode, final int vdest,
+                final long value) {
+            mv.setPatchMode();
+            mv.visitLdcInsn(value);
+            final AbstractInsnNode ldc = mv.getLastInsnNode();
+            mv.visitVarInsn(LSTORE, vdest);
+            final AbstractInsnNode lstore = mv.getLastInsnNode();
+            interpreter.storeArbitraryType(vdest, U64_TYPE, new Patchable() {
+                @Override
+                protected void patch(int registerType) {
+                    if (registerType == DOUBLE_TYPE) {
+                        mv.patch(ldc,
+                                new LdcInsnNode(Double.longBitsToDouble(value)));
+                        mv.patch(lstore, new VarInsnNode(DSTORE, vdest));
+                    }
+                }
+            });
+        }
+
+        // unimplemented
+        @Override
+        public void visitLabel(Label label) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrArray(Opcode opcode, int vsrcOrDest, int varray,
+                int vindex) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrBinOp(Opcode opcode, int vdest, int vsrc,
+                int vsrc2) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrBinOpAndLiteral(Opcode opcode, int vdest,
+                int vsrc, int value) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrClass(Opcode opcode, int vdest, String type) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrConstU32(Opcode opcode, int vdest, int value) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrFillArrayData(Opcode opcode, int vsrc,
+                Object arrayData) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrFilledNewArray(Opcode opcode, int num, int va,
+                int vpacked, String type) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrGoto(Opcode opcode, Label label) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrIfTest(Opcode opcode, int vsrc1, int vsrc2,
+                Label label) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrIfTestZ(Opcode opcode, int vsrc, Label label) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrInstanceof(Opcode opcode, int vdest, int vsrc,
+                String type) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrNewArray(Opcode opcode, int vdest, int vsize,
+                String type) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrOp(Opcode opcode, int srcOrDst) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrSwitch(Opcode opcode, int vsrc,
+                Map<Integer, Label> labels) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitInstrUnaryOp(Opcode opcode, int vdest, int vsrc) {
+            throw new UnsupportedOperationException("NYI");
+        }
+
+        @Override
+        public void visitEnd() {
+            mv.visitMaxs(-1, -1);
+            mv.visitEnd();
+        }
+
+        @Override
+        public void visitTryCatch(Label start, Label end, Label handler,
+                String type) {
+            // TODO Auto-generated method stub
+
+        }
     }
-  }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java	Tue Mar 15 23:25:43 2011 +0100
@@ -4,66 +4,68 @@
 import java.util.HashMap;
 
 public class Interpreter {
-  private final Register[] registers;
-  private final HashMap<Object, Register[]> joinPointMap = 
-    new HashMap<Object, Register[]>();
-  private boolean isDead;
-  
-  public Interpreter(int maxRegisters) {
-    Register[] registers = new Register[maxRegisters];
-    for(int i=0; i< maxRegisters; i++) {
-      registers[i] = new Register();
+    private final Register[] registers;
+    private final HashMap<Object, Register[]> joinPointMap = new HashMap<Object, Register[]>();
+    private boolean isDead;
+
+    public Interpreter(int maxRegisters) {
+        Register[] registers = new Register[maxRegisters];
+        for (int i = 0; i < maxRegisters; i++) {
+            registers[i] = new Register();
+        }
+        this.registers = registers;
+    }
+
+    public void load(int vregister, int expectedType) {
+        registers[vregister].load(expectedType);
+    }
+
+    public void store(int vregister, int type) {
+        registers[vregister].store(type);
+    }
+
+    public void storeArbitraryType(int vregister, int arbitraryType,
+            Patchable patchable) {
+        registers[vregister].storeArbitraryType(arbitraryType, patchable);
+    }
+
+    public void copy(int vdst, int vsrc) {
+        registers[vdst].copy(registers[vsrc]);
+    }
+
+    public void storeJoinPoint(Object label) {
+        joinPointMap.put(label, registers.clone());
     }
-    this.registers = registers;
-  }
-  
-  public void load(int vregister, int expectedType) {
-    registers[vregister].load(expectedType);
-  }
-  
-  public void store(int vregister, int type) {
-    registers[vregister].store(type);
-  }
-  
-  public void storeArbitraryType(int vregister, int arbitraryType, Patchable patchable) {
-    registers[vregister].storeArbitraryType(arbitraryType, patchable);
-  }
-  
-  public void copy(int vdst, int vsrc) {
-    registers[vdst].copy(registers[vsrc]);
-  }
-  
-  public void storeJoinPoint(Object label) {
-    joinPointMap.put(label, registers.clone());
-  }
-  
-  public Register[] getJoinPoint(Object label) {
-    return joinPointMap.get(label);
-  }
-  
-  public void setDead() {
-    this.isDead = true;
-  }
-  public boolean isDead() {
-    return isDead;
-  }
-  
-  public void merge(Register[] registers) {
-    assert this.registers.length == registers.length;
-    
-    if (isDead) {
-      System.arraycopy(registers, registers.length, this.registers, 0, registers.length);
-      isDead = false;
-      return;
+
+    public Register[] getJoinPoint(Object label) {
+        return joinPointMap.get(label);
+    }
+
+    public void setDead() {
+        this.isDead = true;
+    }
+
+    public boolean isDead() {
+        return isDead;
     }
-    
-    for(int i=0; i<registers.length; i++) {
-      this.registers[i].merge(registers[i]);
+
+    public void merge(Register[] registers) {
+        assert this.registers.length == registers.length;
+
+        if (isDead) {
+            System.arraycopy(registers, registers.length, this.registers, 0,
+                    registers.length);
+            isDead = false;
+            return;
+        }
+
+        for (int i = 0; i < registers.length; i++) {
+            this.registers[i].merge(registers[i]);
+        }
     }
-  }
-  
-  @Override
-  public String toString() {
-    return Arrays.toString(registers);
-  }
+
+    @Override
+    public String toString() {
+        return Arrays.toString(registers);
+    }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/Main.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/Main.java	Tue Mar 15 23:25:43 2011 +0100
@@ -14,31 +14,38 @@
 import org.objectweb.asm.util.CheckClassAdapter;
 
 /**
- * Run: java -cp classes:lib/smali-1.2.6.jar:lib/asm-debug-all-4.0.jar org.icedrobot.daneel.rewriter.Main HelloWorld.dex HelloWorld
+ * Run: java -cp classes:lib/smali-1.2.6.jar:lib/asm-debug-all-4.0.jar
+ * org.icedrobot.daneel.rewriter.Main HelloWorld.dex HelloWorld
  */
 public class Main {
-  public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
-    final DexReader dexReader = new DexLibDexReader(new File(args[0]));
-    
-    ClassLoader classLoader = new ClassLoader() {
-      @Override
-      protected Class<?> findClass(String name) throws ClassNotFoundException {
-        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        dexReader.accept(name, new DexRewriter(writer));
-        byte[] array = writer.toByteArray();
-        
-        CheckClassAdapter.verify(new ClassReader(array), true, new PrintWriter(System.err));
-        
-        return defineClass(name, array, 0, array.length);
-      }
-    };
-    
-    Class<?> clazz = classLoader.loadClass(args[1]);
-    Method method = clazz.getMethod("main", String[].class);
-    try {
-      method.invoke(null, (Object)Arrays.asList(args).subList(2, args.length).toArray(new String[0]));
-    } catch(InvocationTargetException e) {
-      e.getCause().printStackTrace();
+    public static void main(String[] args) throws IOException,
+            ClassNotFoundException, NoSuchMethodException,
+            IllegalAccessException {
+        final DexReader dexReader = new DexLibDexReader(new File(args[0]));
+
+        ClassLoader classLoader = new ClassLoader() {
+            @Override
+            protected Class<?> findClass(String name)
+                    throws ClassNotFoundException {
+                ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+                dexReader.accept(name, new DexRewriter(writer));
+                byte[] array = writer.toByteArray();
+
+                CheckClassAdapter.verify(new ClassReader(array), true,
+                        new PrintWriter(System.err));
+
+                return defineClass(name, array, 0, array.length);
+            }
+        };
+
+        Class<?> clazz = classLoader.loadClass(args[1]);
+        Method method = clazz.getMethod("main", String[].class);
+        try {
+            method.invoke(null,
+                    (Object) Arrays.asList(args).subList(2, args.length)
+                            .toArray(new String[0]));
+        } catch (InvocationTargetException e) {
+            e.getCause().printStackTrace();
+        }
     }
-  }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/PatchMethodVisitor.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/PatchMethodVisitor.java	Tue Mar 15 23:25:43 2011 +0100
@@ -9,226 +9,201 @@
 import org.objectweb.asm.tree.MethodNode;
 
 /**
- * A method visitor which is able to patch some of its instruction.
- * To avoid the overhead of always storing all instructions in memory,
- * to patch at least one instruction, the {@link #setPatchMode() patch mode}
- * must be activated.
+ * A method visitor which is able to patch some of its instruction. To avoid the
+ * overhead of always storing all instructions in memory, to patch at least one
+ * instruction, the {@link #setPatchMode() patch mode} must be activated.
  * 
  * By default, this method visitor delegates to the underlying method visitor
- * but if the {@link #setPatchMode() patch mode} is activated,
- * all new instructions are stored and dumped when {@link #visitMaxs(int, int)} is called.
+ * but if the {@link #setPatchMode() patch mode} is activated, all new
+ * instructions are stored and dumped when {@link #visitMaxs(int, int)} is
+ * called.
  * 
- * So if the patch mode is activated, one can get the last instruction {@link #getLastInsnNode()},
- * remember it, and replace it later using {@link #patch(AbstractInsnNode, AbstractInsnNode)}
- * with another instruction.
+ * So if the patch mode is activated, one can get the last instruction
+ * {@link #getLastInsnNode()}, remember it, and replace it later using
+ * {@link #patch(AbstractInsnNode, AbstractInsnNode)} with another instruction.
  * 
- * The methods {@link #getLastInsnNode()} and {@link #patch(AbstractInsnNode, AbstractInsnNode)}
- * can only be called is the patch mode is activated.
- * After a call to {@link #visitMaxs(int, int)}, the patch mode is deactivated.
- * 
- * @author Remi Forax
+ * The methods {@link #getLastInsnNode()} and
+ * {@link #patch(AbstractInsnNode, AbstractInsnNode)} can only be called is the
+ * patch mode is activated. After a call to {@link #visitMaxs(int, int)}, the
+ * patch mode is deactivated.
  */
 public class PatchMethodVisitor implements MethodVisitor {
-  private final MethodVisitor mv;
-  private MethodNode methodNode;
+    private final MethodVisitor mv;
+    private MethodNode methodNode;
 
-  public PatchMethodVisitor(MethodVisitor mv) {
-    this.mv = mv;
-  }
+    public PatchMethodVisitor(MethodVisitor mv) {
+        this.mv = mv;
+    }
 
-  @Override
-  public AnnotationVisitor visitAnnotationDefault() {
-    return mv.visitAnnotationDefault();
-  }
+    @Override
+    public AnnotationVisitor visitAnnotationDefault() {
+        return mv.visitAnnotationDefault();
+    }
 
-  @Override
-  public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-    return mv.visitAnnotation(desc, visible);
-  }
-
-  @Override
-  public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
-    return mv.visitParameterAnnotation(parameter, desc, visible);
-  }
+    @Override
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        return mv.visitAnnotation(desc, visible);
+    }
 
-  @Override
-  public void visitAttribute(Attribute attr) {
-    mv.visitAttribute(attr);
-  }
-
-  @Override
-  public void visitCode() {
-    mv.visitCode();
-  }
-
-  private MethodVisitor mv() {
-    return (methodNode == null)? mv: methodNode;
-  }
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(int parameter,
+            String desc, boolean visible) {
+        return mv.visitParameterAnnotation(parameter, desc, visible);
+    }
 
-  /**
-   * Switch to patch mode.
-   * If the patch mode is already activated, this method does nothing.
-   */
-  public void setPatchMode() {
-    if (methodNode == null) {
-      methodNode = new MethodNode();
+    @Override
+    public void visitAttribute(Attribute attr) {
+        mv.visitAttribute(attr);
     }
-  }
-  
-  public AbstractInsnNode getLastInsnNode() {
-    if (methodNode == null) {
-      throw new IllegalStateException("patchMode is not activated");
+
+    @Override
+    public void visitCode() {
+        mv.visitCode();
+    }
+
+    private MethodVisitor mv() {
+        return (methodNode == null) ? mv : methodNode;
     }
-    return methodNode.instructions.getLast();
-  }
-  
-  public void patch(AbstractInsnNode node, AbstractInsnNode newNode) {
-    if (methodNode == null) {
-      throw new IllegalStateException("patchMode is not activated");
+
+    /**
+     * Switch to patch mode. If the patch mode is already activated, this method
+     * does nothing.
+     */
+    public void setPatchMode() {
+        if (methodNode == null) {
+            methodNode = new MethodNode();
+        }
     }
-    methodNode.instructions.set(node, newNode);
-  }
-  
-  @Override
-  public void visitFrame(
-      int type,
-      int nLocal,
-      Object[] local,
-      int nStack,
-      Object[] stack)
-  {
-    mv().visitFrame(type, nLocal, local, nStack, stack);
-  }
+
+    public AbstractInsnNode getLastInsnNode() {
+        if (methodNode == null) {
+            throw new IllegalStateException("patchMode is not activated");
+        }
+        return methodNode.instructions.getLast();
+    }
+
+    public void patch(AbstractInsnNode node, AbstractInsnNode newNode) {
+        if (methodNode == null) {
+            throw new IllegalStateException("patchMode is not activated");
+        }
+        methodNode.instructions.set(node, newNode);
+    }
 
-  @Override
-  public void visitInsn(int opcode) {
-    mv().visitInsn(opcode);
-  }
+    @Override
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+            Object[] stack) {
+        mv().visitFrame(type, nLocal, local, nStack, stack);
+    }
 
-  @Override
-  public void visitIntInsn(int opcode, int operand) {
-    mv().visitIntInsn(opcode, operand);
-  }
+    @Override
+    public void visitInsn(int opcode) {
+        mv().visitInsn(opcode);
+    }
 
-  @Override
-  public void visitVarInsn(int opcode, int var) {
-    mv().visitVarInsn(opcode, var);
-  }
+    @Override
+    public void visitIntInsn(int opcode, int operand) {
+        mv().visitIntInsn(opcode, operand);
+    }
 
-  @Override
-  public void visitTypeInsn(int opcode, String type) {
-    mv().visitTypeInsn(opcode, type);
-  }
+    @Override
+    public void visitVarInsn(int opcode, int var) {
+        mv().visitVarInsn(opcode, var);
+    }
 
-  @Override
-  public void visitFieldInsn(
-      int opcode,
-      String owner,
-      String name,
-      String desc) {
-    mv().visitFieldInsn(opcode, owner, name, desc);
-  }
+    @Override
+    public void visitTypeInsn(int opcode, String type) {
+        mv().visitTypeInsn(opcode, type);
+    }
 
-  @Override
-  public void visitMethodInsn(
-      int opcode,
-      String owner,
-      String name,
-      String desc) {
-    mv().visitMethodInsn(opcode, owner, name, desc);
-  }
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name,
+            String desc) {
+        mv().visitFieldInsn(opcode, owner, name, desc);
+    }
 
-//  @Override
-//  public void visitInvokeDynamicInsn(
-//      String name,
-//      String desc,
-//      MethodHandle bsm,
-//      Object... bsmArgs) {
-//    mv().visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-//  }
-
-  @Override
-  public void visitJumpInsn( int opcode,  Label label) {
-    mv().visitJumpInsn(opcode, label);
-  }
+    @Override
+    public void visitMethodInsn(int opcode, String owner, String name,
+            String desc) {
+        mv().visitMethodInsn(opcode, owner, name, desc);
+    }
 
-  @Override
-  public void visitLabel( Label label) {
-    mv().visitLabel(label);
-  }
+    // @Override
+    // public void visitInvokeDynamicInsn(
+    // String name,
+    // String desc,
+    // MethodHandle bsm,
+    // Object... bsmArgs) {
+    // mv().visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+    // }
 
-  @Override
-  public void visitLdcInsn( Object cst) {
-    mv().visitLdcInsn(cst);
-  }
+    @Override
+    public void visitJumpInsn(int opcode, Label label) {
+        mv().visitJumpInsn(opcode, label);
+    }
 
-  @Override
-  public void visitIincInsn( int var,  int increment) {
-    mv().visitIincInsn(var, increment);
-  }
+    @Override
+    public void visitLabel(Label label) {
+        mv().visitLabel(label);
+    }
 
-  @Override
-  public void visitTableSwitchInsn(
-      int min,
-      int max,
-      Label dflt,
-      Label... labels) {
-    mv().visitTableSwitchInsn(min, max, dflt, labels);
-  }
+    @Override
+    public void visitLdcInsn(Object cst) {
+        mv().visitLdcInsn(cst);
+    }
+
+    @Override
+    public void visitIincInsn(int var, int increment) {
+        mv().visitIincInsn(var, increment);
+    }
 
-  @Override
-  public void visitLookupSwitchInsn(
-      Label dflt,
-      int[] keys,
-      Label[] labels) {
-    mv().visitLookupSwitchInsn(dflt, keys, labels);
-  }
+    @Override
+    public void visitTableSwitchInsn(int min, int max, Label dflt,
+            Label... labels) {
+        mv().visitTableSwitchInsn(min, max, dflt, labels);
+    }
+
+    @Override
+    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+        mv().visitLookupSwitchInsn(dflt, keys, labels);
+    }
 
-  @Override
-  public void visitMultiANewArrayInsn( String desc,  int dims) {
-    mv().visitMultiANewArrayInsn(desc, dims);
-  }
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+        mv().visitMultiANewArrayInsn(desc, dims);
+    }
 
-  @Override
-  public void visitTryCatchBlock(
-      Label start,
-      Label end,
-      Label handler,
-      String type) {
-    mv().visitTryCatchBlock(start, end, handler, type);
-  }
+    @Override
+    public void visitTryCatchBlock(Label start, Label end, Label handler,
+            String type) {
+        mv().visitTryCatchBlock(start, end, handler, type);
+    }
 
-  @Override
-  public void visitLocalVariable(
-      String name,
-      String desc,
-      String signature,
-      Label start,
-      Label end,
-      int index)
-  {
-    mv().visitLocalVariable(name, desc, signature, start, end, index);
-  }
+    @Override
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
+        mv().visitLocalVariable(name, desc, signature, start, end, index);
+    }
 
-  @Override
-  public void visitLineNumber( int line,  Label start) {
-    mv().visitLineNumber(line, start);
-  }
+    @Override
+    public void visitLineNumber(int line, Label start) {
+        mv().visitLineNumber(line, start);
+    }
 
-  @Override
-  public void visitMaxs( int maxStack,  int maxLocals) {
-    if (methodNode != null) {
-      final MethodVisitor mv = this.mv;
-      for(AbstractInsnNode insn = methodNode.instructions.getFirst(); insn != null; insn = insn.getNext()) {
-        insn.accept(mv);
-      }
-      methodNode = null;
+    @Override
+    public void visitMaxs(int maxStack, int maxLocals) {
+        if (methodNode != null) {
+            final MethodVisitor mv = this.mv;
+            for (AbstractInsnNode insn = methodNode.instructions.getFirst(); insn != null; insn = insn
+                    .getNext()) {
+                insn.accept(mv);
+            }
+            methodNode = null;
+        }
+        mv.visitMaxs(maxStack, maxLocals);
     }
-    mv.visitMaxs(maxStack, maxLocals);
-  }
 
-  @Override
-  public void visitEnd() {
-    mv.visitEnd();
-  }
+    @Override
+    public void visitEnd() {
+        mv.visitEnd();
+    }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/Patchable.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/Patchable.java	Tue Mar 15 23:25:43 2011 +0100
@@ -1,14 +1,14 @@
 package org.icedrobot.daneel.rewriter;
 
 public abstract class Patchable {
-  private boolean patchCalled;
-  
-  void doPatch(int registerType) {
-    if (patchCalled)
-      return;
-    patchCalled = true;
-    patch(registerType);
-  }
-  
-  protected abstract void patch(int registerType);
+    private boolean patchCalled;
+
+    void doPatch(int registerType) {
+        if (patchCalled)
+            return;
+        patchCalled = true;
+        patch(registerType);
+    }
+
+    protected abstract void patch(int registerType);
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/Register.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/Register.java	Tue Mar 15 23:25:43 2011 +0100
@@ -3,125 +3,129 @@
 import org.objectweb.asm.Opcodes;
 
 public class Register {
-  // the order is the same order as java bytecode IALOAD/IASTORE order (see #getJavaOpcode)
-  public static final int INT_TYPE = 0;      // signed int
-  public static final int LONG_TYPE = 1;     // signed long
-  public static final int FLOAT_TYPE = 2;    // 32 bits float
-  public static final int DOUBLE_TYPE = 3;   // 64 bits float
-  public static final int OBJECT_TYPE = 4;   // object reference
-  public static final int BYTE_TYPE = 5;     // byte or boolean
-  public static final int CHAR_TYPE = 6;     // char
-  public static final int SHORT_TYPE = 7;    // short
-  public static final int BOOLEAN_TYPE = 8;  // boolean
-  public static final int VOID_TYPE = 9;     // void, added to simplify management
+    // the order is the same order as java bytecode IALOAD/IASTORE order (see
+    // #getJavaOpcode)
+    public static final int INT_TYPE = 0; // signed int
+    public static final int LONG_TYPE = 1; // signed long
+    public static final int FLOAT_TYPE = 2; // 32 bits float
+    public static final int DOUBLE_TYPE = 3; // 64 bits float
+    public static final int OBJECT_TYPE = 4; // object reference
+    public static final int BYTE_TYPE = 5; // byte or boolean
+    public static final int CHAR_TYPE = 6; // char
+    public static final int SHORT_TYPE = 7; // short
+    public static final int BOOLEAN_TYPE = 8; // boolean
+    public static final int VOID_TYPE = 9; // void, added to simplify management
 
-  public static final int U32_TYPE = -1;      // arbitrary 32bits constant
-  public static final int U64_TYPE = -2;      // arbitrary 64bits constant
-  
-  public static final int NO_TYPE = -3;       // unassigned register
+    public static final int U32_TYPE = -1; // arbitrary 32bits constant
+    public static final int U64_TYPE = -2; // arbitrary 64bits constant
+
+    public static final int NO_TYPE = -3; // unassigned register
 
-  private static final int ARBITRARY_MASK = Integer.MIN_VALUE;
+    private static final int ARBITRARY_MASK = Integer.MIN_VALUE;
 
-  private int type;
+    private int type;
 
-  private Patchable patchable;
+    private Patchable patchable;
 
-  Register() {
-    type = NO_TYPE;
-    // and patchable == null
-  }
-  
-  public void load(int expectedType) {
-    assert (expectedType & ARBITRARY_MASK) == 0;
+    Register() {
+        type = NO_TYPE;
+        // and patchable == null
+    }
 
-    if ((this.type & ARBITRARY_MASK) != 0 && patchable != null) {
-      patchable.doPatch(expectedType);
-      patchable = null;
-    }
-    this.type = expectedType;
-  }
+    public void load(int expectedType) {
+        assert (expectedType & ARBITRARY_MASK) == 0;
 
-  public void store(int type) {
-    this.type = type;
-    this.patchable = null;
-  }
-
-  public void storeArbitraryType(int arbitraryType, Patchable patchable) {
-    this.type = arbitraryType;
-    this.patchable = patchable;
-  }
+        if ((this.type & ARBITRARY_MASK) != 0 && patchable != null) {
+            patchable.doPatch(expectedType);
+            patchable = null;
+        }
+        this.type = expectedType;
+    }
 
-  public void copy(Register register) {
-    this.type = register.type;
-    this.patchable = register.patchable;
-  }
-  
-  public void merge(Register register) {
-    int thisType = this.type;
-    int registerType = register.type;
-    if (thisType == registerType) {  // short cut
-      return;
+    public void store(int type) {
+        this.type = type;
+        this.patchable = null;
+    }
+
+    public void storeArbitraryType(int arbitraryType, Patchable patchable) {
+        this.type = arbitraryType;
+        this.patchable = patchable;
+    }
+
+    public void copy(Register register) {
+        this.type = register.type;
+        this.patchable = register.patchable;
     }
-    
-    boolean thisIsArbitrary = (thisType & ARBITRARY_MASK) != 0;
-    boolean registerIsArbitrary = (registerType & ARBITRARY_MASK) != 0;
-    
-    if (thisIsArbitrary) {
-      if (registerIsArbitrary) {
-        // do nothing, if they are not compatible, the VM verifier will emit a VerifyError
-        return;
-      } 
-      if (patchable != null) {  // otherwise, it's an uninitialized value
-        patchable.doPatch(registerType);
-        patchable = null;
-      }
-      this.type = registerType;
-      return;
-    }
-    
-    // if register.type is not an arbitrary, this means that the code may be not verifiable
-    // it's ok if the register is no more used
-    if (!registerIsArbitrary) {
-      return;
-    }
-    
-    if (register.patchable != null) {
-      register.patchable.doPatch(thisType);
-      register.patchable = null;
-    }
-    register.type = thisType;
-  }
+
+    public void merge(Register register) {
+        int thisType = this.type;
+        int registerType = register.type;
+        if (thisType == registerType) { // short cut
+            return;
+        }
+
+        boolean thisIsArbitrary = (thisType & ARBITRARY_MASK) != 0;
+        boolean registerIsArbitrary = (registerType & ARBITRARY_MASK) != 0;
+
+        if (thisIsArbitrary) {
+            if (registerIsArbitrary) {
+                // do nothing, if they are not compatible, the VM verifier will
+                // emit a VerifyError
+                return;
+            }
+            if (patchable != null) { // otherwise, it's an uninitialized value
+                patchable.doPatch(registerType);
+                patchable = null;
+            }
+            this.type = registerType;
+            return;
+        }
+
+        // if register.type is not an arbitrary, this means that the code may be
+        // not verifiable
+        // it's ok if the register is no more used
+        if (!registerIsArbitrary) {
+            return;
+        }
 
-  public static int getJavaOpcode(int type, int opcode) {
-    assert (type & ARBITRARY_MASK) == 0;
-    
-    if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
-      return opcode + ((type != BOOLEAN_TYPE)? type: BYTE_TYPE);
-    } 
+        if (register.patchable != null) {
+            register.patchable.doPatch(thisType);
+            register.patchable = null;
+        }
+        register.type = thisType;
+    }
 
-    return opcode + ((type>4)? 0: type); // type > 4, integer numeric promotion
-  }
+    public static int getJavaOpcode(int type, int opcode) {
+        assert (type & ARBITRARY_MASK) == 0;
+
+        if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
+            return opcode + ((type != BOOLEAN_TYPE) ? type : BYTE_TYPE);
+        }
+
+        return opcode + ((type > 4) ? 0 : type); // type > 4, integer numeric
+                                                 // promotion
+    }
 
-  @Override
-  public String toString() {
-    switch(type) {
-    case OBJECT_TYPE:
-      return "object";
-    case INT_TYPE:
-      return "int";
-    case FLOAT_TYPE:
-      return "float";
-    case LONG_TYPE:
-      return "long";
-    case DOUBLE_TYPE:
-      return "double";
-    case U32_TYPE:
-      return "u32";
-    case U64_TYPE:
-      return "u64";
-    case NO_TYPE:
-      return "uninitialized";
+    @Override
+    public String toString() {
+        switch (type) {
+        case OBJECT_TYPE:
+            return "object";
+        case INT_TYPE:
+            return "int";
+        case FLOAT_TYPE:
+            return "float";
+        case LONG_TYPE:
+            return "long";
+        case DOUBLE_TYPE:
+            return "double";
+        case U32_TYPE:
+            return "u32";
+        case U64_TYPE:
+            return "u64";
+        case NO_TYPE:
+            return "uninitialized";
+        }
+        throw new AssertionError();
     }
-    throw new AssertionError();
-  }
 }
--- a/src/main/java/org/icedrobot/daneel/rewriter/Registers.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/Registers.java	Tue Mar 15 23:25:43 2011 +0100
@@ -1,23 +1,23 @@
 package org.icedrobot.daneel.rewriter;
 
 public class Registers {
-  private Registers() {
-    // no instance
-  }
-  
-  public static int getRegisterD(int packed) {
-    return packed & 0x0F;
-  }
-  
-  public static int getRegisterE(int packed) {
-    return (packed >> 4) &0x0F;
-  }
-  
-  public static int getRegisterF(int packed) {
-    return (packed >> 8) &0x0F;
-  }
-  
-  public static int getRegisterG(int packed) {
-    return (packed >> 12) &0x0F;
-  }
+    private Registers() {
+        // no instance
+    }
+
+    public static int getRegisterD(int packed) {
+        return packed & 0x0F;
+    }
+
+    public static int getRegisterE(int packed) {
+        return (packed >> 4) & 0x0F;
+    }
+
+    public static int getRegisterF(int packed) {
+        return (packed >> 8) & 0x0F;
+    }
+
+    public static int getRegisterG(int packed) {
+        return (packed >> 12) & 0x0F;
+    }
 }
--- a/src/main/java/org/icedrobot/daneel/util/BufferUtil.java	Tue Mar 15 21:53:43 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/util/BufferUtil.java	Tue Mar 15 23:25:43 2011 +0100
@@ -25,12 +25,12 @@
 /**
  * Utility methods extending the base functionality of the standard
  * {@link java.nio.ByteBuffer} class by means of static methods.
- * @author Michael Starzinger <michi@complang.tuwien.ac.at>
  */
 public class BufferUtil {
 
     /**
      * Reads an array of integers from the buffer's current position.
+     * 
      * @param buffer The byte buffer to read from.
      * @param size The number of values to read.
      * @return An array containing the read values.
@@ -47,6 +47,7 @@
      * buffer's current position. A maximum of five bytes is read because only
      * 32-bit values are encoded this way. For details about this encoding see
      * the "Dalvik Executable Format" specification.
+     * 
      * @param buffer The byte buffer to read from.
      * @return The decoded unsigned 32-bit value.
      */
@@ -66,6 +67,7 @@
      * buffer's current position. A maximum of five bytes is read because only
      * 32-bit values are encoded this way. For details about this encoding see
      * the "Dalvik Executable Format" specification.
+     * 
      * @param buffer The byte buffer to read from.
      * @return The decoded signed 32-bit value.
      */
@@ -87,6 +89,7 @@
      * Reads string encoded using the "Modified UTF-8" encoding at the buffer's
      * current position. The number of bytes read from the buffer is implied by
      * the position of the terminating 0 byte.
+     * 
      * @param buffer The byte buffer to read from.
      * @return The decoded string value.
      */