Merge "Remove dexmaker code from dx."
diff --git a/dx/junit-tests/HelloWorldMaker.java b/dx/junit-tests/HelloWorldMaker.java
deleted file mode 100644
index 038701c..0000000
--- a/dx/junit-tests/HelloWorldMaker.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import com.android.dx.gen.BinaryOp;
-import com.android.dx.gen.Code;
-import com.android.dx.gen.DexGenerator;
-import com.android.dx.gen.FieldId;
-import com.android.dx.gen.Local;
-import com.android.dx.gen.MethodId;
-import com.android.dx.gen.Type;
-import com.android.dx.rop.code.AccessFlags;
-
-import java.io.File;
-import java.io.PrintStream;
-
-public class HelloWorldMaker {
-    private static final Type<PrintStream> PRINT_STREAM = Type.get(PrintStream.class);
-    private static final FieldId<System, PrintStream> SYSTEM_OUT
-            = Type.get(System.class).getField(PRINT_STREAM, "out");
-    private static final MethodId<Integer, String> TO_HEX_STRING
-            = Type.get(Integer.class).getMethod(Type.STRING, "toHexString", Type.INT);
-    private static final MethodId<PrintStream, Void> PRINTLN
-            = PRINT_STREAM.getMethod(Type.VOID, "println", Type.STRING);
-
-    public static void main(String[] args) throws Exception {
-
-        /*
-         * This code generates Dalvik bytecode equivalent to the following
-         * program.
-         *
-         *  public class HelloWorld {
-         *      public static void hello() {
-         *          int a = 0xabcd;
-         *          int b = 0xaaaa;
-         *          int c = a - b;
-         *          String s = Integer.toHexString(c);
-         *          System.out.println(s);
-         *      }
-         *  }
-         */
-
-        DexGenerator generator = new DexGenerator();
-
-        // lookup the symbols of interest
-        Type<?> helloWorld = Type.get("LHelloWorld;");
-        MethodId hello = helloWorld.getMethod(Type.VOID, "hello");
-
-        // create some registers
-        //    (I'd like a better syntax for this)
-        Code code = generator.declare(hello, AccessFlags.ACC_STATIC | AccessFlags.ACC_PUBLIC);
-        Local<Integer> a = code.newLocal(Type.INT);
-        Local<Integer> b = code.newLocal(Type.INT);
-        Local<Integer> c = code.newLocal(Type.INT);
-        Local<String> s = code.newLocal(Type.STRING);
-        Local<PrintStream> localSystemOut = code.newLocal(PRINT_STREAM);
-
-        // specify the code instruction-by-instruction (approximately)
-        code.loadConstant(a, 0xabcd);
-        code.loadConstant(b, 0xaaaa);
-        code.op(BinaryOp.SUBTRACT, c, a, b);
-        code.invokeStatic(TO_HEX_STRING, s, c);
-        code.sget(SYSTEM_OUT, localSystemOut);
-        code.invokeVirtual(PRINTLN, null, localSystemOut, s);
-        code.returnVoid();
-
-        // TODO: create the constructor
-
-        generator.declare(helloWorld, "Generated.java", AccessFlags.ACC_PUBLIC, Type.OBJECT);
-
-        // load the dex
-        File outputDir = new File(".");
-        ClassLoader loader = generator.load(HelloWorldMaker.class.getClassLoader(),
-                outputDir, outputDir);
-        Class<?> helloWorldClass = loader.loadClass("HelloWorld");
-        helloWorldClass.getMethod("hello").invoke(null);
-    }
-}
diff --git a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java b/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
deleted file mode 100644
index 8dc6c8d..0000000
--- a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
+++ /dev/null
@@ -1,1677 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
-import static com.android.dx.rop.code.AccessFlags.ACC_FINAL;
-import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
-import static com.android.dx.rop.code.AccessFlags.ACC_PROTECTED;
-import static com.android.dx.rop.code.AccessFlags.ACC_PUBLIC;
-import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-/**
- * This generates a class named 'Generated' with one or more generated methods
- * and fields. In loads the generated class into the current VM and uses
- * reflection to invoke its methods.
- *
- * <p>This test must run on a Dalvik VM.
- */
-public final class DexGeneratorTest extends TestCase {
-    private DexGenerator generator;
-    private static Type<DexGeneratorTest> TEST_TYPE = Type.get(DexGeneratorTest.class);
-    private static Type<?> INT_ARRAY = Type.get(int[].class);
-    private static Type<boolean[]> BOOLEAN_ARRAY = Type.get(boolean[].class);
-    private static Type<long[]> LONG_ARRAY = Type.get(long[].class);
-    private static Type<Object[]> OBJECT_ARRAY = Type.get(Object[].class);
-    private static Type<long[][]> LONG_2D_ARRAY = Type.get(long[][].class);
-    private static Type<?> GENERATED = Type.get("LGenerated;");
-    private static Type<Callable> CALLABLE = Type.get(Callable.class);
-    private static MethodId<Callable, Object> CALL = CALLABLE.getMethod(Type.OBJECT, "call");
-
-    @Override protected void setUp() throws Exception {
-        super.setUp();
-        reset();
-    }
-
-    /**
-     * The generator is mutable. Calling reset creates a new empty generator.
-     * This is necessary to generate multiple classes in the same test method.
-     */
-    private void reset() {
-        generator = new DexGenerator();
-        generator.declare(GENERATED, "Generated.java", ACC_PUBLIC, Type.OBJECT);
-    }
-
-    public void testNewInstance() throws Exception {
-        /*
-         * public static Constructable call(long a, boolean b) {
-         *   Constructable result = new Constructable(a, b);
-         *   return result;
-         * }
-         */
-        Type<Constructable> constructable = Type.get(Constructable.class);
-        MethodId<?, Constructable> methodId = GENERATED.getMethod(
-                constructable, "call", Type.LONG, Type.BOOLEAN);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Long> localA = code.getParameter(0, Type.LONG);
-        Local<Boolean> localB = code.getParameter(1, Type.BOOLEAN);
-        MethodId<Constructable, Void> constructor
-                = constructable.getConstructor(Type.LONG, Type.BOOLEAN);
-        Local<Constructable> localResult = code.newLocal(constructable);
-        code.newInstance(localResult, constructor, localA, localB);
-        code.returnValue(localResult);
-
-        Constructable constructed = (Constructable) getMethod().invoke(null, 5L, false);
-        assertEquals(5L, constructed.a);
-        assertEquals(false, constructed.b);
-    }
-
-    public static class Constructable {
-        private final long a;
-        private final boolean b;
-        public Constructable(long a, boolean b) {
-            this.a = a;
-            this.b = b;
-        }
-    }
-
-    public void testVoidNoArgMemberMethod() throws Exception {
-        /*
-         * public void call() {
-         * }
-         */
-        MethodId<?, Void> methodId = GENERATED.getMethod(Type.VOID, "call");
-        Code code = generator.declare(methodId, ACC_PUBLIC);
-        code.returnVoid();
-
-        addDefaultConstructor();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Object instance = generatedClass.newInstance();
-        Method method = generatedClass.getMethod("call");
-        method.invoke(instance);
-    }
-
-    public void testInvokeStatic() throws Exception {
-        /*
-         * public static int call(int a) {
-         *   int result = DexGeneratorTest.staticMethod(a);
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localA = code.getParameter(0, Type.INT);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        MethodId<?, Integer> staticMethod
-                = TEST_TYPE.getMethod(Type.INT, "staticMethod", Type.INT);
-        code.invokeStatic(staticMethod, localResult, localA);
-        code.returnValue(localResult);
-
-        assertEquals(10, getMethod().invoke(null, 4));
-    }
-
-    public void testCreateLocalMethodAsNull() throws Exception {
-        /*
-         * public void call(int value) {
-         *   Method method = null;
-         * }
-         */
-        MethodId<?, Void> methodId = GENERATED.getMethod(Type.VOID, "call", Type.INT);
-        Type<Method> methodType = Type.get(Method.class);
-        Code code = generator.declare(methodId, ACC_PUBLIC);
-        Local<Method> localMethod = code.newLocal(methodType);
-        code.loadConstant(localMethod, null);
-        code.returnVoid();
-
-        addDefaultConstructor();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Object instance = generatedClass.newInstance();
-        Method method = generatedClass.getMethod("call", int.class);
-        method.invoke(instance, 0);
-    }
-
-    @SuppressWarnings("unused") // called by generated code
-    public static int staticMethod(int a) {
-        return a + 6;
-    }
-
-    public void testInvokeVirtual() throws Exception {
-        /*
-         * public static int call(DexGeneratorTest test, int a) {
-         *   int result = test.virtualMethod(a);
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", TEST_TYPE, Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<DexGeneratorTest> localInstance = code.getParameter(0, TEST_TYPE);
-        Local<Integer> localA = code.getParameter(1, Type.INT);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        MethodId<DexGeneratorTest, Integer> virtualMethod
-                = TEST_TYPE.getMethod(Type.INT, "virtualMethod", Type.INT);
-        code.invokeVirtual(virtualMethod, localResult, localInstance, localA);
-        code.returnValue(localResult);
-
-        assertEquals(9, getMethod().invoke(null, this, 4));
-    }
-
-    @SuppressWarnings("unused") // called by generated code
-    public int virtualMethod(int a) {
-        return a + 5;
-    }
-
-    public <G> void testInvokeDirect() throws Exception {
-        /*
-         * private int directMethod() {
-         *   int a = 5;
-         *   return a;
-         * }
-         *
-         * public static int call(Generated g) {
-         *   int b = g.directMethod();
-         *   return b;
-         * }
-         */
-        Type<G> generated = Type.get("LGenerated;");
-        MethodId<G, Integer> directMethodId = generated.getMethod(Type.INT, "directMethod");
-        Code directCode = generator.declare(directMethodId, ACC_PRIVATE);
-        directCode.getThis(generated); // 'this' is unused
-        Local<Integer> localA = directCode.newLocal(Type.INT);
-        directCode.loadConstant(localA, 5);
-        directCode.returnValue(localA);
-
-        MethodId<G, Integer> methodId = generated.getMethod(Type.INT, "call", generated);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localB = code.newLocal(Type.INT);
-        Local<G> localG = code.getParameter(0, generated);
-        code.invokeDirect(directMethodId, localB, localG);
-        code.returnValue(localB);
-
-        addDefaultConstructor();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Object instance = generatedClass.newInstance();
-        Method method = generatedClass.getMethod("call", generatedClass);
-        assertEquals(5, method.invoke(null, instance));
-    }
-
-    public <G> void testInvokeSuper() throws Exception {
-        /*
-         * public int superHashCode() {
-         *   int result = super.hashCode();
-         *   return result;
-         * }
-         * public int hashCode() {
-         *   return 0;
-         * }
-         */
-        Type<G> generated = Type.get("LGenerated;");
-        MethodId<Object, Integer> objectHashCode = Type.OBJECT.getMethod(Type.INT, "hashCode");
-        Code superHashCode = generator.declare(
-                GENERATED.getMethod(Type.INT, "superHashCode"), ACC_PUBLIC);
-        Local<Integer> localResult = superHashCode.newLocal(Type.INT);
-        Local<G> localThis = superHashCode.getThis(generated);
-        superHashCode.invokeSuper(objectHashCode, localResult, localThis);
-        superHashCode.returnValue(localResult);
-
-        Code generatedHashCode = generator.declare(
-                GENERATED.getMethod(Type.INT, "hashCode"), ACC_PUBLIC);
-        Local<Integer> localZero = generatedHashCode.newLocal(Type.INT);
-        generatedHashCode.loadConstant(localZero, 0);
-        generatedHashCode.returnValue(localZero);
-
-        addDefaultConstructor();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Object instance = generatedClass.newInstance();
-        Method method = generatedClass.getMethod("superHashCode");
-        assertEquals(System.identityHashCode(instance), method.invoke(instance));
-    }
-
-    @SuppressWarnings("unused") // called by generated code
-    public int superMethod(int a) {
-        return a + 4;
-    }
-
-    public void testInvokeInterface() throws Exception {
-        /*
-         * public static Object call(Callable c) {
-         *   Object result = c.call();
-         *   return result;
-         * }
-         */
-        MethodId<?, Object> methodId = GENERATED.getMethod(Type.OBJECT, "call", CALLABLE);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Callable> localC = code.getParameter(0, CALLABLE);
-        Local<Object> localResult = code.newLocal(Type.OBJECT);
-        code.invokeInterface(CALL, localResult, localC);
-        code.returnValue(localResult);
-
-        Callable<Object> callable = new Callable<Object>() {
-            public Object call() throws Exception {
-                return "abc";
-            }
-        };
-        assertEquals("abc", getMethod().invoke(null, callable));
-    }
-
-    public void testParameterMismatch() throws Exception {
-        Type<?>[] argTypes = {
-                Type.get(Integer.class), // should fail because the code specifies int
-                Type.OBJECT,
-        };
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", argTypes);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        try {
-            code.getParameter(0, Type.INT);
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            code.getParameter(2, Type.INT);
-        } catch (IndexOutOfBoundsException e) {
-        }
-    }
-
-    public void testInvokeTypeSafety() throws Exception {
-        /*
-         * public static boolean call(DexGeneratorTest test) {
-         *   CharSequence cs = test.toString();
-         *   boolean result = cs.equals(test);
-         *   return result;
-         * }
-         */
-        MethodId<?, Boolean> methodId = GENERATED.getMethod(Type.BOOLEAN, "call", TEST_TYPE);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<DexGeneratorTest> localTest = code.getParameter(0, TEST_TYPE);
-        Type<CharSequence> charSequenceType = Type.get(CharSequence.class);
-        MethodId<Object, String> objectToString = Type.OBJECT.getMethod(Type.STRING, "toString");
-        MethodId<Object, Boolean> objectEquals
-                = Type.OBJECT.getMethod(Type.BOOLEAN, "equals", Type.OBJECT);
-        Local<CharSequence> localCs = code.newLocal(charSequenceType);
-        Local<Boolean> localResult = code.newLocal(Type.BOOLEAN);
-        code.invokeVirtual(objectToString, localCs, localTest);
-        code.invokeVirtual(objectEquals, localResult, localCs, localTest);
-        code.returnValue(localResult);
-
-        assertEquals(false, getMethod().invoke(null, this));
-    }
-
-    public void testReturnTypeMismatch() {
-        MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call");
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        try {
-            code.returnValue(code.newLocal(Type.BOOLEAN));
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-        try {
-            code.returnVoid();
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    public void testDeclareStaticFields() throws Exception {
-        /*
-         * class Generated {
-         *   public static int a;
-         *   protected static Object b;
-         * }
-         */
-        generator.declare(GENERATED.getField(Type.INT, "a"), ACC_PUBLIC | ACC_STATIC, 3);
-        generator.declare(GENERATED.getField(Type.OBJECT, "b"), ACC_PROTECTED | ACC_STATIC, null);
-        Class<?> generatedClass = loadAndGenerate();
-
-        Field a = generatedClass.getField("a");
-        assertEquals(int.class, a.getType());
-        assertEquals(3, a.get(null));
-
-        Field b = generatedClass.getDeclaredField("b");
-        assertEquals(Object.class, b.getType());
-        b.setAccessible(true);
-        assertEquals(null, b.get(null));
-    }
-
-    public void testDeclareInstanceFields() throws Exception {
-        /*
-         * class Generated {
-         *   public int a;
-         *   protected Object b;
-         * }
-         */
-        generator.declare(GENERATED.getField(Type.INT, "a"), ACC_PUBLIC, null);
-        generator.declare(GENERATED.getField(Type.OBJECT, "b"), ACC_PROTECTED, null);
-
-        addDefaultConstructor();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Object instance = generatedClass.newInstance();
-
-        Field a = generatedClass.getField("a");
-        assertEquals(int.class, a.getType());
-        assertEquals(0, a.get(instance));
-
-        Field b = generatedClass.getDeclaredField("b");
-        assertEquals(Object.class, b.getType());
-        b.setAccessible(true);
-        assertEquals(null, b.get(instance));
-    }
-
-    /**
-     * Declare a constructor that takes an int parameter and assigns it to a
-     * field.
-     */
-    public <G> void testDeclareConstructor() throws Exception {
-        /*
-         * class Generated {
-         *   public final int a;
-         *   public Generated(int a) {
-         *     this.a = a;
-         *   }
-         * }
-         */
-        Type<G> generated = Type.get("LGenerated;");
-        FieldId<G, Integer> fieldId = generated.getField(Type.INT, "a");
-        generator.declare(fieldId, ACC_PUBLIC | ACC_FINAL, null);
-        MethodId<?, Void> constructor = GENERATED.getConstructor(Type.INT);
-        Code code = generator.declare(constructor, ACC_PUBLIC | ACC_CONSTRUCTOR);
-        Local<G> thisRef = code.getThis(generated);
-        Local<Integer> parameter = code.getParameter(0, Type.INT);
-        code.invokeDirect(Type.OBJECT.getConstructor(), null, thisRef);
-        code.iput(fieldId, thisRef, parameter);
-        code.returnVoid();
-
-        Class<?> generatedClass = loadAndGenerate();
-        Field a = generatedClass.getField("a");
-        Object instance = generatedClass.getConstructor(int.class).newInstance(0xabcd);
-        assertEquals(0xabcd, a.get(instance));
-    }
-
-    public void testReturnBoolean() throws Exception {
-        testReturnType(boolean.class, true);
-        testReturnType(byte.class, (byte) 5);
-        testReturnType(char.class, 'E');
-        testReturnType(double.class, 5.0);
-        testReturnType(float.class, 5.0f);
-        testReturnType(int.class, 5);
-        testReturnType(long.class, 5L);
-        testReturnType(short.class, (short) 5);
-        testReturnType(void.class, null);
-        testReturnType(String.class, "foo");
-        testReturnType(Class.class, List.class);
-    }
-
-    private <T> void testReturnType(Class<T> javaType, T value) throws Exception {
-        /*
-         * public int call() {
-         *   int a = 5;
-         *   return a;
-         * }
-         */
-        reset();
-        Type<T> returnType = Type.get(javaType);
-        Code code = generator.declare(GENERATED.getMethod(returnType, "call"),
-                ACC_PUBLIC | ACC_STATIC);
-        if (value != null) {
-            Local<T> i = code.newLocal(returnType);
-            code.loadConstant(i, value);
-            code.returnValue(i);
-        } else {
-            code.returnVoid();
-        }
-
-        Class<?> generatedClass = loadAndGenerate();
-        Method method = generatedClass.getMethod("call");
-        assertEquals(javaType, method.getReturnType());
-        assertEquals(value, method.invoke(null));
-    }
-
-    public void testBranching() throws Exception {
-        Method lt = branchingMethod(Comparison.LT);
-        assertEquals(Boolean.TRUE, lt.invoke(null, 1, 2));
-        assertEquals(Boolean.FALSE, lt.invoke(null, 1, 1));
-        assertEquals(Boolean.FALSE, lt.invoke(null, 2, 1));
-
-        Method le = branchingMethod(Comparison.LE);
-        assertEquals(Boolean.TRUE, le.invoke(null, 1, 2));
-        assertEquals(Boolean.TRUE, le.invoke(null, 1, 1));
-        assertEquals(Boolean.FALSE, le.invoke(null, 2, 1));
-
-        Method eq = branchingMethod(Comparison.EQ);
-        assertEquals(Boolean.FALSE, eq.invoke(null, 1, 2));
-        assertEquals(Boolean.TRUE, eq.invoke(null, 1, 1));
-        assertEquals(Boolean.FALSE, eq.invoke(null, 2, 1));
-
-        Method ge = branchingMethod(Comparison.GE);
-        assertEquals(Boolean.FALSE, ge.invoke(null, 1, 2));
-        assertEquals(Boolean.TRUE, ge.invoke(null, 1, 1));
-        assertEquals(Boolean.TRUE, ge.invoke(null, 2, 1));
-
-        Method gt = branchingMethod(Comparison.GT);
-        assertEquals(Boolean.FALSE, gt.invoke(null, 1, 2));
-        assertEquals(Boolean.FALSE, gt.invoke(null, 1, 1));
-        assertEquals(Boolean.TRUE, gt.invoke(null, 2, 1));
-
-        Method ne = branchingMethod(Comparison.NE);
-        assertEquals(Boolean.TRUE, ne.invoke(null, 1, 2));
-        assertEquals(Boolean.FALSE, ne.invoke(null, 1, 1));
-        assertEquals(Boolean.TRUE, ne.invoke(null, 2, 1));
-    }
-
-    private Method branchingMethod(Comparison comparison) throws Exception {
-        /*
-         * public static boolean call(int localA, int localB) {
-         *   if (a comparison b) {
-         *     return true;
-         *   }
-         *   return false;
-         * }
-         */
-        reset();
-        MethodId<?, Boolean> methodId = GENERATED.getMethod(
-                Type.BOOLEAN, "call", Type.INT, Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localA = code.getParameter(0, Type.INT);
-        Local<Integer> localB = code.getParameter(1, Type.INT);
-        Local<Boolean> result = code.newLocal(Type.get(boolean.class));
-        Label afterIf = code.newLabel();
-        Label ifBody = code.newLabel();
-        code.compare(comparison, localA, localB, ifBody);
-        code.jump(afterIf);
-
-        code.mark(ifBody);
-        code.loadConstant(result, true);
-        code.returnValue(result);
-
-        code.mark(afterIf);
-        code.loadConstant(result, false);
-        code.returnValue(result);
-        return getMethod();
-    }
-
-    public void testCastIntegerToInteger() throws Exception {
-        Method intToLong = numericCastingMethod(int.class, long.class);
-        assertEquals(0x0000000000000000L, intToLong.invoke(null, 0x00000000));
-        assertEquals(0x000000007fffffffL, intToLong.invoke(null, 0x7fffffff));
-        assertEquals(0xffffffff80000000L, intToLong.invoke(null, 0x80000000));
-        assertEquals(0xffffffffffffffffL, intToLong.invoke(null, 0xffffffff));
-
-        Method longToInt = numericCastingMethod(long.class, int.class);
-        assertEquals(0x1234abcd, longToInt.invoke(null, 0x000000001234abcdL));
-        assertEquals(0x1234abcd, longToInt.invoke(null, 0x123456781234abcdL));
-        assertEquals(0x1234abcd, longToInt.invoke(null, 0xffffffff1234abcdL));
-
-        Method intToShort = numericCastingMethod(int.class, short.class);
-        assertEquals((short) 0x1234, intToShort.invoke(null, 0x00001234));
-        assertEquals((short) 0x1234, intToShort.invoke(null, 0xabcd1234));
-        assertEquals((short) 0x1234, intToShort.invoke(null, 0xffff1234));
-
-        Method intToChar = numericCastingMethod(int.class, char.class);
-        assertEquals((char) 0x1234, intToChar.invoke(null, 0x00001234));
-        assertEquals((char) 0x1234, intToChar.invoke(null, 0xabcd1234));
-        assertEquals((char) 0x1234, intToChar.invoke(null, 0xffff1234));
-
-        Method intToByte = numericCastingMethod(int.class, byte.class);
-        assertEquals((byte) 0x34, intToByte.invoke(null, 0x00000034));
-        assertEquals((byte) 0x34, intToByte.invoke(null, 0xabcd1234));
-        assertEquals((byte) 0x34, intToByte.invoke(null, 0xffffff34));
-    }
-
-    public void testCastIntegerToFloatingPoint() throws Exception {
-        Method intToFloat = numericCastingMethod(int.class, float.class);
-        assertEquals(0.0f, intToFloat.invoke(null, 0));
-        assertEquals(-1.0f, intToFloat.invoke(null, -1));
-        assertEquals(16777216f, intToFloat.invoke(null, 16777216));
-        assertEquals(16777216f, intToFloat.invoke(null, 16777217)); // precision
-
-        Method intToDouble = numericCastingMethod(int.class, double.class);
-        assertEquals(0.0, intToDouble.invoke(null, 0));
-        assertEquals(-1.0, intToDouble.invoke(null, -1));
-        assertEquals(16777216.0, intToDouble.invoke(null, 16777216));
-        assertEquals(16777217.0, intToDouble.invoke(null, 16777217));
-
-        Method longToFloat = numericCastingMethod(long.class, float.class);
-        assertEquals(0.0f, longToFloat.invoke(null, 0L));
-        assertEquals(-1.0f, longToFloat.invoke(null, -1L));
-        assertEquals(16777216f, longToFloat.invoke(null, 16777216L));
-        assertEquals(16777216f, longToFloat.invoke(null, 16777217L));
-
-        Method longToDouble = numericCastingMethod(long.class, double.class);
-        assertEquals(0.0, longToDouble.invoke(null, 0L));
-        assertEquals(-1.0, longToDouble.invoke(null, -1L));
-        assertEquals(9007199254740992.0, longToDouble.invoke(null, 9007199254740992L));
-        assertEquals(9007199254740992.0, longToDouble.invoke(null, 9007199254740993L)); // precision
-    }
-
-    public void testCastFloatingPointToInteger() throws Exception {
-        Method floatToInt = numericCastingMethod(float.class, int.class);
-        assertEquals(0, floatToInt.invoke(null, 0.0f));
-        assertEquals(-1, floatToInt.invoke(null, -1.0f));
-        assertEquals(Integer.MAX_VALUE, floatToInt.invoke(null, 10e15f));
-        assertEquals(0, floatToInt.invoke(null, 0.5f));
-        assertEquals(Integer.MIN_VALUE, floatToInt.invoke(null, Float.NEGATIVE_INFINITY));
-        assertEquals(0, floatToInt.invoke(null, Float.NaN));
-
-        Method floatToLong = numericCastingMethod(float.class, long.class);
-        assertEquals(0L, floatToLong.invoke(null, 0.0f));
-        assertEquals(-1L, floatToLong.invoke(null, -1.0f));
-        assertEquals(10000000272564224L, floatToLong.invoke(null, 10e15f));
-        assertEquals(0L, floatToLong.invoke(null, 0.5f));
-        assertEquals(Long.MIN_VALUE, floatToLong.invoke(null, Float.NEGATIVE_INFINITY));
-        assertEquals(0L, floatToLong.invoke(null, Float.NaN));
-
-        Method doubleToInt = numericCastingMethod(double.class, int.class);
-        assertEquals(0, doubleToInt.invoke(null, 0.0));
-        assertEquals(-1, doubleToInt.invoke(null, -1.0));
-        assertEquals(Integer.MAX_VALUE, doubleToInt.invoke(null, 10e15));
-        assertEquals(0, doubleToInt.invoke(null, 0.5));
-        assertEquals(Integer.MIN_VALUE, doubleToInt.invoke(null, Double.NEGATIVE_INFINITY));
-        assertEquals(0, doubleToInt.invoke(null, Double.NaN));
-
-        Method doubleToLong = numericCastingMethod(double.class, long.class);
-        assertEquals(0L, doubleToLong.invoke(null, 0.0));
-        assertEquals(-1L, doubleToLong.invoke(null, -1.0));
-        assertEquals(10000000000000000L, doubleToLong.invoke(null, 10e15));
-        assertEquals(0L, doubleToLong.invoke(null, 0.5));
-        assertEquals(Long.MIN_VALUE, doubleToLong.invoke(null, Double.NEGATIVE_INFINITY));
-        assertEquals(0L, doubleToLong.invoke(null, Double.NaN));
-    }
-
-    public void testCastFloatingPointToFloatingPoint() throws Exception {
-        Method floatToDouble = numericCastingMethod(float.class, double.class);
-        assertEquals(0.0, floatToDouble.invoke(null, 0.0f));
-        assertEquals(-1.0, floatToDouble.invoke(null, -1.0f));
-        assertEquals(0.5, floatToDouble.invoke(null, 0.5f));
-        assertEquals(Double.NEGATIVE_INFINITY, floatToDouble.invoke(null, Float.NEGATIVE_INFINITY));
-        assertEquals(Double.NaN, floatToDouble.invoke(null, Float.NaN));
-
-        Method doubleToFloat = numericCastingMethod(double.class, float.class);
-        assertEquals(0.0f, doubleToFloat.invoke(null, 0.0));
-        assertEquals(-1.0f, doubleToFloat.invoke(null, -1.0));
-        assertEquals(0.5f, doubleToFloat.invoke(null, 0.5));
-        assertEquals(Float.NEGATIVE_INFINITY, doubleToFloat.invoke(null, Double.NEGATIVE_INFINITY));
-        assertEquals(Float.NaN, doubleToFloat.invoke(null, Double.NaN));
-    }
-
-    private Method numericCastingMethod(Class<?> source, Class<?> target)
-            throws Exception {
-        /*
-         * public static short call(int source) {
-         *   short casted = (short) source;
-         *   return casted;
-         * }
-         */
-        reset();
-        Type<?> sourceType = Type.get(source);
-        Type<?> targetType = Type.get(target);
-        MethodId<?, ?> methodId = GENERATED.getMethod(targetType, "call", sourceType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<?> localSource = code.getParameter(0, sourceType);
-        Local<?> localCasted = code.newLocal(targetType);
-        code.numericCast(localSource, localCasted);
-        code.returnValue(localCasted);
-        return getMethod();
-    }
-
-    public void testNot() throws Exception {
-        Method notInteger = notMethod(int.class);
-        assertEquals(0xffffffff, notInteger.invoke(null, 0x00000000));
-        assertEquals(0x00000000, notInteger.invoke(null, 0xffffffff));
-        assertEquals(0xedcba987, notInteger.invoke(null, 0x12345678));
-
-        Method notLong = notMethod(long.class);
-        assertEquals(0xffffffffffffffffL, notLong.invoke(null, 0x0000000000000000L));
-        assertEquals(0x0000000000000000L, notLong.invoke(null, 0xffffffffffffffffL));
-        assertEquals(0x98765432edcba987L, notLong.invoke(null, 0x6789abcd12345678L));
-    }
-
-    private <T> Method notMethod(Class<T> source) throws Exception {
-        /*
-         * public static short call(int source) {
-         *   source = ~source;
-         *   return not;
-         * }
-         */
-        reset();
-        Type<T> valueType = Type.get(source);
-        MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<T> localSource = code.getParameter(0, valueType);
-        code.not(localSource, localSource);
-        code.returnValue(localSource);
-        return getMethod();
-    }
-
-    public void testNegate() throws Exception {
-        Method negateInteger = negateMethod(int.class);
-        assertEquals(0, negateInteger.invoke(null, 0));
-        assertEquals(-1, negateInteger.invoke(null, 1));
-        assertEquals(Integer.MIN_VALUE, negateInteger.invoke(null, Integer.MIN_VALUE));
-
-        Method negateLong = negateMethod(long.class);
-        assertEquals(0L, negateLong.invoke(null, 0));
-        assertEquals(-1L, negateLong.invoke(null, 1));
-        assertEquals(Long.MIN_VALUE, negateLong.invoke(null, Long.MIN_VALUE));
-
-        Method negateFloat = negateMethod(float.class);
-        assertEquals(-0.0f, negateFloat.invoke(null, 0.0f));
-        assertEquals(-1.0f, negateFloat.invoke(null, 1.0f));
-        assertEquals(Float.NaN, negateFloat.invoke(null, Float.NaN));
-        assertEquals(Float.POSITIVE_INFINITY, negateFloat.invoke(null, Float.NEGATIVE_INFINITY));
-
-        Method negateDouble = negateMethod(double.class);
-        assertEquals(-0.0, negateDouble.invoke(null, 0.0));
-        assertEquals(-1.0, negateDouble.invoke(null, 1.0));
-        assertEquals(Double.NaN, negateDouble.invoke(null, Double.NaN));
-        assertEquals(Double.POSITIVE_INFINITY, negateDouble.invoke(null, Double.NEGATIVE_INFINITY));
-    }
-
-    private <T> Method negateMethod(Class<T> source) throws Exception {
-        /*
-         * public static short call(int source) {
-         *   source = -source;
-         *   return not;
-         * }
-         */
-        reset();
-        Type<T> valueType = Type.get(source);
-        MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<T> localSource = code.getParameter(0, valueType);
-        code.negate(localSource, localSource);
-        code.returnValue(localSource);
-        return getMethod();
-    }
-
-    public void testIntBinaryOps() throws Exception {
-        Method add = binaryOpMethod(int.class, BinaryOp.ADD);
-        assertEquals(79, add.invoke(null, 75, 4));
-
-        Method subtract = binaryOpMethod(int.class, BinaryOp.SUBTRACT);
-        assertEquals(71, subtract.invoke(null, 75, 4));
-
-        Method multiply = binaryOpMethod(int.class, BinaryOp.MULTIPLY);
-        assertEquals(300, multiply.invoke(null, 75, 4));
-
-        Method divide = binaryOpMethod(int.class, BinaryOp.DIVIDE);
-        assertEquals(18, divide.invoke(null, 75, 4));
-        try {
-            divide.invoke(null, 75, 0);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(ArithmeticException.class, expected.getCause().getClass());
-        }
-
-        Method remainder = binaryOpMethod(int.class, BinaryOp.REMAINDER);
-        assertEquals(3, remainder.invoke(null, 75, 4));
-        try {
-            remainder.invoke(null, 75, 0);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(ArithmeticException.class, expected.getCause().getClass());
-        }
-
-        Method and = binaryOpMethod(int.class, BinaryOp.AND);
-        assertEquals(0xff000000, and.invoke(null, 0xff00ff00, 0xffff0000));
-
-        Method or = binaryOpMethod(int.class, BinaryOp.OR);
-        assertEquals(0xffffff00, or.invoke(null, 0xff00ff00, 0xffff0000));
-
-        Method xor = binaryOpMethod(int.class, BinaryOp.XOR);
-        assertEquals(0x00ffff00, xor.invoke(null, 0xff00ff00, 0xffff0000));
-
-        Method shiftLeft = binaryOpMethod(int.class, BinaryOp.SHIFT_LEFT);
-        assertEquals(0xcd123400, shiftLeft.invoke(null, 0xabcd1234, 8));
-
-        Method shiftRight = binaryOpMethod(int.class, BinaryOp.SHIFT_RIGHT);
-        assertEquals(0xffabcd12, shiftRight.invoke(null, 0xabcd1234, 8));
-
-        Method unsignedShiftRight = binaryOpMethod(int.class,
-                BinaryOp.UNSIGNED_SHIFT_RIGHT);
-        assertEquals(0x00abcd12, unsignedShiftRight.invoke(null, 0xabcd1234, 8));
-    }
-
-    public void testLongBinaryOps() throws Exception {
-        Method add = binaryOpMethod(long.class, BinaryOp.ADD);
-        assertEquals(79L, add.invoke(null, 75L, 4L));
-
-        Method subtract = binaryOpMethod(long.class, BinaryOp.SUBTRACT);
-        assertEquals(71L, subtract.invoke(null, 75L, 4L));
-
-        Method multiply = binaryOpMethod(long.class, BinaryOp.MULTIPLY);
-        assertEquals(300L, multiply.invoke(null, 75L, 4L));
-
-        Method divide = binaryOpMethod(long.class, BinaryOp.DIVIDE);
-        assertEquals(18L, divide.invoke(null, 75L, 4L));
-        try {
-            divide.invoke(null, 75L, 0L);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(ArithmeticException.class, expected.getCause().getClass());
-        }
-
-        Method remainder = binaryOpMethod(long.class, BinaryOp.REMAINDER);
-        assertEquals(3L, remainder.invoke(null, 75L, 4L));
-        try {
-            remainder.invoke(null, 75L, 0L);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(ArithmeticException.class, expected.getCause().getClass());
-        }
-
-        Method and = binaryOpMethod(long.class, BinaryOp.AND);
-        assertEquals(0xff00ff0000000000L,
-                and.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
-        Method or = binaryOpMethod(long.class, BinaryOp.OR);
-        assertEquals(0xffffffffff00ff00L,
-                or.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
-        Method xor = binaryOpMethod(long.class, BinaryOp.XOR);
-        assertEquals(0x00ff00ffff00ff00L,
-                xor.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
-        Method shiftLeft = binaryOpMethod(long.class, BinaryOp.SHIFT_LEFT);
-        assertEquals(0xcdef012345678900L, shiftLeft.invoke(null, 0xabcdef0123456789L, 8L));
-
-        Method shiftRight = binaryOpMethod(long.class, BinaryOp.SHIFT_RIGHT);
-        assertEquals(0xffabcdef01234567L, shiftRight.invoke(null, 0xabcdef0123456789L, 8L));
-
-        Method unsignedShiftRight = binaryOpMethod(long.class,
-                BinaryOp.UNSIGNED_SHIFT_RIGHT);
-        assertEquals(0x00abcdef01234567L, unsignedShiftRight.invoke(null, 0xabcdef0123456789L, 8L));
-    }
-
-    public void testFloatBinaryOps() throws Exception {
-        Method add = binaryOpMethod(float.class, BinaryOp.ADD);
-        assertEquals(6.75f, add.invoke(null, 5.5f, 1.25f));
-
-        Method subtract = binaryOpMethod(float.class, BinaryOp.SUBTRACT);
-        assertEquals(4.25f, subtract.invoke(null, 5.5f, 1.25f));
-
-        Method multiply = binaryOpMethod(float.class, BinaryOp.MULTIPLY);
-        assertEquals(6.875f, multiply.invoke(null, 5.5f, 1.25f));
-
-        Method divide = binaryOpMethod(float.class, BinaryOp.DIVIDE);
-        assertEquals(4.4f, divide.invoke(null, 5.5f, 1.25f));
-        assertEquals(Float.POSITIVE_INFINITY, divide.invoke(null, 5.5f, 0.0f));
-
-        Method remainder = binaryOpMethod(float.class, BinaryOp.REMAINDER);
-        assertEquals(0.5f, remainder.invoke(null, 5.5f, 1.25f));
-        assertEquals(Float.NaN, remainder.invoke(null, 5.5f, 0.0f));
-    }
-
-    public void testDoubleBinaryOps() throws Exception {
-        Method add = binaryOpMethod(double.class, BinaryOp.ADD);
-        assertEquals(6.75, add.invoke(null, 5.5, 1.25));
-
-        Method subtract = binaryOpMethod(double.class, BinaryOp.SUBTRACT);
-        assertEquals(4.25, subtract.invoke(null, 5.5, 1.25));
-
-        Method multiply = binaryOpMethod(double.class, BinaryOp.MULTIPLY);
-        assertEquals(6.875, multiply.invoke(null, 5.5, 1.25));
-
-        Method divide = binaryOpMethod(double.class, BinaryOp.DIVIDE);
-        assertEquals(4.4, divide.invoke(null, 5.5, 1.25));
-        assertEquals(Double.POSITIVE_INFINITY, divide.invoke(null, 5.5, 0.0));
-
-        Method remainder = binaryOpMethod(double.class, BinaryOp.REMAINDER);
-        assertEquals(0.5, remainder.invoke(null, 5.5, 1.25));
-        assertEquals(Double.NaN, remainder.invoke(null, 5.5, 0.0));
-    }
-
-    private <T> Method binaryOpMethod(Class<T> valueClass, BinaryOp op)
-            throws Exception {
-        /*
-         * public static int binaryOp(int a, int b) {
-         *   int result = a + b;
-         *   return result;
-         * }
-         */
-        reset();
-        Type<T> valueType = Type.get(valueClass);
-        MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType, valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<T> localA = code.getParameter(0, valueType);
-        Local<T> localB = code.getParameter(1, valueType);
-        Local<T> localResult = code.newLocal(valueType);
-        code.op(op, localResult, localA, localB);
-        code.returnValue(localResult);
-        return getMethod();
-    }
-
-    public void testReadAndWriteInstanceFields() throws Exception {
-        Instance instance = new Instance();
-
-        Method intSwap = instanceSwapMethod(int.class, "intValue");
-        instance.intValue = 5;
-        assertEquals(5, intSwap.invoke(null, instance, 10));
-        assertEquals(10, instance.intValue);
-
-        Method longSwap = instanceSwapMethod(long.class, "longValue");
-        instance.longValue = 500L;
-        assertEquals(500L, longSwap.invoke(null, instance, 1234L));
-        assertEquals(1234L, instance.longValue);
-
-        Method booleanSwap = instanceSwapMethod(boolean.class, "booleanValue");
-        instance.booleanValue = false;
-        assertEquals(false, booleanSwap.invoke(null, instance, true));
-        assertEquals(true, instance.booleanValue);
-
-        Method floatSwap = instanceSwapMethod(float.class, "floatValue");
-        instance.floatValue = 1.5f;
-        assertEquals(1.5f, floatSwap.invoke(null, instance, 0.5f));
-        assertEquals(0.5f, instance.floatValue);
-
-        Method doubleSwap = instanceSwapMethod(double.class, "doubleValue");
-        instance.doubleValue = 155.5;
-        assertEquals(155.5, doubleSwap.invoke(null, instance, 266.6));
-        assertEquals(266.6, instance.doubleValue);
-
-        Method objectSwap = instanceSwapMethod(Object.class, "objectValue");
-        instance.objectValue = "before";
-        assertEquals("before", objectSwap.invoke(null, instance, "after"));
-        assertEquals("after", instance.objectValue);
-
-        Method byteSwap = instanceSwapMethod(byte.class, "byteValue");
-        instance.byteValue = 0x35;
-        assertEquals((byte) 0x35, byteSwap.invoke(null, instance, (byte) 0x64));
-        assertEquals((byte) 0x64, instance.byteValue);
-
-        Method charSwap = instanceSwapMethod(char.class, "charValue");
-        instance.charValue = 'A';
-        assertEquals('A', charSwap.invoke(null, instance, 'B'));
-        assertEquals('B', instance.charValue);
-
-        Method shortSwap = instanceSwapMethod(short.class, "shortValue");
-        instance.shortValue = (short) 0xabcd;
-        assertEquals((short) 0xabcd, shortSwap.invoke(null, instance, (short) 0x1234));
-        assertEquals((short) 0x1234, instance.shortValue);
-    }
-
-    public class Instance {
-        public int intValue;
-        public long longValue;
-        public float floatValue;
-        public double doubleValue;
-        public Object objectValue;
-        public boolean booleanValue;
-        public byte byteValue;
-        public char charValue;
-        public short shortValue;
-    }
-
-    private <V> Method instanceSwapMethod(
-            Class<V> valueClass, String fieldName) throws Exception {
-        /*
-         * public static int call(Instance instance, int newValue) {
-         *   int oldValue = instance.intValue;
-         *   instance.intValue = newValue;
-         *   return oldValue;
-         * }
-         */
-        reset();
-        Type<V> valueType = Type.get(valueClass);
-        Type<Instance> objectType = Type.get(Instance.class);
-        FieldId<Instance, V> fieldId = objectType.getField(valueType, fieldName);
-        MethodId<?, V> methodId = GENERATED.getMethod(valueType, "call", objectType, valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Instance> localInstance = code.getParameter(0, objectType);
-        Local<V> localNewValue = code.getParameter(1, valueType);
-        Local<V> localOldValue = code.newLocal(valueType);
-        code.iget(fieldId, localInstance, localOldValue);
-        code.iput(fieldId, localInstance, localNewValue);
-        code.returnValue(localOldValue);
-        return getMethod();
-    }
-
-    public void testReadAndWriteStaticFields() throws Exception {
-        Method intSwap = staticSwapMethod(int.class, "intValue");
-        Static.intValue = 5;
-        assertEquals(5, intSwap.invoke(null, 10));
-        assertEquals(10, Static.intValue);
-
-        Method longSwap = staticSwapMethod(long.class, "longValue");
-        Static.longValue = 500L;
-        assertEquals(500L, longSwap.invoke(null, 1234L));
-        assertEquals(1234L, Static.longValue);
-
-        Method booleanSwap = staticSwapMethod(boolean.class, "booleanValue");
-        Static.booleanValue = false;
-        assertEquals(false, booleanSwap.invoke(null, true));
-        assertEquals(true, Static.booleanValue);
-
-        Method floatSwap = staticSwapMethod(float.class, "floatValue");
-        Static.floatValue = 1.5f;
-        assertEquals(1.5f, floatSwap.invoke(null, 0.5f));
-        assertEquals(0.5f, Static.floatValue);
-
-        Method doubleSwap = staticSwapMethod(double.class, "doubleValue");
-        Static.doubleValue = 155.5;
-        assertEquals(155.5, doubleSwap.invoke(null, 266.6));
-        assertEquals(266.6, Static.doubleValue);
-
-        Method objectSwap = staticSwapMethod(Object.class, "objectValue");
-        Static.objectValue = "before";
-        assertEquals("before", objectSwap.invoke(null, "after"));
-        assertEquals("after", Static.objectValue);
-
-        Method byteSwap = staticSwapMethod(byte.class, "byteValue");
-        Static.byteValue = 0x35;
-        assertEquals((byte) 0x35, byteSwap.invoke(null, (byte) 0x64));
-        assertEquals((byte) 0x64, Static.byteValue);
-
-        Method charSwap = staticSwapMethod(char.class, "charValue");
-        Static.charValue = 'A';
-        assertEquals('A', charSwap.invoke(null, 'B'));
-        assertEquals('B', Static.charValue);
-
-        Method shortSwap = staticSwapMethod(short.class, "shortValue");
-        Static.shortValue = (short) 0xabcd;
-        assertEquals((short) 0xabcd, shortSwap.invoke(null, (short) 0x1234));
-        assertEquals((short) 0x1234, Static.shortValue);
-    }
-
-    public static class Static {
-        public static int intValue;
-        public static long longValue;
-        public static float floatValue;
-        public static double doubleValue;
-        public static Object objectValue;
-        public static boolean booleanValue;
-        public static byte byteValue;
-        public static char charValue;
-        public static short shortValue;
-    }
-
-    private <V> Method staticSwapMethod(Class<V> valueClass, String fieldName)
-            throws Exception {
-        /*
-         * public static int call(int newValue) {
-         *   int oldValue = Static.intValue;
-         *   Static.intValue = newValue;
-         *   return oldValue;
-         * }
-         */
-        reset();
-        Type<V> valueType = Type.get(valueClass);
-        Type<Static> objectType = Type.get(Static.class);
-        FieldId<Static, V> fieldId = objectType.getField(valueType, fieldName);
-        MethodId<?, V> methodId = GENERATED.getMethod(valueType, "call", valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<V> localNewValue = code.getParameter(0, valueType);
-        Local<V> localOldValue = code.newLocal(valueType);
-        code.sget(fieldId, localOldValue);
-        code.sput(fieldId, localNewValue);
-        code.returnValue(localOldValue);
-        return getMethod();
-    }
-
-    public void testTypeCast() throws Exception {
-        /*
-         * public static String call(Object o) {
-         *   String s = (String) o;
-         * }
-         */
-        MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call", Type.OBJECT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Object> localObject = code.getParameter(0, Type.OBJECT);
-        Local<String> localString = code.newLocal(Type.STRING);
-        code.typeCast(localObject, localString);
-        code.returnValue(localString);
-
-        Method method = getMethod();
-        assertEquals("s", method.invoke(null, "s"));
-        assertEquals(null, method.invoke(null, (String) null));
-        try {
-            method.invoke(null, 5);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(ClassCastException.class, expected.getCause().getClass());
-        }
-    }
-
-    public void testInstanceOf() throws Exception {
-        /*
-         * public static boolean call(Object o) {
-         *   boolean result = o instanceof String;
-         *   return result;
-         * }
-         */
-        MethodId<?, Boolean> methodId = GENERATED.getMethod(Type.BOOLEAN, "call", Type.OBJECT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Object> localObject = code.getParameter(0, Type.OBJECT);
-        Local<Boolean> localResult = code.newLocal(Type.BOOLEAN);
-        code.instanceOfType(localResult, localObject, Type.STRING);
-        code.returnValue(localResult);
-
-        Method method = getMethod();
-        assertEquals(true, method.invoke(null, "s"));
-        assertEquals(false, method.invoke(null, (String) null));
-        assertEquals(false, method.invoke(null, 5));
-    }
-
-    /**
-     * Tests that we can construct a for loop.
-     */
-    public void testForLoop() throws Exception {
-        /*
-         * public static int call(int count) {
-         *   int result = 1;
-         *   for (int i = 0; i < count; i += 1) {
-         *     result = result * 2;
-         *   }
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localCount = code.getParameter(0, Type.INT);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        Local<Integer> localI = code.newLocal(Type.INT);
-        Local<Integer> local1 = code.newLocal(Type.INT);
-        Local<Integer> local2 = code.newLocal(Type.INT);
-        code.loadConstant(local1, 1);
-        code.loadConstant(local2, 2);
-        code.loadConstant(localResult, 1);
-        code.loadConstant(localI, 0);
-        Label loopCondition = code.newLabel();
-        Label loopBody = code.newLabel();
-        Label afterLoop = code.newLabel();
-        code.mark(loopCondition);
-        code.compare(Comparison.LT, localI, localCount, loopBody);
-        code.jump(afterLoop);
-        code.mark(loopBody);
-        code.op(BinaryOp.MULTIPLY, localResult, localResult, local2);
-        code.op(BinaryOp.ADD, localI, localI, local1);
-        code.jump(loopCondition);
-        code.mark(afterLoop);
-        code.returnValue(localResult);
-
-        Method pow2 = getMethod();
-        assertEquals(1, pow2.invoke(null, 0));
-        assertEquals(2, pow2.invoke(null, 1));
-        assertEquals(4, pow2.invoke(null, 2));
-        assertEquals(8, pow2.invoke(null, 3));
-        assertEquals(16, pow2.invoke(null, 4));
-    }
-
-    /**
-     * Tests that we can construct a while loop.
-     */
-    public void testWhileLoop() throws Exception {
-        /*
-         * public static int call(int max) {
-         *   int result = 1;
-         *   while (result < max) {
-         *     result = result * 2;
-         *   }
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localMax = code.getParameter(0, Type.INT);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        Local<Integer> local2 = code.newLocal(Type.INT);
-        code.loadConstant(localResult, 1);
-        code.loadConstant(local2, 2);
-        Label loopCondition = code.newLabel();
-        Label loopBody = code.newLabel();
-        Label afterLoop = code.newLabel();
-        code.mark(loopCondition);
-        code.compare(Comparison.LT, localResult, localMax, loopBody);
-        code.jump(afterLoop);
-        code.mark(loopBody);
-        code.op(BinaryOp.MULTIPLY, localResult, localResult, local2);
-        code.jump(loopCondition);
-        code.mark(afterLoop);
-        code.returnValue(localResult);
-
-        Method ceilPow2 = getMethod();
-        assertEquals(1, ceilPow2.invoke(null, 1));
-        assertEquals(2, ceilPow2.invoke(null, 2));
-        assertEquals(4, ceilPow2.invoke(null, 3));
-        assertEquals(16, ceilPow2.invoke(null, 10));
-        assertEquals(128, ceilPow2.invoke(null, 100));
-        assertEquals(1024, ceilPow2.invoke(null, 1000));
-    }
-
-    public void testIfElseBlock() throws Exception {
-        /*
-         * public static int call(int a, int b, int c) {
-         *   if (a < b) {
-         *     if (a < c) {
-         *       return a;
-         *     } else {
-         *       return c;
-         *     }
-         *   } else if (b < c) {
-         *     return b;
-         *   } else {
-         *     return c;
-         *   }
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(
-                Type.INT, "call", Type.INT, Type.INT, Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localA = code.getParameter(0, Type.INT);
-        Local<Integer> localB = code.getParameter(1, Type.INT);
-        Local<Integer> localC = code.getParameter(2, Type.INT);
-        Label aLessThanB = code.newLabel();
-        Label aLessThanC = code.newLabel();
-        Label bLessThanC = code.newLabel();
-        code.compare(Comparison.LT, localA, localB, aLessThanB);
-        code.compare(Comparison.LT, localB, localC, bLessThanC);
-        code.returnValue(localC);
-        // (a < b)
-        code.mark(aLessThanB);
-        code.compare(Comparison.LT, localA, localC, aLessThanC);
-        code.returnValue(localC);
-        // (a < c)
-        code.mark(aLessThanC);
-        code.returnValue(localA);
-        // (b < c)
-        code.mark(bLessThanC);
-        code.returnValue(localB);
-
-        Method min = getMethod();
-        assertEquals(1, min.invoke(null, 1, 2, 3));
-        assertEquals(1, min.invoke(null, 2, 3, 1));
-        assertEquals(1, min.invoke(null, 2, 1, 3));
-        assertEquals(1, min.invoke(null, 3, 2, 1));
-    }
-
-    public void testRecursion() throws Exception {
-        /*
-         * public static int call(int a) {
-         *   if (a < 2) {
-         *     return a;
-         *   }
-         *   a -= 1;
-         *   int x = call(a)
-         *   a -= 1;
-         *   int y = call(a);
-         *   int result = x + y;
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localA = code.getParameter(0, Type.INT);
-        Local<Integer> local1 = code.newLocal(Type.INT);
-        Local<Integer> local2 = code.newLocal(Type.INT);
-        Local<Integer> localX = code.newLocal(Type.INT);
-        Local<Integer> localY = code.newLocal(Type.INT);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        Label baseCase = code.newLabel();
-        code.loadConstant(local1, 1);
-        code.loadConstant(local2, 2);
-        code.compare(Comparison.LT, localA, local2, baseCase);
-        code.op(BinaryOp.SUBTRACT, localA, localA, local1);
-        code.invokeStatic(methodId, localX, localA);
-        code.op(BinaryOp.SUBTRACT, localA, localA, local1);
-        code.invokeStatic(methodId, localY, localA);
-        code.op(BinaryOp.ADD, localResult, localX, localY);
-        code.returnValue(localResult);
-        code.mark(baseCase);
-        code.returnValue(localA);
-
-        Method fib = getMethod();
-        assertEquals(0, fib.invoke(null, 0));
-        assertEquals(1, fib.invoke(null, 1));
-        assertEquals(1, fib.invoke(null, 2));
-        assertEquals(2, fib.invoke(null, 3));
-        assertEquals(3, fib.invoke(null, 4));
-        assertEquals(5, fib.invoke(null, 5));
-        assertEquals(8, fib.invoke(null, 6));
-    }
-
-    public void testCatchExceptions() throws Exception {
-        /*
-         * public static String call(int i) {
-         *   try {
-         *     DexGeneratorTest.thrower(i);
-         *     return "NONE";
-         *   } catch (IllegalArgumentException e) {
-         *     return "IAE";
-         *   } catch (IllegalStateException e) {
-         *     return "ISE";
-         *   } catch (RuntimeException e) {
-         *     return "RE";
-         *   }
-         */
-        MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localI = code.getParameter(0, Type.INT);
-        Local<String> result = code.newLocal(Type.STRING);
-        Label catchIae = code.newLabel();
-        Label catchIse = code.newLabel();
-        Label catchRe = code.newLabel();
-
-        code.addCatchClause(Type.get(IllegalArgumentException.class), catchIae);
-        code.addCatchClause(Type.get(IllegalStateException.class), catchIse);
-        code.addCatchClause(Type.get(RuntimeException.class), catchRe);
-        MethodId<?, ?> thrower = TEST_TYPE.getMethod(Type.VOID, "thrower", Type.INT);
-        code.invokeStatic(thrower, null, localI);
-        code.loadConstant(result, "NONE");
-        code.returnValue(result);
-
-        code.mark(catchIae);
-        code.loadConstant(result, "IAE");
-        code.returnValue(result);
-
-        code.mark(catchIse);
-        code.loadConstant(result, "ISE");
-        code.returnValue(result);
-
-        code.mark(catchRe);
-        code.loadConstant(result, "RE");
-        code.returnValue(result);
-
-        Method method = getMethod();
-        assertEquals("NONE", method.invoke(null, 0));
-        assertEquals("IAE", method.invoke(null, 1));
-        assertEquals("ISE", method.invoke(null, 2));
-        assertEquals("RE", method.invoke(null, 3));
-        try {
-            method.invoke(null, 4);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(IOException.class, expected.getCause().getClass());
-        }
-    }
-
-    @SuppressWarnings("unused") // called by generated code
-    public static void thrower(int a) throws Exception {
-        switch (a) {
-        case 0:
-            return;
-        case 1:
-            throw new IllegalArgumentException();
-        case 2:
-            throw new IllegalStateException();
-        case 3:
-            throw new UnsupportedOperationException();
-        case 4:
-            throw new IOException();
-        default:
-            throw new AssertionError();
-        }
-    }
-
-    public void testNestedCatchClauses() throws Exception {
-        /*
-         * public static String call(int a, int b, int c) {
-         *   try {
-         *     DexGeneratorTest.thrower(a);
-         *     try {
-         *       DexGeneratorTest.thrower(b);
-         *     } catch (IllegalArgumentException) {
-         *       return "INNER";
-         *     }
-         *     DexGeneratorTest.thrower(c);
-         *     return "NONE";
-         *   } catch (IllegalArgumentException e) {
-         *     return "OUTER";
-         *   }
-         */
-        MethodId<?, String> methodId = GENERATED.getMethod(
-                Type.STRING, "call", Type.INT, Type.INT, Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localA = code.getParameter(0, Type.INT);
-        Local<Integer> localB = code.getParameter(1, Type.INT);
-        Local<Integer> localC = code.getParameter(2, Type.INT);
-        Local<String> localResult = code.newLocal(Type.STRING);
-        Label catchInner = code.newLabel();
-        Label catchOuter = code.newLabel();
-
-        Type<IllegalArgumentException> iaeType = Type.get(IllegalArgumentException.class);
-        code.addCatchClause(iaeType, catchOuter);
-
-        MethodId<?, ?> thrower = TEST_TYPE.getMethod(Type.VOID, "thrower", Type.INT);
-        code.invokeStatic(thrower, null, localA);
-
-        // for the inner catch clause, we stash the old label and put it back afterwards.
-        Label previousLabel = code.removeCatchClause(iaeType);
-        code.addCatchClause(iaeType, catchInner);
-        code.invokeStatic(thrower, null, localB);
-        code.removeCatchClause(iaeType);
-        code.addCatchClause(iaeType, previousLabel);
-        code.invokeStatic(thrower, null, localC);
-        code.loadConstant(localResult, "NONE");
-        code.returnValue(localResult);
-
-        code.mark(catchInner);
-        code.loadConstant(localResult, "INNER");
-        code.returnValue(localResult);
-
-        code.mark(catchOuter);
-        code.loadConstant(localResult, "OUTER");
-        code.returnValue(localResult);
-
-        Method method = getMethod();
-        assertEquals("OUTER", method.invoke(null, 1, 0, 0));
-        assertEquals("INNER", method.invoke(null, 0, 1, 0));
-        assertEquals("OUTER", method.invoke(null, 0, 0, 1));
-        assertEquals("NONE", method.invoke(null, 0, 0, 0));
-    }
-
-    public void testThrow() throws Exception {
-        /*
-         * public static void call() {
-         *   throw new IllegalStateException();
-         * }
-         */
-        MethodId<?, Void> methodId = GENERATED.getMethod(Type.VOID, "call");
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Type<IllegalStateException> iseType = Type.get(IllegalStateException.class);
-        MethodId<IllegalStateException, Void> iseConstructor = iseType.getConstructor();
-        Local<IllegalStateException> localIse = code.newLocal(iseType);
-        code.newInstance(localIse, iseConstructor);
-        code.throwValue(localIse);
-
-        try {
-            getMethod().invoke(null);
-            fail();
-        } catch (InvocationTargetException expected) {
-            assertEquals(IllegalStateException.class, expected.getCause().getClass());
-        }
-    }
-
-    public void testUnusedParameters() throws Exception {
-        /*
-         * public static void call(int unused1, long unused2, long unused3) {}
-         */
-        MethodId<?, Void> methodId = GENERATED.getMethod(
-                Type.VOID, "call", Type.INT, Type.LONG, Type.LONG);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        code.returnVoid();
-        getMethod().invoke(null, 1, 2, 3);
-    }
-
-    public void testFloatingPointCompare() throws Exception {
-        Method floatG = floatingPointCompareMethod(Type.FLOAT, 1);
-        assertEquals(-1, floatG.invoke(null, 1.0f, Float.POSITIVE_INFINITY));
-        assertEquals(-1, floatG.invoke(null, 1.0f, 2.0f));
-        assertEquals(0, floatG.invoke(null, 1.0f, 1.0f));
-        assertEquals(1, floatG.invoke(null, 2.0f, 1.0f));
-        assertEquals(1, floatG.invoke(null, 1.0f, Float.NaN));
-        assertEquals(1, floatG.invoke(null, Float.NaN, 1.0f));
-        assertEquals(1, floatG.invoke(null, Float.NaN, Float.NaN));
-        assertEquals(1, floatG.invoke(null, Float.NaN, Float.POSITIVE_INFINITY));
-
-        Method floatL = floatingPointCompareMethod(Type.FLOAT, -1);
-        assertEquals(-1, floatG.invoke(null, 1.0f, Float.POSITIVE_INFINITY));
-        assertEquals(-1, floatL.invoke(null, 1.0f, 2.0f));
-        assertEquals(0, floatL.invoke(null, 1.0f, 1.0f));
-        assertEquals(1, floatL.invoke(null, 2.0f, 1.0f));
-        assertEquals(-1, floatL.invoke(null, 1.0f, Float.NaN));
-        assertEquals(-1, floatL.invoke(null, Float.NaN, 1.0f));
-        assertEquals(-1, floatL.invoke(null, Float.NaN, Float.NaN));
-        assertEquals(-1, floatL.invoke(null, Float.NaN, Float.POSITIVE_INFINITY));
-
-        Method doubleG = floatingPointCompareMethod(Type.DOUBLE, 1);
-        assertEquals(-1, doubleG.invoke(null, 1.0, Double.POSITIVE_INFINITY));
-        assertEquals(-1, doubleG.invoke(null, 1.0, 2.0));
-        assertEquals(0, doubleG.invoke(null, 1.0, 1.0));
-        assertEquals(1, doubleG.invoke(null, 2.0, 1.0));
-        assertEquals(1, doubleG.invoke(null, 1.0, Double.NaN));
-        assertEquals(1, doubleG.invoke(null, Double.NaN, 1.0));
-        assertEquals(1, doubleG.invoke(null, Double.NaN, Double.NaN));
-        assertEquals(1, doubleG.invoke(null, Double.NaN, Double.POSITIVE_INFINITY));
-
-        Method doubleL = floatingPointCompareMethod(Type.DOUBLE, -1);
-        assertEquals(-1, doubleL.invoke(null, 1.0, Double.POSITIVE_INFINITY));
-        assertEquals(-1, doubleL.invoke(null, 1.0, 2.0));
-        assertEquals(0, doubleL.invoke(null, 1.0, 1.0));
-        assertEquals(1, doubleL.invoke(null, 2.0, 1.0));
-        assertEquals(-1, doubleL.invoke(null, 1.0, Double.NaN));
-        assertEquals(-1, doubleL.invoke(null, Double.NaN, 1.0));
-        assertEquals(-1, doubleL.invoke(null, Double.NaN, Double.NaN));
-        assertEquals(-1, doubleL.invoke(null, Double.NaN, Double.POSITIVE_INFINITY));
-    }
-
-    private <T extends Number> Method floatingPointCompareMethod(
-            Type<T> valueType, int nanValue) throws Exception {
-        /*
-         * public static int call(float a, float b) {
-         *     int result = a <=> b;
-         *     return result;
-         * }
-         */
-        reset();
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", valueType, valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<T> localA = code.getParameter(0, valueType);
-        Local<T> localB = code.getParameter(1, valueType);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        code.compare(localA, localB, localResult, nanValue);
-        code.returnValue(localResult);
-        return getMethod();
-    }
-
-    public void testLongCompare() throws Exception {
-        /*
-         * public static int call(long a, long b) {
-         *   int result = a <=> b;
-         *   return result;
-         * }
-         */
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.LONG, Type.LONG);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Long> localA = code.getParameter(0, Type.LONG);
-        Local<Long> localB = code.getParameter(1, Type.LONG);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        code.compare(localA, localB, localResult);
-        code.returnValue(localResult);
-
-        Method method = getMethod();
-        assertEquals(0, method.invoke(null, Long.MIN_VALUE, Long.MIN_VALUE));
-        assertEquals(-1, method.invoke(null, Long.MIN_VALUE, 0));
-        assertEquals(-1, method.invoke(null, Long.MIN_VALUE, Long.MAX_VALUE));
-        assertEquals(1, method.invoke(null, 0, Long.MIN_VALUE));
-        assertEquals(0, method.invoke(null, 0, 0));
-        assertEquals(-1, method.invoke(null, 0, Long.MAX_VALUE));
-        assertEquals(1, method.invoke(null, Long.MAX_VALUE, Long.MIN_VALUE));
-        assertEquals(1, method.invoke(null, Long.MAX_VALUE, 0));
-        assertEquals(0, method.invoke(null, Long.MAX_VALUE, Long.MAX_VALUE));
-    }
-
-    public void testArrayLength() throws Exception {
-        Method booleanArrayLength = arrayLengthMethod(BOOLEAN_ARRAY);
-        assertEquals(0, booleanArrayLength.invoke(null, new Object[] { new boolean[0] }));
-        assertEquals(5, booleanArrayLength.invoke(null, new Object[] { new boolean[5] }));
-
-        Method intArrayLength = arrayLengthMethod(INT_ARRAY);
-        assertEquals(0, intArrayLength.invoke(null, new Object[] { new int[0] }));
-        assertEquals(5, intArrayLength.invoke(null, new Object[] { new int[5] }));
-
-        Method longArrayLength = arrayLengthMethod(LONG_ARRAY);
-        assertEquals(0, longArrayLength.invoke(null, new Object[] { new long[0] }));
-        assertEquals(5, longArrayLength.invoke(null, new Object[] { new long[5] }));
-
-        Method objectArrayLength = arrayLengthMethod(OBJECT_ARRAY);
-        assertEquals(0, objectArrayLength.invoke(null, new Object[] { new Object[0] }));
-        assertEquals(5, objectArrayLength.invoke(null, new Object[] { new Object[5] }));
-
-        Method long2dArrayLength = arrayLengthMethod(LONG_2D_ARRAY);
-        assertEquals(0, long2dArrayLength.invoke(null, new Object[] { new long[0][0] }));
-        assertEquals(5, long2dArrayLength.invoke(null, new Object[] { new long[5][10] }));
-    }
-
-    private <T> Method arrayLengthMethod(Type<T> valueType) throws Exception {
-        /*
-         * public static int call(long[] array) {
-         *   int result = array.length;
-         *   return result;
-         * }
-         */
-        reset();
-        MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", valueType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<T> localArray = code.getParameter(0, valueType);
-        Local<Integer> localResult = code.newLocal(Type.INT);
-        code.arrayLength(localArray, localResult);
-        code.returnValue(localResult);
-        return getMethod();
-    }
-
-    public void testNewArray() throws Exception {
-        Method newBooleanArray = newArrayMethod(BOOLEAN_ARRAY);
-        assertEquals("[]", Arrays.toString((boolean[]) newBooleanArray.invoke(null, 0)));
-        assertEquals("[false, false, false]",
-                Arrays.toString((boolean[]) newBooleanArray.invoke(null, 3)));
-
-        Method newIntArray = newArrayMethod(INT_ARRAY);
-        assertEquals("[]", Arrays.toString((int[]) newIntArray.invoke(null, 0)));
-        assertEquals("[0, 0, 0]", Arrays.toString((int[]) newIntArray.invoke(null, 3)));
-
-        Method newLongArray = newArrayMethod(LONG_ARRAY);
-        assertEquals("[]", Arrays.toString((long[]) newLongArray.invoke(null, 0)));
-        assertEquals("[0, 0, 0]", Arrays.toString((long[]) newLongArray.invoke(null, 3)));
-
-        Method newObjectArray = newArrayMethod(OBJECT_ARRAY);
-        assertEquals("[]", Arrays.toString((Object[]) newObjectArray.invoke(null, 0)));
-        assertEquals("[null, null, null]",
-                Arrays.toString((Object[]) newObjectArray.invoke(null, 3)));
-
-        Method new2dLongArray = newArrayMethod(LONG_2D_ARRAY);
-        assertEquals("[]", Arrays.deepToString((long[][]) new2dLongArray.invoke(null, 0)));
-        assertEquals("[null, null, null]",
-                Arrays.deepToString((long[][]) new2dLongArray.invoke(null, 3)));
-    }
-
-    private <T> Method newArrayMethod(Type<T> valueType) throws Exception {
-        /*
-         * public static long[] call(int length) {
-         *   long[] result = new long[length];
-         *   return result;
-         * }
-         */
-        reset();
-        MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", Type.INT);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<Integer> localLength = code.getParameter(0, Type.INT);
-        Local<T> localResult = code.newLocal(valueType);
-        code.newArray(localLength, localResult);
-        code.returnValue(localResult);
-        return getMethod();
-    }
-
-    public void testReadAndWriteArray() throws Exception {
-        Method swapBooleanArray = arraySwapMethod(BOOLEAN_ARRAY, Type.BOOLEAN);
-        boolean[] booleans = new boolean[3];
-        assertEquals(false, swapBooleanArray.invoke(null, booleans, 1, true));
-        assertEquals("[false, true, false]", Arrays.toString(booleans));
-
-        Method swapIntArray = arraySwapMethod(INT_ARRAY, Type.INT);
-        int[] ints = new int[3];
-        assertEquals(0, swapIntArray.invoke(null, ints, 1, 5));
-        assertEquals("[0, 5, 0]", Arrays.toString(ints));
-
-        Method swapLongArray = arraySwapMethod(LONG_ARRAY, Type.LONG);
-        long[] longs = new long[3];
-        assertEquals(0L, swapLongArray.invoke(null, longs, 1, 6L));
-        assertEquals("[0, 6, 0]", Arrays.toString(longs));
-
-        Method swapObjectArray = arraySwapMethod(OBJECT_ARRAY, Type.OBJECT);
-        Object[] objects = new Object[3];
-        assertEquals(null, swapObjectArray.invoke(null, objects, 1, "X"));
-        assertEquals("[null, X, null]", Arrays.toString(objects));
-
-        Method swapLong2dArray = arraySwapMethod(LONG_2D_ARRAY, LONG_ARRAY);
-        long[][] longs2d = new long[3][];
-        assertEquals(null, swapLong2dArray.invoke(null, longs2d, 1, new long[] { 7 }));
-        assertEquals("[null, [7], null]", Arrays.deepToString(longs2d));
-    }
-
-    private <A, T> Method arraySwapMethod(Type<A> arrayType, Type<T> singleType)
-            throws Exception {
-        /*
-         * public static long swap(long[] array, int index, long newValue) {
-         *   long result = array[index];
-         *   array[index] = newValue;
-         *   return result;
-         * }
-         */
-        reset();
-        MethodId<?, T> methodId = GENERATED.getMethod(
-                singleType, "call", arrayType, Type.INT, singleType);
-        Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
-        Local<A> localArray = code.getParameter(0, arrayType);
-        Local<Integer> localIndex = code.getParameter(1, Type.INT);
-        Local<T> localNewValue = code.getParameter(2, singleType);
-        Local<T> localResult = code.newLocal(singleType);
-        code.aget(localArray, localIndex, localResult);
-        code.aput(localArray, localIndex, localNewValue);
-        code.returnValue(localResult);
-        return getMethod();
-    }
-
-    // TODO: fail if a label is unreachable (never navigated to)
-
-    // TODO: more strict type parameters: Integer on methods
-
-    // TODO: don't generate multiple times (?)
-
-    private void addDefaultConstructor() {
-        Code code = generator.declare(GENERATED.getConstructor(), ACC_PUBLIC | ACC_CONSTRUCTOR);
-        Local<?> thisRef = code.getThis(GENERATED);
-        code.invokeDirect(Type.OBJECT.getConstructor(), null, thisRef);
-        code.returnVoid();
-    }
-
-    /**
-     * Returns the generated method.
-     */
-    private Method getMethod() throws Exception {
-        Class<?> generated = loadAndGenerate();
-        for (Method method : generated.getMethods()) {
-            if (method.getName().equals("call")) {
-                return method;
-            }
-        }
-        throw new IllegalStateException("no call() method");
-    }
-
-    public static File getDataDirectory() throws Exception {
-        Class<?> environmentClass = Class.forName("android.os.Environment");
-        Method method = environmentClass.getMethod("getDataDirectory");
-        Object dataDirectory = method.invoke(null);
-        return (File) dataDirectory;
-    }
-
-    private Class<?> loadAndGenerate() throws Exception {
-        return generator.load(getClass().getClassLoader(),
-                getDataDirectory(), getDataDirectory()).loadClass("Generated");
-    }
-}
diff --git a/dx/junit-tests/com/android/dx/gen/ProxyBuilderTest.java b/dx/junit-tests/com/android/dx/gen/ProxyBuilderTest.java
deleted file mode 100644
index 070031c..0000000
--- a/dx/junit-tests/com/android/dx/gen/ProxyBuilderTest.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.Random;
-
-public class ProxyBuilderTest extends TestCase {
-    private FakeInvocationHandler fakeHandler = new FakeInvocationHandler();
-
-    public static class SimpleClass {
-        public String simpleMethod() {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testExampleOperation() throws Throwable {
-        fakeHandler.setFakeResult("expected");
-        SimpleClass proxy = proxyFor(SimpleClass.class).build();
-        assertEquals("expected", proxy.simpleMethod());
-    }
-
-    public static class ConstructorTakesArguments {
-        private final String argument;
-
-        public ConstructorTakesArguments(String arg) {
-            argument = arg;
-        }
-
-        public String method() {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testConstruction_SucceedsIfCorrectArgumentsProvided() throws Throwable {
-        ConstructorTakesArguments proxy = proxyFor(ConstructorTakesArguments.class)
-                .constructorArgTypes(String.class)
-                .constructorArgValues("hello")
-                .build();
-        assertEquals("hello", proxy.argument);
-        proxy.method();
-    }
-
-    public void testConstruction_FailsWithWrongNumberOfArguments() throws Throwable {
-        try {
-            proxyFor(ConstructorTakesArguments.class).build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public void testClassIsNotAccessbile_FailsWithUnsupportedOperationException() throws Exception {
-        class MethodVisibilityClass {
-        }
-        try {
-            proxyFor(MethodVisibilityClass.class).build();
-            fail();
-        } catch (UnsupportedOperationException expected) {}
-    }
-
-    private static class PrivateVisibilityClass {
-    }
-
-    public void testPrivateClass_FailsWithUnsupportedOperationException() throws Exception {
-        try {
-            proxyFor(PrivateVisibilityClass.class).build();
-            fail();
-        } catch (UnsupportedOperationException expected) {}
-    }
-
-    protected static class ProtectedVisibilityClass {
-        public String foo() {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testProtectedVisibility_WorksFine() throws Exception {
-        assertEquals("fake result", proxyFor(ProtectedVisibilityClass.class).build().foo());
-    }
-
-    public static class HasFinalMethod {
-        public String nonFinalMethod() {
-            return "non-final method";
-        }
-
-        public final String finalMethod() {
-            return "final method";
-        }
-    }
-
-    public void testCanProxyClassesWithFinalMethods_WillNotCallTheFinalMethod() throws Throwable {
-        HasFinalMethod proxy = proxyFor(HasFinalMethod.class).build();
-        assertEquals("final method", proxy.finalMethod());
-        assertEquals("fake result", proxy.nonFinalMethod());
-    }
-
-    public static class HasPrivateMethod {
-        private String result() {
-            return "expected";
-        }
-    }
-
-    public void testProxyingPrivateMethods_NotIntercepted() throws Throwable {
-        assertEquals("expected", proxyFor(HasPrivateMethod.class).build().result());
-    }
-
-    public static class HasPackagePrivateMethod {
-        String result() {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testProxyingPackagePrivateMethods_AreIntercepted() throws Throwable {
-        assertEquals("fake result", proxyFor(HasPackagePrivateMethod.class).build().result());
-    }
-
-    public static class HasProtectedMethod {
-        protected String result() {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testProxyingProtectedMethods_AreIntercepted() throws Throwable {
-        assertEquals("fake result", proxyFor(HasProtectedMethod.class).build().result());
-    }
-
-    public static class HasVoidMethod {
-        public void dangerousMethod() {
-            fail();
-        }
-    }
-
-    public void testVoidMethod_ShouldNotThrowRuntimeException() throws Throwable {
-        proxyFor(HasVoidMethod.class).build().dangerousMethod();
-    }
-
-    public void testObjectMethodsAreAlsoProxied() throws Throwable {
-        Object proxy = proxyFor(Object.class).build();
-        fakeHandler.setFakeResult("mystring");
-        assertEquals("mystring", proxy.toString());
-        fakeHandler.setFakeResult(-1);
-        assertEquals(-1, proxy.hashCode());
-        fakeHandler.setFakeResult(false);
-        assertEquals(false, proxy.equals(proxy));
-    }
-
-    public static class AllPrimitiveMethods {
-        public boolean getBoolean() { return true; }
-        public int getInt() { return 1; }
-        public byte getByte() { return 2; }
-        public long getLong() { return 3L; }
-        public short getShort() { return 4; }
-        public float getFloat() { return 5f; }
-        public double getDouble() { return 6.0; }
-        public char getChar() { return 'c'; }
-    }
-
-    public void testAllPrimitiveReturnTypes() throws Throwable {
-        AllPrimitiveMethods proxy = proxyFor(AllPrimitiveMethods.class).build();
-        fakeHandler.setFakeResult(false);
-        assertEquals(false, proxy.getBoolean());
-        fakeHandler.setFakeResult(8);
-        assertEquals(8, proxy.getInt());
-        fakeHandler.setFakeResult((byte) 9);
-        assertEquals(9, proxy.getByte());
-        fakeHandler.setFakeResult(10L);
-        assertEquals(10, proxy.getLong());
-        fakeHandler.setFakeResult((short) 11);
-        assertEquals(11, proxy.getShort());
-        fakeHandler.setFakeResult(12f);
-        assertEquals(12f, proxy.getFloat());
-        fakeHandler.setFakeResult(13.0);
-        assertEquals(13.0, proxy.getDouble());
-        fakeHandler.setFakeResult('z');
-        assertEquals('z', proxy.getChar());
-    }
-
-    public static class PassThroughAllPrimitives {
-        public boolean getBoolean(boolean input) { return input; }
-        public int getInt(int input) { return input; }
-        public byte getByte(byte input) { return input; }
-        public long getLong(long input) { return input; }
-        public short getShort(short input) { return input; }
-        public float getFloat(float input) { return input; }
-        public double getDouble(double input) { return input; }
-        public char getChar(char input) { return input; }
-        public String getString(String input) { return input; }
-        public Object getObject(Object input) { return input; }
-        public void getNothing() {}
-    }
-
-    public static class InvokeSuperHandler implements InvocationHandler {
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            return ProxyBuilder.callSuper(proxy, method, args);
-        }
-    }
-
-    public void testPassThroughWorksForAllPrimitives() throws Exception {
-        PassThroughAllPrimitives proxy = proxyFor(PassThroughAllPrimitives.class)
-                .handler(new InvokeSuperHandler())
-                .build();
-        assertEquals(false, proxy.getBoolean(false));
-        assertEquals(true, proxy.getBoolean(true));
-        assertEquals(0, proxy.getInt(0));
-        assertEquals(1, proxy.getInt(1));
-        assertEquals((byte) 2, proxy.getByte((byte) 2));
-        assertEquals((byte) 3, proxy.getByte((byte) 3));
-        assertEquals(4L, proxy.getLong(4L));
-        assertEquals(5L, proxy.getLong(5L));
-        assertEquals((short) 6, proxy.getShort((short) 6));
-        assertEquals((short) 7, proxy.getShort((short) 7));
-        assertEquals(8f, proxy.getFloat(8f));
-        assertEquals(9f, proxy.getFloat(9f));
-        assertEquals(10.0, proxy.getDouble(10.0));
-        assertEquals(11.0, proxy.getDouble(11.0));
-        assertEquals('a', proxy.getChar('a'));
-        assertEquals('b', proxy.getChar('b'));
-        assertEquals("asdf", proxy.getString("asdf"));
-        assertEquals("qwer", proxy.getString("qwer"));
-        assertEquals(null, proxy.getString(null));
-        Object a = new Object();
-        assertEquals(a, proxy.getObject(a));
-        assertEquals(null, proxy.getObject(null));
-        proxy.getNothing();
-    }
-
-    public static class ExtendsAllPrimitiveMethods extends AllPrimitiveMethods {
-        public int example() { return 0; }
-    }
-
-    public void testProxyWorksForSuperclassMethodsAlso() throws Throwable {
-        ExtendsAllPrimitiveMethods proxy = proxyFor(ExtendsAllPrimitiveMethods.class).build();
-        fakeHandler.setFakeResult(99);
-        assertEquals(99, proxy.example());
-        assertEquals(99, proxy.getInt());
-        assertEquals(99, proxy.hashCode());
-    }
-
-    public static class HasOddParams {
-        public long method(int first, Integer second) {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testMixingBoxedAndUnboxedParams() throws Throwable {
-        HasOddParams proxy = proxyFor(HasOddParams.class).build();
-        fakeHandler.setFakeResult(99L);
-        assertEquals(99L, proxy.method(1, Integer.valueOf(2)));
-    }
-
-    public static class SingleInt {
-        public String getString(int value) {
-            throw new AssertionFailedError();
-        }
-    }
-
-    public void testSinglePrimitiveParameter() throws Throwable {
-        InvocationHandler handler = new InvocationHandler() {
-            @Override
-            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                return "asdf" + ((Integer) args[0]).intValue();
-            }
-        };
-        assertEquals("asdf1", proxyFor(SingleInt.class).handler(handler).build().getString(1));
-    }
-
-    public static class TwoConstructors {
-        private final String string;
-
-        public TwoConstructors() {
-            string = "no-arg";
-        }
-
-        public TwoConstructors(boolean unused) {
-            string = "one-arg";
-        }
-    }
-
-    public void testNoConstructorArguments_CallsNoArgConstructor() throws Throwable {
-        TwoConstructors twoConstructors = proxyFor(TwoConstructors.class).build();
-        assertEquals("no-arg", twoConstructors.string);
-    }
-
-    public void testWithoutInvocationHandler_ThrowsIllegalArgumentException() throws Throwable {
-        try {
-            ProxyBuilder.forClass(TwoConstructors.class)
-                    .dexCache(DexGeneratorTest.getDataDirectory())
-                    .build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public static class HardToConstructCorrectly {
-        public HardToConstructCorrectly() { fail(); }
-        public HardToConstructCorrectly(Runnable ignored) { fail(); }
-        public HardToConstructCorrectly(Exception ignored) { fail(); }
-        public HardToConstructCorrectly(Boolean ignored) { /* safe */ }
-        public HardToConstructCorrectly(Integer ignored) { fail(); }
-    }
-
-    public void testHardToConstruct_WorksIfYouSpecifyTheConstructorCorrectly() throws Throwable {
-        proxyFor(HardToConstructCorrectly.class)
-                .constructorArgTypes(Boolean.class)
-                .constructorArgValues(true)
-                .build();
-    }
-
-    public void testHardToConstruct_EvenWorksWhenArgsAreAmbiguous() throws Throwable {
-        proxyFor(HardToConstructCorrectly.class)
-                .constructorArgTypes(Boolean.class)
-                .constructorArgValues(new Object[] { null })
-                .build();
-    }
-
-    public void testHardToConstruct_DoesNotInferTypesFromValues() throws Throwable {
-        try {
-            proxyFor(HardToConstructCorrectly.class)
-                    .constructorArgValues(true)
-                    .build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public void testDefaultProxyHasSuperMethodToAccessOriginal() throws Exception {
-        Object objectProxy = proxyFor(Object.class).build();
-        assertNotNull(objectProxy.getClass().getMethod("super_hashCode"));
-    }
-
-    public static class PrintsOddAndValue {
-        public String method(int value) {
-            return "odd " + value;
-        }
-    }
-
-    public void testSometimesDelegateToSuper() throws Exception {
-        InvocationHandler delegatesOddValues = new InvocationHandler() {
-            @Override
-            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                if (method.getName().equals("method")) {
-                    int intValue = ((Integer) args[0]).intValue();
-                    if (intValue % 2 == 0) {
-                        return "even " + intValue;
-                    }
-                }
-                return ProxyBuilder.callSuper(proxy, method, args);
-            }
-        };
-        PrintsOddAndValue proxy = proxyFor(PrintsOddAndValue.class)
-                .handler(delegatesOddValues)
-                .build();
-        assertEquals("even 0", proxy.method(0));
-        assertEquals("odd 1", proxy.method(1));
-        assertEquals("even 2", proxy.method(2));
-        assertEquals("odd 3", proxy.method(3));
-    }
-
-    public static class DoubleReturn {
-        public double getValue() {
-            return 2.0;
-        }
-    }
-
-    public void testUnboxedResult() throws Exception {
-        fakeHandler.fakeResult = 2.0;
-        assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue());
-    }
-
-    public static void staticMethod() {
-    }
-
-    public void testDoesNotOverrideStaticMethods() throws Exception {
-        // Method should exist on this test class itself.
-        ProxyBuilderTest.class.getDeclaredMethod("staticMethod");
-        // Method should not exist on the subclass.
-        try {
-            proxyFor(ProxyBuilderTest.class).build().getClass().getDeclaredMethod("staticMethod");
-            fail();
-        } catch (NoSuchMethodException expected) {}
-    }
-
-    public void testIllegalCacheDirectory() throws Exception {
-        try {
-          proxyFor(Object.class).dexCache(new File("//////")).build();
-          fail();
-        } catch (DexCacheException expected) {}
-    }
-
-    public void testInvalidConstructorSpecification() throws Exception {
-        try {
-            proxyFor(Object.class)
-                    .constructorArgTypes(String.class, Boolean.class)
-                    .constructorArgValues("asdf", true)
-                    .build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public static abstract class AbstractClass {
-        public abstract Object getValue();
-    }
-
-    public void testAbstractClassBehaviour() throws Exception {
-        assertEquals("fake result", proxyFor(AbstractClass.class).build().getValue());
-    }
-
-    public static class CtorHasDeclaredException {
-        public CtorHasDeclaredException() throws IOException {
-            throw new IOException();
-        }
-    }
-
-    public static class CtorHasRuntimeException {
-        public CtorHasRuntimeException() {
-            throw new RuntimeException("my message");
-        }
-    }
-
-    public static class CtorHasError {
-        public CtorHasError() {
-            throw new Error("my message again");
-        }
-    }
-
-    public void testParentConstructorThrowsDeclaredException() throws Exception {
-        try {
-            proxyFor(CtorHasDeclaredException.class).build();
-            fail();
-        } catch (UndeclaredThrowableException expected) {
-            assertTrue(expected.getCause() instanceof IOException);
-        }
-        try {
-            proxyFor(CtorHasRuntimeException.class).build();
-            fail();
-        } catch (RuntimeException expected) {
-            assertEquals("my message", expected.getMessage());
-        }
-        try {
-            proxyFor(CtorHasError.class).build();
-            fail();
-        } catch (Error expected) {
-            assertEquals("my message again", expected.getMessage());
-        }
-    }
-
-    public void testGetInvocationHandler_NormalOperation() throws Exception {
-        Object proxy = proxyFor(Object.class).build();
-        assertSame(fakeHandler, ProxyBuilder.getInvocationHandler(proxy));
-    }
-
-    public void testGetInvocationHandler_NotAProxy() {
-        try {
-            ProxyBuilder.getInvocationHandler(new Object());
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public static class ReturnsObject {
-        public Object getValue() {
-            return new Object();
-        }
-    }
-
-    public static class ReturnsString extends ReturnsObject {
-        @Override
-        public String getValue() {
-            return "a string";
-        }
-    }
-
-    public void testCovariantReturnTypes_NormalBehaviour() throws Exception {
-        String expected = "some string";
-        fakeHandler.setFakeResult(expected);
-        assertSame(expected, proxyFor(ReturnsObject.class).build().getValue());
-        assertSame(expected, proxyFor(ReturnsString.class).build().getValue());
-    }
-
-    public void testCovariantReturnTypes_WrongReturnType() throws Exception {
-        try {
-            fakeHandler.setFakeResult(new Object());
-            proxyFor(ReturnsString.class).build().getValue();
-            fail();
-        } catch (ClassCastException expected) {}
-    }
-
-    public void testCaching_ShouldWork() {
-        // TODO: We're not supporting caching yet.  But we should as soon as possible.
-        fail();
-    }
-
-    public void testSubclassOfRandom() throws Exception {
-        proxyFor(Random.class)
-                .handler(new InvokeSuperHandler())
-                .build();
-    }
-
-    /** Simple helper to add the most common args for this test to the proxy builder. */
-    private <T> ProxyBuilder<T> proxyFor(Class<T> clazz) throws Exception {
-        return ProxyBuilder.forClass(clazz)
-                .handler(fakeHandler)
-                .dexCache(DexGeneratorTest.getDataDirectory());
-    }
-
-    private static class FakeInvocationHandler implements InvocationHandler {
-        private Object fakeResult = "fake result";
-
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            return fakeResult;
-        }
-
-        public void setFakeResult(Object result) {
-            fakeResult = result;
-        }
-    }
-}
diff --git a/dx/junit-tests/com/android/dx/gen/TypeTest.java b/dx/junit-tests/com/android/dx/gen/TypeTest.java
deleted file mode 100644
index a7e17e8..0000000
--- a/dx/junit-tests/com/android/dx/gen/TypeTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import junit.framework.TestCase;
-
-public final class TypeTest extends TestCase {
-    public void testGetType() {
-        assertEquals("Ljava/lang/String;", Type.get(String.class).getName());
-        assertEquals("[Ljava/lang/String;", Type.get(String[].class).getName());
-        assertEquals("[[Ljava/lang/String;", Type.get(String[][].class).getName());
-        assertEquals("I", Type.get(int.class).getName());
-        assertEquals("[I", Type.get(int[].class).getName());
-        assertEquals("[[I", Type.get(int[][].class).getName());
-    }
-}
diff --git a/dx/src/com/android/dx/gen/BinaryOp.java b/dx/src/com/android/dx/gen/BinaryOp.java
deleted file mode 100644
index 65a2998..0000000
--- a/dx/src/com/android/dx/gen/BinaryOp.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * An operation on two values of the same type.
- *
- * <p>Math operations ({@link #ADD}, {@link #SUBTRACT}, {@link #MULTIPLY},
- * {@link #DIVIDE}, and {@link #REMAINDER}) support ints, longs, floats and
- * doubles.
- *
- * <p>Bit operations ({@link #AND}, {@link #OR}, {@link #XOR}, {@link
- * #SHIFT_LEFT}, {@link #SHIFT_RIGHT}, {@link #UNSIGNED_SHIFT_RIGHT}) support
- * ints and longs.
- *
- * <p>Division by zero behaves differently depending on the operand type.
- * For int and long operands, {@link #DIVIDE} and {@link #REMAINDER} throw
- * {@link ArithmeticException} if {@code b == 0}. For float and double operands,
- * the operations return {@code NaN}.
- */
-public enum BinaryOp {
-    /** {@code a + b} */
-    ADD() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opAdd(types);
-        }
-    },
-
-    /** {@code a - b} */
-    SUBTRACT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opSub(types);
-        }
-    },
-
-    /** {@code a * b} */
-    MULTIPLY() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opMul(types);
-        }
-    },
-
-    /** {@code a / b} */
-    DIVIDE() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opDiv(types);
-        }
-    },
-
-    /** {@code a % b} */
-    REMAINDER() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opRem(types);
-        }
-    },
-
-    /** {@code a & b} */
-    AND() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opAnd(types);
-        }
-    },
-
-    /** {@code a | b} */
-    OR() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opOr(types);
-        }
-    },
-
-    /** {@code a ^ b} */
-    XOR() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opXor(types);
-        }
-    },
-
-    /** {@code a << b} */
-    SHIFT_LEFT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opShl(types);
-        }
-    },
-
-    /** {@code a >> b} */
-    SHIFT_RIGHT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opShr(types);
-        }
-    },
-
-    /** {@code a >>> b} */
-    UNSIGNED_SHIFT_RIGHT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opUshr(types);
-        }
-    };
-
-    abstract Rop rop(com.android.dx.rop.type.TypeList types);
-}
diff --git a/dx/src/com/android/dx/gen/Code.java b/dx/src/com/android/dx/gen/Code.java
deleted file mode 100644
index 3868cd3..0000000
--- a/dx/src/com/android/dx/gen/Code.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.PlainCstInsn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import static com.android.dx.rop.code.Rop.BRANCH_GOTO;
-import static com.android.dx.rop.code.Rop.BRANCH_NONE;
-import static com.android.dx.rop.code.Rop.BRANCH_RETURN;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.code.ThrowingCstInsn;
-import com.android.dx.rop.code.ThrowingInsn;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.type.StdTypeList;
-import static com.android.dx.rop.type.Type.BT_BYTE;
-import static com.android.dx.rop.type.Type.BT_CHAR;
-import static com.android.dx.rop.type.Type.BT_INT;
-import static com.android.dx.rop.type.Type.BT_SHORT;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Builds a sequence of instructions.
- */
-public final class Code {
-    private final MethodId<?, ?> method;
-    /**
-     * All allocated labels. Although the order of the labels in this list
-     * shouldn't impact behavior, it is used to determine basic block indices.
-     */
-    private final List<Label> labels = new ArrayList<Label>();
-
-    /**
-     * The label currently receiving instructions. This is null if the most
-     * recent instruction was a return or goto.
-     */
-    private Label currentLabel;
-
-    /** true once we've fixed the positions of the parameter registers */
-    private boolean localsInitialized;
-
-    private final Local<?> thisLocal;
-    private final List<Local<?>> parameters = new ArrayList<Local<?>>();
-    private final List<Local<?>> locals = new ArrayList<Local<?>>();
-    private SourcePosition sourcePosition = SourcePosition.NO_INFO;
-    private final List<Type<?>> catchTypes = new ArrayList<Type<?>>();
-    private final List<Label> catchLabels = new ArrayList<Label>();
-    private StdTypeList catches = StdTypeList.EMPTY;
-
-    Code(DexGenerator.MethodDeclaration methodDeclaration) {
-        this.method = methodDeclaration.method;
-        this.thisLocal = methodDeclaration.isStatic()
-                ? null
-                : Local.get(this, method.declaringType);
-        for (Type<?> parameter : method.parameters.types) {
-            parameters.add(Local.get(this, parameter));
-        }
-        this.currentLabel = newLabel();
-        this.currentLabel.marked = true;
-    }
-
-    public <T> Local<T> newLocal(Type<T> type) {
-        if (localsInitialized) {
-            throw new IllegalStateException("Cannot allocate locals after adding instructions");
-        }
-        Local<T> result = Local.get(this, type);
-        locals.add(result);
-        return result;
-    }
-
-    public <T> Local<T> getParameter(int index, Type<T> type) {
-        return coerce(parameters.get(index), type);
-    }
-
-    public <T> Local<T> getThis(Type<T> type) {
-        if (thisLocal == null) {
-            throw new IllegalStateException("static methods cannot access 'this'");
-        }
-        return coerce(thisLocal, type);
-    }
-
-    @SuppressWarnings("unchecked") // guarded by an equals check
-    private <T> Local<T> coerce(Local<?> local, Type<T> expectedType) {
-        if (!local.type.equals(expectedType)) {
-            throw new IllegalArgumentException(
-                    "requested " + expectedType + " but was " + local.type);
-        }
-        return (Local<T>) local;
-    }
-
-    /**
-     * Assigns registers to locals. From the spec:
-     *  "the N arguments to a method land in the last N registers of the
-     *   method's invocation frame, in order. Wide arguments consume two
-     *   registers. Instance methods are passed a this reference as their
-     *   first argument."
-     *
-     * In addition to assigning registers to each of the locals, this creates
-     * instructions to move parameters into their initial registers. These
-     * instructions are inserted before the code's first real instruction.
-     */
-    void initializeLocals() {
-        if (localsInitialized) {
-            throw new AssertionError();
-        }
-        localsInitialized = true;
-
-        int reg = 0;
-        for (Local<?> local : locals) {
-            reg += local.initialize(reg);
-        }
-        if (thisLocal != null) {
-            reg += thisLocal.initialize(reg);
-        }
-        int firstParamReg = reg;
-
-        List<Insn> moveParameterInstructions = new ArrayList<Insn>();
-        for (Local<?> local : parameters) {
-            CstInteger paramConstant = CstInteger.make(reg - firstParamReg);
-            reg += local.initialize(reg);
-            moveParameterInstructions.add(new PlainCstInsn(Rops.opMoveParam(local.type.ropType),
-                    sourcePosition, local.spec(), RegisterSpecList.EMPTY, paramConstant));
-        }
-        labels.get(0).instructions.addAll(0, moveParameterInstructions);
-    }
-
-    int paramSize() {
-        int result = 0;
-        for (Local<?> local : parameters) {
-            result += local.size();
-        }
-        return result;
-    }
-
-    // labels
-
-    /**
-     * Creates a new label for use as a branch target. The new label must have
-     * code attached to it later by calling {@link #mark(Label)}.
-     */
-    public Label newLabel() {
-        Label result = new Label();
-        labels.add(result);
-        return result;
-    }
-
-    /**
-     * Start defining instructions for the named label.
-     */
-    public void mark(Label label) {
-        if (label.marked) {
-            throw new IllegalStateException("already marked");
-        }
-        label.marked = true;
-        if (currentLabel != null) {
-            jump(label); // blocks must end with a branch, return or throw
-        }
-        currentLabel = label;
-    }
-
-    public void jump(Label target) {
-        addInstruction(new PlainInsn(Rops.GOTO, sourcePosition, null, RegisterSpecList.EMPTY),
-                target);
-    }
-
-    public void addCatchClause(Type<?> throwable, Label catchClause) {
-        if (catchTypes.contains(throwable)) {
-            throw new IllegalArgumentException("Already caught: " + throwable);
-        }
-        catchTypes.add(throwable);
-        catches = toTypeList(catchTypes);
-        catchLabels.add(catchClause);
-    }
-
-    public Label removeCatchClause(Type<?> throwable) {
-        int index = catchTypes.indexOf(throwable);
-        if (index == -1) {
-            throw new IllegalArgumentException("No catch clause: " + throwable);
-        }
-        catchTypes.remove(index);
-        catches = toTypeList(catchTypes);
-        return catchLabels.remove(index);
-    }
-
-    public void throwValue(Local<?> throwable) {
-        addInstruction(new ThrowingInsn(Rops.THROW, sourcePosition,
-                RegisterSpecList.make(throwable.spec()), catches));
-    }
-
-    private StdTypeList toTypeList(List<Type<?>> types) {
-        StdTypeList result = new StdTypeList(types.size());
-        for (int i = 0; i < types.size(); i++) {
-            result.set(i, types.get(i).ropType);
-        }
-        return result;
-    }
-
-    private void addInstruction(Insn insn) {
-        addInstruction(insn, null);
-    }
-
-    /**
-     * @param branch the branches to follow; interpretation depends on the
-     *     instruction's branchingness.
-     */
-    private void addInstruction(Insn insn, Label branch) {
-        if (currentLabel == null || !currentLabel.marked) {
-            throw new IllegalStateException("no current label");
-        }
-        currentLabel.instructions.add(insn);
-
-        switch (insn.getOpcode().getBranchingness()) {
-        case BRANCH_NONE:
-            if (branch != null) {
-                throw new IllegalArgumentException("unexpected branch: " + branch);
-            }
-            return;
-
-        case BRANCH_RETURN:
-            if (branch != null) {
-                throw new IllegalArgumentException("unexpected branch: " + branch);
-            }
-            currentLabel = null;
-            break;
-
-        case BRANCH_GOTO:
-            if (branch == null) {
-                throw new IllegalArgumentException("branch == null");
-            }
-            currentLabel.primarySuccessor = branch;
-            currentLabel = null;
-            break;
-
-        case Rop.BRANCH_IF:
-            if (branch == null) {
-                throw new IllegalArgumentException("branch == null");
-            }
-            splitCurrentLabel(branch, Collections.<Label>emptyList());
-            break;
-
-        case Rop.BRANCH_THROW:
-            if (branch != null) {
-                throw new IllegalArgumentException("unexpected branch: " + branch);
-            }
-            splitCurrentLabel(null, new ArrayList<Label>(catchLabels));
-            break;
-
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    /**
-     * Closes the current label and starts a new one.
-     *
-     * @param catchLabels an immutable list of catch labels
-     */
-    private void splitCurrentLabel(Label alternateSuccessor, List<Label> catchLabels) {
-        Label newLabel = newLabel();
-        currentLabel.primarySuccessor = newLabel;
-        currentLabel.alternateSuccessor = alternateSuccessor;
-        currentLabel.catchLabels = catchLabels;
-        currentLabel = newLabel;
-        currentLabel.marked = true;
-    }
-
-    // instructions: constants
-
-    public <T> void loadConstant(Local<T> target, T value) {
-        Rop rop = value == null
-                ? Rops.CONST_OBJECT_NOTHROW
-                : Rops.opConst(target.type.ropType);
-        if (rop.getBranchingness() == BRANCH_NONE) {
-            addInstruction(new PlainCstInsn(rop, sourcePosition, target.spec(),
-                    RegisterSpecList.EMPTY, Constants.getConstant(value)));
-        } else {
-            addInstruction(new ThrowingCstInsn(rop, sourcePosition,
-                    RegisterSpecList.EMPTY, catches, Constants.getConstant(value)));
-            moveResult(target, true);
-        }
-    }
-
-    // instructions: unary
-
-    public <T> void negate(Local<T> source, Local<T> target) {
-        unary(Rops.opNeg(source.type.ropType), source, target);
-    }
-
-    public <T> void not(Local<T> source, Local<T> target) {
-        unary(Rops.opNot(source.type.ropType), source, target);
-    }
-
-    public void numericCast(Local<?> source, Local<?> target) {
-        unary(getCastRop(source.type.ropType, target.type.ropType), source, target);
-    }
-
-    private Rop getCastRop(com.android.dx.rop.type.Type sourceType,
-            com.android.dx.rop.type.Type targetType) {
-        if (sourceType.getBasicType() == BT_INT) {
-            switch (targetType.getBasicType()) {
-            case BT_SHORT:
-                return Rops.TO_SHORT;
-            case BT_CHAR:
-                return Rops.TO_CHAR;
-            case BT_BYTE:
-                return Rops.TO_BYTE;
-            }
-        }
-        return Rops.opConv(targetType, sourceType);
-    }
-
-    private void unary(Rop rop, Local<?> source, Local<?> target) {
-        addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), source.spec()));
-    }
-
-    // instructions: binary
-
-    public <T> void op(BinaryOp op, Local<T> target, Local<T> a, Local<T> b) {
-        Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
-        RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec());
-
-        if (rop.getBranchingness() == BRANCH_NONE) {
-            addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources));
-        } else {
-            addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches));
-            moveResult(target, true);
-        }
-    }
-
-    // instructions: branches
-
-    /**
-     * Compare ints. If the comparison is true, execution jumps to {@code
-     * trueLabel}. If it is false, execution continues to the next instruction.
-     */
-    public <T> void compare(Comparison comparison, Local<T> a, Local<T> b, Label trueLabel) {
-        if (trueLabel == null) {
-            throw new IllegalArgumentException();
-        }
-        Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
-        addInstruction(new PlainInsn(rop, sourcePosition, null,
-                RegisterSpecList.make(a.spec(), b.spec())), trueLabel);
-    }
-
-    /**
-     * Compare floats or doubles.
-     */
-    public <T extends Number> void compare(Local<T> a, Local<T> b, Local<Integer> target,
-            int nanValue) {
-        Rop rop;
-        if (nanValue == 1) {
-            rop = Rops.opCmpg(a.type.ropType);
-        } else if (nanValue == -1) {
-            rop = Rops.opCmpl(a.type.ropType);
-        } else {
-            throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue);
-        }
-        addInstruction(new PlainInsn(rop, sourcePosition, target.spec(),
-                RegisterSpecList.make(a.spec(), b.spec())));
-    }
-
-    /**
-     * Compare longs.
-     */
-    public <T> void compare(Local<T> a, Local<T> b, Local<?> target) {
-        addInstruction(new PlainInsn(Rops.CMPL_LONG, sourcePosition, target.spec(),
-                RegisterSpecList.make(a.spec(), b.spec())));
-    }
-
-    // instructions: fields
-
-    public <D, V> void iget(FieldId<D, V> fieldId, Local<D> instance, Local<V> target) {
-        addInstruction(new ThrowingCstInsn(Rops.opGetField(target.type.ropType), sourcePosition,
-                RegisterSpecList.make(instance.spec()), catches, fieldId.constant));
-        moveResult(target, true);
-    }
-
-    public <D, V> void iput(FieldId<D, V> fieldId, Local<D> instance, Local<V> source) {
-        addInstruction(new ThrowingCstInsn(Rops.opPutField(source.type.ropType), sourcePosition,
-                RegisterSpecList.make(source.spec(), instance.spec()), catches, fieldId.constant));
-    }
-
-    public <V> void sget(FieldId<?, V> fieldId, Local<V> target) {
-        addInstruction(new ThrowingCstInsn(Rops.opGetStatic(target.type.ropType), sourcePosition,
-                RegisterSpecList.EMPTY, catches, fieldId.constant));
-        moveResult(target, true);
-    }
-
-    public <V> void sput(FieldId<?, V> fieldId, Local<V> source) {
-        addInstruction(new ThrowingCstInsn(Rops.opPutStatic(source.type.ropType), sourcePosition,
-                RegisterSpecList.make(source.spec()), catches, fieldId.constant));
-    }
-
-    // instructions: invoke
-
-    public <T> void newInstance(Local<T> target, MethodId<T, Void> constructor, Local<?>... args) {
-        if (target == null) {
-            throw new IllegalArgumentException();
-        }
-        addInstruction(new ThrowingCstInsn(Rops.NEW_INSTANCE, sourcePosition,
-                RegisterSpecList.EMPTY, catches, constructor.declaringType.constant));
-        moveResult(target, true);
-        invokeDirect(constructor, null, target, args);
-    }
-
-    public <R> void invokeStatic(MethodId<?, R> method, Local<? super R> target, Local<?>... args) {
-        invoke(Rops.opInvokeStatic(method.prototype(true)), method, target, null, args);
-    }
-
-    public <D, R> void invokeVirtual(MethodId<D, R> method, Local<? super R> target,
-            Local<? extends D> object, Local<?>... args) {
-        invoke(Rops.opInvokeVirtual(method.prototype(true)), method, target, object, args);
-    }
-
-    public <D, R> void invokeDirect(MethodId<D, R> method, Local<? super R> target,
-            Local<? extends D> object, Local<?>... args) {
-        invoke(Rops.opInvokeDirect(method.prototype(true)), method, target, object, args);
-    }
-
-    public <D, R> void invokeSuper(MethodId<D, R> method, Local<? super R> target,
-            Local<? extends D> object, Local<?>... args) {
-        invoke(Rops.opInvokeSuper(method.prototype(true)), method, target, object, args);
-    }
-
-    public <D, R> void invokeInterface(MethodId<D, R> method, Local<? super R> target,
-            Local<? extends D> object, Local<?>... args) {
-        invoke(Rops.opInvokeInterface(method.prototype(true)), method, target, object, args);
-    }
-
-    private <D, R> void invoke(Rop rop, MethodId<D, R> method, Local<? super R> target,
-            Local<? extends D> object, Local<?>... args) {
-        addInstruction(new ThrowingCstInsn(rop, sourcePosition, concatenate(object, args),
-                catches, method.constant));
-        if (target != null) {
-            moveResult(target, false);
-        }
-    }
-
-    // instructions: types
-
-    public void instanceOfType(Local<?> target, Local<?> source, Type<?> type) {
-        addInstruction(new ThrowingCstInsn(Rops.INSTANCE_OF, sourcePosition,
-                RegisterSpecList.make(source.spec()), catches, type.constant));
-        moveResult(target, true);
-    }
-
-    public void typeCast(Local<?> source, Local<?> target) {
-        addInstruction(new ThrowingCstInsn(Rops.CHECK_CAST, sourcePosition,
-                RegisterSpecList.make(source.spec()), catches, target.type.constant));
-        moveResult(target, true);
-    }
-
-    // instructions: arrays
-
-    public <T> void arrayLength(Local<T> array, Local<Integer> target) {
-        addInstruction(new ThrowingInsn(Rops.ARRAY_LENGTH, sourcePosition,
-                RegisterSpecList.make(array.spec()), catches));
-        moveResult(target, true);
-    }
-
-    public <T> void newArray(Local<Integer> length, Local<T> target) {
-        addInstruction(new ThrowingCstInsn(Rops.opNewArray(target.type.ropType), sourcePosition,
-                RegisterSpecList.make(length.spec()), catches, target.type.constant));
-        moveResult(target, true);
-    }
-
-    public void aget(Local<?> array, Local<Integer> index, Local<?> target) {
-        addInstruction(new ThrowingInsn(Rops.opAget(target.type.ropType), sourcePosition,
-                RegisterSpecList.make(array.spec(), index.spec()), catches));
-        moveResult(target, true);
-    }
-
-    public void aput(Local<?> array, Local<Integer> index, Local<?> source) {
-        addInstruction(new ThrowingInsn(Rops.opAput(source.type.ropType), sourcePosition,
-                RegisterSpecList.make(source.spec(), array.spec(), index.spec()), catches));
-    }
-
-    // instructions: return
-
-    public void returnVoid() {
-        if (!method.returnType.equals(Type.VOID)) {
-            throw new IllegalArgumentException("declared " + method.returnType
-                    + " but returned void");
-        }
-        addInstruction(new PlainInsn(Rops.RETURN_VOID, sourcePosition, null,
-                RegisterSpecList.EMPTY));
-    }
-
-    public void returnValue(Local<?> result) {
-        if (!result.type.equals(method.returnType)) {
-            // TODO: this is probably too strict.
-            throw new IllegalArgumentException("declared " + method.returnType
-                    + " but returned " + result.type);
-        }
-        addInstruction(new PlainInsn(Rops.opReturn(result.type.ropType), sourcePosition,
-                null, RegisterSpecList.make(result.spec())));
-    }
-
-    private void moveResult(Local<?> target, boolean afterNonInvokeThrowingInsn) {
-        Rop rop = afterNonInvokeThrowingInsn
-                ? Rops.opMoveResultPseudo(target.type.ropType)
-                : Rops.opMoveResult(target.type.ropType);
-        addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), RegisterSpecList.EMPTY));
-    }
-
-    // produce BasicBlocks for dex
-
-    BasicBlockList toBasicBlocks() {
-        if (!localsInitialized) {
-            initializeLocals();
-        }
-
-        cleanUpLabels();
-
-        BasicBlockList result = new BasicBlockList(labels.size());
-        for (int i = 0; i < labels.size(); i++) {
-            result.set(i, labels.get(i).toBasicBlock());
-        }
-        return result;
-    }
-
-    /**
-     * Removes empty labels and assigns IDs to non-empty labels.
-     */
-    private void cleanUpLabels() {
-        int id = 0;
-        for (Iterator<Label> i = labels.iterator(); i.hasNext();) {
-            Label label = i.next();
-            if (label.isEmpty()) {
-                i.remove();
-            } else {
-                label.compact();
-                label.id = id++;
-            }
-        }
-    }
-
-    private static RegisterSpecList concatenate(Local<?> first, Local<?>[] rest) {
-        int offset = (first != null) ? 1 : 0;
-        RegisterSpecList result = new RegisterSpecList(offset + rest.length);
-        if (first != null) {
-            result.set(0, first.spec());
-        }
-        for (int i = 0; i < rest.length; i++) {
-            result.set(i + offset, rest[i].spec());
-        }
-        return result;
-    }
-}
diff --git a/dx/src/com/android/dx/gen/Comparison.java b/dx/src/com/android/dx/gen/Comparison.java
deleted file mode 100644
index 40a6e97..0000000
--- a/dx/src/com/android/dx/gen/Comparison.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * A comparison between two values of the same type.
- */
-public enum Comparison {
-
-    /** {@code a < b} */
-    LT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfLt(types);
-        }
-    },
-
-    /** {@code a <= b} */
-    LE() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfLe(types);
-        }
-    },
-
-    /** {@code a == b} */
-    EQ() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfEq(types);
-        }
-    },
-
-    /** {@code a >= b} */
-    GE() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfGe(types);
-        }
-    },
-
-    /** {@code a > b} */
-    GT() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfGt(types);
-        }
-    },
-
-    /** {@code a != b} */
-    NE() {
-        @Override Rop rop(TypeList types) {
-            return Rops.opIfNe(types);
-        }
-    };
-
-    abstract Rop rop(TypeList types);
-}
diff --git a/dx/src/com/android/dx/gen/Constants.java b/dx/src/com/android/dx/gen/Constants.java
deleted file mode 100644
index 255c2e4..0000000
--- a/dx/src/com/android/dx/gen/Constants.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstBoolean;
-import com.android.dx.rop.cst.CstByte;
-import com.android.dx.rop.cst.CstChar;
-import com.android.dx.rop.cst.CstDouble;
-import com.android.dx.rop.cst.CstFloat;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.cst.CstKnownNull;
-import com.android.dx.rop.cst.CstLong;
-import com.android.dx.rop.cst.CstShort;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.TypedConstant;
-
-/**
- * Factory for rop constants.
- */
-final class Constants {
-    private Constants() {}
-
-    /**
-     * Returns a rop constant for the specified value.
-     *
-     * @param value null, a boxed primitive, String, Class, or Type.
-     */
-    static TypedConstant getConstant(Object value) {
-        if (value == null) {
-            return CstKnownNull.THE_ONE;
-        } else if (value instanceof Boolean) {
-            return CstBoolean.make((Boolean) value);
-        } else if (value instanceof Byte) {
-            return CstByte.make((Byte) value);
-        } else if (value instanceof Character) {
-            return CstChar.make((Character) value);
-        } else if (value instanceof Double) {
-            return CstDouble.make(Double.doubleToLongBits((Double) value));
-        } else if (value instanceof Float) {
-            return CstFloat.make(Float.floatToIntBits((Float) value));
-        } else if (value instanceof Integer) {
-            return CstInteger.make((Integer) value);
-        } else if (value instanceof Long) {
-            return CstLong.make((Long) value);
-        } else if (value instanceof Short) {
-            return CstShort.make((Short) value);
-        } else if (value instanceof String) {
-            return new CstString((String) value);
-        } else if (value instanceof Class) {
-            return new CstType(Type.get((Class<?>) value).ropType);
-        } else if (value instanceof Type) {
-            return new CstType(((Type) value).ropType);
-        } else {
-            throw new UnsupportedOperationException("Not a constant: " + value);
-        }
-    }
-}
diff --git a/dx/src/com/android/dx/gen/DexCacheException.java b/dx/src/com/android/dx/gen/DexCacheException.java
deleted file mode 100644
index 5608440..0000000
--- a/dx/src/com/android/dx/gen/DexCacheException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import java.io.IOException;
-
-/** Thrown when there is an IOException when writing to the dex cache directory. */
-public final class DexCacheException extends RuntimeException {
-    private static final long serialVersionUID = 0L;
-
-    public DexCacheException(IOException cause) {
-        super(cause);
-    }
-}
diff --git a/dx/src/com/android/dx/gen/DexGenerator.java b/dx/src/com/android/dx/gen/DexGenerator.java
deleted file mode 100644
index 56c516b..0000000
--- a/dx/src/com/android/dx/gen/DexGenerator.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
-import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
-import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
-
-import com.android.dx.dex.DexFormat;
-import com.android.dx.dex.DexOptions;
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.dex.code.RopTranslator;
-import com.android.dx.dex.file.ClassDefItem;
-import com.android.dx.dex.file.DexFile;
-import com.android.dx.dex.file.EncodedField;
-import com.android.dx.dex.file.EncodedMethod;
-import com.android.dx.rop.code.AccessFlags;
-import com.android.dx.rop.code.LocalVariableInfo;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.StdTypeList;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-
-/**
- * Define types, fields and methods.
- */
-public final class DexGenerator {
-    private final Map<Type<?>, TypeDeclaration> types
-            = new LinkedHashMap<Type<?>, TypeDeclaration>();
-
-    private TypeDeclaration getTypeDeclaration(Type<?> type) {
-        TypeDeclaration result = types.get(type);
-        if (result == null) {
-            result = new TypeDeclaration(type);
-            types.put(type, result);
-        }
-        return result;
-    }
-
-    /**
-     * @param flags any flags masked by {@link com.android.dx.rop.code.AccessFlags#CLASS_FLAGS}.
-     */
-    public void declare(Type<?> type, String sourceFile, int flags,
-            Type<?> supertype, Type<?>... interfaces) {
-        TypeDeclaration declaration = getTypeDeclaration(type);
-        if (declaration.declared) {
-            throw new IllegalStateException("already declared: " + type);
-        }
-        declaration.declared = true;
-        declaration.flags = flags;
-        declaration.supertype = supertype;
-        declaration.sourceFile = sourceFile;
-        declaration.interfaces = new TypeList(interfaces);
-    }
-
-    /**
-     * @param flags any flags masked by {@link com.android.dx.rop.code.AccessFlags#METHOD_FLAGS}.
-     */
-    public Code declare(MethodId<?, ?> method, int flags) {
-        TypeDeclaration typeDeclaration = getTypeDeclaration(method.declaringType);
-        if (typeDeclaration.methods.containsKey(method)) {
-            throw new IllegalStateException("already declared: " + method);
-        }
-        MethodDeclaration methodDeclaration = new MethodDeclaration(method, flags);
-        typeDeclaration.methods.put(method, methodDeclaration);
-        return methodDeclaration.code;
-    }
-
-    /**
-     * @param flags any flags masked by {@link AccessFlags#FIELD_FLAGS}.
-     */
-    public void declare(FieldId<?, ?> fieldId, int flags, Object staticValue) {
-        TypeDeclaration typeDeclaration = getTypeDeclaration(fieldId.declaringType);
-        if (typeDeclaration.fields.containsKey(fieldId)) {
-            throw new IllegalStateException("already declared: " + fieldId);
-        }
-        FieldDeclaration fieldDeclaration = new FieldDeclaration(fieldId, flags, staticValue);
-        typeDeclaration.fields.put(fieldId, fieldDeclaration);
-    }
-
-    /**
-     * Returns a .dex formatted file.
-     */
-    public byte[] generate() {
-        DexOptions options = new DexOptions();
-        options.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
-        DexFile outputDex = new DexFile(options);
-
-        for (TypeDeclaration typeDeclaration : types.values()) {
-            outputDex.add(typeDeclaration.toClassDefItem());
-        }
-
-        try {
-            return outputDex.toDex(null, false);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Loads the generated types into the current process.
-     *
-     * <p>All parameters are optional, you may pass {@code null} and suitable
-     * defaults will be used.
-     *
-     * <p>If you opt to provide your own output directories, take care to
-     * ensure that they are not world-readable, otherwise a malicious app will
-     * be able to inject code to run.  A suitable parameter for these output
-     * directories would be something like this:
-     * {@code getApplicationContext().getDir("dx", Context.MODE_PRIVATE); }
-     *
-     * @param parent the parent ClassLoader to be used when loading
-     *     our generated types
-     * @param dexOutputDir the destination directory wherein we will write
-     *     emitted .dex files before they end up in the cache directory
-     * @param dexOptCacheDir where optimized .dex files are to be written
-     */
-    public ClassLoader load(ClassLoader parent, File dexOutputDir, File dexOptCacheDir)
-            throws IOException {
-        byte[] dex = generate();
-
-        /*
-         * This implementation currently dumps the dex to the filesystem. It
-         * jars the emitted .dex for the benefit of Gingerbread and earlier
-         * devices, which can't load .dex files directly.
-         *
-         * TODO: load the dex from memory where supported.
-         */
-        File result = File.createTempFile("Generated", ".jar", dexOutputDir);
-        result.deleteOnExit();
-        JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
-        jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
-        jarOut.write(dex);
-        jarOut.closeEntry();
-        jarOut.close();
-        try {
-            return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
-                    .getConstructor(String.class, String.class, String.class, ClassLoader.class)
-                    .newInstance(result.getPath(), dexOptCacheDir.getAbsolutePath(), null, parent);
-        } catch (ClassNotFoundException e) {
-            throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
-        } catch (InvocationTargetException e) {
-            throw new RuntimeException(e.getCause());
-        } catch (InstantiationException e) {
-            throw new AssertionError();
-        } catch (NoSuchMethodException e) {
-            throw new AssertionError();
-        } catch (IllegalAccessException e) {
-            throw new AssertionError();
-        }
-    }
-
-    private static class TypeDeclaration {
-        private final Type<?> type;
-
-        /** declared state */
-        private boolean declared;
-        private int flags;
-        private Type<?> supertype;
-        private String sourceFile;
-        private TypeList interfaces;
-
-        private final Map<FieldId, FieldDeclaration> fields
-                = new LinkedHashMap<FieldId, FieldDeclaration>();
-        private final Map<MethodId, MethodDeclaration> methods
-                = new LinkedHashMap<MethodId, MethodDeclaration>();
-
-        TypeDeclaration(Type<?> type) {
-            this.type = type;
-        }
-
-        ClassDefItem toClassDefItem() {
-            if (!declared) {
-                throw new IllegalStateException("Undeclared type " + type + " declares members: "
-                        + fields.keySet() + " " + methods.keySet());
-            }
-
-            DexOptions dexOptions = new DexOptions();
-            dexOptions.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
-
-            CstType thisType = type.constant;
-
-            ClassDefItem out = new ClassDefItem(thisType, flags, supertype.constant,
-                    interfaces.ropTypes, new CstString(sourceFile));
-
-            for (MethodDeclaration method : methods.values()) {
-                EncodedMethod encoded = method.toEncodedMethod(dexOptions);
-                if (method.isDirect()) {
-                    out.addDirectMethod(encoded);
-                } else {
-                    out.addVirtualMethod(encoded);
-                }
-            }
-            for (FieldDeclaration field : fields.values()) {
-                EncodedField encoded = field.toEncodedField();
-                if (field.isStatic()) {
-                    out.addStaticField(encoded, Constants.getConstant(field.staticValue));
-                } else {
-                    out.addInstanceField(encoded);
-                }
-            }
-
-            return out;
-        }
-    }
-
-    static class FieldDeclaration {
-        final FieldId<?, ?> fieldId;
-        private final int accessFlags;
-        private final Object staticValue;
-
-        FieldDeclaration(FieldId<?, ?> fieldId, int accessFlags, Object staticValue) {
-            if ((accessFlags & (AccessFlags.ACC_STATIC)) == 0 && staticValue != null) {
-                throw new IllegalArgumentException("instance fields may not have a value");
-            }
-            this.fieldId = fieldId;
-            this.accessFlags = accessFlags;
-            this.staticValue = staticValue;
-        }
-
-        EncodedField toEncodedField() {
-            return new EncodedField(fieldId.constant, accessFlags);
-        }
-
-        public boolean isStatic() {
-            return (accessFlags & (AccessFlags.ACC_STATIC)) != 0;
-        }
-    }
-
-    static class MethodDeclaration {
-        final MethodId<?, ?> method;
-        private final int flags;
-        private final Code code;
-
-        public MethodDeclaration(MethodId<?, ?> method, int flags) {
-            this.method = method;
-            this.flags = flags;
-            this.code = new Code(this);
-        }
-
-        boolean isStatic() {
-            return (flags & ACC_STATIC) != 0;
-        }
-
-        boolean isDirect() {
-            return (flags & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR)) != 0;
-        }
-
-        EncodedMethod toEncodedMethod(DexOptions dexOptions) {
-            RopMethod ropMethod = new RopMethod(code.toBasicBlocks(), 0);
-            LocalVariableInfo locals = null;
-            DalvCode dalvCode = RopTranslator.translate(
-                    ropMethod, PositionList.NONE, locals, code.paramSize(), dexOptions);
-            return new EncodedMethod(method.constant, flags, dalvCode, StdTypeList.EMPTY);
-        }
-    }
-}
diff --git a/dx/src/com/android/dx/gen/FieldId.java b/dx/src/com/android/dx/gen/FieldId.java
deleted file mode 100644
index 62ef73b..0000000
--- a/dx/src/com/android/dx/gen/FieldId.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.rop.cst.CstString;
-
-/**
- * A field.
- */
-public final class FieldId<D, V> {
-    final Type<D> declaringType;
-    final Type<V> type;
-    final String name;
-
-    /** cached converted state */
-    final CstNat nat;
-    final CstFieldRef constant;
-
-    FieldId(Type<D> declaringType, Type<V> type, String name) {
-        if (declaringType == null || type == null || name == null) {
-            throw new NullPointerException();
-        }
-        this.declaringType = declaringType;
-        this.type = type;
-        this.name = name;
-        this.nat = new CstNat(new CstString(name), new CstString(type.name));
-        this.constant = new CstFieldRef(declaringType.constant, nat);
-    }
-
-    public Type<D> getDeclaringType() {
-        return declaringType;
-    }
-
-    public Type<V> getType() {
-        return type;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override public boolean equals(Object o) {
-        return o instanceof FieldId
-                && ((FieldId<?, ?>) o).declaringType.equals(declaringType)
-                && ((FieldId<?, ?>) o).name.equals(name);
-    }
-
-    @Override public int hashCode() {
-        return declaringType.hashCode() + 37 * name.hashCode();
-    }
-
-    @Override public String toString() {
-        return declaringType + "." + name;
-    }
-}
diff --git a/dx/src/com/android/dx/gen/Label.java b/dx/src/com/android/dx/gen/Label.java
deleted file mode 100644
index 633b5f1..0000000
--- a/dx/src/com/android/dx/gen/Label.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.util.IntList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A branch target in a list of instructions.
- */
-public final class Label {
-
-    final List<Insn> instructions = new ArrayList<Insn>();
-
-    boolean marked = false;
-
-    /** an immutable list of labels corresponding to the types in the catch list */
-    List<Label> catchLabels = Collections.emptyList();
-
-    /** contains the next instruction if no branch occurs */
-    Label primarySuccessor;
-
-    /** contains the instruction to jump to if the if is true */
-    Label alternateSuccessor;
-
-    int id = -1;
-
-    Label() {}
-
-    boolean isEmpty() {
-        return instructions.isEmpty();
-    }
-
-    void compact() {
-        for (int i = 0; i < catchLabels.size(); i++) {
-            while (catchLabels.get(i).isEmpty()) {
-                catchLabels.set(i, catchLabels.get(i).primarySuccessor);
-            }
-        }
-        while (primarySuccessor != null && primarySuccessor.isEmpty()) {
-            primarySuccessor = primarySuccessor.primarySuccessor;
-        }
-        while (alternateSuccessor != null && alternateSuccessor.isEmpty()) {
-            alternateSuccessor = alternateSuccessor.primarySuccessor;
-        }
-    }
-
-    BasicBlock toBasicBlock() {
-        InsnList result = new InsnList(instructions.size());
-        for (int i = 0; i < instructions.size(); i++) {
-            result.set(i, instructions.get(i));
-        }
-        result.setImmutable();
-
-        int primarySuccessorIndex = -1;
-        IntList successors = new IntList();
-        for (Label catchLabel : catchLabels) {
-            successors.add(catchLabel.id);
-        }
-        if (primarySuccessor != null) {
-            primarySuccessorIndex = primarySuccessor.id;
-            successors.add(primarySuccessorIndex);
-        }
-        if (alternateSuccessor != null) {
-            successors.add(alternateSuccessor.id);
-        }
-        successors.setImmutable();
-
-        return new BasicBlock(id, result, successors, primarySuccessorIndex);
-    }
-}
diff --git a/dx/src/com/android/dx/gen/Local.java b/dx/src/com/android/dx/gen/Local.java
deleted file mode 100644
index b98759c..0000000
--- a/dx/src/com/android/dx/gen/Local.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.RegisterSpec;
-
-/**
- * A temporary variable that holds a single value.
- */
-public final class Local<T> {
-    private final Code code;
-    final Type<T> type;
-    private int reg = -1;
-    private RegisterSpec spec;
-
-    private Local(Code code, Type<T> type) {
-        this.code = code;
-        this.type = type;
-    }
-
-    static <T> Local<T> get(Code code, Type<T> type) {
-        return new Local<T>(code, type);
-    }
-
-    /**
-     * Assigns registers to this local.
-     *
-     * @return the number of registers required.
-     */
-    int initialize(int reg) {
-        this.reg = reg;
-        this.spec = RegisterSpec.make(reg, type.ropType);
-        return size();
-    }
-
-    int size() {
-        return type.ropType.getCategory();
-    }
-
-    RegisterSpec spec() {
-        if (spec == null) {
-            code.initializeLocals();
-            if (spec == null) {
-                throw new AssertionError();
-            }
-        }
-        return spec;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    @Override public String toString() {
-        return "v" + reg + "(" + type + ")";
-    }
-}
diff --git a/dx/src/com/android/dx/gen/MethodId.java b/dx/src/com/android/dx/gen/MethodId.java
deleted file mode 100644
index 29d088a..0000000
--- a/dx/src/com/android/dx/gen/MethodId.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Prototype;
-import java.util.List;
-
-/**
- * A method or constructor.
- */
-public final class MethodId<D, R> {
-    final Type<D> declaringType;
-    final Type<R> returnType;
-    final String name;
-    final TypeList parameters;
-
-    /** cached converted state */
-    final CstNat nat;
-    final CstMethodRef constant;
-
-    MethodId(Type<D> declaringType, Type<R> returnType, String name, TypeList parameters) {
-        if (declaringType == null || returnType == null || name == null || parameters == null) {
-            throw new NullPointerException();
-        }
-        this.declaringType = declaringType;
-        this.returnType = returnType;
-        this.name = name;
-        this.parameters = parameters;
-        this.nat = new CstNat(new CstString(name), new CstString(descriptor(false)));
-        this.constant = new CstMethodRef(declaringType.constant, nat);
-    }
-
-    public Type<D> getDeclaringType() {
-        return declaringType;
-    }
-
-    public Type<R> getReturnType() {
-        return returnType;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public List<Type<?>> getParameters() {
-        return parameters.asList();
-    }
-
-    /**
-     * Returns a descriptor like "(Ljava/lang/Class;[I)Ljava/lang/Object;".
-     */
-    String descriptor(boolean includeThis) {
-        StringBuilder result = new StringBuilder();
-        result.append("(");
-        if (includeThis) {
-            result.append(declaringType.name);
-        }
-        for (Type t : parameters.types) {
-            result.append(t.name);
-        }
-        result.append(")");
-        result.append(returnType.name);
-        return result.toString();
-    }
-
-    Prototype prototype(boolean includeThis) {
-        return Prototype.intern(descriptor(includeThis));
-    }
-
-    @Override public boolean equals(Object o) {
-        return o instanceof MethodId
-                && ((MethodId<?, ?>) o).declaringType.equals(declaringType)
-                && ((MethodId<?, ?>) o).name.equals(name)
-                && ((MethodId<?, ?>) o).parameters.equals(parameters)
-                && ((MethodId<?, ?>) o).returnType.equals(returnType);
-    }
-
-    @Override public int hashCode() {
-        int result = 17;
-        result = 31 * result + declaringType.hashCode();
-        result = 31 * result + name.hashCode();
-        result = 31 * result + parameters.hashCode();
-        result = 31 * result + returnType.hashCode();
-        return result;
-    }
-
-    @Override public String toString() {
-        return declaringType + "." + name + "(" + parameters + ")";
-    }
-}
diff --git a/dx/src/com/android/dx/gen/ProxyBuilder.java b/dx/src/com/android/dx/gen/ProxyBuilder.java
deleted file mode 100644
index 852fe66..0000000
--- a/dx/src/com/android/dx/gen/ProxyBuilder.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
-import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
-import static com.android.dx.rop.code.AccessFlags.ACC_PUBLIC;
-import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Creates dynamic proxies of concrete classes.
- * <p>
- * This is similar to the {@code java.lang.reflect.Proxy} class, but works for classes instead of
- * interfaces.
- * <h3>Example</h3>
- * The following example demonstrates the creation of a dynamic proxy for {@code java.util.Random}
- * which will always return 4 when asked for integers, and which logs method calls to every method.
- * <pre>
- * InvocationHandler handler = new InvocationHandler() {
- *     &#64;Override
- *     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- *         if (method.getName().equals("nextInt")) {
- *             // Chosen by fair dice roll, guaranteed to be random.
- *             return 4;
- *         }
- *         Object result = ProxyBuilder.callSuper(proxy, method, args);
- *         System.out.println("Method: " + method.getName() + " args: "
- *                 + Arrays.toString(args) + " result: " + result);
- *         return result;
- *     }
- * };
- * Random debugRandom = ProxyBuilder.forClass(Random.class)
- *         .dexCache(getInstrumentation().getTargetContext().getDir("dx", Context.MODE_PRIVATE))
- *         .handler(handler)
- *         .build();
- * assertEquals(4, debugRandom.nextInt());
- * debugRandom.setSeed(0);
- * assertTrue(debugRandom.nextBoolean());
- * </pre>
- * <h3>Usage</h3>
- * Call {@link #forClass(Class)} for the Class you wish to proxy. Call
- * {@link #handler(InvocationHandler)} passing in an {@link InvocationHandler}, and then call
- * {@link #build()}. The returned instance will be a dynamically generated subclass where all method
- * calls will be delegated to the invocation handler, except as noted below.
- * <p>
- * The static method {@link #callSuper(Object, Method, Object...)} allows you to access the original
- * super method for a given proxy. This allows the invocation handler to selectively override some
- * methods but not others.
- * <p>
- * By default, the {@link #build()} method will call the no-arg constructor belonging to the class
- * being proxied. If you wish to call a different constructor, you must provide arguments for both
- * {@link #constructorArgTypes(Class[])} and {@link #constructorArgValues(Object[])}.
- * <p>
- * This process works only for classes with public and protected level of visibility.
- * <p>
- * You may proxy abstract classes.  You may not proxy final classes.
- * <p>
- * Only non-private, non-final, non-static methods will be dispatched to the invocation handler.
- * Private, static or final methods will always call through to the superclass as normal.
- * <p>
- * The {@link #finalize()} method on {@code Object} will not be proxied.
- * <p>
- * You must provide a dex cache directory via the {@link #dexCache(File)} method. You should take
- * care not to make this a world-writable directory, so that third parties cannot inject code into
- * your application.  A suitable parameter for these output directories would be something like
- * this:
- * <pre>{@code
- *     getApplicationContext().getDir("dx", Context.MODE_PRIVATE);
- * }</pre>
- * <p>
- * If the base class to be proxied leaks the {@code this} pointer in the constructor (bad practice),
- * that is to say calls a non-private non-final method from the constructor, the invocation handler
- * will not be invoked.  As a simple concrete example, when proxying Random we discover that it
- * inernally calls setSeed during the constructor.  The proxy will not intercept this call during
- * proxy construction, but will intercept as normal afterwards.  This behaviour may be subject to
- * change in future releases.
- * <p>
- * This class is <b>not thread safe</b>.
- */
-public final class ProxyBuilder<T> {
-    private static final String FIELD_NAME_HANDLER = "$__handler";
-    private static final String FIELD_NAME_METHODS = "$__methodArray";
-
-    private final Class<T> baseClass;
-    private ClassLoader parentClassLoader = ProxyBuilder.class.getClassLoader();
-    private InvocationHandler handler;
-    private File dexCache;
-    private Class<?>[] constructorArgTypes = new Class[0];
-    private Object[] constructorArgValues = new Object[0];
-
-    private ProxyBuilder(Class<T> clazz) {
-        baseClass = clazz;
-    }
-
-    public static <T> ProxyBuilder<T> forClass(Class<T> clazz) {
-        return new ProxyBuilder<T>(clazz);
-    }
-
-    /**
-     * Specifies the parent ClassLoader to use when creating the proxy.
-     *
-     * <p>If null, {@code ProxyBuilder.class.getClassLoader()} will be used.
-     */
-    public ProxyBuilder<T> parentClassLoader(ClassLoader parent) {
-        parentClassLoader = parent;
-        return this;
-    }
-
-    public ProxyBuilder<T> handler(InvocationHandler handler) {
-        this.handler = handler;
-        return this;
-    }
-
-    public ProxyBuilder<T> dexCache(File dexCache) {
-        this.dexCache = dexCache;
-        return this;
-    }
-
-    public ProxyBuilder<T> constructorArgValues(Object... constructorArgValues) {
-        this.constructorArgValues = constructorArgValues;
-        return this;
-    }
-
-    public ProxyBuilder<T> constructorArgTypes(Class<?>... constructorArgTypes) {
-        this.constructorArgTypes = constructorArgTypes;
-        return this;
-    }
-
-    /**
-     * Create a new instance of the class to proxy.
-     *
-     * @throws UnsupportedOperationException if the class we are trying to create a proxy for is
-     *     not accessible.
-     * @throws DexCacheException if an exception occurred writing to the {@code dexCache} directory.
-     * @throws UndeclaredThrowableException if the constructor for the base class to proxy throws
-     *     a declared exception during construction.
-     * @throws IllegalArgumentException if the handler is null, if the constructor argument types
-     *     do not match the constructor argument values, or if no such constructor exists.
-     */
-    public T build() {
-        check(handler != null, "handler == null");
-        check(constructorArgTypes.length == constructorArgValues.length,
-                "constructorArgValues.length != constructorArgTypes.length");
-        DexGenerator generator = new DexGenerator();
-        String generatedName = getMethodNameForProxyOf(baseClass);
-        Type<? extends T> generatedType = Type.get("L" + generatedName + ";");
-        Type<T> superType = Type.get(baseClass);
-        generateConstructorsAndFields(generator, generatedType, superType, baseClass);
-        Method[] methodsToProxy = getMethodsToProxy(baseClass);
-        generateCodeForAllMethods(generator, generatedType, methodsToProxy, superType);
-        generator.declare(generatedType, generatedName + ".generated", ACC_PUBLIC, superType);
-        ClassLoader classLoader;
-        try {
-            classLoader = generator.load(parentClassLoader, dexCache, dexCache);
-        } catch (IOException e) {
-            throw new DexCacheException(e);
-        }
-        Class<? extends T> proxyClass;
-        try {
-            proxyClass = loadClass(classLoader, generatedName);
-        } catch (IllegalAccessError e) {
-            // Thrown when the base class is not accessible.
-            throw new UnsupportedOperationException("cannot proxy inaccessible classes", e);
-        } catch (ClassNotFoundException e) {
-            // Should not be thrown, we're sure to have generated this class.
-            throw new AssertionError(e);
-        }
-        setMethodsStaticField(proxyClass, methodsToProxy);
-        Constructor<? extends T> constructor;
-        try {
-            constructor = proxyClass.getConstructor(constructorArgTypes);
-        } catch (NoSuchMethodException e) {
-            // Thrown when the ctor to be called does not exist.
-            throw new IllegalArgumentException("could not find matching constructor", e);
-        }
-        T result;
-        try {
-            result = constructor.newInstance(constructorArgValues);
-        } catch (InstantiationException e) {
-            // Should not be thrown, generated class is not abstract.
-            throw new AssertionError(e);
-        } catch (IllegalAccessException e) {
-            // Should not be thrown, the generated constructor is accessible.
-            throw new AssertionError(e);
-        } catch (InvocationTargetException e) {
-            // Thrown when the base class ctor throws an exception.
-            throw launderCause(e);
-        }
-        setHandlerInstanceField(result, handler);
-        return result;
-    }
-
-    // The type cast is safe: the generated type will extend the base class type.
-    @SuppressWarnings("unchecked")
-    private Class<? extends T> loadClass(ClassLoader classLoader, String generatedName)
-            throws ClassNotFoundException {
-        return (Class<? extends T>) classLoader.loadClass(generatedName);
-    }
-
-    private static RuntimeException launderCause(InvocationTargetException e) {
-        Throwable cause = e.getCause();
-        // Errors should be thrown as they are.
-        if (cause instanceof Error) {
-            throw (Error) cause;
-        }
-        // RuntimeException can be thrown as-is.
-        if (cause instanceof RuntimeException) {
-            throw (RuntimeException) cause;
-        }
-        // Declared exceptions will have to be wrapped.
-        throw new UndeclaredThrowableException(cause);
-    }
-
-    private static void setHandlerInstanceField(Object instance, InvocationHandler handler) {
-        try {
-            Field handlerField = instance.getClass().getDeclaredField(FIELD_NAME_HANDLER);
-            handlerField.setAccessible(true);
-            handlerField.set(instance, handler);
-        } catch (NoSuchFieldException e) {
-            // Should not be thrown, generated proxy class has been generated with this field.
-            throw new AssertionError(e);
-        } catch (IllegalAccessException e) {
-            // Should not be thrown, we just set the field to accessible.
-            throw new AssertionError(e);
-        }
-    }
-
-    private static void setMethodsStaticField(Class<?> proxyClass, Method[] methodsToProxy) {
-        try {
-            Field methodArrayField = proxyClass.getDeclaredField(FIELD_NAME_METHODS);
-            methodArrayField.setAccessible(true);
-            methodArrayField.set(null, methodsToProxy);
-        } catch (NoSuchFieldException e) {
-            // Should not be thrown, generated proxy class has been generated with this field.
-            throw new AssertionError(e);
-        } catch (IllegalAccessException e) {
-            // Should not be thrown, we just set the field to accessible.
-            throw new AssertionError(e);
-        }
-    }
-
-    /**
-     * Returns the proxy's {@link InvocationHandler}.
-     *
-     * @throws IllegalArgumentException if the object supplied is not a proxy created by this class.
-     */
-    public static InvocationHandler getInvocationHandler(Object instance) {
-        try {
-            Field field = instance.getClass().getDeclaredField(FIELD_NAME_HANDLER);
-            field.setAccessible(true);
-            return (InvocationHandler) field.get(instance);
-        } catch (NoSuchFieldException e) {
-            throw new IllegalArgumentException("Not a valid proxy instance", e);
-        } catch (IllegalAccessException e) {
-            // Should not be thrown, we just set the field to accessible.
-            throw new AssertionError(e);
-        }
-    }
-
-    private static <T, G extends T> void generateCodeForAllMethods(DexGenerator generator,
-            Type<G> generatedType, Method[] methodsToProxy, Type<T> superclassType) {
-        Type<InvocationHandler> handlerType = Type.get(InvocationHandler.class);
-        Type<Method[]> methodArrayType = Type.get(Method[].class);
-        FieldId<G, InvocationHandler> handlerField =
-                generatedType.getField(handlerType, FIELD_NAME_HANDLER);
-        FieldId<G, Method[]> allMethods =
-                generatedType.getField(methodArrayType, FIELD_NAME_METHODS);
-        Type<Method> methodType = Type.get(Method.class);
-        Type<Object[]> objectArrayType = Type.get(Object[].class);
-        MethodId<InvocationHandler, Object> methodInvoke = handlerType.getMethod(Type.OBJECT,
-                "invoke", Type.OBJECT, methodType, objectArrayType);
-        for (int m = 0; m < methodsToProxy.length; ++m) {
-            /*
-             * If the 5th method on the superclass Example that can be overridden were to look like
-             * this:
-             *
-             *     public int doSomething(Bar param0, int param1) {
-             *         ...
-             *     }
-             *
-             * Then the following code will generate a method on the proxy that looks something
-             * like this:
-             *
-             *     public int doSomething(Bar param0, int param1) {
-             *         int methodIndex = 4;
-             *         Method[] allMethods = Example_Proxy.$__methodArray;
-             *         Method thisMethod = allMethods[methodIndex];
-             *         int argsLength = 2;
-             *         Object[] args = new Object[argsLength];
-             *         InvocationHandler localHandler = this.$__handler;
-             *         // for-loop begins
-             *         int p = 0;
-             *         Bar parameter0 = param0;
-             *         args[p] = parameter0;
-             *         p = 1;
-             *         int parameter1 = param1;
-             *         Integer boxed1 = Integer.valueOf(parameter1);
-             *         args[p] = boxed1;
-             *         // for-loop ends
-             *         Object result = localHandler.invoke(this, thisMethod, args);
-             *         Integer castResult = (Integer) result;
-             *         int unboxedResult = castResult.intValue();
-             *         return unboxedResult;
-             *     }
-             *
-             * Or, in more idiomatic Java:
-             *
-             *     public int doSomething(Bar param0, int param1) {
-             *         if ($__handler == null) {
-             *             return super.doSomething(param0, param1);
-             *         }
-             *         return __handler.invoke(this, __methodArray[4],
-             *                 new Object[] { param0, Integer.valueOf(param1) });
-             *     }
-             */
-            Method method = methodsToProxy[m];
-            String name = method.getName();
-            Class<?>[] argClasses = method.getParameterTypes();
-            Type<?>[] argTypes = new Type<?>[argClasses.length];
-            for (int i = 0; i < argTypes.length; ++i) {
-                argTypes[i] = Type.get(argClasses[i]);
-            }
-            Class<?> returnType = method.getReturnType();
-            Type<?> resultType = Type.get(returnType);
-            MethodId<T, ?> superMethod = superclassType.getMethod(resultType, name, argTypes);
-            MethodId<?, ?> methodId = generatedType.getMethod(resultType, name, argTypes);
-            Code code = generator.declare(methodId, ACC_PUBLIC);
-            Local<G> localThis = code.getThis(generatedType);
-            Local<InvocationHandler> localHandler = code.newLocal(handlerType);
-            Local<Object> invokeResult = code.newLocal(Type.OBJECT);
-            Local<Integer> intValue = code.newLocal(Type.INT);
-            Local<Object[]> args = code.newLocal(objectArrayType);
-            Local<Integer> argsLength = code.newLocal(Type.INT);
-            Local<Object> temp = code.newLocal(Type.OBJECT);
-            Local<?> resultHolder = code.newLocal(resultType);
-            Local<Method[]> methodArray = code.newLocal(methodArrayType);
-            Local<Method> thisMethod = code.newLocal(methodType);
-            Local<Integer> methodIndex = code.newLocal(Type.INT);
-            Class<?> aBoxedClass = PRIMITIVE_TO_BOXED.get(returnType);
-            Local<?> aBoxedResult = null;
-            if (aBoxedClass != null) {
-                aBoxedResult = code.newLocal(Type.get(aBoxedClass));
-            }
-            Local<?>[] superArgs2 = new Local<?>[argClasses.length];
-            Local<?> superResult2 = code.newLocal(resultType);
-            Local<InvocationHandler> nullHandler = code.newLocal(handlerType);
-
-            code.loadConstant(methodIndex, m);
-            code.sget(allMethods, methodArray);
-            code.aget(methodArray, methodIndex, thisMethod);
-            code.loadConstant(argsLength, argTypes.length);
-            code.newArray(argsLength, args);
-            code.iget(handlerField, localThis, localHandler);
-
-            // if (proxy == null)
-            code.loadConstant(nullHandler, null);
-            Label handlerNullCase = code.newLabel();
-            code.compare(Comparison.EQ, nullHandler, localHandler, handlerNullCase);
-
-            // This code is what we execute when we have a valid proxy: delegate to invocation
-            // handler.
-            for (int p = 0; p < argTypes.length; ++p) {
-                code.loadConstant(intValue, p);
-                Local<?> parameter = code.getParameter(p, argTypes[p]);
-                Local<?> unboxedIfNecessary = boxIfRequired(generator, code, parameter, temp);
-                code.aput(args, intValue, unboxedIfNecessary);
-            }
-            code.invokeInterface(methodInvoke, invokeResult, localHandler,
-                    localThis, thisMethod, args);
-            generateCodeForReturnStatement(code, returnType, invokeResult, resultHolder,
-                    aBoxedResult);
-
-            // This code is executed if proxy is null: call the original super method.
-            // This is required to handle the case of construction of an object which leaks the
-            // "this" pointer.
-            code.mark(handlerNullCase);
-            for (int i = 0; i < superArgs2.length; ++i) {
-                superArgs2[i] = code.getParameter(i, argTypes[i]);
-            }
-            if (void.class.equals(returnType)) {
-                code.invokeSuper(superMethod, null, localThis, superArgs2);
-                code.returnVoid();
-            } else {
-                invokeSuper(superMethod, code, localThis, superArgs2, superResult2);
-                code.returnValue(superResult2);
-            }
-
-            /*
-             * And to allow calling the original super method, the following is also generated:
-             *
-             *     public int super_doSomething(Bar param0, int param1) {
-             *          int result = super.doSomething(param0, param1);
-             *          return result;
-             *     }
-             */
-            String superName = "super_" + name;
-            MethodId<G, ?> callsSuperMethod = generatedType.getMethod(
-                    resultType, superName, argTypes);
-            Code superCode = generator.declare(callsSuperMethod, ACC_PUBLIC);
-            Local<G> superThis = superCode.getThis(generatedType);
-            Local<?>[] superArgs = new Local<?>[argClasses.length];
-            for (int i = 0; i < superArgs.length; ++i) {
-                superArgs[i] = superCode.getParameter(i, argTypes[i]);
-            }
-            if (void.class.equals(returnType)) {
-                superCode.invokeSuper(superMethod, null, superThis, superArgs);
-                superCode.returnVoid();
-            } else {
-                Local<?> superResult = superCode.newLocal(resultType);
-                invokeSuper(superMethod, superCode, superThis, superArgs, superResult);
-                superCode.returnValue(superResult);
-            }
-        }
-    }
-
-    // This one is tricky to fix, I gave up.
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private static <T> void invokeSuper(MethodId superMethod, Code superCode,
-            Local superThis, Local[] superArgs, Local superResult) {
-        superCode.invokeSuper(superMethod, superResult, superThis, superArgs);
-    }
-
-    private static Local<?> boxIfRequired(DexGenerator generator, Code code, Local<?> parameter,
-            Local<Object> temp) {
-        MethodId<?, ?> unboxMethod = PRIMITIVE_TYPE_TO_UNBOX_METHOD.get(parameter.getType());
-        if (unboxMethod == null) {
-            return parameter;
-        }
-        code.invokeStatic(unboxMethod, temp, parameter);
-        return temp;
-    }
-
-    public static Object callSuper(Object proxy, Method method, Object... args)
-            throws SecurityException, IllegalAccessException,
-            InvocationTargetException, NoSuchMethodException {
-        return proxy.getClass()
-                .getMethod("super_" + method.getName(), method.getParameterTypes())
-                .invoke(proxy, args);
-    }
-
-    private static void check(boolean condition, String message) {
-        if (!condition) {
-            throw new IllegalArgumentException(message);
-        }
-    }
-
-    private static <T, G extends T> void generateConstructorsAndFields(DexGenerator generator,
-            Type<G> generatedType, Type<T> superType, Class<T> superClass) {
-        Type<InvocationHandler> handlerType = Type.get(InvocationHandler.class);
-        Type<Method[]> methodArrayType = Type.get(Method[].class);
-        FieldId<G, InvocationHandler> handlerField = generatedType.getField(
-                handlerType, FIELD_NAME_HANDLER);
-        generator.declare(handlerField, ACC_PRIVATE, null);
-        FieldId<G, Method[]> allMethods = generatedType.getField(
-                methodArrayType, FIELD_NAME_METHODS);
-        generator.declare(allMethods, ACC_PRIVATE | ACC_STATIC, null);
-        for (Constructor<T> constructor : getConstructorsToOverwrite(superClass)) {
-            if (constructor.getModifiers() == Modifier.FINAL) {
-                continue;
-            }
-            Type<?>[] types = classArrayToTypeArray(constructor.getParameterTypes());
-            MethodId<?, ?> method = generatedType.getConstructor(types);
-            Code constructorCode = generator.declare(method, ACC_PUBLIC | ACC_CONSTRUCTOR);
-            Local<G> thisRef = constructorCode.getThis(generatedType);
-            Local<?>[] params = new Local[types.length];
-            for (int i = 0; i < params.length; ++i) {
-                params[i] = constructorCode.getParameter(i, types[i]);
-            }
-            MethodId<T, ?> superConstructor = superType.getConstructor(types);
-            constructorCode.invokeDirect(superConstructor, null, thisRef, params);
-            constructorCode.returnVoid();
-        }
-    }
-
-    // The type parameter on Constructor is the class in which the constructor is declared.
-    // The getDeclaredConstructors() method gets constructors declared only in the given class,
-    // hence this cast is safe.
-    @SuppressWarnings("unchecked")
-    private static <T> Constructor<T>[] getConstructorsToOverwrite(Class<T> clazz) {
-        return (Constructor<T>[]) clazz.getDeclaredConstructors();
-    }
-
-    /**
-     * Gets all {@link Method} objects we can proxy in the hierarchy of the supplied class.
-     */
-    private static <T> Method[] getMethodsToProxy(Class<T> clazz) {
-        Set<MethodSetEntry> methodsToProxy = new HashSet<MethodSetEntry>();
-        for (Class<?> current = clazz; current != null; current = current.getSuperclass()) {
-            for (Method method : current.getDeclaredMethods()) {
-                if ((method.getModifiers() & Modifier.FINAL) != 0) {
-                    // Skip final methods, we can't override them.
-                    continue;
-                }
-                if ((method.getModifiers() & Modifier.STATIC) != 0) {
-                    // Skip static methods, overriding them has no effect.
-                    continue;
-                }
-                if (method.getName().equals("finalize") && method.getParameterTypes().length == 0) {
-                    // Skip finalize method, it's likely important that it execute as normal.
-                    continue;
-                }
-                methodsToProxy.add(new MethodSetEntry(method));
-            }
-        }
-        Method[] results = new Method[methodsToProxy.size()];
-        int i = 0;
-        for (MethodSetEntry entry : methodsToProxy) {
-            results[i++] = entry.originalMethod;
-        }
-        return results;
-    }
-
-    private static <T> String getMethodNameForProxyOf(Class<T> clazz) {
-        return clazz.getSimpleName() + "_Proxy";
-    }
-
-    private static Type<?>[] classArrayToTypeArray(Class<?>[] input) {
-        Type<?>[] result = new Type[input.length];
-        for (int i = 0; i < input.length; ++i) {
-            result[i] = Type.get(input[i]);
-        }
-        return result;
-    }
-
-    /**
-     * Calculates the correct return statement code for a method.
-     * <p>
-     * A void method will not return anything.  A method that returns a primitive will need to
-     * unbox the boxed result.  Otherwise we will cast the result.
-     */
-    // This one is tricky to fix, I gave up.
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    private static void generateCodeForReturnStatement(Code code, Class methodReturnType,
-            Local localForResultOfInvoke, Local localOfMethodReturnType, Local aBoxedResult) {
-        if (PRIMITIVE_TO_UNBOX_METHOD.containsKey(methodReturnType)) {
-            code.typeCast(localForResultOfInvoke, aBoxedResult);
-            MethodId unboxingMethodFor = getUnboxMethodForPrimitive(methodReturnType);
-            code.invokeVirtual(unboxingMethodFor, localOfMethodReturnType, aBoxedResult);
-            code.returnValue(localOfMethodReturnType);
-        } else if (void.class.equals(methodReturnType)) {
-            code.returnVoid();
-        } else {
-            code.typeCast(localForResultOfInvoke, localOfMethodReturnType);
-            code.returnValue(localOfMethodReturnType);
-        }
-    }
-
-    private static MethodId<?, ?> getUnboxMethodForPrimitive(Class<?> methodReturnType) {
-        return PRIMITIVE_TO_UNBOX_METHOD.get(methodReturnType);
-    }
-
-    private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED;
-    static {
-        PRIMITIVE_TO_BOXED = new HashMap<Class<?>, Class<?>>();
-        PRIMITIVE_TO_BOXED.put(boolean.class, Boolean.class);
-        PRIMITIVE_TO_BOXED.put(int.class, Integer.class);
-        PRIMITIVE_TO_BOXED.put(byte.class, Byte.class);
-        PRIMITIVE_TO_BOXED.put(long.class, Long.class);
-        PRIMITIVE_TO_BOXED.put(short.class, Short.class);
-        PRIMITIVE_TO_BOXED.put(float.class, Float.class);
-        PRIMITIVE_TO_BOXED.put(double.class, Double.class);
-        PRIMITIVE_TO_BOXED.put(char.class, Character.class);
-    }
-
-    private static final Map<Type<?>, MethodId<?, ?>> PRIMITIVE_TYPE_TO_UNBOX_METHOD;
-    static {
-        PRIMITIVE_TYPE_TO_UNBOX_METHOD = new HashMap<Type<?>, MethodId<?, ?>>();
-        for (Map.Entry<Class<?>, Class<?>> entry : PRIMITIVE_TO_BOXED.entrySet()) {
-            Type<?> primitiveType = Type.get(entry.getKey());
-            Type<?> boxedType = Type.get(entry.getValue());
-            MethodId<?, ?> valueOfMethod = boxedType.getMethod(boxedType, "valueOf", primitiveType);
-            PRIMITIVE_TYPE_TO_UNBOX_METHOD.put(primitiveType, valueOfMethod);
-        }
-    }
-
-    /**
-     * Map from primitive type to method used to unbox a boxed version of the primitive.
-     * <p>
-     * This is required for methods whose return type is primitive, since the
-     * {@link InvocationHandler} will return us a boxed result, and we'll need to convert it back to
-     * primitive value.
-     */
-    private static final Map<Class<?>, MethodId<?, ?>> PRIMITIVE_TO_UNBOX_METHOD;
-    static {
-        Map<Class<?>, MethodId<?, ?>> map = new HashMap<Class<?>, MethodId<?, ?>>();
-        map.put(boolean.class, Type.get(Boolean.class).getMethod(Type.BOOLEAN, "booleanValue"));
-        map.put(int.class, Type.get(Integer.class).getMethod(Type.INT, "intValue"));
-        map.put(byte.class, Type.get(Byte.class).getMethod(Type.BYTE, "byteValue"));
-        map.put(long.class, Type.get(Long.class).getMethod(Type.LONG, "longValue"));
-        map.put(short.class, Type.get(Short.class).getMethod(Type.SHORT, "shortValue"));
-        map.put(float.class, Type.get(Float.class).getMethod(Type.FLOAT, "floatValue"));
-        map.put(double.class, Type.get(Double.class).getMethod(Type.DOUBLE, "doubleValue"));
-        map.put(char.class, Type.get(Character.class).getMethod(Type.CHAR, "charValue"));
-        PRIMITIVE_TO_UNBOX_METHOD = map;
-    }
-
-    /**
-     * Wrapper class to let us disambiguate {@link Method} objects.
-     * <p>
-     * The purpose of this class is to override the {@link #equals(Object)} and {@link #hashCode()}
-     * methods so we can use a {@link Set} to remove duplicate methods that are overrides of one
-     * another. For these purposes, we consider two methods to be equal if they have the same
-     * name, return type, and parameter types.
-     */
-    private static class MethodSetEntry {
-        private final String name;
-        private final Class<?>[] paramTypes;
-        private final Class<?> returnType;
-        private final Method originalMethod;
-
-        public MethodSetEntry(Method method) {
-            originalMethod = method;
-            name = method.getName();
-            paramTypes = method.getParameterTypes();
-            returnType = method.getReturnType();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o instanceof MethodSetEntry) {
-                MethodSetEntry other = (MethodSetEntry) o;
-                return name.equals(other.name)
-                        && returnType.equals(other.returnType)
-                        && Arrays.equals(paramTypes, other.paramTypes);
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = 17;
-            result += 31 * result + name.hashCode();
-            result += 31 * result + returnType.hashCode();
-            result += 31 * result + Arrays.hashCode(paramTypes);
-            return result;
-        }
-    }
-}
diff --git a/dx/src/com/android/dx/gen/Type.java b/dx/src/com/android/dx/gen/Type.java
deleted file mode 100644
index 3b81f6d..0000000
--- a/dx/src/com/android/dx/gen/Type.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstType;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A primitive type, interface or class.
- */
-public final class Type<T> {
-    /** The {@code boolean} primitive type. */
-    public static final Type<Boolean> BOOLEAN
-            = new Type<Boolean>(com.android.dx.rop.type.Type.BOOLEAN);
-
-    /** The {@code byte} primitive type. */
-    public static final Type<Byte> BYTE = new Type<Byte>(com.android.dx.rop.type.Type.BYTE);
-
-    /** The {@code char} primitive type. */
-    public static final Type<Character> CHAR
-            = new Type<Character>(com.android.dx.rop.type.Type.CHAR);
-
-    /** The {@code double} primitive type. */
-    public static final Type<Double> DOUBLE = new Type<Double>(com.android.dx.rop.type.Type.DOUBLE);
-
-    /** The {@code float} primitive type. */
-    public static final Type<Float> FLOAT = new Type<Float>(com.android.dx.rop.type.Type.FLOAT);
-
-    /** The {@code int} primitive type. */
-    public static final Type<Integer> INT = new Type<Integer>(com.android.dx.rop.type.Type.INT);
-
-    /** The {@code long} primitive type. */
-    public static final Type<Long> LONG = new Type<Long>(com.android.dx.rop.type.Type.LONG);
-
-    /** The {@code short} primitive type. */
-    public static final Type<Short> SHORT = new Type<Short>(com.android.dx.rop.type.Type.SHORT);
-
-    /** The {@code void} primitive type. Only used as a return type. */
-    public static final Type<Void> VOID = new Type<Void>(com.android.dx.rop.type.Type.VOID);
-
-    /** The {@code Object} type. */
-    public static final Type<Object> OBJECT = new Type<Object>(com.android.dx.rop.type.Type.OBJECT);
-
-    /** The {@code String} type. */
-    public static final Type<String> STRING = new Type<String>(com.android.dx.rop.type.Type.STRING);
-
-    private static final Map<Class<?>, Type<?>> PRIMITIVE_TO_TYPE
-            = new HashMap<Class<?>, Type<?>>();
-    static {
-        PRIMITIVE_TO_TYPE.put(boolean.class, BOOLEAN);
-        PRIMITIVE_TO_TYPE.put(byte.class, BYTE);
-        PRIMITIVE_TO_TYPE.put(char.class, CHAR);
-        PRIMITIVE_TO_TYPE.put(double.class, DOUBLE);
-        PRIMITIVE_TO_TYPE.put(float.class, FLOAT);
-        PRIMITIVE_TO_TYPE.put(int.class, INT);
-        PRIMITIVE_TO_TYPE.put(long.class, LONG);
-        PRIMITIVE_TO_TYPE.put(short.class, SHORT);
-        PRIMITIVE_TO_TYPE.put(void.class, VOID);
-    }
-
-    final String name;
-
-    /** cached converted values */
-    final com.android.dx.rop.type.Type ropType;
-    final CstType constant;
-
-    Type(com.android.dx.rop.type.Type ropType) {
-        this(ropType.getDescriptor(), ropType);
-    }
-
-    Type(String name, com.android.dx.rop.type.Type ropType) {
-        if (name == null || ropType == null) {
-            throw new NullPointerException();
-        }
-        this.name = name;
-        this.ropType = ropType;
-        this.constant = CstType.intern(ropType);
-    }
-
-    /**
-     * @param name a descriptor like "Ljava/lang/Class;".
-     */
-    public static <T> Type<T> get(String name) {
-        return new Type<T>(name, com.android.dx.rop.type.Type.internReturnType(name));
-    }
-
-    public static <T> Type<T> get(Class<T> type) {
-        if (type.isPrimitive()) {
-            @SuppressWarnings("unchecked") // guarded by equals
-            Type<T> result = (Type<T>) PRIMITIVE_TO_TYPE.get(type);
-            return result;
-        }
-        String name = type.getName().replace('.', '/');
-        return get(type.isArray() ? name : 'L' + name + ';');
-    }
-
-    public <V> FieldId<T, V> getField(Type<V> type, String name) {
-        return new FieldId<T, V>(this, type, name);
-    }
-
-    public MethodId<T, Void> getConstructor(Type<?>... parameters) {
-        return new MethodId<T, Void>(this, VOID, "<init>", new TypeList(parameters));
-    }
-
-    public <R> MethodId<T, R> getMethod(Type<R> returnType, String name, Type<?>... parameters) {
-        return new MethodId<T, R>(this, returnType, name, new TypeList(parameters));
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override public boolean equals(Object o) {
-        return o instanceof Type
-                && ((Type) o).name.equals(name);
-    }
-
-    @Override public int hashCode() {
-        return name.hashCode();
-    }
-
-    @Override public String toString() {
-        return name;
-    }
-}
diff --git a/dx/src/com/android/dx/gen/TypeList.java b/dx/src/com/android/dx/gen/TypeList.java
deleted file mode 100644
index e18ed4a..0000000
--- a/dx/src/com/android/dx/gen/TypeList.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.type.StdTypeList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * An immutable of types.
- */
-final class TypeList {
-    final Type<?>[] types;
-    final StdTypeList ropTypes;
-
-    TypeList(Type<?>[] types) {
-        this.types = types.clone();
-        this.ropTypes = new StdTypeList(types.length);
-        for (int i = 0; i < types.length; i++) {
-            ropTypes.set(i, types[i].ropType);
-        }
-    }
-
-    /**
-     * Returns an immutable list.
-     */
-    public List<Type<?>> asList() {
-        return Collections.unmodifiableList(Arrays.asList(types));
-    }
-
-    @Override public boolean equals(Object o) {
-        return o instanceof TypeList && Arrays.equals(((TypeList) o).types, types);
-    }
-
-    @Override public int hashCode() {
-        return Arrays.hashCode(types);
-    }
-
-    @Override public String toString() {
-        StringBuilder result = new StringBuilder();
-        for (int i = 0; i < types.length; i++) {
-            if (i > 0) {
-                result.append(", ");
-            }
-            result.append(types[i]);
-        }
-        return result.toString();
-    }
-}