diff --git a/Android.mk b/Android.mk
index 786957f..54323e0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,7 +16,9 @@
 include $(CLEAR_VARS)
 
 # Include all the java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, dexmaker/src/main/java dx/src/main/java)
+LOCAL_SRC_FILES := $(call all-java-files-under, dexmaker/src/main/java)
+
+LOCAL_STATIC_JAVA_LIBRARIES := dexmaker-dx-target dexmaker-dex-target
 
 LOCAL_SDK_VERSION := 10
 
@@ -26,19 +28,6 @@
 # Build a static jar file.
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
-# Build Dexmaker's tests
-#
-# Run the tests as follows:
-#   vogar --classpath ${ANDROID_PRODUCT_OUT}/obj/JAVA_LIBRARIES/dexmaker-tests_intermediates/classes.jack \
-        com.google.dexmaker
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := dexmaker-tests
-LOCAL_SDK_VERSION := 10
-LOCAL_SRC_FILES := $(call all-java-files-under, dexmaker/src/test/java)
-LOCAL_STATIC_JAVA_LIBRARIES := dexmaker android-support-test
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
 # Build Dexmaker's MockMaker, a plugin to Mockito
 include $(CLEAR_VARS)
 LOCAL_MODULE := dexmaker-mockmaker
@@ -48,19 +37,14 @@
 LOCAL_JAVA_LIBRARIES := dexmaker mockito-api
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
-# Build a test APK
-#
-# Run the tests as follows:
-# m -j32 DexmakerTests && \
-        am install -r -g $OUT/data/app/DexmakerTests/DexmakerTests.apk \
-        adb shell am instrument -w com.google.dexmaker.tests
-#
+# Target prebuilt dependencies.
+# ============================================================
 include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_PACKAGE_NAME := DexmakerTests
-LOCAL_STATIC_JAVA_LIBRARIES := \
-        dexmaker-tests
 
-include $(BUILD_PACKAGE)
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+    dexmaker-dx-target:lib/dalvik-dx-1$(COMMON_JAVA_PACKAGE_SUFFIX) \
+    dexmaker-dex-target:lib/libcore-dex-2$(COMMON_JAVA_PACKAGE_SUFFIX) \
+
+include $(BUILD_MULTI_PREBUILT)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/README.version b/README.version
index b9485fd..f823769 100644
--- a/README.version
+++ b/README.version
@@ -1,5 +1,5 @@
 URL: https://github.com/crittercism/dexmaker/
-Version: v1.3
+Version: 2.2.0
 License: Apache 2.0
 Description:
 Dexmaker is a Java-language API for doing compile time or runtime code generation targeting the Dalvik VM. Unlike cglib or ASM, this library creates Dalvik .dex files instead of Java .class files.
@@ -9,8 +9,4 @@
 It includes a stock code generator for class proxies. If you just want to do AOP or class mocking, you don't need to mess around with bytecodes.
 
 Local Modifications:
-bug-8108255.patch: temporary workaround to ClassLoading issues
-    (see https://code.google.com/p/dexmaker/issues/detail?id=20)
-
-to apply, run 'patch -p1 < bug-xyz.patch' from a fresh src
-to remove, use 'patch -p1 -R < bug-xyz.patch'
+        Support mocking of package private classes using dexmaker.share_classloader
diff --git a/dexmaker-mockito/build.gradle b/dexmaker-mockito/build.gradle
new file mode 100644
index 0000000..36fa92f
--- /dev/null
+++ b/dexmaker-mockito/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'java'
+apply from: "$rootDir/gradle/publishing.gradle"
+
+version = VERSION_NAME
+description = "Implementation of the Mockito API for use on the Android Dalvik VM"
+
+targetCompatibility = '1.7'
+sourceCompatibility = '1.7'
+
+repositories {
+    jcenter()
+}
+
+dependencies {
+    compile project(":dexmaker")
+
+    compile 'org.mockito:mockito-core:2.2.29'
+}
diff --git a/dexmaker-mockito/pom.xml b/dexmaker-mockito/pom.xml
deleted file mode 100644
index c2bb0b9..0000000
--- a/dexmaker-mockito/pom.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Copyright (C) 2012 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>com.crittercism.dexmaker</groupId>
-        <artifactId>dexmaker-parent</artifactId>
-        <version>1.3</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>dexmaker-mockito</artifactId>
-    <packaging>jar</packaging>
-    <name>dexmaker mockito</name>
-
-    <dependencies>
-        <dependency>
-            <groupId>com.crittercism.dexmaker</groupId>
-            <artifactId>dexmaker</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <version>1.10.5</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/DexmakerMockMaker.java b/dexmaker-mockito/src/main/java/com/android/dx/mockito/DexmakerMockMaker.java
similarity index 71%
rename from dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/DexmakerMockMaker.java
rename to dexmaker-mockito/src/main/java/com/android/dx/mockito/DexmakerMockMaker.java
index 7bf2e4d..fb701c9 100644
--- a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/DexmakerMockMaker.java
+++ b/dexmaker-mockito/src/main/java/com/android/dx/mockito/DexmakerMockMaker.java
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.mockito;
+package com.android.dx.mockito;
 
-import com.google.dexmaker.stock.ProxyBuilder;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.util.Set;
+import com.android.dx.stock.ProxyBuilder;
 import org.mockito.exceptions.base.MockitoException;
 import org.mockito.exceptions.stacktrace.StackTraceCleaner;
 import org.mockito.invocation.MockHandler;
@@ -27,15 +24,21 @@
 import org.mockito.plugins.MockMaker;
 import org.mockito.plugins.StackTraceCleanerProvider;
 
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.Set;
+
 /**
  * Generates mock instances on Android's runtime.
  */
 public final class DexmakerMockMaker implements MockMaker, StackTraceCleanerProvider {
     private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create();
 
+    @Override
     public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) {
         Class<T> typeToMock = settings.getTypeToMock();
-        Set<Class> interfacesSet = settings.getExtraInterfaces();
+        Set<Class<?>> interfacesSet = settings.getExtraInterfaces();
         Class<?>[] extraInterfaces = interfacesSet.toArray(new Class[interfacesSet.size()]);
         InvocationHandler invocationHandler = new InvocationHandlerAdapter(handler);
 
@@ -44,10 +47,9 @@
             Class[] classesToMock = new Class[extraInterfaces.length + 1];
             classesToMock[0] = typeToMock;
             System.arraycopy(extraInterfaces, 0, classesToMock, 1, extraInterfaces.length);
-            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-            @SuppressWarnings("unchecked") // newProxyInstance returns the type of typeToMock
-            T mock = (T) Proxy.newProxyInstance(contextClassLoader, classesToMock,
-                    invocationHandler);
+            // newProxyInstance returns the type of typeToMock
+            @SuppressWarnings("unchecked")
+            T mock = (T) Proxy.newProxyInstance(typeToMock.getClassLoader(), classesToMock, invocationHandler);
             return mock;
 
         } else {
@@ -67,16 +69,54 @@
         }
     }
 
+    @Override
     public void resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings) {
         InvocationHandlerAdapter adapter = getInvocationHandlerAdapter(mock);
         adapter.setHandler(newHandler);
     }
 
+    @Override
+    public TypeMockability isTypeMockable(final Class<?> type) {
+        return new TypeMockability() {
+            @Override
+            public boolean mockable() {
+                return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers());
+            }
+
+            @Override
+            public String nonMockableReason() {
+                if (type.isPrimitive()) {
+                    return "primitive type";
+                }
+
+                if (Modifier.isFinal(type.getModifiers())) {
+                    return "final or anonymous class";
+                }
+
+                return "not handled type";
+            }
+        };
+    }
+
+    @Override
     public MockHandler getHandler(Object mock) {
         InvocationHandlerAdapter adapter = getInvocationHandlerAdapter(mock);
         return adapter != null ? adapter.getHandler() : null;
     }
 
+    @Override
+    public StackTraceCleaner getStackTraceCleaner(final StackTraceCleaner defaultCleaner) {
+        return new StackTraceCleaner() {
+            @Override
+            public boolean isIn(StackTraceElement candidate) {
+                return defaultCleaner.isIn(candidate)
+                        && !candidate.getClassName().endsWith("_Proxy") // dexmaker class proxies
+                        && !candidate.getClassName().startsWith("$Proxy") // dalvik interface proxies
+                        && !candidate.getClassName().startsWith("com.google.dexmaker.mockito.");
+            }
+        };
+    }
+
     private InvocationHandlerAdapter getInvocationHandlerAdapter(Object mock) {
         if (mock == null) {
             return null;
@@ -97,15 +137,4 @@
 
         return null;
     }
-
-    public StackTraceCleaner getStackTraceCleaner(final StackTraceCleaner defaultCleaner) {
-        return new StackTraceCleaner() {
-            public boolean isOut(StackTraceElement candidate) {
-                return defaultCleaner.isOut(candidate)
-                        || candidate.getClassName().endsWith("_Proxy") // dexmaker class proxies
-                        || candidate.getClassName().startsWith("$Proxy") // dalvik interface proxies
-                        || candidate.getClassName().startsWith("com.google.dexmaker.mockito.");
-            }
-        };
-    }
 }
diff --git a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/InvocationHandlerAdapter.java b/dexmaker-mockito/src/main/java/com/android/dx/mockito/InvocationHandlerAdapter.java
similarity index 73%
rename from dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/InvocationHandlerAdapter.java
rename to dexmaker-mockito/src/main/java/com/android/dx/mockito/InvocationHandlerAdapter.java
index cf062b9..e2a5957 100644
--- a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/InvocationHandlerAdapter.java
+++ b/dexmaker-mockito/src/main/java/com/android/dx/mockito/InvocationHandlerAdapter.java
@@ -14,42 +14,44 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.mockito;
+package com.android.dx.mockito;
 
-import com.google.dexmaker.stock.ProxyBuilder;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
+import com.android.dx.stock.ProxyBuilder;
+import org.mockito.internal.debugging.LocationImpl;
 import org.mockito.internal.invocation.InvocationImpl;
 import org.mockito.internal.invocation.MockitoMethod;
 import org.mockito.internal.invocation.realmethod.RealMethod;
 import org.mockito.internal.progress.SequenceNumber;
-import org.mockito.internal.util.ObjectMethodsGuru;
 import org.mockito.invocation.MockHandler;
 
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
 /**
  * Handles proxy method invocations to dexmaker's InvocationHandler by calling
  * a MockitoInvocationHandler.
  */
 final class InvocationHandlerAdapter implements InvocationHandler {
     private MockHandler handler;
-    private final ObjectMethodsGuru objectMethodsGuru = new ObjectMethodsGuru();
 
     public InvocationHandlerAdapter(MockHandler handler) {
         this.handler = handler;
     }
 
+    @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        if (objectMethodsGuru.isEqualsMethod(method)) {
+        // args can be null if the method invoked has no arguments, but Mockito expects a non-null array
+        args = args != null ? args : new Object[0];
+        if (isEqualsMethod(method)) {
             return proxy == args[0];
-        } else if (objectMethodsGuru.isHashCodeMethod(method)) {
+        } else if (isHashCodeMethod(method)) {
             return System.identityHashCode(proxy);
         }
 
         ProxiedMethod proxiedMethod = new ProxiedMethod(method);
         return handler.handle(new InvocationImpl(proxy, proxiedMethod, args, SequenceNumber.next(),
-                proxiedMethod));
+                proxiedMethod, new LocationImpl()));
     }
 
     public MockHandler getHandler() {
@@ -60,41 +62,60 @@
         this.handler = handler;
     }
 
+    private static boolean isEqualsMethod(Method method) {
+        return method.getName().equals("equals")
+                && method.getParameterTypes().length == 1
+                && method.getParameterTypes()[0] == Object.class;
+    }
+
+    private static boolean isHashCodeMethod(Method method) {
+        return method.getName().equals("hashCode")
+                && method.getParameterTypes().length == 0;
+    }
+
     private static class ProxiedMethod implements MockitoMethod, RealMethod {
         private final Method method;
 
-        public ProxiedMethod(Method method) {
+        ProxiedMethod(Method method) {
             this.method = method;
         }
 
+        @Override
         public String getName() {
             return method.getName();
         }
 
+        @Override
         public Class<?> getReturnType() {
             return method.getReturnType();
         }
 
+        @Override
         public Class<?>[] getParameterTypes() {
             return method.getParameterTypes();
         }
 
+        @Override
         public Class<?>[] getExceptionTypes() {
             return method.getExceptionTypes();
         }
 
+        @Override
         public boolean isVarArgs() {
             return method.isVarArgs();
         }
 
+        @Override
         public Method getJavaMethod() {
             return method;
         }
 
+        @Override
         public Object invoke(Object target, Object[] arguments) throws Throwable {
             return ProxyBuilder.callSuper(target, method, arguments);
         }
 
+        @Override
         public boolean isAbstract() {
             return Modifier.isAbstract(method.getModifiers());
         }
diff --git a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/UnsafeAllocator.java b/dexmaker-mockito/src/main/java/com/android/dx/mockito/UnsafeAllocator.java
similarity index 98%
rename from dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/UnsafeAllocator.java
rename to dexmaker-mockito/src/main/java/com/android/dx/mockito/UnsafeAllocator.java
index 2e10b41..eedd12d 100644
--- a/dexmaker-mockito/src/main/java/com/google/dexmaker/mockito/UnsafeAllocator.java
+++ b/dexmaker-mockito/src/main/java/com/android/dx/mockito/UnsafeAllocator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.mockito;
+package com.android.dx.mockito;
 
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
diff --git a/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.MockMaker b/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.MockMaker
index 9f6df44..06a696b 100644
--- a/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.MockMaker
+++ b/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -1 +1 @@
-com.google.dexmaker.mockito.DexmakerMockMaker
+com.android.dx.mockito.DexmakerMockMaker
diff --git a/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider b/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider
index 9f6df44..06a696b 100644
--- a/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider
+++ b/dexmaker-mockito/src/main/resources/mockito-extensions/org.mockito.plugins.StackTraceCleanerProvider
@@ -1 +1 @@
-com.google.dexmaker.mockito.DexmakerMockMaker
+com.android.dx.mockito.DexmakerMockMaker
diff --git a/dexmaker-tests/Android.mk b/dexmaker-tests/Android.mk
new file mode 100644
index 0000000..c05d208
--- /dev/null
+++ b/dexmaker-tests/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2017 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.
+#
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# Build Dexmaker's tests
+#
+# Run the tests as follows:
+#   vogar --classpath ${ANDROID_PRODUCT_OUT}/obj/JAVA_LIBRARIES/dexmaker-tests_intermediates/classes.jack \
+        com.google.dexmaker
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dexmaker-tests
+LOCAL_SDK_VERSION := 10
+LOCAL_SRC_FILES := $(call all-java-files-under, dexmaker-tests/src/androidTest/java)
+LOCAL_STATIC_JAVA_LIBRARIES := dexmaker android-support-test
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Build a test APK
+#
+# Run the tests as follows:
+# m -j32 DexmakerTests && \
+        am install -r -g $OUT/data/app/DexmakerTests/DexmakerTests.apk \
+        adb shell am instrument -w com.google.dexmaker.tests
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_PACKAGE_NAME := DexmakerTests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        dexmaker-tests
+
+include $(BUILD_PACKAGE)
diff --git a/dexmaker-tests/AndroidManifest.xml b/dexmaker-tests/AndroidManifest.xml
new file mode 100644
index 0000000..7849b0b
--- /dev/null
+++ b/dexmaker-tests/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<!--
+  Copyright (C) 2016 LinkedIn Corp.
+
+  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.
+-->
+<manifest package="com.linkedin.dexmaker"
+          xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+
+    <application/>
+</manifest>
\ No newline at end of file
diff --git a/dexmaker-tests/build.gradle b/dexmaker-tests/build.gradle
new file mode 100644
index 0000000..5bd40cd
--- /dev/null
+++ b/dexmaker-tests/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.android.application'
+
+repositories {
+    jcenter()
+}
+
+android {
+    compileSdkVersion 25
+    buildToolsVersion '25.0.0'
+
+    defaultConfig {
+        applicationId "com.linkedin.dexmaker"
+        minSdkVersion 8
+        targetSdkVersion 25
+        versionCode 1
+        versionName VERSION_NAME
+
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+}
+
+dependencies {
+    compile project(":dexmaker")
+
+    androidTestCompile 'com.android.support.test:runner:0.5'
+    androidTestCompile 'junit:junit:4.12'
+}
diff --git a/dexmaker/src/test/java/com/google/dexmaker/AppDataDirGuesserTest.java b/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java
similarity index 74%
rename from dexmaker/src/test/java/com/google/dexmaker/AppDataDirGuesserTest.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java
index b638509..b1ff25f 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/AppDataDirGuesserTest.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java
@@ -14,52 +14,63 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
+import android.os.Build;
+import org.junit.Test;
+
 import java.io.File;
-import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
-import junit.framework.TestCase;
 
-public final class AppDataDirGuesserTest extends TestCase {
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public final class AppDataDirGuesserTest {
+    @Test
     public void testGuessCacheDir_SimpleExample() {
         guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
         guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache");
     }
 
+    @Test
     public void testGuessCacheDir_MultipleResultsSeparatedByColon() {
         guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
                 .shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache");
     }
 
+    @Test
     public void testGuessCacheDir_NotWriteableSkipped() {
         guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
                 .withNonWriteable("/data/data/a.b.c/cache")
                 .shouldGive("/data/data/d.e.f/cache");
     }
 
+    @Test
     public void testGuessCacheDir_StripHyphenatedSuffixes() {
         guessCacheDirFor("/data/app/a.b.c-2.apk").shouldGive("/data/data/a.b.c/cache");
     }
 
+    @Test
     public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() {
         guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache");
         guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
     }
 
+    @Test
     public void testGuessCacheDir_InvalidInputsGiveEmptyArray() {
         guessCacheDirFor("").shouldGive();
     }
 
+    @Test
     public void testGuessCacheDir_JarsIgnored() {
         guessCacheDirFor("/data/app/a.b.c.jar").shouldGive();
         guessCacheDirFor("/system/framework/android.test.runner.jar").shouldGive();
     }
 
+    @Test
     public void testGuessCacheDir_RealWorldExample() {
         String realPath = "/system/framework/android.test.runner.jar:" +
                 "/data/app/com.google.android.voicesearch.tests-2.apk:" +
@@ -69,6 +80,7 @@
                 .shouldGive("/data/data/com.google.android.voicesearch/cache");
     }
 
+    @Test
     public void testSplitPathList() {
         final String[] expected = { "foo", "bar" };
         assertTrue(Arrays.equals(expected, AppDataDirGuesser.splitPathList("foo:bar")));
@@ -78,6 +90,7 @@
                 AppDataDirGuesser.splitPathList("dexPath=foo:bar,bazPath=bar:bar2")));
     }
 
+    @Test
     public void testPre43PathProcessing() {
         String input = "dalvik.system.PathClassLoader[dexPath=/data/app/abc-1.apk," +
                        "libraryPath=/data/app-lib/abc-1]";
@@ -85,6 +98,7 @@
         assertTrue("dexPath=/data/app/abc-1.apk,libraryPath=/data/app-lib/abc-1".equals(processed));
     }
 
+    @Test
     public void test43PathProcessing() {
         String input = "dalvik.system.PathClassLoader[DexPathList[[zip file " +
                        "\"/data/app/abc-1/base.apk\", zip file \"/data/app/def-1/base.apk\"], " +
@@ -93,50 +107,13 @@
         assertTrue("/data/app/abc-1/base.apk:/data/app/def-1/base.apk".equals(processed));
     }
 
-    // Try to find the SDK level of the device.
-    private int getSDKLevel() {
-        // Maybe the version is reflected into the system properties correctly.
-        String level = System.getProperty("ro.build.version.sdk");
-        try {
-            return Integer.parseInt(level);
-        } catch (Exception ignored) {
-        }
-
-        // Run getprop and parse the result.
-        try {
-            Process p = Runtime.getRuntime().exec("/system/bin/getprop ro.build.version.sdk");
-            int exitValue = p.waitFor();
-            if (exitValue == 0) {
-                String line =
-                        new BufferedReader(new InputStreamReader(p.getInputStream())).readLine();
-                if (line != null) {
-                    return Integer.parseInt(line);
-                }
-            }
-        } catch (Exception ignored) {
-        }
-
-        // It would be nice to access android.os.Build.SDK_INT. However, that bottoms out in some
-        // native code reading system properties. Try to load the library and *hope* that the
-        // methods don't need registration code. Note: this will likely fail.
-        try {
-            // Need to load android_runtime.
-            System.loadLibrary("android_runtime");
-            Class<?> buildClass = Class.forName("android.os.Build");
-            java.lang.reflect.Field field = buildClass.getDeclaredField("SDK_INT");
-            return field.getInt(null);
-        } catch (Throwable exc) {
-            // This is already the fallback of the fallback, so throw an unchecked exception.
-            throw new RuntimeException(exc);
-        }
-    }
-
+    @Test
     public void testApiLevel17PlusPathProcessing() {
-        int level = getSDKLevel();
-        if (level >= 17) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             // Our processing should work for anything >= Android 4.2.
             String input = getClass().getClassLoader().toString();
             String processed = AppDataDirGuesser.processClassLoaderString(input);
+            // TODO: this comment is no longer true now that we run tests on Android instead of vogar
             // A tighter check would be interesting. But vogar doesn't run the tests in a directory
             // recognized by the guesser (usually under /data/local/tmp), so we cannot use the
             // processed result as input to guessPath.
@@ -150,7 +127,7 @@
     }
 
     private TestCondition guessCacheDirFor(final String path) {
-        final Set<String> notWriteable = new HashSet<String>();
+        final Set<String> notWriteable = new HashSet<>();
         return new TestCondition() {
             public void shouldGive(String... files) {
                 AppDataDirGuesser guesser = new AppDataDirGuesser() {
diff --git a/dexmaker/src/test/java/com/google/dexmaker/DexMakerTest.java b/dexmaker-tests/src/androidTest/java/com/android/dx/DexMakerTest.java
similarity index 97%
rename from dexmaker/src/test/java/com/google/dexmaker/DexMakerTest.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/DexMakerTest.java
index 36e6c00..e955d82 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/DexMakerTest.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/DexMakerTest.java
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import android.support.test.InstrumentationRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
@@ -24,6 +27,12 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import static com.android.dx.util.TestUtil.DELTA_DOUBLE;
+import static com.android.dx.util.TestUtil.DELTA_FLOAT;
 import static java.lang.reflect.Modifier.ABSTRACT;
 import static java.lang.reflect.Modifier.FINAL;
 import static java.lang.reflect.Modifier.NATIVE;
@@ -32,10 +41,10 @@
 import static java.lang.reflect.Modifier.PUBLIC;
 import static java.lang.reflect.Modifier.STATIC;
 import static java.lang.reflect.Modifier.SYNCHRONIZED;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * This generates a class named 'Generated' with one or more generated methods
@@ -44,7 +53,7 @@
  *
  * <p>This test must run on a Dalvik VM.
  */
-public final class DexMakerTest extends TestCase {
+public final class DexMakerTest {
     private DexMaker dexMaker;
     private static TypeId<DexMakerTest> TEST_TYPE = TypeId.get(DexMakerTest.class);
     private static TypeId<?> INT_ARRAY = TypeId.get(int[].class);
@@ -56,8 +65,8 @@
     private static TypeId<Callable> CALLABLE = TypeId.get(Callable.class);
     private static MethodId<Callable, Object> CALL = CALLABLE.getMethod(TypeId.OBJECT, "call");
 
-    @Override protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setup() {
         reset();
     }
 
@@ -79,6 +88,7 @@
         }
     }
 
+    @Test
     public void testNewInstance() throws Exception {
         /*
          * public static Constructable call(long a, boolean b) {
@@ -112,6 +122,7 @@
         }
     }
 
+    @Test
     public void testVoidNoArgMemberMethod() throws Exception {
         /*
          * public void call() {
@@ -129,6 +140,7 @@
         method.invoke(instance);
     }
 
+    @Test
     public void testInvokeStatic() throws Exception {
         /*
          * public static int call(int a) {
@@ -148,6 +160,7 @@
         assertEquals(10, getMethod().invoke(null, 4));
     }
 
+    @Test
     public void testCreateLocalMethodAsNull() throws Exception {
         /*
          * public void call(int value) {
@@ -174,6 +187,7 @@
         return a + 6;
     }
 
+    @Test
     public void testInvokeVirtual() throws Exception {
         /*
          * public static int call(DexMakerTest test, int a) {
@@ -199,6 +213,7 @@
         return a + 5;
     }
 
+    @Test
     public <G> void testInvokeDirect() throws Exception {
         /*
          * private int directMethod() {
@@ -234,6 +249,7 @@
         assertEquals(5, method.invoke(null, instance));
     }
 
+    @Test
     public <G> void testInvokeSuper() throws Exception {
         /*
          * public int superHashCode() {
@@ -267,6 +283,7 @@
         assertEquals(System.identityHashCode(instance), method.invoke(instance));
     }
 
+    @Test
     public void testInvokeInterface() throws Exception {
         /*
          * public static Object call(Callable c) {
@@ -289,6 +306,7 @@
         assertEquals("abc", getMethod().invoke(null, callable));
     }
 
+    @Test
     public void testInvokeVoidMethodIgnoresTargetLocal() throws Exception {
         /*
          * public static int call() {
@@ -309,9 +327,9 @@
     }
 
     @SuppressWarnings("unused") // called by generated code
-    public static void voidMethod() {
-    }
+    public static void voidMethod() {}
 
+    @Test
     public void testParameterMismatch() throws Exception {
         TypeId<?>[] argTypes = {
                 TypeId.get(Integer.class), // should fail because the code specifies int
@@ -329,6 +347,7 @@
         }
     }
 
+    @Test
     public void testInvokeTypeSafety() throws Exception {
         /*
          * public static boolean call(DexMakerTest test) {
@@ -354,6 +373,7 @@
         assertEquals(false, getMethod().invoke(null, this));
     }
 
+    @Test
     public void testReturnTypeMismatch() {
         MethodId<?, String> methodId = GENERATED.getMethod(TypeId.STRING, "call");
         Code code = dexMaker.declare(methodId, PUBLIC | STATIC);
@@ -369,6 +389,7 @@
         }
     }
 
+    @Test
     public void testDeclareStaticFields() throws Exception {
         /*
          * class Generated {
@@ -390,6 +411,7 @@
         assertEquals(null, b.get(null));
     }
 
+    @Test
     public void testDeclareInstanceFields() throws Exception {
         /*
          * class Generated {
@@ -419,6 +441,7 @@
      * Declare a constructor that takes an int parameter and assigns it to a
      * field.
      */
+    @Test
     public <G> void testDeclareConstructor() throws Exception {
         /*
          * class Generated {
@@ -445,6 +468,7 @@
         assertEquals(0xabcd, a.get(instance));
     }
 
+    @Test
     public void testReturnType() throws Exception {
         testReturnType(boolean.class, true);
         testReturnType(byte.class, (byte) 5);
@@ -483,6 +507,7 @@
         assertEquals(value, method.invoke(null));
     }
 
+    @Test
     public void testBranching() throws Exception {
         Method lt = branchingMethod(Comparison.LT);
         assertEquals(Boolean.TRUE, lt.invoke(null, 1, 2));
@@ -546,6 +571,7 @@
         return getMethod();
     }
 
+    @Test
     public void testCastIntegerToInteger() throws Exception {
         Method intToLong = numericCastingMethod(int.class, long.class);
         assertEquals(0x0000000000000000L, intToLong.invoke(null, 0x00000000));
@@ -574,6 +600,7 @@
         assertEquals((byte) 0x34, intToByte.invoke(null, 0xffffff34));
     }
 
+    @Test
     public void testCastIntegerToFloatingPoint() throws Exception {
         Method intToFloat = numericCastingMethod(int.class, float.class);
         assertEquals(0.0f, intToFloat.invoke(null, 0));
@@ -600,6 +627,7 @@
         assertEquals(9007199254740992.0, longToDouble.invoke(null, 9007199254740993L)); // precision
     }
 
+    @Test
     public void testCastFloatingPointToInteger() throws Exception {
         Method floatToInt = numericCastingMethod(float.class, int.class);
         assertEquals(0, floatToInt.invoke(null, 0.0f));
@@ -634,6 +662,7 @@
         assertEquals(0L, doubleToLong.invoke(null, Double.NaN));
     }
 
+    @Test
     public void testCastFloatingPointToFloatingPoint() throws Exception {
         Method floatToDouble = numericCastingMethod(float.class, double.class);
         assertEquals(0.0, floatToDouble.invoke(null, 0.0f));
@@ -670,6 +699,7 @@
         return getMethod();
     }
 
+    @Test
     public void testNot() throws Exception {
         Method notInteger = notMethod(int.class);
         assertEquals(0xffffffff, notInteger.invoke(null, 0x00000000));
@@ -699,6 +729,7 @@
         return getMethod();
     }
 
+    @Test
     public void testNegate() throws Exception {
         Method negateInteger = negateMethod(int.class);
         assertEquals(0, negateInteger.invoke(null, 0));
@@ -740,6 +771,7 @@
         return getMethod();
     }
 
+    @Test
     public void testIntBinaryOps() throws Exception {
         Method add = binaryOpMethod(int.class, int.class, BinaryOp.ADD);
         assertEquals(79, add.invoke(null, 75, 4));
@@ -788,6 +820,7 @@
         assertEquals(0x00abcd12, unsignedShiftRight.invoke(null, 0xabcd1234, 8));
     }
 
+    @Test
     public void testLongBinaryOps() throws Exception {
         Method add = binaryOpMethod(long.class, long.class, BinaryOp.ADD);
         assertEquals(30000000079L, add.invoke(null, 10000000075L, 20000000004L));
@@ -839,6 +872,7 @@
         assertEquals(0x00abcdef01234567L, unsignedShiftRight.invoke(null, 0xabcdef0123456789L, 8));
     }
 
+    @Test
     public void testFloatBinaryOps() throws Exception {
         Method add = binaryOpMethod(float.class, float.class, BinaryOp.ADD);
         assertEquals(6.75f, add.invoke(null, 5.5f, 1.25f));
@@ -858,6 +892,7 @@
         assertEquals(Float.NaN, remainder.invoke(null, 5.5f, 0.0f));
     }
 
+    @Test
     public void testDoubleBinaryOps() throws Exception {
         Method add = binaryOpMethod(double.class, double.class, BinaryOp.ADD);
         assertEquals(6.75, add.invoke(null, 5.5, 1.25));
@@ -898,6 +933,7 @@
         return getMethod();
     }
 
+    @Test
     public void testReadAndWriteInstanceFields() throws Exception {
         Instance instance = new Instance();
 
@@ -919,12 +955,12 @@
         Method floatSwap = instanceSwapMethod(float.class, "floatValue");
         instance.floatValue = 1.5f;
         assertEquals(1.5f, floatSwap.invoke(null, instance, 0.5f));
-        assertEquals(0.5f, instance.floatValue);
+        assertEquals(0.5f, instance.floatValue, DELTA_FLOAT);
 
         Method doubleSwap = instanceSwapMethod(double.class, "doubleValue");
         instance.doubleValue = 155.5;
         assertEquals(155.5, doubleSwap.invoke(null, instance, 266.6));
-        assertEquals(266.6, instance.doubleValue);
+        assertEquals(266.6, instance.doubleValue, DELTA_DOUBLE);
 
         Method objectSwap = instanceSwapMethod(Object.class, "objectValue");
         instance.objectValue = "before";
@@ -983,6 +1019,7 @@
         return getMethod();
     }
 
+    @Test
     public void testReadAndWriteStaticFields() throws Exception {
         Method intSwap = staticSwapMethod(int.class, "intValue");
         Static.intValue = 5;
@@ -1002,12 +1039,12 @@
         Method floatSwap = staticSwapMethod(float.class, "floatValue");
         Static.floatValue = 1.5f;
         assertEquals(1.5f, floatSwap.invoke(null, 0.5f));
-        assertEquals(0.5f, Static.floatValue);
+        assertEquals(0.5f, Static.floatValue, DELTA_FLOAT);
 
         Method doubleSwap = staticSwapMethod(double.class, "doubleValue");
         Static.doubleValue = 155.5;
         assertEquals(155.5, doubleSwap.invoke(null, 266.6));
-        assertEquals(266.6, Static.doubleValue);
+        assertEquals(266.6, Static.doubleValue, DELTA_DOUBLE);
 
         Method objectSwap = staticSwapMethod(Object.class, "objectValue");
         Static.objectValue = "before";
@@ -1065,6 +1102,7 @@
         return getMethod();
     }
 
+    @Test
     public void testTypeCast() throws Exception {
         /*
          * public static String call(Object o) {
@@ -1089,6 +1127,7 @@
         }
     }
 
+    @Test
     public void testInstanceOf() throws Exception {
         /*
          * public static boolean call(Object o) {
@@ -1112,6 +1151,7 @@
     /**
      * Tests that we can construct a for loop.
      */
+    @Test
     public void testForLoop() throws Exception {
         /*
          * public static int call(int count) {
@@ -1157,6 +1197,7 @@
     /**
      * Tests that we can construct a while loop.
      */
+    @Test
     public void testWhileLoop() throws Exception {
         /*
          * public static int call(int max) {
@@ -1195,6 +1236,7 @@
         assertEquals(1024, ceilPow2.invoke(null, 1000));
     }
 
+    @Test
     public void testIfElseBlock() throws Exception {
         /*
          * public static int call(int a, int b, int c) {
@@ -1241,6 +1283,7 @@
         assertEquals(1, min.invoke(null, 3, 2, 1));
     }
 
+    @Test
     public void testRecursion() throws Exception {
         /*
          * public static int call(int a) {
@@ -1286,6 +1329,7 @@
         assertEquals(8, fib.invoke(null, 6));
     }
 
+    @Test
     public void testCatchExceptions() throws Exception {
         /*
          * public static String call(int i) {
@@ -1359,6 +1403,7 @@
         }
     }
 
+    @Test
     public void testNestedCatchClauses() throws Exception {
         /*
          * public static String call(int a, int b, int c) {
@@ -1416,6 +1461,7 @@
         assertEquals("NONE", method.invoke(null, 0, 0, 0));
     }
 
+    @Test
     public void testThrow() throws Exception {
         /*
          * public static void call() {
@@ -1438,6 +1484,7 @@
         }
     }
 
+    @Test
     public void testUnusedParameters() throws Exception {
         /*
          * public static void call(int unused1, long unused2, long unused3) {}
@@ -1449,6 +1496,7 @@
         getMethod().invoke(null, 1, 2, 3);
     }
 
+    @Test
     public void testFloatingPointCompare() throws Exception {
         Method floatG = floatingPointCompareMethod(TypeId.FLOAT, 1);
         assertEquals(-1, floatG.invoke(null, 1.0f, Float.POSITIVE_INFINITY));
@@ -1511,6 +1559,7 @@
         return getMethod();
     }
 
+    @Test
     public void testLongCompare() throws Exception {
         /*
          * public static int call(long a, long b) {
@@ -1538,6 +1587,7 @@
         assertEquals(0, method.invoke(null, Long.MAX_VALUE, Long.MAX_VALUE));
     }
 
+    @Test
     public void testArrayLength() throws Exception {
         Method booleanArrayLength = arrayLengthMethod(BOOLEAN_ARRAY);
         assertEquals(0, booleanArrayLength.invoke(null, new Object[] { new boolean[0] }));
@@ -1577,6 +1627,7 @@
         return getMethod();
     }
 
+    @Test
     public void testNewArray() throws Exception {
         Method newBooleanArray = newArrayMethod(BOOLEAN_ARRAY);
         assertEquals("[]", Arrays.toString((boolean[]) newBooleanArray.invoke(null, 0)));
@@ -1619,6 +1670,7 @@
         return getMethod();
     }
 
+    @Test
     public void testReadAndWriteArray() throws Exception {
         Method swapBooleanArray = arraySwapMethod(BOOLEAN_ARRAY, TypeId.BOOLEAN);
         boolean[] booleans = new boolean[3];
@@ -1669,6 +1721,7 @@
         return getMethod();
     }
 
+    @Test
     public void testSynchronizedFlagImpactsDeclarationOnly() throws Exception {
         /*
          * public synchronized void call() {
@@ -1698,6 +1751,7 @@
         }
     }
 
+    @Test
     public void testMonitorEnterMonitorExit() throws Exception {
         /*
          * public synchronized void call() {
@@ -1726,6 +1780,7 @@
         method.invoke(instance); // will take 100ms
     }
 
+    @Test
     public void testMoveInt() throws Exception {
         /*
          * public static int call(int a) {
@@ -1746,6 +1801,7 @@
         assertEquals(6, getMethod().invoke(null, 3));
     }
 
+    @Test
     public void testPrivateClassesAreUnsupported() {
         try {
             dexMaker.declare(TypeId.get("LPrivateClass;"), "PrivateClass.generated", PRIVATE,
@@ -1755,6 +1811,7 @@
         }
     }
 
+    @Test
     public void testAbstractMethodsAreUnsupported() {
         MethodId<?, Void> methodId = GENERATED.getMethod(TypeId.VOID, "call");
         try {
@@ -1764,6 +1821,7 @@
         }
     }
 
+    @Test
     public void testNativeMethodsAreUnsupported() {
         MethodId<?, Void> methodId = GENERATED.getMethod(TypeId.VOID, "call");
         try {
@@ -1773,6 +1831,7 @@
         }
     }
 
+    @Test
     public void testSynchronizedFieldsAreUnsupported() {
         try {
             FieldId<?, ?> fieldId = GENERATED.getField(TypeId.OBJECT, "synchronizedField");
@@ -1782,6 +1841,7 @@
         }
     }
 
+    @Test
     public void testInitialValueWithNonStaticField() {
         try {
             FieldId<?, ?> fieldId = GENERATED.getField(TypeId.OBJECT, "nonStaticField");
@@ -1812,6 +1872,7 @@
         code.returnVoid();
     }
 
+    @Test
     public void testCaching_Methods() throws Exception {
         int origSize = getDataDirectory().listFiles().length;
         final String defaultMethodName = "call";
@@ -1890,14 +1951,11 @@
         assertEquals(origSize + 16, getDataDirectory().listFiles().length);
     }
 
-    public static class BlankClassA {
+    public static class BlankClassA {}
 
-    }
+    public static class BlankClassB {}
 
-    public static class BlankClassB {
-
-    }
-
+    @Test
     public void testCaching_DifferentParentClasses() throws Exception {
         int origSize = getDataDirectory().listFiles().length;
         final String defaultMethodName = "call";
@@ -1936,6 +1994,7 @@
         }
     }
 
+    @Test
     public void testCaching_Constructors() throws Exception {
         int origSize = getDataDirectory().listFiles().length;
 
@@ -2008,22 +2067,8 @@
     }
 
     public static File getDataDirectory() {
-        // Assume that this is being run as an APK by AndroidJUnitRunner and so get the directory
-        // where the APK can create files.
-        try {
-            // This will fail on Vogar as it will not register an Instrumentation.
-            return InstrumentationRegistry.getContext().getFilesDir();
-        } catch (IllegalStateException t) {
-            // Drop through to an alternate mechanism for getting a directory that works on Vogar.
-            if (!t.getMessage().contains("No instrumentation registered!")) {
-                // The exception wasn't expected.
-                throw t;
-            }
-        }
-        String envVariable = "ANDROID_DATA";
-        String defaultLoc = "/data";
-        String path = System.getenv(envVariable);
-        return path == null ? new File(defaultLoc) : new File(path);
+        String dataDir = InstrumentationRegistry.getTargetContext().getApplicationInfo().dataDir;
+        return new File(dataDir);
     }
 
     private Class<?> generateAndLoad() throws Exception {
diff --git a/dexmaker/src/test/java/com/google/dexmaker/TypeIdTest.java b/dexmaker-tests/src/androidTest/java/com/android/dx/TypeIdTest.java
similarity index 88%
rename from dexmaker/src/test/java/com/google/dexmaker/TypeIdTest.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/TypeIdTest.java
index 26e8413..77f6754 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/TypeIdTest.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/TypeIdTest.java
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
-public final class TypeIdTest extends TestCase {
+import static org.junit.Assert.assertEquals;
+
+public final class TypeIdTest {
+    @Test
     public void testGetType() {
         assertEquals("Ljava/lang/String;", TypeId.get(String.class).getName());
         assertEquals("[Ljava/lang/String;", TypeId.get(String[].class).getName());
diff --git a/dexmaker/src/test/java/com/google/dexmaker/examples/FibonacciMaker.java b/dexmaker-tests/src/androidTest/java/com/android/dx/examples/FibonacciMaker.java
similarity index 89%
rename from dexmaker/src/test/java/com/google/dexmaker/examples/FibonacciMaker.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/examples/FibonacciMaker.java
index ced3d53..14ff994 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/examples/FibonacciMaker.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/examples/FibonacciMaker.java
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.examples;
+package com.android.dx.examples;
 
-import com.google.dexmaker.BinaryOp;
-import com.google.dexmaker.Code;
-import com.google.dexmaker.Comparison;
-import com.google.dexmaker.DexMaker;
-import com.google.dexmaker.Label;
-import com.google.dexmaker.Local;
-import com.google.dexmaker.MethodId;
-import com.google.dexmaker.TypeId;
+import com.android.dx.Code;
+import com.android.dx.Comparison;
+import com.android.dx.DexMaker;
+import com.android.dx.Label;
+import com.android.dx.Local;
+import com.android.dx.MethodId;
+import com.android.dx.TypeId;
+import com.android.dx.BinaryOp;
+
 import java.io.File;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
diff --git a/dexmaker/src/test/java/com/google/dexmaker/examples/HelloWorldMaker.java b/dexmaker-tests/src/androidTest/java/com/android/dx/examples/HelloWorldMaker.java
similarity index 92%
rename from dexmaker/src/test/java/com/google/dexmaker/examples/HelloWorldMaker.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/examples/HelloWorldMaker.java
index 40dd1aa..e1abcd9 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/examples/HelloWorldMaker.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/examples/HelloWorldMaker.java
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.examples;
+package com.android.dx.examples;
 
-import com.google.dexmaker.BinaryOp;
-import com.google.dexmaker.Code;
-import com.google.dexmaker.DexMaker;
-import com.google.dexmaker.FieldId;
-import com.google.dexmaker.Local;
-import com.google.dexmaker.MethodId;
-import com.google.dexmaker.TypeId;
+import com.android.dx.Code;
+import com.android.dx.FieldId;
+import com.android.dx.Local;
+import com.android.dx.TypeId;
+import com.android.dx.BinaryOp;
+import com.android.dx.DexMaker;
+import com.android.dx.MethodId;
+
 import java.io.File;
 import java.io.PrintStream;
 import java.lang.reflect.Modifier;
diff --git a/dexmaker/src/test/java/com/google/dexmaker/stock/ProxyBuilderTest.java b/dexmaker-tests/src/androidTest/java/com/android/dx/stock/ProxyBuilderTest.java
similarity index 89%
rename from dexmaker/src/test/java/com/google/dexmaker/stock/ProxyBuilderTest.java
rename to dexmaker-tests/src/androidTest/java/com/android/dx/stock/ProxyBuilderTest.java
index 9c4cffe..f0e7599 100644
--- a/dexmaker/src/test/java/com/google/dexmaker/stock/ProxyBuilderTest.java
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/stock/ProxyBuilderTest.java
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.stock;
+package com.android.dx.stock;
 
-import com.google.dexmaker.DexMakerTest;
+import com.android.dx.DexMakerTest;
+import junit.framework.AssertionFailedError;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Field;
@@ -28,31 +33,36 @@
 import java.util.Random;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicInteger;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
 
-public class ProxyBuilderTest extends TestCase {
+import static com.android.dx.util.TestUtil.DELTA_DOUBLE;
+import static com.android.dx.util.TestUtil.DELTA_FLOAT;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+
+public class ProxyBuilderTest {
     private FakeInvocationHandler fakeHandler = new FakeInvocationHandler();
     private File versionedDxDir = new File(DexMakerTest.getDataDirectory(), "v1");
 
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        if (!versionedDxDir.exists() && !versionedDxDir.mkdirs()) {
-            throw new IOException("Could not create " + versionedDxDir);
-        }
+        versionedDxDir.mkdirs();
         clearVersionedDxDir();
         getGeneratedProxyClasses().clear();
     }
 
+    @After
     public void tearDown() throws Exception {
         getGeneratedProxyClasses().clear();
         clearVersionedDxDir();
-        super.tearDown();
     }
 
     private void clearVersionedDxDir() {
-        for (File f : versionedDxDir.listFiles()) {
-            f.delete();
+        for (File file : versionedDxDir.listFiles()) {
+            file.delete();
         }
     }
 
@@ -62,25 +72,39 @@
         }
     }
 
+    public static class ExampleClass {
+        public String exampleMethod() {
+            throw new AssertionFailedError();
+        }
+    }
+
+    public static class ExampleOperationClass {
+        public String exampleMethod() {
+            throw new AssertionFailedError();
+        }
+    }
+
+    @Test
     public void testExampleOperation() throws Throwable {
         fakeHandler.setFakeResult("expected");
-        SimpleClass proxy = proxyFor(SimpleClass.class).build();
-        assertEquals("expected", proxy.simpleMethod());
+        ExampleClass proxy = proxyFor(ExampleClass.class).build();
+        assertEquals("expected", proxy.exampleMethod());
         assertEquals(2, versionedDxDir.listFiles().length);
     }
 
+    @Test
     public void testExampleOperation_DexMakerCaching() throws Throwable {
         fakeHandler.setFakeResult("expected");
-        SimpleClass proxy = proxyFor(SimpleClass.class).build();
+        ExampleOperationClass proxy = proxyFor(ExampleOperationClass.class).build();
         assertEquals(2, versionedDxDir.listFiles().length);
-        assertEquals("expected", proxy.simpleMethod());
+        assertEquals("expected", proxy.exampleMethod());
 
         // Force ProxyBuilder to create a DexMaker generator and call DexMaker.generateAndLoad().
         getGeneratedProxyClasses().clear();
 
-        proxy = proxyFor(SimpleClass.class).build();
+        proxy = proxyFor(ExampleOperationClass.class).build();
         assertEquals(2, versionedDxDir.listFiles().length);
-        assertEquals("expected", proxy.simpleMethod());
+        assertEquals("expected", proxy.exampleMethod());
     }
 
     public static class ConstructorTakesArguments {
@@ -95,6 +119,7 @@
         }
     }
 
+    @Test
     public void testConstruction_SucceedsIfCorrectArgumentsProvided() throws Throwable {
         ConstructorTakesArguments proxy = proxyFor(ConstructorTakesArguments.class)
                 .constructorArgTypes(String.class)
@@ -104,30 +129,22 @@
         proxy.method();
     }
 
+    @Test(expected = IllegalArgumentException.class)
     public void testConstruction_FailsWithWrongNumberOfArguments() throws Throwable {
-        try {
-            proxyFor(ConstructorTakesArguments.class).build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
+        proxyFor(ConstructorTakesArguments.class).build();
     }
 
+    @Test(expected = UnsupportedOperationException.class)
     public void testClassIsNotAccessbile_FailsWithUnsupportedOperationException() throws Exception {
-        class MethodVisibilityClass {
-        }
-        try {
-            proxyFor(MethodVisibilityClass.class).build();
-            fail();
-        } catch (UnsupportedOperationException expected) {}
+        class MethodVisibilityClass {}
+        proxyFor(MethodVisibilityClass.class).build();
     }
 
-    private static class PrivateVisibilityClass {
-    }
+    private static class PrivateVisibilityClass {}
 
+    @Test(expected = UnsupportedOperationException.class)
     public void testPrivateClass_FailsWithUnsupportedOperationException() throws Exception {
-        try {
-            proxyFor(PrivateVisibilityClass.class).build();
-            fail();
-        } catch (UnsupportedOperationException expected) {}
+        proxyFor(PrivateVisibilityClass.class).build();
     }
 
     protected static class ProtectedVisibilityClass {
@@ -136,6 +153,7 @@
         }
     }
 
+    @Test
     public void testProtectedVisibility_WorksFine() throws Exception {
         assertEquals("fake result", proxyFor(ProtectedVisibilityClass.class).build().foo());
     }
@@ -150,6 +168,7 @@
         }
     }
 
+    @Test
     public void testCanProxyClassesWithFinalMethods_WillNotCallTheFinalMethod() throws Throwable {
         HasFinalMethod proxy = proxyFor(HasFinalMethod.class).build();
         assertEquals("final method", proxy.finalMethod());
@@ -162,6 +181,7 @@
         }
     }
 
+    @Test
     public void testProxyingPrivateMethods_NotIntercepted() throws Throwable {
         HasPrivateMethod proxy = proxyFor(HasPrivateMethod.class).build();
         try {
@@ -205,6 +225,7 @@
         }
     }
 
+    @Test
     public void testProxyingProtectedMethods_AreIntercepted() throws Throwable {
         assertEquals("fake result", proxyFor(HasProtectedMethod.class).build().result());
     }
@@ -229,6 +250,7 @@
         }
     }
 
+    @Test
     public void testProxying_ClassHierarchy() throws Throwable {
         assertEquals("package", proxyFor(MyParentClass.class).build().someMethod());
         assertEquals("fake result", proxyFor(MyChildClassWithProtectedMethod.class).build().someMethod());
@@ -241,10 +263,13 @@
         }
     }
 
+    @Test
     public void testVoidMethod_ShouldNotThrowRuntimeException() throws Throwable {
         proxyFor(HasVoidMethod.class).build().dangerousMethod();
     }
 
+    @Test
+    @SuppressWarnings("EqualsWithItself")
     public void testObjectMethodsAreAlsoProxied() throws Throwable {
         Object proxy = proxyFor(Object.class).build();
         fakeHandler.setFakeResult("mystring");
@@ -268,6 +293,7 @@
         public String[] getStringArray() { return new String[] { "d", "e" }; }
     }
 
+    @Test
     public void testAllReturnTypes() throws Throwable {
         AllReturnTypes proxy = proxyFor(AllReturnTypes.class).build();
         fakeHandler.setFakeResult(false);
@@ -281,9 +307,9 @@
         fakeHandler.setFakeResult((short) 11);
         assertEquals(11, proxy.getShort());
         fakeHandler.setFakeResult(12f);
-        assertEquals(12f, proxy.getFloat());
+        assertEquals(12f, proxy.getFloat(), DELTA_FLOAT);
         fakeHandler.setFakeResult(13.0);
-        assertEquals(13.0, proxy.getDouble());
+        assertEquals(13.0, proxy.getDouble(), DELTA_FLOAT);
         fakeHandler.setFakeResult('z');
         assertEquals('z', proxy.getChar());
         fakeHandler.setFakeResult(new int[] { -1, -2 });
@@ -312,6 +338,7 @@
         }
     }
 
+    @Test
     public void testPassThroughWorksForAllTypes() throws Exception {
         PassThroughAllTypes proxy = proxyFor(PassThroughAllTypes.class)
                 .handler(new InvokeSuperHandler())
@@ -326,10 +353,10 @@
         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(8f, proxy.getFloat(8f), DELTA_FLOAT);
+        assertEquals(9f, proxy.getFloat(9f), DELTA_FLOAT);
+        assertEquals(10.0, proxy.getDouble(10.0), DELTA_DOUBLE);
+        assertEquals(11.0, proxy.getDouble(11.0), DELTA_DOUBLE);
         assertEquals('a', proxy.getChar('a'));
         assertEquals('b', proxy.getChar('b'));
         assertEquals("asdf", proxy.getString("asdf"));
@@ -345,6 +372,7 @@
         public int example() { return 0; }
     }
 
+    @Test
     public void testProxyWorksForSuperclassMethodsAlso() throws Throwable {
         ExtendsAllReturnTypes proxy = proxyFor(ExtendsAllReturnTypes.class).build();
         fakeHandler.setFakeResult(99);
@@ -359,6 +387,7 @@
         }
     }
 
+    @Test
     public void testMixingBoxedAndUnboxedParams() throws Throwable {
         HasOddParams proxy = proxyFor(HasOddParams.class).build();
         fakeHandler.setFakeResult(99L);
@@ -371,6 +400,7 @@
         }
     }
 
+    @Test
     public void testSinglePrimitiveParameter() throws Throwable {
         InvocationHandler handler = new InvocationHandler() {
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -392,11 +422,13 @@
         }
     }
 
+    @Test
     public void testNoConstructorArguments_CallsNoArgConstructor() throws Throwable {
         TwoConstructors twoConstructors = proxyFor(TwoConstructors.class).build();
         assertEquals("no-arg", twoConstructors.string);
     }
 
+    @Test
     public void testWithoutInvocationHandler_ThrowsIllegalArgumentException() throws Throwable {
         try {
             ProxyBuilder.forClass(TwoConstructors.class)
@@ -414,6 +446,7 @@
         public HardToConstructCorrectly(Integer ignored) { fail(); }
     }
 
+    @Test
     public void testHardToConstruct_WorksIfYouSpecifyTheConstructorCorrectly() throws Throwable {
         proxyFor(HardToConstructCorrectly.class)
                 .constructorArgTypes(Boolean.class)
@@ -421,6 +454,7 @@
                 .build();
     }
 
+    @Test
     public void testHardToConstruct_EvenWorksWhenArgsAreAmbiguous() throws Throwable {
         proxyFor(HardToConstructCorrectly.class)
                 .constructorArgTypes(Boolean.class)
@@ -428,15 +462,14 @@
                 .build();
     }
 
+    @Test(expected = IllegalArgumentException.class)
     public void testHardToConstruct_DoesNotInferTypesFromValues() throws Throwable {
-        try {
-            proxyFor(HardToConstructCorrectly.class)
-                    .constructorArgValues(true)
-                    .build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
+        proxyFor(HardToConstructCorrectly.class)
+                .constructorArgValues(true)
+                .build();
     }
 
+    @Test
     public void testDefaultProxyHasSuperMethodToAccessOriginal() throws Exception {
         Object objectProxy = proxyFor(Object.class).build();
         assertNotNull(objectProxy.getClass().getMethod("super$hashCode$int"));
@@ -448,6 +481,7 @@
         }
     }
 
+    @Test
     public void testSometimesDelegateToSuper() throws Exception {
         InvocationHandler delegatesOddValues = new InvocationHandler() {
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -468,7 +502,8 @@
         assertEquals("even 2", proxy.method(2));
         assertEquals("odd 3", proxy.method(3));
     }
-    
+
+    @Test
     public void testCallSuperThrows() throws Exception {
         InvocationHandler handler = new InvocationHandler() {
             public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
@@ -487,7 +522,7 @@
             assertEquals("boom!", expected.getMessage());
         }
     }
-    
+
     public static class FooThrows {
         public void foo() {
             throw new IllegalStateException("boom!");
@@ -500,14 +535,15 @@
         }
     }
 
+    @Test
     public void testUnboxedResult() throws Exception {
         fakeHandler.fakeResult = 2.0;
-        assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue());
+        assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue(), DELTA_DOUBLE);
     }
 
-    public static void staticMethod() {
-    }
+    public static void staticMethod() {}
 
+    @Test
     public void testDoesNotOverrideStaticMethods() throws Exception {
         // Method should exist on this test class itself.
         ProxyBuilderTest.class.getDeclaredMethod("staticMethod");
@@ -518,33 +554,28 @@
         } catch (NoSuchMethodException expected) {}
     }
 
+    @Test(expected = IOException.class)
     public void testIllegalCacheDirectory() throws Exception {
-        try {
-          proxyFor(ProxyForIllegalCacheDirectory.class)
-                  .dexCache(new File("/poop/"))
-                  .build();
-          fail();
-        } catch (IOException expected) {
-        }
+        proxyFor(ProxyForIllegalCacheDirectory.class)
+                .dexCache(new File("/poop/"))
+                .build();
     }
 
-    public static class ProxyForIllegalCacheDirectory {
-    }
+    public static class ProxyForIllegalCacheDirectory {}
 
+    @Test(expected = IllegalArgumentException.class)
     public void testInvalidConstructorSpecification() throws Exception {
-        try {
-            proxyFor(Object.class)
-                    .constructorArgTypes(String.class, Boolean.class)
-                    .constructorArgValues("asdf", true)
-                    .build();
-            fail();
-        } catch (IllegalArgumentException expected) {}
+        proxyFor(Object.class)
+                .constructorArgTypes(String.class, Boolean.class)
+                .constructorArgValues("asdf", true)
+                .build();
     }
 
     public static abstract class AbstractClass {
         public abstract Object getValue();
     }
 
+    @Test
     public void testAbstractClassBehaviour() throws Exception {
         assertEquals("fake result", proxyFor(AbstractClass.class).build().getValue());
     }
@@ -567,6 +598,7 @@
         }
     }
 
+    @Test
     public void testParentConstructorThrowsDeclaredException() throws Exception {
         try {
             proxyFor(CtorHasDeclaredException.class).build();
@@ -588,16 +620,15 @@
         }
     }
 
+    @Test
     public void testGetInvocationHandler_NormalOperation() throws Exception {
         Object proxy = proxyFor(Object.class).build();
         assertSame(fakeHandler, ProxyBuilder.getInvocationHandler(proxy));
     }
 
+    @Test(expected = IllegalArgumentException.class)
     public void testGetInvocationHandler_NotAProxy() {
-        try {
-            ProxyBuilder.getInvocationHandler(new Object());
-            fail();
-        } catch (IllegalArgumentException expected) {}
+        ProxyBuilder.getInvocationHandler(new Object());
     }
 
     public static class ReturnsObject {
@@ -613,6 +644,7 @@
         }
     }
 
+    @Test
     public void testCovariantReturnTypes_NormalBehaviour() throws Exception {
         String expected = "some string";
         fakeHandler.setFakeResult(expected);
@@ -620,6 +652,7 @@
         assertSame(expected, proxyFor(ReturnsString.class).build().getValue());
     }
 
+    @Test
     public void testCovariantReturnTypes_WrongReturnType() throws Exception {
         try {
             fakeHandler.setFakeResult(new Object());
@@ -628,12 +661,14 @@
         } catch (ClassCastException expected) {}
     }
 
+    @Test
     public void testCaching() throws Exception {
         SimpleClass a = proxyFor(SimpleClass.class).build();
         SimpleClass b = proxyFor(SimpleClass.class).build();
         assertSame(a.getClass(), b.getClass());
     }
 
+    @Test
     public void testCachingWithMultipleConstructors() throws Exception {
         HasMultipleConstructors a = ProxyBuilder.forClass(HasMultipleConstructors.class)
                 .constructorArgTypes()
@@ -671,6 +706,7 @@
         }
     }
 
+    @Test
     public void testClassNotCachedWithDifferentParentClassLoaders() throws Exception {
         ClassLoader classLoaderA = newPathClassLoader();
         SimpleClass a = proxyFor(SimpleClass.class)
@@ -686,7 +722,8 @@
 
         assertTrue(a.getClass() != b.getClass());
     }
-    
+
+    @Test
     public void testAbstractClassWithUndeclaredInterfaceMethod() throws Throwable {
         DeclaresInterface declaresInterface = proxyFor(DeclaresInterface.class)
                 .build();
@@ -694,13 +731,13 @@
         try {
             ProxyBuilder.callSuper(declaresInterface, Callable.class.getMethod("call"));
             fail();
-        } catch (AbstractMethodError expected) {
+        } catch (IncompatibleClassChangeError expected) {
         }
     }
-    
-    public static abstract class DeclaresInterface implements Callable<String> {
-    }
 
+    public static abstract class DeclaresInterface implements Callable<String> {}
+
+    @Test
     public void testImplementingInterfaces() throws Throwable {
         SimpleClass simpleClass = proxyFor(SimpleClass.class)
                 .implementing(Callable.class)
@@ -716,6 +753,7 @@
         assertEquals(3, asComparable.compareTo(null));
     }
 
+    @Test
     public void testCallSuperWithInterfaceMethod() throws Throwable {
         SimpleClass simpleClass = proxyFor(SimpleClass.class)
                 .implementing(Callable.class)
@@ -728,6 +766,7 @@
         }
     }
 
+    @Test
     public void testImplementInterfaceCallingThroughConcreteClass() throws Throwable {
         InvocationHandler invocationHandler = new InvocationHandler() {
             public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
@@ -743,13 +782,14 @@
         assertEquals("a", ProxyBuilder.callSuper(
                 proxy, ImplementsCallable.class.getMethod("call")));
     }
-    
+
     /**
      * This test is a bit unintuitive because it exercises the synthetic methods
      * that support covariant return types. Calling 'Object call()' on the
      * interface bridges to 'String call()', and so the super method appears to
      * also be proxied.
      */
+    @Test
     public void testImplementInterfaceCallingThroughInterface() throws Throwable {
         final AtomicInteger count = new AtomicInteger();
 
@@ -773,7 +813,7 @@
         assertEquals("a", ProxyBuilder.callSuper(proxy, Callable.class.getMethod("call")));
         assertEquals(3, count.get());
     }
-    
+
     public static class ImplementsCallable implements Callable<String> {
         public String call() throws Exception {
             return "a";
@@ -786,6 +826,7 @@
      * different from javac's convention where return types must be assignable
      * in one direction or the other.
      */
+    @Test
     public void testInterfacesSameNamesDifferentReturnTypes() throws Throwable {
         InvocationHandler handler = new InvocationHandler() {
             public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
@@ -800,27 +841,28 @@
                 }
             }
         };
-        
+
         Object o = proxyFor(Object.class)
                 .implementing(FooReturnsVoid.class, FooReturnsString.class, FooReturnsInt.class)
                 .handler(handler)
                 .build();
-        
+
         FooReturnsVoid a = (FooReturnsVoid) o;
         a.foo();
-        
+
         FooReturnsString b = (FooReturnsString) o;
         assertEquals("X", b.foo());
-        
+
         FooReturnsInt c = (FooReturnsInt) o;
         assertEquals(3, c.foo());
     }
-    
+
+    @Test
     public void testInterfacesSameNamesSameReturnType() throws Throwable {
         Object o = proxyFor(Object.class)
                 .implementing(FooReturnsInt.class, FooReturnsInt2.class)
                 .build();
-        
+
         fakeHandler.setFakeResult(3);
 
         FooReturnsInt a = (FooReturnsInt) o;
@@ -829,7 +871,7 @@
         FooReturnsInt2 b = (FooReturnsInt2) o;
         assertEquals(3, b.foo());
     }
-    
+
     public interface FooReturnsVoid {
         void foo();
     }
@@ -841,11 +883,11 @@
     public interface FooReturnsInt {
         int foo();
     }
-    
+
     public interface FooReturnsInt2 {
         int foo();
     }
-    
+
     private ClassLoader newPathClassLoader() throws Exception {
         return (ClassLoader) Class.forName("dalvik.system.PathClassLoader")
                 .getConstructor(String.class, ClassLoader.class)
@@ -853,6 +895,7 @@
 
     }
 
+    @Test
     public void testSubclassOfRandom() throws Exception {
         proxyFor(Random.class)
                 .handler(new InvokeSuperHandler())
@@ -860,18 +903,21 @@
     }
 
     public static class FinalToString {
-        @Override public final String toString() {
+        @Override
+        public final String toString() {
             return "no proxy";
         }
     }
 
     // https://code.google.com/p/dexmaker/issues/detail?id=12
+    @Test
     public void testFinalToString() throws Throwable {
         assertEquals("no proxy", proxyFor(FinalToString.class).build().toString());
     }
 
     public static class FinalInterfaceImpl implements FooReturnsString {
-        @Override public final String foo() {
+        @Override
+        public final String foo() {
           return "no proxy";
         }
     }
@@ -880,6 +926,7 @@
             implements FooReturnsString {
     }
 
+    @Test
     public void testFinalInterfaceImpl() throws Throwable {
         assertEquals("no proxy", proxyFor(ExtenstionOfFinalInterfaceImpl.class).build().foo());
     }
@@ -896,23 +943,11 @@
     public static class YouDoNotChooseYourFamily
             extends MakesMethodFinalEarly implements DeclaresMethodLate {}
 
+    @Test
     public void testInterfaceMethodMadeFinalBeforeActualInheritance() throws Exception {
         proxyFor(YouDoNotChooseYourFamily.class).build();
     }
 
-    public interface ExtendsAnotherInterface extends FooReturnsString {
-
-    }
-
-    public void testExtraInterfaceExtendsInterface() throws Exception {
-        ExtendsAnotherInterface proxy = (ExtendsAnotherInterface)
-                proxyFor(SimpleClass.class)
-                        .implementing(ExtendsAnotherInterface.class)
-                        .build();
-        fakeHandler.setFakeResult(ExtendsAnotherInterface.class.getName());
-        assertEquals(ExtendsAnotherInterface.class.getName(), proxy.foo());
-    }
-
     /** 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)
@@ -958,6 +993,7 @@
         }
     }
 
+    @Test
     @SuppressWarnings("unchecked")
     public void testMethodsGeneratedInDeterministicOrder() throws Exception {
         // Grab the static methods array from the original class.
@@ -978,6 +1014,7 @@
         assertTrue(Arrays.equals(methods1, methods2));
     }
 
+    @Test
     public void testOrderingClassWithDexMakerCaching() throws Exception {
         doTestOrderClassWithDexMakerCaching();
 
@@ -996,9 +1033,9 @@
         assertEquals(1, proxy.returnsInt(1, 1));
         assertEquals("string", proxy.returnsString());
         assertFalse(proxy.returnsBoolean());
-        assertEquals(1.0, proxy.returnsDouble());
+        assertEquals(1.0, proxy.returnsDouble(), DELTA_DOUBLE);
         assertNotNull(proxy.returnsObject());
-        assertEquals(2, versionedDxDir.listFiles().length);
+        assertTrue(versionedDxDir.listFiles().length != 0);
     }
 
     // Returns static methods array from a proxy class.
@@ -1047,6 +1084,7 @@
         }
     }
 
+    @Test
     public void testTwoClassesWithIdenticalMethodSignatures_DexMakerCaching() throws Exception {
         ConcreteClassA proxyA = ProxyBuilder.forClass(ConcreteClassA.class)
                 .handler(new InvokeSuperHandler())
diff --git a/dexmaker-tests/src/androidTest/java/com/android/dx/util/TestUtil.java b/dexmaker-tests/src/androidTest/java/com/android/dx/util/TestUtil.java
new file mode 100644
index 0000000..5f89ead
--- /dev/null
+++ b/dexmaker-tests/src/androidTest/java/com/android/dx/util/TestUtil.java
@@ -0,0 +1,6 @@
+package com.android.dx.util;
+
+public class TestUtil {
+    public static final float DELTA_FLOAT = 0.0001f;
+    public static final double DELTA_DOUBLE = 0.0001;
+}
diff --git a/dexmaker/build.gradle b/dexmaker/build.gradle
new file mode 100644
index 0000000..eb337ec
--- /dev/null
+++ b/dexmaker/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'java'
+apply from: "$rootDir/gradle/publishing.gradle"
+
+version = VERSION_NAME
+description = "A utility for doing compile or runtime code generation targeting Android's Dalvik VM"
+
+targetCompatibility = '1.7'
+sourceCompatibility = '1.7'
+
+repositories {
+    jcenter()
+}
+
+dependencies {
+    compile 'com.jakewharton.android.repackaged:dalvik-dx:7.1.0_r7'
+
+    testCompile 'junit:junit:4.12'
+}
diff --git a/dexmaker/pom.xml b/dexmaker/pom.xml
deleted file mode 100644
index 9e6b526..0000000
--- a/dexmaker/pom.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Copyright (C) 2012 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>com.crittercism.dexmaker</groupId>
-        <artifactId>dexmaker-parent</artifactId>
-        <version>1.3</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>dexmaker</artifactId>
-    <name>dexmaker</name>
-
-    <dependencies>
-        <dependency>
-            <groupId>com.crittercism.dexmaker</groupId>
-            <artifactId>dexmaker-dx</artifactId>
-            <version>${project.version}</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.sonatype.plugins</groupId>
-                <artifactId>jarjar-maven-plugin</artifactId>
-                <version>1.8</version>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>jarjar</goal>
-                        </goals>
-                        <configuration>
-                            <includes>
-                                <include>com.google.dexmaker:dexmaker-dx</include>
-                            </includes>
-                            <rules>
-                                <rule>
-                                    <pattern>com.android.dx.**</pattern>
-                                    <result>com.google.dexmaker.dx.@1</result>
-                                </rule>
-                            </rules>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/dexmaker/src/main/java/com/google/dexmaker/AppDataDirGuesser.java b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java
similarity index 97%
rename from dexmaker/src/main/java/com/google/dexmaker/AppDataDirGuesser.java
rename to dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java
index 4479887..fa0ef69 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/AppDataDirGuesser.java
+++ b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import java.io.File;
 import java.lang.reflect.Field;
@@ -47,8 +47,7 @@
         return AppDataDirGuesser.class.getClassLoader();
     }
 
-    private String getPathFromThisClassLoader(ClassLoader classLoader,
-            Class<?> pathClassLoaderClass) {
+    private String getPathFromThisClassLoader(ClassLoader classLoader, Class<?> pathClassLoaderClass) {
         // Prior to ICS, we can simply read the "path" field of the
         // PathClassLoader.
         try {
@@ -132,7 +131,7 @@
     }
 
     File[] guessPath(String input) {
-        List<File> results = new ArrayList<File>();
+        List<File> results = new ArrayList<>();
         for (String potential : splitPathList(input)) {
             if (!potential.startsWith("/data/app/")) {
                 continue;
diff --git a/dexmaker/src/main/java/com/google/dexmaker/BinaryOp.java b/dexmaker/src/main/java/com/android/dx/BinaryOp.java
similarity index 80%
rename from dexmaker/src/main/java/com/google/dexmaker/BinaryOp.java
rename to dexmaker/src/main/java/com/android/dx/BinaryOp.java
index 04734cf..95eef6a 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/BinaryOp.java
+++ b/dexmaker/src/main/java/com/android/dx/BinaryOp.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.Rop;
 import com.android.dx.rop.code.Rops;
@@ -39,77 +39,88 @@
 public enum BinaryOp {
     /** {@code a + b} */
     ADD() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opAdd(types);
         }
     },
 
     /** {@code a - b} */
     SUBTRACT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opSub(types);
         }
     },
 
     /** {@code a * b} */
     MULTIPLY() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opMul(types);
         }
     },
 
     /** {@code a / b} */
     DIVIDE() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opDiv(types);
         }
     },
 
     /** {@code a % b} */
     REMAINDER() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opRem(types);
         }
     },
 
     /** {@code a & b} */
     AND() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opAnd(types);
         }
     },
 
     /** {@code a | b} */
     OR() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opOr(types);
         }
     },
 
     /** {@code a ^ b} */
     XOR() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opXor(types);
         }
     },
 
     /** {@code a << b} */
     SHIFT_LEFT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opShl(types);
         }
     },
 
     /** {@code a >> b} */
     SHIFT_RIGHT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opShr(types);
         }
     },
 
     /** {@code a >>> b} */
     UNSIGNED_SHIFT_RIGHT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opUshr(types);
         }
     };
diff --git a/dexmaker/src/main/java/com/google/dexmaker/Code.java b/dexmaker/src/main/java/com/android/dx/Code.java
similarity index 99%
rename from dexmaker/src/main/java/com/google/dexmaker/Code.java
rename to dexmaker/src/main/java/com/android/dx/Code.java
index d85dece..721d659 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/Code.java
+++ b/dexmaker/src/main/java/com/android/dx/Code.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.BasicBlockList;
 import com.android.dx.rop.code.Insn;
@@ -22,24 +22,26 @@
 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;
 
+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 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;
+
 /**
  * Builds a sequence of instructions.
  *
@@ -718,7 +720,7 @@
      * {@code 0x12345678} to a short yields {@code 0x5678}, losing the high
      * bytes. The following numeric casts are supported:
      *
-     * <p><table border="1">
+     * <p><table border="1" summary="Supported Numeric Casts">
      * <tr><th>From</th><th>To</th></tr>
      * <tr><td>int</td><td>byte, char, short, long, float, double</td></tr>
      * <tr><td>long</td><td>int, float, double</td></tr>
diff --git a/dexmaker/src/main/java/com/google/dexmaker/Comparison.java b/dexmaker/src/main/java/com/android/dx/Comparison.java
similarity index 82%
rename from dexmaker/src/main/java/com/google/dexmaker/Comparison.java
rename to dexmaker/src/main/java/com/android/dx/Comparison.java
index 06e3ca3..8c2fd7a 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/Comparison.java
+++ b/dexmaker/src/main/java/com/android/dx/Comparison.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.Rop;
 import com.android.dx.rop.code.Rops;
@@ -27,42 +27,48 @@
 
     /** {@code a < b}. Supports int only. */
     LT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfLt(types);
         }
     },
 
     /** {@code a <= b}. Supports int only. */
     LE() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfLe(types);
         }
     },
 
     /** {@code a == b}. Supports int and reference types. */
     EQ() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfEq(types);
         }
     },
 
     /** {@code a >= b}. Supports int only. */
     GE() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfGe(types);
         }
     },
 
     /** {@code a > b}. Supports int only. */
     GT() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfGt(types);
         }
     },
 
     /** {@code a != b}. Supports int and reference types. */
     NE() {
-        @Override Rop rop(TypeList types) {
+        @Override
+        Rop rop(TypeList types) {
             return Rops.opIfNe(types);
         }
     };
diff --git a/dexmaker/src/main/java/com/google/dexmaker/Constants.java b/dexmaker/src/main/java/com/android/dx/Constants.java
similarity index 98%
rename from dexmaker/src/main/java/com/google/dexmaker/Constants.java
rename to dexmaker/src/main/java/com/android/dx/Constants.java
index ec21cb8..68e5024 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/Constants.java
+++ b/dexmaker/src/main/java/com/android/dx/Constants.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.cst.CstBoolean;
 import com.android.dx.rop.cst.CstByte;
diff --git a/dexmaker/src/main/java/com/google/dexmaker/DexMaker.java b/dexmaker/src/main/java/com/android/dx/DexMaker.java
similarity index 96%
rename from dexmaker/src/main/java/com/google/dexmaker/DexMaker.java
rename to dexmaker/src/main/java/com/android/dx/DexMaker.java
index a6a0999..ee8d722 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/DexMaker.java
+++ b/dexmaker/src/main/java/com/android/dx/DexMaker.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
-import com.android.dx.dex.DexFormat;
+import com.android.dex.DexFormat;
 import com.android.dx.dex.DexOptions;
 import com.android.dx.dex.code.DalvCode;
 import com.android.dx.dex.code.PositionList;
@@ -26,21 +26,17 @@
 import com.android.dx.dex.file.EncodedField;
 import com.android.dx.dex.file.EncodedMethod;
 import com.android.dx.rop.code.AccessFlags;
-import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
 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 com.google.dexmaker.stock.ProxyBuilder;
+import com.android.dx.stock.ProxyBuilder;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Modifier;
-import static java.lang.reflect.Modifier.PRIVATE;
-import static java.lang.reflect.Modifier.STATIC;
-
 import dalvik.system.DexClassLoader;
 
 import java.util.Arrays;
@@ -51,8 +47,12 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 
+import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
+import static java.lang.reflect.Modifier.PRIVATE;
+import static java.lang.reflect.Modifier.STATIC;
+
 /**
- * Generates a </i><strong>D</strong>alvik <strong>EX</strong>ecutable (dex)
+ * Generates a <strong>D</strong>alvik <strong>EX</strong>ecutable (dex)
  * file for execution on Android. Dex files define classes and interfaces,
  * including their member methods and fields, executable code, and debugging
  * information. They also define annotations, though this API currently has no
@@ -198,8 +198,7 @@
  * }</pre>
  */
 public final class DexMaker {
-    private final Map<TypeId<?>, TypeDeclaration> types
-            = new LinkedHashMap<TypeId<?>, TypeDeclaration>();
+    private final Map<TypeId<?>, TypeDeclaration> types = new LinkedHashMap<>();
 
     /**
      * Creates a new {@code DexMaker} instance, which can be used to create a
@@ -415,7 +414,8 @@
         return generateAndLoad(parent, parent, dexCache);
     }
 
-    public ClassLoader generateAndLoad(ClassLoader classLoader, ClassLoader parent, File dexCache) throws IOException {
+    public ClassLoader generateAndLoad(ClassLoader classLoader, ClassLoader parent, File dexCache)
+            throws IOException {
         if (dexCache == null) {
             String property = System.getProperty("dexmaker.dexcache");
             if (property != null) {
@@ -466,10 +466,8 @@
         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>();
+        private final Map<FieldId, FieldDeclaration> fields = new LinkedHashMap<>();
+        private final Map<MethodId, MethodDeclaration> methods = new LinkedHashMap<>();
 
         TypeDeclaration(TypeId<?> type) {
             this.type = type;
diff --git a/dexmaker/src/main/java/com/google/dexmaker/FieldId.java b/dexmaker/src/main/java/com/android/dx/FieldId.java
similarity index 92%
rename from dexmaker/src/main/java/com/google/dexmaker/FieldId.java
rename to dexmaker/src/main/java/com/android/dx/FieldId.java
index c03e1d1..1acc958 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/FieldId.java
+++ b/dexmaker/src/main/java/com/android/dx/FieldId.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.cst.CstFieldRef;
 import com.android.dx.rop.cst.CstNat;
@@ -58,17 +58,20 @@
         return name;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
         return o instanceof FieldId
                 && ((FieldId<?, ?>) o).declaringType.equals(declaringType)
                 && ((FieldId<?, ?>) o).name.equals(name);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
         return declaringType.hashCode() + 37 * name.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return declaringType + "." + name;
     }
 }
diff --git a/dexmaker/src/main/java/com/google/dexmaker/Label.java b/dexmaker/src/main/java/com/android/dx/Label.java
similarity index 96%
rename from dexmaker/src/main/java/com/google/dexmaker/Label.java
rename to dexmaker/src/main/java/com/android/dx/Label.java
index b37b18c..21f855d 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/Label.java
+++ b/dexmaker/src/main/java/com/android/dx/Label.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.BasicBlock;
 import com.android.dx.rop.code.Insn;
@@ -29,7 +29,7 @@
  */
 public final class Label {
 
-    final List<Insn> instructions = new ArrayList<Insn>();
+    final List<Insn> instructions = new ArrayList<>();
 
     Code code;
 
diff --git a/dexmaker/src/main/java/com/google/dexmaker/Local.java b/dexmaker/src/main/java/com/android/dx/Local.java
similarity index 96%
rename from dexmaker/src/main/java/com/google/dexmaker/Local.java
rename to dexmaker/src/main/java/com/android/dx/Local.java
index c89436d..914f115 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/Local.java
+++ b/dexmaker/src/main/java/com/android/dx/Local.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.RegisterSpec;
 
@@ -68,7 +68,8 @@
         return type;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return "v" + reg + "(" + type + ")";
     }
 }
diff --git a/dexmaker/src/main/java/com/google/dexmaker/MethodId.java b/dexmaker/src/main/java/com/android/dx/MethodId.java
similarity index 93%
rename from dexmaker/src/main/java/com/google/dexmaker/MethodId.java
rename to dexmaker/src/main/java/com/android/dx/MethodId.java
index a43060c..746d73e 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/MethodId.java
+++ b/dexmaker/src/main/java/com/android/dx/MethodId.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.cst.CstMethodRef;
 import com.android.dx.rop.cst.CstNat;
@@ -66,7 +66,7 @@
     }
 
     /**
-     * Returns the method's name. This is "<init>" if this is a constructor.
+     * Returns the method's name. This is "&lt;init&gt;" if this is a constructor.
      */
     public String getName() {
         return name;
@@ -97,7 +97,8 @@
         return Prototype.intern(descriptor(includeThis));
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
         return o instanceof MethodId
                 && ((MethodId<?, ?>) o).declaringType.equals(declaringType)
                 && ((MethodId<?, ?>) o).name.equals(name)
@@ -105,7 +106,8 @@
                 && ((MethodId<?, ?>) o).returnType.equals(returnType);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
         int result = 17;
         result = 31 * result + declaringType.hashCode();
         result = 31 * result + name.hashCode();
@@ -114,7 +116,8 @@
         return result;
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return declaringType + "." + name + "(" + parameters + ")";
     }
 }
diff --git a/dexmaker/src/main/java/com/google/dexmaker/TypeId.java b/dexmaker/src/main/java/com/android/dx/TypeId.java
similarity index 67%
rename from dexmaker/src/main/java/com/google/dexmaker/TypeId.java
rename to dexmaker/src/main/java/com/android/dx/TypeId.java
index 36e0b5a..de96028 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/TypeId.java
+++ b/dexmaker/src/main/java/com/android/dx/TypeId.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.cst.CstType;
 import java.util.HashMap;
@@ -33,42 +33,39 @@
  */
 public final class TypeId<T> {
     /** The {@code boolean} primitive type. */
-    public static final TypeId<Boolean> BOOLEAN
-            = new TypeId<Boolean>(com.android.dx.rop.type.Type.BOOLEAN);
+    public static final TypeId<Boolean> BOOLEAN = new TypeId<>(com.android.dx.rop.type.Type.BOOLEAN);
 
     /** The {@code byte} primitive type. */
-    public static final TypeId<Byte> BYTE = new TypeId<Byte>(com.android.dx.rop.type.Type.BYTE);
+    public static final TypeId<Byte> BYTE = new TypeId<>(com.android.dx.rop.type.Type.BYTE);
 
     /** The {@code char} primitive type. */
-    public static final TypeId<Character> CHAR
-            = new TypeId<Character>(com.android.dx.rop.type.Type.CHAR);
+    public static final TypeId<Character> CHAR = new TypeId<>(com.android.dx.rop.type.Type.CHAR);
 
     /** The {@code double} primitive type. */
-    public static final TypeId<Double> DOUBLE = new TypeId<Double>(com.android.dx.rop.type.Type.DOUBLE);
+    public static final TypeId<Double> DOUBLE = new TypeId<>(com.android.dx.rop.type.Type.DOUBLE);
 
     /** The {@code float} primitive type. */
-    public static final TypeId<Float> FLOAT = new TypeId<Float>(com.android.dx.rop.type.Type.FLOAT);
+    public static final TypeId<Float> FLOAT = new TypeId<>(com.android.dx.rop.type.Type.FLOAT);
 
     /** The {@code int} primitive type. */
-    public static final TypeId<Integer> INT = new TypeId<Integer>(com.android.dx.rop.type.Type.INT);
+    public static final TypeId<Integer> INT = new TypeId<>(com.android.dx.rop.type.Type.INT);
 
     /** The {@code long} primitive type. */
-    public static final TypeId<Long> LONG = new TypeId<Long>(com.android.dx.rop.type.Type.LONG);
+    public static final TypeId<Long> LONG = new TypeId<>(com.android.dx.rop.type.Type.LONG);
 
     /** The {@code short} primitive type. */
-    public static final TypeId<Short> SHORT = new TypeId<Short>(com.android.dx.rop.type.Type.SHORT);
+    public static final TypeId<Short> SHORT = new TypeId<>(com.android.dx.rop.type.Type.SHORT);
 
     /** The {@code void} primitive type. Only used as a return type. */
-    public static final TypeId<Void> VOID = new TypeId<Void>(com.android.dx.rop.type.Type.VOID);
+    public static final TypeId<Void> VOID = new TypeId<>(com.android.dx.rop.type.Type.VOID);
 
     /** The {@code Object} type. */
-    public static final TypeId<Object> OBJECT = new TypeId<Object>(com.android.dx.rop.type.Type.OBJECT);
+    public static final TypeId<Object> OBJECT = new TypeId<>(com.android.dx.rop.type.Type.OBJECT);
 
     /** The {@code String} type. */
-    public static final TypeId<String> STRING = new TypeId<String>(com.android.dx.rop.type.Type.STRING);
+    public static final TypeId<String> STRING = new TypeId<>(com.android.dx.rop.type.Type.STRING);
 
-    private static final Map<Class<?>, TypeId<?>> PRIMITIVE_TO_TYPE
-            = new HashMap<Class<?>, TypeId<?>>();
+    private static final Map<Class<?>, TypeId<?>> PRIMITIVE_TO_TYPE = new HashMap<>();
     static {
         PRIMITIVE_TO_TYPE.put(boolean.class, BOOLEAN);
         PRIMITIVE_TO_TYPE.put(byte.class, BYTE);
@@ -104,13 +101,14 @@
      * @param name a descriptor like "Ljava/lang/Class;".
      */
     public static <T> TypeId<T> get(String name) {
-        return new TypeId<T>(name, com.android.dx.rop.type.Type.internReturnType(name));
+        return new TypeId<>(name, com.android.dx.rop.type.Type.internReturnType(name));
     }
 
     public static <T> TypeId<T> get(Class<T> type) {
         if (type.isPrimitive()) {
-            @SuppressWarnings("unchecked") // guarded by equals
-                    TypeId<T> result = (TypeId<T>) PRIMITIVE_TO_TYPE.get(type);
+            // guarded by equals
+            @SuppressWarnings("unchecked")
+            TypeId<T> result = (TypeId<T>) PRIMITIVE_TO_TYPE.get(type);
             return result;
         }
         String name = type.getName().replace('.', '/');
@@ -118,31 +116,34 @@
     }
 
     public <V> FieldId<T, V> getField(TypeId<V> type, String name) {
-        return new FieldId<T, V>(this, type, name);
+        return new FieldId<>(this, type, name);
     }
 
     public MethodId<T, Void> getConstructor(TypeId<?>... parameters) {
-        return new MethodId<T, Void>(this, VOID, "<init>", new TypeList(parameters));
+        return new MethodId<>(this, VOID, "<init>", new TypeList(parameters));
     }
 
     public <R> MethodId<T, R> getMethod(TypeId<R> returnType, String name, TypeId<?>... parameters) {
-        return new MethodId<T, R>(this, returnType, name, new TypeList(parameters));
+        return new MethodId<>(this, returnType, name, new TypeList(parameters));
     }
 
     public String getName() {
         return name;
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
         return o instanceof TypeId
                 && ((TypeId) o).name.equals(name);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
         return name.hashCode();
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return name;
     }
 }
diff --git a/dexmaker/src/main/java/com/google/dexmaker/TypeList.java b/dexmaker/src/main/java/com/android/dx/TypeList.java
similarity index 90%
rename from dexmaker/src/main/java/com/google/dexmaker/TypeList.java
rename to dexmaker/src/main/java/com/android/dx/TypeList.java
index 688157f..03f77ab 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/TypeList.java
+++ b/dexmaker/src/main/java/com/android/dx/TypeList.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.type.StdTypeList;
 import java.util.Arrays;
@@ -43,15 +43,18 @@
         return Collections.unmodifiableList(Arrays.asList(types));
     }
 
-    @Override public boolean equals(Object o) {
+    @Override
+    public boolean equals(Object o) {
         return o instanceof TypeList && Arrays.equals(((TypeList) o).types, types);
     }
 
-    @Override public int hashCode() {
+    @Override
+    public int hashCode() {
         return Arrays.hashCode(types);
     }
 
-    @Override public String toString() {
+    @Override
+    public String toString() {
         StringBuilder result = new StringBuilder();
         for (int i = 0; i < types.length; i++) {
             if (i > 0) {
diff --git a/dexmaker/src/main/java/com/google/dexmaker/UnaryOp.java b/dexmaker/src/main/java/com/android/dx/UnaryOp.java
similarity index 88%
rename from dexmaker/src/main/java/com/google/dexmaker/UnaryOp.java
rename to dexmaker/src/main/java/com/android/dx/UnaryOp.java
index cf565bb..fb21c0f 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/UnaryOp.java
+++ b/dexmaker/src/main/java/com/android/dx/UnaryOp.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker;
+package com.android.dx;
 
 import com.android.dx.rop.code.Rop;
 import com.android.dx.rop.code.Rops;
@@ -26,14 +26,16 @@
 
     /** {@code ~a}. Supports int and long. */
     NOT() {
-        @Override Rop rop(TypeId<?> type) {
+        @Override
+        Rop rop(TypeId<?> type) {
             return Rops.opNot(type.ropType);
         }
     },
 
     /** {@code -a}. Supports int, long, float and double. */
     NEGATE() {
-        @Override Rop rop(TypeId<?> type) {
+        @Override
+        Rop rop(TypeId<?> type) {
             return Rops.opNeg(type.ropType);
         }
     };
diff --git a/dexmaker/src/main/java/com/google/dexmaker/stock/ProxyBuilder.java b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
similarity index 95%
rename from dexmaker/src/main/java/com/google/dexmaker/stock/ProxyBuilder.java
rename to dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
index 8ab06c1..1daf8e3 100644
--- a/dexmaker/src/main/java/com/google/dexmaker/stock/ProxyBuilder.java
+++ b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package com.google.dexmaker.stock;
+package com.android.dx.stock;
 
-import com.google.dexmaker.Code;
-import com.google.dexmaker.Comparison;
-import com.google.dexmaker.DexMaker;
-import com.google.dexmaker.FieldId;
-import com.google.dexmaker.Label;
-import com.google.dexmaker.Local;
-import com.google.dexmaker.MethodId;
-import com.google.dexmaker.TypeId;
+import com.android.dx.Code;
+import com.android.dx.Comparison;
+import com.android.dx.DexMaker;
+import com.android.dx.FieldId;
+import com.android.dx.Label;
+import com.android.dx.Local;
+import com.android.dx.MethodId;
+import com.android.dx.TypeId;
+
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
@@ -32,9 +33,6 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import static java.lang.reflect.Modifier.PRIVATE;
-import static java.lang.reflect.Modifier.PUBLIC;
-import static java.lang.reflect.Modifier.STATIC;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -45,6 +43,10 @@
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 
+import static java.lang.reflect.Modifier.PRIVATE;
+import static java.lang.reflect.Modifier.PUBLIC;
+import static java.lang.reflect.Modifier.STATIC;
+
 /**
  * Creates dynamic proxies of concrete classes.
  * <p>
@@ -109,7 +111,7 @@
  * 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
+ * internally 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>
@@ -137,7 +139,7 @@
     private File dexCache;
     private Class<?>[] constructorArgTypes = new Class[0];
     private Object[] constructorArgValues = new Object[0];
-    private Set<Class<?>> interfaces = new HashSet<Class<?>>();
+    private Set<Class<?>> interfaces = new HashSet<>();
 
     private ProxyBuilder(Class<T> clazz) {
         baseClass = clazz;
@@ -172,7 +174,7 @@
         dexCache.mkdir();
         return this;
     }
-    
+
     public ProxyBuilder<T> implementing(Class<?>... interfaces) {
         for (Class<?> i : interfaces) {
             if (!i.isInterface()) {
@@ -243,7 +245,8 @@
      */
     public Class<? extends T> buildProxyClass() throws IOException {
         // try the cache to see if we've generated this one before
-        @SuppressWarnings("unchecked") // we only populate the map with matching types
+        // we only populate the map with matching types
+        @SuppressWarnings("unchecked")
         Class<? extends T> proxyClass = (Class) generatedProxyClasses.get(baseClass);
         if (proxyClass != null) {
             boolean shareClassLoader = Boolean.parseBoolean(System.getProperty(
@@ -269,8 +272,7 @@
         generateConstructorsAndFields(dexMaker, generatedType, superType, baseClass);
         Method[] methodsToProxy = getMethodsToProxyRecursive();
         generateCodeForAllMethods(dexMaker, generatedType, methodsToProxy, superType);
-        dexMaker.declare(generatedType, generatedName + ".generated", PUBLIC, superType,
-                getInterfacesAsTypeIds());
+        dexMaker.declare(generatedType, generatedName + ".generated", PUBLIC, superType, getInterfacesAsTypeIds());
         ClassLoader classLoader = dexMaker.generateAndLoad(baseClass.getClassLoader(),
                 parentClassLoader, dexCache);
         try {
@@ -367,7 +369,7 @@
     }
 
     // TODO: test coverage for isProxyClass
-    
+
     /**
      * Returns true if {@code c} is a proxy class created by this builder.
      */
@@ -628,15 +630,11 @@
      * supplied class.
      */
     private Method[] getMethodsToProxyRecursive() {
-        Set<MethodSetEntry> methodsToProxy = new HashSet<MethodSetEntry>();
-        Set<MethodSetEntry> seenFinalMethods = new HashSet<MethodSetEntry>();
-        // Traverse the class hierarchy to ensure that all concrete methods (which could be marked
-        // as final) are visited before any abstract methods from interfaces.
+        Set<MethodSetEntry> methodsToProxy = new HashSet<>();
+        Set<MethodSetEntry> seenFinalMethods = new HashSet<>();
         for (Class<?> c = baseClass; c != null; c = c.getSuperclass()) {
             getMethodsToProxy(methodsToProxy, seenFinalMethods, c);
         }
-        // Now traverse the interface hierarchy, starting with the ones implemented by the class,
-        // followed by any extra interfaces.
         for (Class<?> c = baseClass; c != null; c = c.getSuperclass()) {
             for (Class<?> i : c.getInterfaces()) {
                 getMethodsToProxy(methodsToProxy, seenFinalMethods, i);
@@ -712,14 +710,6 @@
             }
             sink.add(entry);
         }
-
-        // Only visit the interfaces of this class if it is itself an interface. That prevents
-        // visiting interfaces of a class before its super classes.
-        if (c.isInterface()) {
-            for (Class<?> i : c.getInterfaces()) {
-                getMethodsToProxy(sink, seenFinalMethods, i);
-            }
-        }
     }
 
     private static <T> String getMethodNameForProxyOf(Class<T> clazz) {
@@ -758,7 +748,7 @@
     }
 
     private static <T> Set<T> asSet(T... array) {
-        return new CopyOnWriteArraySet<T>(Arrays.asList(array));
+        return new CopyOnWriteArraySet<>(Arrays.asList(array));
     }
 
     private static MethodId<?, ?> getUnboxMethodForPrimitive(Class<?> methodReturnType) {
@@ -767,7 +757,7 @@
 
     private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED;
     static {
-        PRIMITIVE_TO_BOXED = new HashMap<Class<?>, Class<?>>();
+        PRIMITIVE_TO_BOXED = new HashMap<>();
         PRIMITIVE_TO_BOXED.put(boolean.class, Boolean.class);
         PRIMITIVE_TO_BOXED.put(int.class, Integer.class);
         PRIMITIVE_TO_BOXED.put(byte.class, Byte.class);
@@ -780,7 +770,7 @@
 
     private static final Map<TypeId<?>, MethodId<?, ?>> PRIMITIVE_TYPE_TO_UNBOX_METHOD;
     static {
-        PRIMITIVE_TYPE_TO_UNBOX_METHOD = new HashMap<TypeId<?>, MethodId<?, ?>>();
+        PRIMITIVE_TYPE_TO_UNBOX_METHOD = new HashMap<>();
         for (Map.Entry<Class<?>, Class<?>> entry : PRIMITIVE_TO_BOXED.entrySet()) {
             TypeId<?> primitiveType = TypeId.get(entry.getKey());
             TypeId<?> boxedType = TypeId.get(entry.getValue());
@@ -798,7 +788,7 @@
      */
     private static final Map<Class<?>, MethodId<?, ?>> PRIMITIVE_TO_UNBOX_METHOD;
     static {
-        Map<Class<?>, MethodId<?, ?>> map = new HashMap<Class<?>, MethodId<?, ?>>();
+        Map<Class<?>, MethodId<?, ?>> map = new HashMap<>();
         map.put(boolean.class, TypeId.get(Boolean.class).getMethod(TypeId.BOOLEAN, "booleanValue"));
         map.put(int.class, TypeId.get(Integer.class).getMethod(TypeId.INT, "intValue"));
         map.put(byte.class, TypeId.get(Byte.class).getMethod(TypeId.BYTE, "byteValue"));
diff --git a/dx/pom.xml b/dx/pom.xml
deleted file mode 100644
index d9977d1..0000000
--- a/dx/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Copyright (C) 2012 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>com.crittercism.dexmaker</groupId>
-        <artifactId>dexmaker-parent</artifactId>
-        <version>1.3</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>dexmaker-dx</artifactId>
-    <packaging>jar</packaging>
-    <name>dexmaker dx</name>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/dx/src/main/java/com/android/dx/Version.java b/dx/src/main/java/com/android/dx/Version.java
deleted file mode 100644
index 130025a..0000000
--- a/dx/src/main/java/com/android/dx/Version.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-/**
- * Version number for dx.
- */
-public class Version {
-    /** {@code non-null;} version string */
-    public static final String VERSION = "1.7";
-}
diff --git a/dx/src/main/java/com/android/dx/cf/code/Merger.java b/dx/src/main/java/com/android/dx/cf/code/Merger.java
deleted file mode 100644
index cce3f25..0000000
--- a/dx/src/main/java/com/android/dx/cf/code/Merger.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2007 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.cf.code;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-
-/**
- * Utility methods to merge various frame information.
- */
-public final class Merger {
-    /**
-     * Merges two frame types.
-     *
-     * @param ft1 {@code non-null;} a frame type
-     * @param ft2 {@code non-null;} another frame type
-     * @return {@code non-null;} the result of merging the two types
-     */
-    public static TypeBearer mergeType(TypeBearer ft1, TypeBearer ft2) {
-        if ((ft1 == null) || ft1.equals(ft2)) {
-            return ft1;
-        } else if (ft2 == null) {
-            return null;
-        } else {
-            Type type1 = ft1.getType();
-            Type type2 = ft2.getType();
-
-            if (type1 == type2) {
-                return type1;
-            } else if (type1.isReference() && type2.isReference()) {
-                if (type1 == Type.KNOWN_NULL) {
-                    /*
-                     * A known-null merges with any other reference type to
-                     * be that reference type.
-                     */
-                    return type2;
-                } else if (type2 == Type.KNOWN_NULL) {
-                    /*
-                     * The same as above, but this time it's type2 that's
-                     * the known-null.
-                     */
-                    return type1;
-                } else if (type1.isArray() && type2.isArray()) {
-                    TypeBearer componentUnion =
-                        mergeType(type1.getComponentType(),
-                                type2.getComponentType());
-                    if (componentUnion == null) {
-                        /*
-                         * At least one of the types is a primitive type,
-                         * so the merged result is just Object.
-                         */
-                        return Type.OBJECT;
-                    }
-                    return ((Type) componentUnion).getArrayType();
-                } else {
-                    /*
-                     * All other unequal reference types get merged to be
-                     * Object in this phase. This is fine here, but it
-                     * won't be the right thing to do in the verifier.
-                     */
-                    return Type.OBJECT;
-                }
-            } else if (type1.isIntlike() && type2.isIntlike()) {
-                /*
-                 * Merging two non-identical int-like types results in
-                 * the type int.
-                 */
-                return Type.INT;
-            } else {
-                return null;
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/DexFormat.java b/dx/src/main/java/com/android/dx/dex/DexFormat.java
deleted file mode 100644
index 3543b35..0000000
--- a/dx/src/main/java/com/android/dx/dex/DexFormat.java
+++ /dev/null
@@ -1,98 +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.dex;
-
-/**
- * Constants that show up in and are otherwise related to {@code .dex}
- * files, and helper methods for same.
- */
-public final class DexFormat {
-    private DexFormat() {}
-
-    /**
-     * API level to target in order to produce the most modern file
-     * format
-     */
-    public static final int API_CURRENT = 14;
-
-    /** API level to target in order to suppress extended opcode usage */
-    public static final int API_NO_EXTENDED_OPCODES = 13;
-
-    /**
-     * file name of the primary {@code .dex} file inside an
-     * application or library {@code .jar} file
-     */
-    public static final String DEX_IN_JAR_NAME = "classes.dex";
-
-    /** common prefix for all dex file "magic numbers" */
-    public static final String MAGIC_PREFIX = "dex\n";
-
-    /** common suffix for all dex file "magic numbers" */
-    public static final String MAGIC_SUFFIX = "\0";
-
-    /** dex file version number for the current format variant */
-    public static final String VERSION_CURRENT = "036";
-
-    /** dex file version number for API level 13 and earlier */
-    public static final String VERSION_FOR_API_13 = "035";
-
-    /**
-     * value used to indicate endianness of file contents
-     */
-    public static final int ENDIAN_TAG = 0x12345678;
-
-    /**
-     * Returns the API level corresponding to the given magic number,
-     * or {@code -1} if the given array is not a well-formed dex file
-     * magic number.
-     */
-    public static int magicToApi(byte[] magic) {
-        if (magic.length != 8) {
-            return -1;
-        }
-
-        if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
-                (magic[7] != '\0')) {
-            return -1;
-        }
-
-        String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
-
-        if (version.equals(VERSION_CURRENT)) {
-            return API_CURRENT;
-        } else if (version.equals(VERSION_FOR_API_13)) {
-            return 13;
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the magic number corresponding to the given target API level.
-     */
-    public static String apiToMagic(int targetApiLevel) {
-        String version;
-
-        if (targetApiLevel >= API_CURRENT) {
-            version = VERSION_CURRENT;
-        } else {
-            version = VERSION_FOR_API_13;
-        }
-
-        return MAGIC_PREFIX + version + MAGIC_SUFFIX;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/DexOptions.java b/dx/src/main/java/com/android/dx/dex/DexOptions.java
deleted file mode 100644
index 0357384..0000000
--- a/dx/src/main/java/com/android/dx/dex/DexOptions.java
+++ /dev/null
@@ -1,40 +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.dex;
-
-/**
- * Container for options used to control details of dex file generation.
- */
-public class DexOptions {
-    /** target API level */
-    public int targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
-
-    /**
-     * Gets the dex file magic number corresponding to this instance.
-     */
-    public String getMagic() {
-        return DexFormat.apiToMagic(targetApiLevel);
-    }
-
-    /**
-     * Returns whether extended opcodes are allowed. This became
-     * allowed as of Ice Cream Sandwich.
-     */
-    public boolean canUseExtendedOpcodes() {
-        return targetApiLevel >= DexFormat.API_CURRENT;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/SizeOf.java b/dx/src/main/java/com/android/dx/dex/SizeOf.java
deleted file mode 100644
index 476f7bb..0000000
--- a/dx/src/main/java/com/android/dx/dex/SizeOf.java
+++ /dev/null
@@ -1,103 +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.dex;
-
-public final class SizeOf {
-    private SizeOf() {}
-
-    public static final int UBYTE = 1;
-    public static final int USHORT = 2;
-    public static final int UINT = 4;
-
-    public static final int SIGNATURE = UBYTE * 20;
-
-    /**
-     * magic ubyte[8]
-     * checksum uint
-     * signature ubyte[20]
-     * file_size uint
-     * header_size uint
-     * endian_tag uint
-     * link_size uint
-     * link_off uint
-     * map_off uint
-     * string_ids_size uint
-     * string_ids_off uint
-     * type_ids_size uint
-     * type_ids_off uint
-     * proto_ids_size uint
-     * proto_ids_off uint
-     * field_ids_size uint
-     * field_ids_off uint
-     * method_ids_size uint
-     * method_ids_off uint
-     * class_defs_size uint
-     * class_defs_off uint
-     * data_size uint
-     * data_off uint
-     */
-    public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70
-
-    /**
-     * string_data_off uint
-     */
-    public static final int STRING_ID_ITEM = UINT;
-
-    /**
-     * descriptor_idx uint
-     */
-    public static final int TYPE_ID_ITEM = UINT;
-
-    /**
-     * type_idx ushort
-     */
-    public static final int TYPE_ITEM = USHORT;
-
-    /**
-     * shorty_idx uint
-     * return_type_idx uint
-     * return_type_idx uint
-     */
-    public static final int PROTO_ID_ITEM = UINT + UINT + UINT;
-
-    /**
-     * class_idx ushort
-     * type_idx/proto_idx ushort
-     * name_idx uint
-     */
-    public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;
-
-    /**
-     * class_idx uint
-     * access_flags uint
-     * superclass_idx uint
-     * interfaces_off uint
-     * source_file_idx uint
-     * annotations_off uint
-     * class_data_off uint
-     * static_values_off uint
-     */
-    public static final int CLASS_DEF_ITEM = 8 * UINT;
-
-    /**
-     * type ushort
-     * unused ushort
-     * size uint
-     * offset uint
-     */
-    public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/ArrayData.java b/dx/src/main/java/com/android/dx/dex/code/ArrayData.java
deleted file mode 100644
index 6674b75..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/ArrayData.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.code;
-
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.cst.*;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.rop.type.Type;
-import java.util.ArrayList;
-
-/**
- * Pseudo-instruction which holds fill array data.
- */
-public final class ArrayData extends VariableSizeInsn {
-    /**
-     * {@code non-null;} address representing the instruction that uses this
-     * instance
-     */
-    private final CodeAddress user;
-
-    /** {@code non-null;} initial values to be filled into an array */
-    private final ArrayList<Constant> values;
-
-    /** non-null: type of constant that initializes the array */
-    private final Constant arrayType;
-
-    /** Width of the init value element */
-    private final int elemWidth;
-
-    /** Length of the init list */
-    private final int initLength;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param user {@code non-null;} address representing the instruction that
-     * uses this instance
-     * @param values {@code non-null;} initial values to be filled into an array
-     */
-    public ArrayData(SourcePosition position, CodeAddress user,
-                     ArrayList<Constant> values,
-                     Constant arrayType) {
-        super(position, RegisterSpecList.EMPTY);
-
-        if (user == null) {
-            throw new NullPointerException("user == null");
-        }
-
-        if (values == null) {
-            throw new NullPointerException("values == null");
-        }
-
-        int sz = values.size();
-
-        if (sz <= 0) {
-            throw new IllegalArgumentException("Illegal number of init values");
-        }
-
-        this.arrayType = arrayType;
-
-        if (arrayType == CstType.BYTE_ARRAY ||
-                arrayType == CstType.BOOLEAN_ARRAY) {
-            elemWidth = 1;
-        } else if (arrayType == CstType.SHORT_ARRAY ||
-                arrayType == CstType.CHAR_ARRAY) {
-            elemWidth = 2;
-        } else if (arrayType == CstType.INT_ARRAY ||
-                arrayType == CstType.FLOAT_ARRAY) {
-            elemWidth = 4;
-        } else if (arrayType == CstType.LONG_ARRAY ||
-                arrayType == CstType.DOUBLE_ARRAY) {
-            elemWidth = 8;
-        } else {
-            throw new IllegalArgumentException("Unexpected constant type");
-        }
-        this.user = user;
-        this.values = values;
-        initLength = values.size();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        int sz = initLength;
-        // Note: the unit here is 16-bit
-        return 4 + ((sz * elemWidth) + 1) / 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out) {
-        int sz = values.size();
-
-        out.writeShort(Opcodes.FILL_ARRAY_DATA_PAYLOAD);
-        out.writeShort(elemWidth);
-        out.writeInt(initLength);
-
-
-        // For speed reasons, replicate the for loop in each case
-        switch (elemWidth) {
-            case 1: {
-                for (int i = 0; i < sz; i++) {
-                    Constant cst = values.get(i);
-                    out.writeByte((byte) ((CstLiteral32) cst).getIntBits());
-                }
-                break;
-            }
-            case 2: {
-                for (int i = 0; i < sz; i++) {
-                    Constant cst = values.get(i);
-                    out.writeShort((short) ((CstLiteral32) cst).getIntBits());
-                }
-                break;
-            }
-            case 4: {
-                for (int i = 0; i < sz; i++) {
-                    Constant cst = values.get(i);
-                    out.writeInt(((CstLiteral32) cst).getIntBits());
-                }
-                break;
-            }
-            case 8: {
-                for (int i = 0; i < sz; i++) {
-                    Constant cst = values.get(i);
-                    out.writeLong(((CstLiteral64) cst).getLongBits());
-                }
-                break;
-            }
-            default:
-                break;
-        }
-
-        // Pad one byte to make the size of data table multiples of 16-bits
-        if (elemWidth == 1 && (sz % 2 != 0)) {
-            out.writeByte(0x00);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new ArrayData(getPosition(), user, values, arrayType);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        int sz = values.size();
-        for (int i = 0; i < sz; i++) {
-            sb.append("\n    ");
-            sb.append(i);
-            sb.append(": ");
-            sb.append(values.get(i).toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        int baseAddress = user.getAddress();
-        StringBuffer sb = new StringBuffer(100);
-        int sz = values.size();
-
-        sb.append("fill-array-data-payload // for fill-array-data @ ");
-        sb.append(Hex.u2(baseAddress));
-
-        for (int i = 0; i < sz; i++) {
-            sb.append("\n  ");
-            sb.append(i);
-            sb.append(": ");
-            sb.append(values.get(i).toHuman());
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/BlockAddresses.java b/dx/src/main/java/com/android/dx/dex/code/BlockAddresses.java
deleted file mode 100644
index 1a1d184..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/BlockAddresses.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Container for the set of {@link CodeAddress} instances associated with
- * the blocks of a particular method. Each block has a corresponding
- * start address, end address, and last instruction address.
- */
-public final class BlockAddresses {
-    /** {@code non-null;} array containing addresses for the start of each basic
-     * block (indexed by basic block label) */
-    private final CodeAddress[] starts;
-
-    /** {@code non-null;} array containing addresses for the final instruction
-     * of each basic block (indexed by basic block label) */
-    private final CodeAddress[] lasts;
-
-    /** {@code non-null;} array containing addresses for the end (just past the
-     * final instruction) of each basic block (indexed by basic block
-     * label) */
-    private final CodeAddress[] ends;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the method to have block addresses for
-     */
-    public BlockAddresses(RopMethod method) {
-        BasicBlockList blocks = method.getBlocks();
-        int maxLabel = blocks.getMaxLabel();
-
-        this.starts = new CodeAddress[maxLabel];
-        this.lasts = new CodeAddress[maxLabel];
-        this.ends = new CodeAddress[maxLabel];
-
-        setupArrays(method);
-    }
-
-    /**
-     * Gets the instance for the start of the given block.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getStart(BasicBlock block) {
-        return starts[block.getLabel()];
-    }
-
-    /**
-     * Gets the instance for the start of the block with the given label.
-     *
-     * @param label {@code non-null;} the label of the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getStart(int label) {
-        return starts[label];
-    }
-
-    /**
-     * Gets the instance for the final instruction of the given block.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getLast(BasicBlock block) {
-        return lasts[block.getLabel()];
-    }
-
-    /**
-     * Gets the instance for the final instruction of the block with
-     * the given label.
-     *
-     * @param label {@code non-null;} the label of the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getLast(int label) {
-        return lasts[label];
-    }
-
-    /**
-     * Gets the instance for the end (address after the final instruction)
-     * of the given block.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getEnd(BasicBlock block) {
-        return ends[block.getLabel()];
-    }
-
-    /**
-     * Gets the instance for the end (address after the final instruction)
-     * of the block with the given label.
-     *
-     * @param label {@code non-null;} the label of the block in question
-     * @return {@code non-null;} the appropriate instance
-     */
-    public CodeAddress getEnd(int label) {
-        return ends[label];
-    }
-
-    /**
-     * Sets up the address arrays.
-     */
-    private void setupArrays(RopMethod method) {
-        BasicBlockList blocks = method.getBlocks();
-        int sz = blocks.size();
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = blocks.get(i);
-            int label = one.getLabel();
-            Insn insn = one.getInsns().get(0);
-
-            starts[label] = new CodeAddress(insn.getPosition());
-
-            SourcePosition pos = one.getLastInsn().getPosition();
-
-            lasts[label] = new CodeAddress(pos);
-            ends[label] = new CodeAddress(pos);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/CatchBuilder.java b/dx/src/main/java/com/android/dx/dex/code/CatchBuilder.java
deleted file mode 100644
index 90d2e8d..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/CatchBuilder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.code;
-
-import com.android.dx.rop.type.Type;
-
-import java.util.HashSet;
-
-/**
- * Interface for the construction of {@link CatchTable} instances.
- */
-public interface CatchBuilder {
-    /**
-     * Builds and returns the catch table for this instance.
-     *
-     * @return {@code non-null;} the constructed table
-     */
-    public CatchTable build();
-
-    /**
-     * Gets whether this instance has any catches at all (either typed
-     * or catch-all).
-     *
-     * @return whether this instance has any catches at all
-     */
-    public boolean hasAnyCatches();
-
-    /**
-     * Gets the set of catch types associated with this instance.
-     *
-     * @return {@code non-null;} the set of catch types
-     */
-    public HashSet<Type> getCatchTypes();
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/CatchHandlerList.java b/dx/src/main/java/com/android/dx/dex/code/CatchHandlerList.java
deleted file mode 100644
index 8472584..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/CatchHandlerList.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.code;
-
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.FixedSizeList;
-import com.android.dx.util.Hex;
-
-/**
- * Ordered list of (exception type, handler address) entries.
- */
-public final class CatchHandlerList extends FixedSizeList
-        implements Comparable<CatchHandlerList> {
-    /** {@code non-null;} empty instance */
-    public static final CatchHandlerList EMPTY = new CatchHandlerList(0);
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size {@code >= 0;} the size of the list
-     */
-    public CatchHandlerList(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Entry get(int n) {
-        return (Entry) get0(n);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return toHuman("", "");
-    }
-
-    /**
-     * Get the human form of this instance, prefixed on each line
-     * with the string.
-     *
-     * @param prefix {@code non-null;} the prefix for every line
-     * @param header {@code non-null;} the header for the first line (after the
-     * first prefix)
-     * @return {@code non-null;} the human form
-     */
-    public String toHuman(String prefix, String header) {
-        StringBuilder sb = new StringBuilder(100);
-        int size = size();
-
-        sb.append(prefix);
-        sb.append(header);
-        sb.append("catch ");
-
-        for (int i = 0; i < size; i++) {
-            Entry entry = get(i);
-
-            if (i != 0) {
-                sb.append(",\n");
-                sb.append(prefix);
-                sb.append("  ");
-            }
-
-            if ((i == (size - 1)) && catchesAll()) {
-                sb.append("<any>");
-            } else {
-                sb.append(entry.getExceptionType().toHuman());
-            }
-
-            sb.append(" -> ");
-            sb.append(Hex.u2or4(entry.getHandler()));
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Returns whether or not this instance ends with a "catch-all"
-     * handler.
-     *
-     * @return {@code true} if this instance ends with a "catch-all"
-     * handler or {@code false} if not
-     */
-    public boolean catchesAll() {
-        int size = size();
-
-        if (size == 0) {
-            return false;
-        }
-
-        Entry last = get(size - 1);
-        return last.getExceptionType().equals(CstType.OBJECT);
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param exceptionType {@code non-null;} type of exception handled
-     * @param handler {@code >= 0;} exception handler address
-     */
-    public void set(int n, CstType exceptionType, int handler) {
-        set0(n, new Entry(exceptionType, handler));
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param entry {@code non-null;} the entry to set at {@code n}
-     */
-    public void set(int n, Entry entry) {
-        set0(n, entry);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(CatchHandlerList other) {
-        if (this == other) {
-            // Easy out.
-            return 0;
-        }
-
-        int thisSize = size();
-        int otherSize = other.size();
-        int checkSize = Math.min(thisSize, otherSize);
-
-        for (int i = 0; i < checkSize; i++) {
-            Entry thisEntry = get(i);
-            Entry otherEntry = other.get(i);
-            int compare = thisEntry.compareTo(otherEntry);
-            if (compare != 0) {
-                return compare;
-            }
-        }
-
-        if (thisSize < otherSize) {
-            return -1;
-        } else if (thisSize > otherSize) {
-            return 1;
-        }
-
-        return 0;
-    }
-
-    /**
-     * Entry in the list.
-     */
-    public static class Entry implements Comparable<Entry> {
-        /** {@code non-null;} type of exception handled */
-        private final CstType exceptionType;
-
-        /** {@code >= 0;} exception handler address */
-        private final int handler;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param exceptionType {@code non-null;} type of exception handled
-         * @param handler {@code >= 0;} exception handler address
-         */
-        public Entry(CstType exceptionType, int handler) {
-            if (handler < 0) {
-                throw new IllegalArgumentException("handler < 0");
-            }
-
-            if (exceptionType == null) {
-                throw new NullPointerException("exceptionType == null");
-            }
-
-            this.handler = handler;
-            this.exceptionType = exceptionType;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public int hashCode() {
-            return (handler * 31) + exceptionType.hashCode();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof Entry) {
-                return (compareTo((Entry) other) == 0);
-            }
-
-            return false;
-        }
-
-        /** {@inheritDoc} */
-        public int compareTo(Entry other) {
-            if (handler < other.handler) {
-                return -1;
-            } else if (handler > other.handler) {
-                return 1;
-            }
-
-            return exceptionType.compareTo(other.exceptionType);
-        }
-
-        /**
-         * Gets the exception type handled.
-         *
-         * @return {@code non-null;} the exception type
-         */
-        public CstType getExceptionType() {
-            return exceptionType;
-        }
-
-        /**
-         * Gets the handler address.
-         *
-         * @return {@code >= 0;} the handler address
-         */
-        public int getHandler() {
-            return handler;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/CatchTable.java b/dx/src/main/java/com/android/dx/dex/code/CatchTable.java
deleted file mode 100644
index 0ee890f..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/CatchTable.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.code;
-
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.FixedSizeList;
-
-/**
- * Table of catch entries. Each entry includes a range of code
- * addresses for which it is valid and an associated {@link
- * CatchHandlerList}.
- */
-public final class CatchTable extends FixedSizeList
-        implements Comparable<CatchTable> {
-    /** {@code non-null;} empty instance */
-    public static final CatchTable EMPTY = new CatchTable(0);
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size {@code >= 0;} the size of the table
-     */
-    public CatchTable(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Entry get(int n) {
-        return (Entry) get0(n);
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param entry {@code non-null;} the entry to set at {@code n}
-     */
-    public void set(int n, Entry entry) {
-        set0(n, entry);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(CatchTable other) {
-        if (this == other) {
-            // Easy out.
-            return 0;
-        }
-
-        int thisSize = size();
-        int otherSize = other.size();
-        int checkSize = Math.min(thisSize, otherSize);
-
-        for (int i = 0; i < checkSize; i++) {
-            Entry thisEntry = get(i);
-            Entry otherEntry = other.get(i);
-            int compare = thisEntry.compareTo(otherEntry);
-            if (compare != 0) {
-                return compare;
-            }
-        }
-
-        if (thisSize < otherSize) {
-            return -1;
-        } else if (thisSize > otherSize) {
-            return 1;
-        }
-
-        return 0;
-    }
-
-    /**
-     * Entry in a catch list.
-     */
-    public static class Entry implements Comparable<Entry> {
-        /** {@code >= 0;} start address */
-        private final int start;
-
-        /** {@code > start;} end address (exclusive) */
-        private final int end;
-
-        /** {@code non-null;} list of catch handlers */
-        private final CatchHandlerList handlers;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param start {@code >= 0;} start address
-         * @param end {@code > start;} end address (exclusive)
-         * @param handlers {@code non-null;} list of catch handlers
-         */
-        public Entry(int start, int end, CatchHandlerList handlers) {
-            if (start < 0) {
-                throw new IllegalArgumentException("start < 0");
-            }
-
-            if (end <= start) {
-                throw new IllegalArgumentException("end <= start");
-            }
-
-            if (handlers.isMutable()) {
-                throw new IllegalArgumentException("handlers.isMutable()");
-            }
-
-            this.start = start;
-            this.end = end;
-            this.handlers = handlers;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public int hashCode() {
-            int hash = (start * 31) + end;
-            hash = (hash * 31) + handlers.hashCode();
-            return hash;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof Entry) {
-                return (compareTo((Entry) other) == 0);
-            }
-
-            return false;
-        }
-
-        /** {@inheritDoc} */
-        public int compareTo(Entry other) {
-            if (start < other.start) {
-                return -1;
-            } else if (start > other.start) {
-                return 1;
-            }
-
-            if (end < other.end) {
-                return -1;
-            } else if (end > other.end) {
-                return 1;
-            }
-
-            return handlers.compareTo(other.handlers);
-        }
-
-        /**
-         * Gets the start address.
-         *
-         * @return {@code >= 0;} the start address
-         */
-        public int getStart() {
-            return start;
-        }
-
-        /**
-         * Gets the end address (exclusive).
-         *
-         * @return {@code > start;} the end address (exclusive)
-         */
-        public int getEnd() {
-            return end;
-        }
-
-        /**
-         * Gets the handlers.
-         *
-         * @return {@code non-null;} the handlers
-         */
-        public CatchHandlerList getHandlers() {
-            return handlers;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/CodeAddress.java b/dx/src/main/java/com/android/dx/dex/code/CodeAddress.java
deleted file mode 100644
index 5d26bd1..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/CodeAddress.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Pseudo-instruction which is used to track an address within a code
- * array. Instances are used for such things as branch targets and
- * exception handler ranges. Its code size is zero, and so instances
- * do not in general directly wind up in any output (either
- * human-oriented or binary file).
- */
-public final class CodeAddress extends ZeroSizeInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     */
-    public CodeAddress(SourcePosition position) {
-        super(position);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final DalvInsn withRegisters(RegisterSpecList registers) {
-        return new CodeAddress(getPosition());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        return "code-address";
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/CstInsn.java b/dx/src/main/java/com/android/dx/dex/code/CstInsn.java
deleted file mode 100644
index 3f848c0..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/CstInsn.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.cst.Constant;
-
-/**
- * Instruction which has a single constant argument in addition
- * to all the normal instruction information.
- */
-public final class CstInsn extends FixedSizeInsn {
-    /** {@code non-null;} the constant argument for this instruction */
-    private final Constant constant;
-
-    /**
-     * {@code >= -1;} the constant pool index for {@link #constant}, or
-     * {@code -1} if not yet set
-     */
-    private int index;
-
-    /**
-     * {@code >= -1;} the constant pool index for the class reference in
-     * {@link #constant} if any, or {@code -1} if not yet set
-     */
-    private int classIndex;
-
-    /**
-     * Constructs an instance. The output address of this instance is
-     * initially unknown ({@code -1}) as is the constant pool index.
-     *
-     * @param opcode the opcode; one of the constants from {@link Dops}
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} register list, including a
-     * result register if appropriate (that is, registers may be either
-     * ins or outs)
-     * @param constant {@code non-null;} constant argument
-     */
-    public CstInsn(Dop opcode, SourcePosition position,
-                   RegisterSpecList registers, Constant constant) {
-        super(opcode, position, registers);
-
-        if (constant == null) {
-            throw new NullPointerException("constant == null");
-        }
-
-        this.constant = constant;
-        this.index = -1;
-        this.classIndex = -1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withOpcode(Dop opcode) {
-        CstInsn result =
-            new CstInsn(opcode, getPosition(), getRegisters(), constant);
-
-        if (index >= 0) {
-            result.setIndex(index);
-        }
-
-        if (classIndex >= 0) {
-            result.setClassIndex(classIndex);
-        }
-
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        CstInsn result =
-            new CstInsn(getOpcode(), getPosition(), registers, constant);
-
-        if (index >= 0) {
-            result.setIndex(index);
-        }
-
-        if (classIndex >= 0) {
-            result.setClassIndex(classIndex);
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the constant argument.
-     *
-     * @return {@code non-null;} the constant argument
-     */
-    public Constant getConstant() {
-        return constant;
-    }
-
-    /**
-     * Gets the constant's index. It is only valid to call this after
-     * {@link #setIndex} has been called.
-     *
-     * @return {@code >= 0;} the constant pool index
-     */
-    public int getIndex() {
-        if (index < 0) {
-            throw new RuntimeException("index not yet set for " + constant);
-        }
-
-        return index;
-    }
-
-    /**
-     * Returns whether the constant's index has been set for this instance.
-     *
-     * @see #setIndex
-     *
-     * @return {@code true} iff the index has been set
-     */
-    public boolean hasIndex() {
-        return (index >= 0);
-    }
-
-    /**
-     * Sets the constant's index. It is only valid to call this method once
-     * per instance.
-     *
-     * @param index {@code >= 0;} the constant pool index
-     */
-    public void setIndex(int index) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index < 0");
-        }
-
-        if (this.index >= 0) {
-            throw new RuntimeException("index already set");
-        }
-
-        this.index = index;
-    }
-
-    /**
-     * Gets the constant's class index. It is only valid to call this after
-     * {@link #setClassIndex} has been called.
-     *
-     * @return {@code >= 0;} the constant's class's constant pool index
-     */
-    public int getClassIndex() {
-        if (classIndex < 0) {
-            throw new RuntimeException("class index not yet set");
-        }
-
-        return classIndex;
-    }
-
-    /**
-     * Returns whether the constant's class index has been set for this
-     * instance.
-     *
-     * @see #setClassIndex
-     *
-     * @return {@code true} iff the index has been set
-     */
-    public boolean hasClassIndex() {
-        return (classIndex >= 0);
-    }
-
-    /**
-     * Sets the constant's class index. This is the constant pool index
-     * for the class referred to by this instance's constant. Only
-     * reference constants have a class, so it is only on instances
-     * with reference constants that this method should ever be
-     * called. It is only valid to call this method once per instance.
-     *
-     * @param index {@code >= 0;} the constant's class's constant pool index
-     */
-    public void setClassIndex(int index) {
-        if (index < 0) {
-            throw new IllegalArgumentException("index < 0");
-        }
-
-        if (this.classIndex >= 0) {
-            throw new RuntimeException("class index already set");
-        }
-
-        this.classIndex = index;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return constant.toHuman();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/DalvCode.java b/dx/src/main/java/com/android/dx/dex/code/DalvCode.java
deleted file mode 100644
index 58f191b..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/DalvCode.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.type.Type;
-
-import java.util.HashSet;
-
-/**
- * Container for all the pieces of a concrete method. Each instance
- * corresponds to a {@code code} structure in a {@code .dex} file.
- */
-public final class DalvCode {
-    /**
-     * how much position info to preserve; one of the static
-     * constants in {@link PositionList}
-     */
-    private final int positionInfo;
-
-    /**
-     * {@code null-ok;} the instruction list, ready for final processing;
-     * nulled out in {@link #finishProcessingIfNecessary}
-     */
-    private OutputFinisher unprocessedInsns;
-
-    /**
-     * {@code non-null;} unprocessed catch table;
-     * nulled out in {@link #finishProcessingIfNecessary}
-     */
-    private CatchBuilder unprocessedCatches;
-
-    /**
-     * {@code null-ok;} catch table; set in
-     * {@link #finishProcessingIfNecessary}
-     */
-    private CatchTable catches;
-
-    /**
-     * {@code null-ok;} source positions list; set in
-     * {@link #finishProcessingIfNecessary}
-     */
-    private PositionList positions;
-
-    /**
-     * {@code null-ok;} local variable list; set in
-     * {@link #finishProcessingIfNecessary}
-     */
-    private LocalList locals;
-
-    /**
-     * {@code null-ok;} the processed instruction list; set in
-     * {@link #finishProcessingIfNecessary}
-     */
-    private DalvInsnList insns;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param positionInfo how much position info to preserve; one of the
-     * static constants in {@link PositionList}
-     * @param unprocessedInsns {@code non-null;} the instruction list, ready
-     * for final processing
-     * @param unprocessedCatches {@code non-null;} unprocessed catch
-     * (exception handler) table
-     */
-    public DalvCode(int positionInfo, OutputFinisher unprocessedInsns,
-            CatchBuilder unprocessedCatches) {
-        if (unprocessedInsns == null) {
-            throw new NullPointerException("unprocessedInsns == null");
-        }
-
-        if (unprocessedCatches == null) {
-            throw new NullPointerException("unprocessedCatches == null");
-        }
-
-        this.positionInfo = positionInfo;
-        this.unprocessedInsns = unprocessedInsns;
-        this.unprocessedCatches = unprocessedCatches;
-        this.catches = null;
-        this.positions = null;
-        this.locals = null;
-        this.insns = null;
-    }
-
-    /**
-     * Finish up processing of the method.
-     */
-    private void finishProcessingIfNecessary() {
-        if (insns != null) {
-            return;
-        }
-
-        insns = unprocessedInsns.finishProcessingAndGetList();
-        positions = PositionList.make(insns, positionInfo);
-        locals = LocalList.make(insns);
-        catches = unprocessedCatches.build();
-
-        // Let them be gc'ed.
-        unprocessedInsns = null;
-        unprocessedCatches = null;
-    }
-
-    /**
-     * Assign indices in all instructions that need them, using the
-     * given callback to perform lookups. This must be called before
-     * {@link #getInsns}.
-     *
-     * @param callback {@code non-null;} callback object
-     */
-    public void assignIndices(AssignIndicesCallback callback) {
-        unprocessedInsns.assignIndices(callback);
-    }
-
-    /**
-     * Gets whether this instance has any position data to represent.
-     *
-     * @return {@code true} iff this instance has any position
-     * data to represent
-     */
-    public boolean hasPositions() {
-        return (positionInfo != PositionList.NONE)
-            && unprocessedInsns.hasAnyPositionInfo();
-    }
-
-    /**
-     * Gets whether this instance has any local variable data to represent.
-     *
-     * @return {@code true} iff this instance has any local variable
-     * data to represent
-     */
-    public boolean hasLocals() {
-        return unprocessedInsns.hasAnyLocalInfo();
-    }
-
-    /**
-     * Gets whether this instance has any catches at all (either typed
-     * or catch-all).
-     *
-     * @return whether this instance has any catches at all
-     */
-    public boolean hasAnyCatches() {
-        return unprocessedCatches.hasAnyCatches();
-    }
-
-    /**
-     * Gets the set of catch types handled anywhere in the code.
-     *
-     * @return {@code non-null;} the set of catch types
-     */
-    public HashSet<Type> getCatchTypes() {
-        return unprocessedCatches.getCatchTypes();
-    }
-
-    /**
-     * Gets the set of all constants referred to by instructions in
-     * the code.
-     *
-     * @return {@code non-null;} the set of constants
-     */
-    public HashSet<Constant> getInsnConstants() {
-        return unprocessedInsns.getAllConstants();
-    }
-
-    /**
-     * Gets the list of instructions.
-     *
-     * @return {@code non-null;} the instruction list
-     */
-    public DalvInsnList getInsns() {
-        finishProcessingIfNecessary();
-        return insns;
-    }
-
-    /**
-     * Gets the catch (exception handler) table.
-     *
-     * @return {@code non-null;} the catch table
-     */
-    public CatchTable getCatches() {
-        finishProcessingIfNecessary();
-        return catches;
-    }
-
-    /**
-     * Gets the source positions list.
-     *
-     * @return {@code non-null;} the source positions list
-     */
-    public PositionList getPositions() {
-        finishProcessingIfNecessary();
-        return positions;
-    }
-
-    /**
-     * Gets the source positions list.
-     *
-     * @return {@code non-null;} the source positions list
-     */
-    public LocalList getLocals() {
-        finishProcessingIfNecessary();
-        return locals;
-    }
-
-    /**
-     * Class used as a callback for {@link #assignIndices}.
-     */
-    public static interface AssignIndicesCallback {
-        /**
-         * Gets the index for the given constant.
-         *
-         * @param cst {@code non-null;} the constant
-         * @return {@code >= -1;} the index or {@code -1} if the constant
-         * shouldn't actually be reified with an index
-         */
-        public int getIndex(Constant cst);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/DalvInsn.java b/dx/src/main/java/com/android/dx/dex/code/DalvInsn.java
deleted file mode 100644
index d0cf395..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/DalvInsn.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.TwoColumnOutput;
-
-import java.util.BitSet;
-
-/**
- * Base class for Dalvik instructions.
- */
-public abstract class DalvInsn {
-    /**
-     * the actual output address of this instance, if known, or
-     * {@code -1} if not
-     */
-    private int address;
-
-    /** the opcode; one of the constants from {@link Dops} */
-    private final Dop opcode;
-
-    /** {@code non-null;} source position */
-    private final SourcePosition position;
-
-    /** {@code non-null;} list of register arguments */
-    private final RegisterSpecList registers;
-
-    /**
-     * Makes a move instruction, appropriate and ideal for the given arguments.
-     *
-     * @param position {@code non-null;} source position information
-     * @param dest {@code non-null;} destination register
-     * @param src {@code non-null;} source register
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static SimpleInsn makeMove(SourcePosition position,
-            RegisterSpec dest, RegisterSpec src) {
-        boolean category1 = dest.getCategory() == 1;
-        boolean reference = dest.getType().isReference();
-        int destReg = dest.getReg();
-        int srcReg = src.getReg();
-        Dop opcode;
-
-        if ((srcReg | destReg) < 16) {
-            opcode = reference ? Dops.MOVE_OBJECT :
-                (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
-        } else if (destReg < 256) {
-            opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
-                (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
-        } else {
-            opcode = reference ? Dops.MOVE_OBJECT_16 :
-                (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
-        }
-
-        return new SimpleInsn(opcode, position,
-                              RegisterSpecList.make(dest, src));
-    }
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * <p><b>Note:</b> In the unlikely event that an instruction takes
-     * absolutely no registers (e.g., a {@code nop} or a
-     * no-argument no-result static method call), then the given
-     * register list may be passed as {@link
-     * RegisterSpecList#EMPTY}.</p>
-     *
-     * @param opcode the opcode; one of the constants from {@link Dops}
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} register list, including a
-     * result register if appropriate (that is, registers may be either
-     * ins and outs)
-     */
-    public DalvInsn(Dop opcode, SourcePosition position,
-                    RegisterSpecList registers) {
-        if (opcode == null) {
-            throw new NullPointerException("opcode == null");
-        }
-
-        if (position == null) {
-            throw new NullPointerException("position == null");
-        }
-
-        if (registers == null) {
-            throw new NullPointerException("registers == null");
-        }
-
-        this.address = -1;
-        this.opcode = opcode;
-        this.position = position;
-        this.registers = registers;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final String toString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append(identifierString());
-        sb.append(' ');
-        sb.append(position);
-
-        sb.append(": ");
-        sb.append(opcode.getName());
-
-        boolean needComma = false;
-        if (registers.size() != 0) {
-            sb.append(registers.toHuman(" ", ", ", null));
-            needComma = true;
-        }
-
-        String extra = argString();
-        if (extra != null) {
-            if (needComma) {
-                sb.append(',');
-            }
-            sb.append(' ');
-            sb.append(extra);
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets whether the address of this instruction is known.
-     *
-     * @see #getAddress
-     * @see #setAddress
-     */
-    public final boolean hasAddress() {
-        return (address >= 0);
-    }
-
-    /**
-     * Gets the output address of this instruction, if it is known. This throws
-     * a {@code RuntimeException} if it has not yet been set.
-     *
-     * @see #setAddress
-     *
-     * @return {@code >= 0;} the output address
-     */
-    public final int getAddress() {
-        if (address < 0) {
-            throw new RuntimeException("address not yet known");
-        }
-
-        return address;
-    }
-
-    /**
-     * Gets the opcode.
-     *
-     * @return {@code non-null;} the opcode
-     */
-    public final Dop getOpcode() {
-        return opcode;
-    }
-
-    /**
-     * Gets the source position.
-     *
-     * @return {@code non-null;} the source position
-     */
-    public final SourcePosition getPosition() {
-        return position;
-    }
-
-    /**
-     * Gets the register list for this instruction.
-     *
-     * @return {@code non-null;} the registers
-     */
-    public final RegisterSpecList getRegisters() {
-        return registers;
-    }
-
-    /**
-     * Returns whether this instance's opcode uses a result register.
-     * This method is a convenient shorthand for
-     * {@code getOpcode().hasResult()}.
-     *
-     * @return {@code true} iff this opcode uses a result register
-     */
-    public final boolean hasResult() {
-        return opcode.hasResult();
-    }
-
-    /**
-     * Gets the minimum distinct registers required for this instruction.
-     * Uses the given BitSet to determine which registers require
-     * replacement, and ignores registers that are already compatible.
-     * This assumes that the result (if any) can share registers with the
-     * sources (if any), that each source register is unique, and that
-     * (to be explicit here) category-2 values take up two consecutive
-     * registers.
-     *
-     * @param compatRegs {@code non-null;} set of compatible registers
-     * @return {@code >= 0;} the minimum distinct register requirement
-     */
-    public final int getMinimumRegisterRequirement(BitSet compatRegs) {
-        boolean hasResult = hasResult();
-        int regSz = registers.size();
-        int resultRequirement = 0;
-        int sourceRequirement = 0;
-
-        if (hasResult && !compatRegs.get(0)) {
-            resultRequirement = registers.get(0).getCategory();
-        }
-
-        for (int i = hasResult ? 1 : 0; i < regSz; i++) {
-            if (!compatRegs.get(i)) {
-                sourceRequirement += registers.get(i).getCategory();
-            }
-        }
-
-        return Math.max(sourceRequirement, resultRequirement);
-    }
-
-    /**
-     * Gets the instruction that is equivalent to this one, except that
-     * it uses sequential registers starting at {@code 0} (storing
-     * the result, if any, in register {@code 0} as well).
-     *
-     * @return {@code non-null;} the replacement
-     */
-    public DalvInsn getLowRegVersion() {
-        RegisterSpecList regs =
-            registers.withExpandedRegisters(0, hasResult(), null);
-        return withRegisters(regs);
-    }
-
-    /**
-     * Gets the instruction prefix required, if any, to use in an expanded
-     * version of this instance. Will not generate moves for registers
-     * marked compatible to the format by the given BitSet.
-     *
-     * @see #expandedVersion
-     *
-     * @param compatRegs {@code non-null;} set of compatible registers
-     * @return {@code null-ok;} the prefix, if any
-     */
-    public DalvInsn expandedPrefix(BitSet compatRegs) {
-        RegisterSpecList regs = registers;
-        boolean firstBit = compatRegs.get(0);
-
-        if (hasResult()) compatRegs.set(0);
-
-        regs = regs.subset(compatRegs);
-
-        if (hasResult()) compatRegs.set(0, firstBit);
-
-        if (regs.size() == 0) return null;
-
-        return new HighRegisterPrefix(position, regs);
-    }
-
-    /**
-     * Gets the instruction suffix required, if any, to use in an expanded
-     * version of this instance. Will not generate a move for a register
-     * marked compatible to the format by the given BitSet.
-     *
-     * @see #expandedVersion
-     *
-     * @param compatRegs {@code non-null;} set of compatible registers
-     * @return {@code null-ok;} the suffix, if any
-     */
-    public DalvInsn expandedSuffix(BitSet compatRegs) {
-        if (hasResult() && !compatRegs.get(0)) {
-            RegisterSpec r = registers.get(0);
-            return makeMove(position, r, r.withReg(0));
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the instruction that is equivalent to this one, except that
-     * it replaces incompatible registers with sequential registers
-     * starting at {@code 0} (storing the result, if any, in register
-     * {@code 0} as well). The sequence of instructions from
-     * {@link #expandedPrefix} and {@link #expandedSuffix} (if non-null)
-     * surrounding the result of a call to this method are the expanded
-     * transformation of this instance, and it is guaranteed that the
-     * number of low registers used will be the number returned by
-     * {@link #getMinimumRegisterRequirement}.
-     *
-     * @param compatRegs {@code non-null;} set of compatible registers
-     * @return {@code non-null;} the replacement
-     */
-    public DalvInsn expandedVersion(BitSet compatRegs) {
-        RegisterSpecList regs =
-            registers.withExpandedRegisters(0, hasResult(), compatRegs);
-        return withRegisters(regs);
-    }
-
-    /**
-     * Gets the short identifier for this instruction. This is its
-     * address, if assigned, or its identity hashcode if not.
-     *
-     * @return {@code non-null;} the identifier
-     */
-    public final String identifierString() {
-        if (address != -1) {
-            return String.format("%04x", address);
-        }
-
-        return Hex.u4(System.identityHashCode(this));
-    }
-
-    /**
-     * Returns the string form of this instance suitable for inclusion in
-     * a human-oriented listing dump. This method will return {@code null}
-     * if this instance should not appear in a listing.
-     *
-     * @param prefix {@code non-null;} prefix before the address; each follow-on
-     * line will be indented to match as well
-     * @param width {@code >= 0;} the width of the output or {@code 0} for
-     * unlimited width
-     * @param noteIndices whether to include an explicit notation of
-     * constant pool indices
-     * @return {@code null-ok;} the string form or {@code null} if this
-     * instance should not appear in a listing
-     */
-    public final String listingString(String prefix, int width,
-            boolean noteIndices) {
-        String insnPerSe = listingString0(noteIndices);
-
-        if (insnPerSe == null) {
-            return null;
-        }
-
-        String addr = prefix + identifierString() + ": ";
-        int w1 = addr.length();
-        int w2 = (width == 0) ? insnPerSe.length() : (width - w1);
-
-        return TwoColumnOutput.toString(addr, w1, "", insnPerSe, w2);
-    }
-
-    /**
-     * Sets the output address.
-     *
-     * @param address {@code >= 0;} the output address
-     */
-    public final void setAddress(int address) {
-        if (address < 0) {
-            throw new IllegalArgumentException("address < 0");
-        }
-
-        this.address = address;
-    }
-
-    /**
-     * Gets the address immediately after this instance. This is only
-     * calculable if this instance's address is known, and it is equal
-     * to the address plus the length of the instruction format of this
-     * instance's opcode.
-     *
-     * @return {@code >= 0;} the next address
-     */
-    public final int getNextAddress() {
-        return getAddress() + codeSize();
-    }
-
-    /**
-     * Gets the size of this instruction, in 16-bit code units.
-     *
-     * @return {@code >= 0;} the code size of this instruction
-     */
-    public abstract int codeSize();
-
-    /**
-     * Writes this instance to the given output. This method should
-     * never annotate the output.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    public abstract void writeTo(AnnotatedOutput out);
-
-    /**
-     * Returns an instance that is just like this one, except that its
-     * opcode is replaced by the one given, and its address is reset.
-     *
-     * @param opcode {@code non-null;} the new opcode
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract DalvInsn withOpcode(Dop opcode);
-
-    /**
-     * Returns an instance that is just like this one, except that all
-     * register references have been offset by the given delta, and its
-     * address is reset.
-     *
-     * @param delta the amount to offset register references by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract DalvInsn withRegisterOffset(int delta);
-
-    /**
-     * Returns an instance that is just like this one, except that the
-     * register list is replaced by the given one, and its address is
-     * reset.
-     *
-     * @param registers {@code non-null;} new register list
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract DalvInsn withRegisters(RegisterSpecList registers);
-
-    /**
-     * Gets the string form for any arguments to this instance. Subclasses
-     * must override this.
-     *
-     * @return {@code null-ok;} the string version of any arguments or
-     * {@code null} if there are none
-     */
-    protected abstract String argString();
-
-    /**
-     * Helper for {@link #listingString}, which returns the string
-     * form of this instance suitable for inclusion in a
-     * human-oriented listing dump, not including the instruction
-     * address and without respect for any output formatting. This
-     * method should return {@code null} if this instance should
-     * not appear in a listing.
-     *
-     * @param noteIndices whether to include an explicit notation of
-     * constant pool indices
-     * @return {@code null-ok;} the listing string
-     */
-    protected abstract String listingString0(boolean noteIndices);
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/DalvInsnList.java b/dx/src/main/java/com/android/dx/dex/code/DalvInsnList.java
deleted file mode 100644
index e856cb4..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/DalvInsnList.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstBaseMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-import com.android.dx.util.FixedSizeList;
-import com.android.dx.util.IndentingWriter;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-
-/**
- * List of {@link DalvInsn} instances.
- */
-public final class DalvInsnList extends FixedSizeList {
-
-    /**
-     * The amount of register space, in register units, required for this
-     * code block. This may be greater than the largest observed register+
-     * category because the method this code block exists in may
-     * specify arguments that are unused by the method.
-     */
-    private final int regCount;
-
-    /**
-     * Constructs and returns an immutable instance whose elements are
-     * identical to the ones in the given list, in the same order.
-     *
-     * @param list {@code non-null;} the list to use for elements
-     * @param regCount count, in register-units, of the number of registers
-     * this code block requires.
-     * @return {@code non-null;} an appropriately-constructed instance of this
-     * class
-     */
-    public static DalvInsnList makeImmutable(ArrayList<DalvInsn> list,
-            int regCount) {
-        int size = list.size();
-        DalvInsnList result = new DalvInsnList(size, regCount);
-
-        for (int i = 0; i < size; i++) {
-            result.set(i, list.get(i));
-        }
-
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public DalvInsnList(int size, int regCount) {
-        super(size);
-        this.regCount = regCount;
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public DalvInsn get(int n) {
-        return (DalvInsn) get0(n);
-    }
-
-    /**
-     * Sets the instruction at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param insn {@code non-null;} the instruction to set at {@code n}
-     */
-    public void set(int n, DalvInsn insn) {
-        set0(n, insn);
-    }
-
-    /**
-     * Gets the size of this instance, in 16-bit code units. This will only
-     * return a meaningful result if the instructions in this instance all
-     * have valid addresses.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int codeSize() {
-        int sz = size();
-
-        if (sz == 0) {
-            return 0;
-        }
-
-        DalvInsn last = get(sz - 1);
-        return last.getNextAddress();
-    }
-
-    /**
-     * Writes all the instructions in this instance to the given output
-     * destination.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    public void writeTo(AnnotatedOutput out) {
-        int startCursor = out.getCursor();
-        int sz = size();
-
-        if (out.annotates()) {
-            boolean verbose = out.isVerbose();
-
-            for (int i = 0; i < sz; i++) {
-                DalvInsn insn = (DalvInsn) get0(i);
-                int codeBytes = insn.codeSize() * 2;
-                String s;
-
-                if ((codeBytes != 0) || verbose) {
-                    s = insn.listingString("  ", out.getAnnotationWidth(),
-                            true);
-                } else {
-                    s = null;
-                }
-
-                if (s != null) {
-                    out.annotate(codeBytes, s);
-                } else if (codeBytes != 0) {
-                    out.annotate(codeBytes, "");
-                }
-            }
-        }
-
-        for (int i = 0; i < sz; i++) {
-            DalvInsn insn = (DalvInsn) get0(i);
-            try {
-                insn.writeTo(out);
-            } catch (RuntimeException ex) {
-                throw ExceptionWithContext.withContext(ex,
-                        "...while writing " + insn);
-            }
-        }
-
-        // Sanity check of the amount written.
-        int written = (out.getCursor() - startCursor) / 2;
-        if (written != codeSize()) {
-            throw new RuntimeException("write length mismatch; expected " +
-                    codeSize() + " but actually wrote " + written);
-        }
-    }
-
-    /**
-     * Gets the minimum required register count implied by this
-     * instance.  This includes any unused parameters that could
-     * potentially be at the top of the register space.
-     * @return {@code >= 0;} the required registers size
-     */
-    public int getRegistersSize() {
-        return regCount;
-    }
-
-    /**
-     * Gets the size of the outgoing arguments area required by this
-     * method. This is equal to the largest argument word count of any
-     * method referred to by this instance.
-     *
-     * @return {@code >= 0;} the required outgoing arguments size
-     */
-    public int getOutsSize() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            DalvInsn insn = (DalvInsn) get0(i);
-
-            if (!(insn instanceof CstInsn)) {
-                continue;
-            }
-
-            Constant cst = ((CstInsn) insn).getConstant();
-
-            if (!(cst instanceof CstBaseMethodRef)) {
-                continue;
-            }
-
-            boolean isStatic =
-                (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC);
-            int count =
-                ((CstBaseMethodRef) cst).getParameterWordCount(isStatic);
-
-            if (count > result) {
-                result = count;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} prefix to attach to each line of output
-     * @param verbose whether to be verbose; verbose output includes
-     * lines for zero-size instructions and explicit constant pool indices
-     */
-    public void debugPrint(Writer out, String prefix, boolean verbose) {
-        IndentingWriter iw = new IndentingWriter(out, 0, prefix);
-        int sz = size();
-
-        try {
-            for (int i = 0; i < sz; i++) {
-                DalvInsn insn = (DalvInsn) get0(i);
-                String s;
-
-                if ((insn.codeSize() != 0) || verbose) {
-                    s = insn.listingString("", 0, verbose);
-                } else {
-                    s = null;
-                }
-
-                if (s != null) {
-                    iw.write(s);
-                }
-            }
-
-            iw.flush();
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} prefix to attach to each line of output
-     * @param verbose whether to be verbose; verbose output includes
-     * lines for zero-size instructions
-     */
-    public void debugPrint(OutputStream out, String prefix, boolean verbose) {
-        Writer w = new OutputStreamWriter(out);
-        debugPrint(w, prefix, verbose);
-
-        try {
-            w.flush();
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/Dop.java b/dx/src/main/java/com/android/dx/dex/code/Dop.java
deleted file mode 100644
index 51d1b51..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/Dop.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.io.OpcodeInfo;
-import com.android.dx.io.Opcodes;
-
-/**
- * Representation of an opcode.
- */
-public final class Dop {
-    /** {@code Opcodes.isValid();} the opcode value itself */
-    private final int opcode;
-
-    /** {@code Opcodes.isValid();} the opcode family */
-    private final int family;
-
-    /**
-     * {@code Opcodes.isValid();} what opcode (by number) to try next
-     * when attempting to match an opcode to particular arguments;
-     * {@code Opcodes.NO_NEXT} to indicate that this is the last
-     * opcode to try in a particular chain
-     */
-    private final int nextOpcode;
-
-    /** {@code non-null;} the instruction format */
-    private final InsnFormat format;
-
-    /** whether this opcode uses a result register */
-    private final boolean hasResult;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code Opcodes.isValid();} the opcode value
-     * itself
-     * @param family {@code Opcodes.isValid();} the opcode family
-     * @param nextOpcode {@code Opcodes.isValid();} what opcode (by
-     * number) to try next when attempting to match an opcode to
-     * particular arguments; {@code Opcodes.NO_NEXT} to indicate that
-     * this is the last opcode to try in a particular chain
-     * @param format {@code non-null;} the instruction format
-     * @param hasResult whether the opcode has a result register; if so it
-     * is always the first register
-     */
-    public Dop(int opcode, int family, int nextOpcode, InsnFormat format,
-            boolean hasResult) {
-        if (!Opcodes.isValidShape(opcode)) {
-            throw new IllegalArgumentException("bogus opcode");
-        }
-
-        if (!Opcodes.isValidShape(family)) {
-            throw new IllegalArgumentException("bogus family");
-        }
-
-        if (!Opcodes.isValidShape(nextOpcode)) {
-            throw new IllegalArgumentException("bogus nextOpcode");
-        }
-
-        if (format == null) {
-            throw new NullPointerException("format == null");
-        }
-
-        this.opcode = opcode;
-        this.family = family;
-        this.nextOpcode = nextOpcode;
-        this.format = format;
-        this.hasResult = hasResult;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return getName();
-    }
-
-    /**
-     * Gets the opcode value.
-     *
-     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value
-     */
-    public int getOpcode() {
-        return opcode;
-    }
-
-    /**
-     * Gets the opcode family. The opcode family is the unmarked (no
-     * "/...") opcode that has equivalent semantics to this one.
-     *
-     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode family
-     */
-    public int getFamily() {
-        return family;
-    }
-
-    /**
-     * Gets the instruction format.
-     *
-     * @return {@code non-null;} the instruction format
-     */
-    public InsnFormat getFormat() {
-        return format;
-    }
-
-    /**
-     * Returns whether this opcode uses a result register.
-     *
-     * @return {@code true} iff this opcode uses a result register
-     */
-    public boolean hasResult() {
-        return hasResult;
-    }
-
-    /**
-     * Gets the opcode name.
-     *
-     * @return {@code non-null;} the opcode name
-     */
-    public String getName() {
-        return OpcodeInfo.getName(opcode);
-    }
-
-    /**
-     * Gets the opcode value to try next when attempting to match an
-     * opcode to particular arguments. This returns {@code
-     * Opcodes.NO_NEXT} to indicate that this is the last opcode to
-     * try in a particular chain.
-     *
-     * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value
-     */
-    public int getNextOpcode() {
-        return nextOpcode;
-    }
-
-    /**
-     * Gets the opcode for the opposite test of this instance. This is only
-     * valid for opcodes which are in fact tests.
-     *
-     * @return {@code non-null;} the opposite test
-     */
-    public Dop getOppositeTest() {
-        switch (opcode) {
-            case Opcodes.IF_EQ:  return Dops.IF_NE;
-            case Opcodes.IF_NE:  return Dops.IF_EQ;
-            case Opcodes.IF_LT:  return Dops.IF_GE;
-            case Opcodes.IF_GE:  return Dops.IF_LT;
-            case Opcodes.IF_GT:  return Dops.IF_LE;
-            case Opcodes.IF_LE:  return Dops.IF_GT;
-            case Opcodes.IF_EQZ: return Dops.IF_NEZ;
-            case Opcodes.IF_NEZ: return Dops.IF_EQZ;
-            case Opcodes.IF_LTZ: return Dops.IF_GEZ;
-            case Opcodes.IF_GEZ: return Dops.IF_LTZ;
-            case Opcodes.IF_GTZ: return Dops.IF_LEZ;
-            case Opcodes.IF_LEZ: return Dops.IF_GTZ;
-        }
-
-        throw new IllegalArgumentException("bogus opcode: " + this);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/Dops.java b/dx/src/main/java/com/android/dx/dex/code/Dops.java
deleted file mode 100644
index c066252..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/Dops.java
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.dex.DexOptions;
-import com.android.dx.dex.code.form.Form10t;
-import com.android.dx.dex.code.form.Form10x;
-import com.android.dx.dex.code.form.Form11n;
-import com.android.dx.dex.code.form.Form11x;
-import com.android.dx.dex.code.form.Form12x;
-import com.android.dx.dex.code.form.Form20t;
-import com.android.dx.dex.code.form.Form21c;
-import com.android.dx.dex.code.form.Form21h;
-import com.android.dx.dex.code.form.Form21s;
-import com.android.dx.dex.code.form.Form21t;
-import com.android.dx.dex.code.form.Form22b;
-import com.android.dx.dex.code.form.Form22c;
-import com.android.dx.dex.code.form.Form22s;
-import com.android.dx.dex.code.form.Form22t;
-import com.android.dx.dex.code.form.Form22x;
-import com.android.dx.dex.code.form.Form23x;
-import com.android.dx.dex.code.form.Form30t;
-import com.android.dx.dex.code.form.Form31c;
-import com.android.dx.dex.code.form.Form31i;
-import com.android.dx.dex.code.form.Form31t;
-import com.android.dx.dex.code.form.Form32x;
-import com.android.dx.dex.code.form.Form35c;
-import com.android.dx.dex.code.form.Form3rc;
-import com.android.dx.dex.code.form.Form41c;
-import com.android.dx.dex.code.form.Form51l;
-import com.android.dx.dex.code.form.Form52c;
-import com.android.dx.dex.code.form.Form5rc;
-import com.android.dx.dex.code.form.SpecialFormat;
-import com.android.dx.io.Opcodes;
-
-/**
- * Standard instances of {@link Dop} and utility methods for getting
- * them.
- */
-public final class Dops {
-    /** {@code non-null;} array containing all the standard instances */
-    private static final Dop[] DOPS;
-
-    /**
-     * pseudo-opcode used for nonstandard formatted "instructions"
-     * (which are mostly not actually instructions, though they do
-     * appear in instruction lists). TODO: Retire the usage of this
-     * constant.
-     */
-    public static final Dop SPECIAL_FORMAT =
-        new Dop(Opcodes.SPECIAL_FORMAT, Opcodes.SPECIAL_FORMAT,
-                Opcodes.NO_NEXT, SpecialFormat.THE_ONE, false);
-
-    // BEGIN(dops); GENERATED AUTOMATICALLY BY opcode-gen
-    public static final Dop NOP =
-        new Dop(Opcodes.NOP, Opcodes.NOP,
-            Opcodes.NO_NEXT, Form10x.THE_ONE, false);
-
-    public static final Dop MOVE =
-        new Dop(Opcodes.MOVE, Opcodes.MOVE,
-            Opcodes.MOVE_FROM16, Form12x.THE_ONE, true);
-
-    public static final Dop MOVE_FROM16 =
-        new Dop(Opcodes.MOVE_FROM16, Opcodes.MOVE,
-            Opcodes.MOVE_16, Form22x.THE_ONE, true);
-
-    public static final Dop MOVE_16 =
-        new Dop(Opcodes.MOVE_16, Opcodes.MOVE,
-            Opcodes.NO_NEXT, Form32x.THE_ONE, true);
-
-    public static final Dop MOVE_WIDE =
-        new Dop(Opcodes.MOVE_WIDE, Opcodes.MOVE_WIDE,
-            Opcodes.MOVE_WIDE_FROM16, Form12x.THE_ONE, true);
-
-    public static final Dop MOVE_WIDE_FROM16 =
-        new Dop(Opcodes.MOVE_WIDE_FROM16, Opcodes.MOVE_WIDE,
-            Opcodes.MOVE_WIDE_16, Form22x.THE_ONE, true);
-
-    public static final Dop MOVE_WIDE_16 =
-        new Dop(Opcodes.MOVE_WIDE_16, Opcodes.MOVE_WIDE,
-            Opcodes.NO_NEXT, Form32x.THE_ONE, true);
-
-    public static final Dop MOVE_OBJECT =
-        new Dop(Opcodes.MOVE_OBJECT, Opcodes.MOVE_OBJECT,
-            Opcodes.MOVE_OBJECT_FROM16, Form12x.THE_ONE, true);
-
-    public static final Dop MOVE_OBJECT_FROM16 =
-        new Dop(Opcodes.MOVE_OBJECT_FROM16, Opcodes.MOVE_OBJECT,
-            Opcodes.MOVE_OBJECT_16, Form22x.THE_ONE, true);
-
-    public static final Dop MOVE_OBJECT_16 =
-        new Dop(Opcodes.MOVE_OBJECT_16, Opcodes.MOVE_OBJECT,
-            Opcodes.NO_NEXT, Form32x.THE_ONE, true);
-
-    public static final Dop MOVE_RESULT =
-        new Dop(Opcodes.MOVE_RESULT, Opcodes.MOVE_RESULT,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, true);
-
-    public static final Dop MOVE_RESULT_WIDE =
-        new Dop(Opcodes.MOVE_RESULT_WIDE, Opcodes.MOVE_RESULT_WIDE,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, true);
-
-    public static final Dop MOVE_RESULT_OBJECT =
-        new Dop(Opcodes.MOVE_RESULT_OBJECT, Opcodes.MOVE_RESULT_OBJECT,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, true);
-
-    public static final Dop MOVE_EXCEPTION =
-        new Dop(Opcodes.MOVE_EXCEPTION, Opcodes.MOVE_EXCEPTION,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, true);
-
-    public static final Dop RETURN_VOID =
-        new Dop(Opcodes.RETURN_VOID, Opcodes.RETURN_VOID,
-            Opcodes.NO_NEXT, Form10x.THE_ONE, false);
-
-    public static final Dop RETURN =
-        new Dop(Opcodes.RETURN, Opcodes.RETURN,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop RETURN_WIDE =
-        new Dop(Opcodes.RETURN_WIDE, Opcodes.RETURN_WIDE,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop RETURN_OBJECT =
-        new Dop(Opcodes.RETURN_OBJECT, Opcodes.RETURN_OBJECT,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop CONST_4 =
-        new Dop(Opcodes.CONST_4, Opcodes.CONST,
-            Opcodes.CONST_16, Form11n.THE_ONE, true);
-
-    public static final Dop CONST_16 =
-        new Dop(Opcodes.CONST_16, Opcodes.CONST,
-            Opcodes.CONST_HIGH16, Form21s.THE_ONE, true);
-
-    public static final Dop CONST =
-        new Dop(Opcodes.CONST, Opcodes.CONST,
-            Opcodes.NO_NEXT, Form31i.THE_ONE, true);
-
-    public static final Dop CONST_HIGH16 =
-        new Dop(Opcodes.CONST_HIGH16, Opcodes.CONST,
-            Opcodes.CONST, Form21h.THE_ONE, true);
-
-    public static final Dop CONST_WIDE_16 =
-        new Dop(Opcodes.CONST_WIDE_16, Opcodes.CONST_WIDE,
-            Opcodes.CONST_WIDE_HIGH16, Form21s.THE_ONE, true);
-
-    public static final Dop CONST_WIDE_32 =
-        new Dop(Opcodes.CONST_WIDE_32, Opcodes.CONST_WIDE,
-            Opcodes.CONST_WIDE, Form31i.THE_ONE, true);
-
-    public static final Dop CONST_WIDE =
-        new Dop(Opcodes.CONST_WIDE, Opcodes.CONST_WIDE,
-            Opcodes.NO_NEXT, Form51l.THE_ONE, true);
-
-    public static final Dop CONST_WIDE_HIGH16 =
-        new Dop(Opcodes.CONST_WIDE_HIGH16, Opcodes.CONST_WIDE,
-            Opcodes.CONST_WIDE_32, Form21h.THE_ONE, true);
-
-    public static final Dop CONST_STRING =
-        new Dop(Opcodes.CONST_STRING, Opcodes.CONST_STRING,
-            Opcodes.CONST_STRING_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop CONST_STRING_JUMBO =
-        new Dop(Opcodes.CONST_STRING_JUMBO, Opcodes.CONST_STRING,
-            Opcodes.NO_NEXT, Form31c.THE_ONE, true);
-
-    public static final Dop CONST_CLASS =
-        new Dop(Opcodes.CONST_CLASS, Opcodes.CONST_CLASS,
-            Opcodes.CONST_CLASS_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop MONITOR_ENTER =
-        new Dop(Opcodes.MONITOR_ENTER, Opcodes.MONITOR_ENTER,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop MONITOR_EXIT =
-        new Dop(Opcodes.MONITOR_EXIT, Opcodes.MONITOR_EXIT,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop CHECK_CAST =
-        new Dop(Opcodes.CHECK_CAST, Opcodes.CHECK_CAST,
-            Opcodes.CHECK_CAST_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop INSTANCE_OF =
-        new Dop(Opcodes.INSTANCE_OF, Opcodes.INSTANCE_OF,
-            Opcodes.INSTANCE_OF_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop ARRAY_LENGTH =
-        new Dop(Opcodes.ARRAY_LENGTH, Opcodes.ARRAY_LENGTH,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NEW_INSTANCE =
-        new Dop(Opcodes.NEW_INSTANCE, Opcodes.NEW_INSTANCE,
-            Opcodes.NEW_INSTANCE_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop NEW_ARRAY =
-        new Dop(Opcodes.NEW_ARRAY, Opcodes.NEW_ARRAY,
-            Opcodes.NEW_ARRAY_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop FILLED_NEW_ARRAY =
-        new Dop(Opcodes.FILLED_NEW_ARRAY, Opcodes.FILLED_NEW_ARRAY,
-            Opcodes.FILLED_NEW_ARRAY_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop FILLED_NEW_ARRAY_RANGE =
-        new Dop(Opcodes.FILLED_NEW_ARRAY_RANGE, Opcodes.FILLED_NEW_ARRAY,
-            Opcodes.FILLED_NEW_ARRAY_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop FILL_ARRAY_DATA =
-        new Dop(Opcodes.FILL_ARRAY_DATA, Opcodes.FILL_ARRAY_DATA,
-            Opcodes.NO_NEXT, Form31t.THE_ONE, false);
-
-    public static final Dop THROW =
-        new Dop(Opcodes.THROW, Opcodes.THROW,
-            Opcodes.NO_NEXT, Form11x.THE_ONE, false);
-
-    public static final Dop GOTO =
-        new Dop(Opcodes.GOTO, Opcodes.GOTO,
-            Opcodes.GOTO_16, Form10t.THE_ONE, false);
-
-    public static final Dop GOTO_16 =
-        new Dop(Opcodes.GOTO_16, Opcodes.GOTO,
-            Opcodes.GOTO_32, Form20t.THE_ONE, false);
-
-    public static final Dop GOTO_32 =
-        new Dop(Opcodes.GOTO_32, Opcodes.GOTO,
-            Opcodes.NO_NEXT, Form30t.THE_ONE, false);
-
-    public static final Dop PACKED_SWITCH =
-        new Dop(Opcodes.PACKED_SWITCH, Opcodes.PACKED_SWITCH,
-            Opcodes.NO_NEXT, Form31t.THE_ONE, false);
-
-    public static final Dop SPARSE_SWITCH =
-        new Dop(Opcodes.SPARSE_SWITCH, Opcodes.SPARSE_SWITCH,
-            Opcodes.NO_NEXT, Form31t.THE_ONE, false);
-
-    public static final Dop CMPL_FLOAT =
-        new Dop(Opcodes.CMPL_FLOAT, Opcodes.CMPL_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop CMPG_FLOAT =
-        new Dop(Opcodes.CMPG_FLOAT, Opcodes.CMPG_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop CMPL_DOUBLE =
-        new Dop(Opcodes.CMPL_DOUBLE, Opcodes.CMPL_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop CMPG_DOUBLE =
-        new Dop(Opcodes.CMPG_DOUBLE, Opcodes.CMPG_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop CMP_LONG =
-        new Dop(Opcodes.CMP_LONG, Opcodes.CMP_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop IF_EQ =
-        new Dop(Opcodes.IF_EQ, Opcodes.IF_EQ,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_NE =
-        new Dop(Opcodes.IF_NE, Opcodes.IF_NE,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_LT =
-        new Dop(Opcodes.IF_LT, Opcodes.IF_LT,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_GE =
-        new Dop(Opcodes.IF_GE, Opcodes.IF_GE,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_GT =
-        new Dop(Opcodes.IF_GT, Opcodes.IF_GT,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_LE =
-        new Dop(Opcodes.IF_LE, Opcodes.IF_LE,
-            Opcodes.NO_NEXT, Form22t.THE_ONE, false);
-
-    public static final Dop IF_EQZ =
-        new Dop(Opcodes.IF_EQZ, Opcodes.IF_EQZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop IF_NEZ =
-        new Dop(Opcodes.IF_NEZ, Opcodes.IF_NEZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop IF_LTZ =
-        new Dop(Opcodes.IF_LTZ, Opcodes.IF_LTZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop IF_GEZ =
-        new Dop(Opcodes.IF_GEZ, Opcodes.IF_GEZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop IF_GTZ =
-        new Dop(Opcodes.IF_GTZ, Opcodes.IF_GTZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop IF_LEZ =
-        new Dop(Opcodes.IF_LEZ, Opcodes.IF_LEZ,
-            Opcodes.NO_NEXT, Form21t.THE_ONE, false);
-
-    public static final Dop AGET =
-        new Dop(Opcodes.AGET, Opcodes.AGET,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_WIDE =
-        new Dop(Opcodes.AGET_WIDE, Opcodes.AGET_WIDE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_OBJECT =
-        new Dop(Opcodes.AGET_OBJECT, Opcodes.AGET_OBJECT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_BOOLEAN =
-        new Dop(Opcodes.AGET_BOOLEAN, Opcodes.AGET_BOOLEAN,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_BYTE =
-        new Dop(Opcodes.AGET_BYTE, Opcodes.AGET_BYTE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_CHAR =
-        new Dop(Opcodes.AGET_CHAR, Opcodes.AGET_CHAR,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AGET_SHORT =
-        new Dop(Opcodes.AGET_SHORT, Opcodes.AGET_SHORT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop APUT =
-        new Dop(Opcodes.APUT, Opcodes.APUT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_WIDE =
-        new Dop(Opcodes.APUT_WIDE, Opcodes.APUT_WIDE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_OBJECT =
-        new Dop(Opcodes.APUT_OBJECT, Opcodes.APUT_OBJECT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_BOOLEAN =
-        new Dop(Opcodes.APUT_BOOLEAN, Opcodes.APUT_BOOLEAN,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_BYTE =
-        new Dop(Opcodes.APUT_BYTE, Opcodes.APUT_BYTE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_CHAR =
-        new Dop(Opcodes.APUT_CHAR, Opcodes.APUT_CHAR,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop APUT_SHORT =
-        new Dop(Opcodes.APUT_SHORT, Opcodes.APUT_SHORT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, false);
-
-    public static final Dop IGET =
-        new Dop(Opcodes.IGET, Opcodes.IGET,
-            Opcodes.IGET_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_WIDE =
-        new Dop(Opcodes.IGET_WIDE, Opcodes.IGET_WIDE,
-            Opcodes.IGET_WIDE_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_OBJECT =
-        new Dop(Opcodes.IGET_OBJECT, Opcodes.IGET_OBJECT,
-            Opcodes.IGET_OBJECT_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_BOOLEAN =
-        new Dop(Opcodes.IGET_BOOLEAN, Opcodes.IGET_BOOLEAN,
-            Opcodes.IGET_BOOLEAN_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_BYTE =
-        new Dop(Opcodes.IGET_BYTE, Opcodes.IGET_BYTE,
-            Opcodes.IGET_BYTE_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_CHAR =
-        new Dop(Opcodes.IGET_CHAR, Opcodes.IGET_CHAR,
-            Opcodes.IGET_CHAR_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IGET_SHORT =
-        new Dop(Opcodes.IGET_SHORT, Opcodes.IGET_SHORT,
-            Opcodes.IGET_SHORT_JUMBO, Form22c.THE_ONE, true);
-
-    public static final Dop IPUT =
-        new Dop(Opcodes.IPUT, Opcodes.IPUT,
-            Opcodes.IPUT_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_WIDE =
-        new Dop(Opcodes.IPUT_WIDE, Opcodes.IPUT_WIDE,
-            Opcodes.IPUT_WIDE_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_OBJECT =
-        new Dop(Opcodes.IPUT_OBJECT, Opcodes.IPUT_OBJECT,
-            Opcodes.IPUT_OBJECT_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_BOOLEAN =
-        new Dop(Opcodes.IPUT_BOOLEAN, Opcodes.IPUT_BOOLEAN,
-            Opcodes.IPUT_BOOLEAN_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_BYTE =
-        new Dop(Opcodes.IPUT_BYTE, Opcodes.IPUT_BYTE,
-            Opcodes.IPUT_BYTE_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_CHAR =
-        new Dop(Opcodes.IPUT_CHAR, Opcodes.IPUT_CHAR,
-            Opcodes.IPUT_CHAR_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop IPUT_SHORT =
-        new Dop(Opcodes.IPUT_SHORT, Opcodes.IPUT_SHORT,
-            Opcodes.IPUT_SHORT_JUMBO, Form22c.THE_ONE, false);
-
-    public static final Dop SGET =
-        new Dop(Opcodes.SGET, Opcodes.SGET,
-            Opcodes.SGET_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_WIDE =
-        new Dop(Opcodes.SGET_WIDE, Opcodes.SGET_WIDE,
-            Opcodes.SGET_WIDE_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_OBJECT =
-        new Dop(Opcodes.SGET_OBJECT, Opcodes.SGET_OBJECT,
-            Opcodes.SGET_OBJECT_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_BOOLEAN =
-        new Dop(Opcodes.SGET_BOOLEAN, Opcodes.SGET_BOOLEAN,
-            Opcodes.SGET_BOOLEAN_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_BYTE =
-        new Dop(Opcodes.SGET_BYTE, Opcodes.SGET_BYTE,
-            Opcodes.SGET_BYTE_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_CHAR =
-        new Dop(Opcodes.SGET_CHAR, Opcodes.SGET_CHAR,
-            Opcodes.SGET_CHAR_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SGET_SHORT =
-        new Dop(Opcodes.SGET_SHORT, Opcodes.SGET_SHORT,
-            Opcodes.SGET_SHORT_JUMBO, Form21c.THE_ONE, true);
-
-    public static final Dop SPUT =
-        new Dop(Opcodes.SPUT, Opcodes.SPUT,
-            Opcodes.SPUT_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_WIDE =
-        new Dop(Opcodes.SPUT_WIDE, Opcodes.SPUT_WIDE,
-            Opcodes.SPUT_WIDE_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_OBJECT =
-        new Dop(Opcodes.SPUT_OBJECT, Opcodes.SPUT_OBJECT,
-            Opcodes.SPUT_OBJECT_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_BOOLEAN =
-        new Dop(Opcodes.SPUT_BOOLEAN, Opcodes.SPUT_BOOLEAN,
-            Opcodes.SPUT_BOOLEAN_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_BYTE =
-        new Dop(Opcodes.SPUT_BYTE, Opcodes.SPUT_BYTE,
-            Opcodes.SPUT_BYTE_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_CHAR =
-        new Dop(Opcodes.SPUT_CHAR, Opcodes.SPUT_CHAR,
-            Opcodes.SPUT_CHAR_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop SPUT_SHORT =
-        new Dop(Opcodes.SPUT_SHORT, Opcodes.SPUT_SHORT,
-            Opcodes.SPUT_SHORT_JUMBO, Form21c.THE_ONE, false);
-
-    public static final Dop INVOKE_VIRTUAL =
-        new Dop(Opcodes.INVOKE_VIRTUAL, Opcodes.INVOKE_VIRTUAL,
-            Opcodes.INVOKE_VIRTUAL_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop INVOKE_SUPER =
-        new Dop(Opcodes.INVOKE_SUPER, Opcodes.INVOKE_SUPER,
-            Opcodes.INVOKE_SUPER_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop INVOKE_DIRECT =
-        new Dop(Opcodes.INVOKE_DIRECT, Opcodes.INVOKE_DIRECT,
-            Opcodes.INVOKE_DIRECT_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop INVOKE_STATIC =
-        new Dop(Opcodes.INVOKE_STATIC, Opcodes.INVOKE_STATIC,
-            Opcodes.INVOKE_STATIC_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop INVOKE_INTERFACE =
-        new Dop(Opcodes.INVOKE_INTERFACE, Opcodes.INVOKE_INTERFACE,
-            Opcodes.INVOKE_INTERFACE_RANGE, Form35c.THE_ONE, false);
-
-    public static final Dop INVOKE_VIRTUAL_RANGE =
-        new Dop(Opcodes.INVOKE_VIRTUAL_RANGE, Opcodes.INVOKE_VIRTUAL,
-            Opcodes.INVOKE_VIRTUAL_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop INVOKE_SUPER_RANGE =
-        new Dop(Opcodes.INVOKE_SUPER_RANGE, Opcodes.INVOKE_SUPER,
-            Opcodes.INVOKE_SUPER_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop INVOKE_DIRECT_RANGE =
-        new Dop(Opcodes.INVOKE_DIRECT_RANGE, Opcodes.INVOKE_DIRECT,
-            Opcodes.INVOKE_DIRECT_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop INVOKE_STATIC_RANGE =
-        new Dop(Opcodes.INVOKE_STATIC_RANGE, Opcodes.INVOKE_STATIC,
-            Opcodes.INVOKE_STATIC_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop INVOKE_INTERFACE_RANGE =
-        new Dop(Opcodes.INVOKE_INTERFACE_RANGE, Opcodes.INVOKE_INTERFACE,
-            Opcodes.INVOKE_INTERFACE_JUMBO, Form3rc.THE_ONE, false);
-
-    public static final Dop NEG_INT =
-        new Dop(Opcodes.NEG_INT, Opcodes.NEG_INT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NOT_INT =
-        new Dop(Opcodes.NOT_INT, Opcodes.NOT_INT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NEG_LONG =
-        new Dop(Opcodes.NEG_LONG, Opcodes.NEG_LONG,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NOT_LONG =
-        new Dop(Opcodes.NOT_LONG, Opcodes.NOT_LONG,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NEG_FLOAT =
-        new Dop(Opcodes.NEG_FLOAT, Opcodes.NEG_FLOAT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop NEG_DOUBLE =
-        new Dop(Opcodes.NEG_DOUBLE, Opcodes.NEG_DOUBLE,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_LONG =
-        new Dop(Opcodes.INT_TO_LONG, Opcodes.INT_TO_LONG,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_FLOAT =
-        new Dop(Opcodes.INT_TO_FLOAT, Opcodes.INT_TO_FLOAT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_DOUBLE =
-        new Dop(Opcodes.INT_TO_DOUBLE, Opcodes.INT_TO_DOUBLE,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop LONG_TO_INT =
-        new Dop(Opcodes.LONG_TO_INT, Opcodes.LONG_TO_INT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop LONG_TO_FLOAT =
-        new Dop(Opcodes.LONG_TO_FLOAT, Opcodes.LONG_TO_FLOAT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop LONG_TO_DOUBLE =
-        new Dop(Opcodes.LONG_TO_DOUBLE, Opcodes.LONG_TO_DOUBLE,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop FLOAT_TO_INT =
-        new Dop(Opcodes.FLOAT_TO_INT, Opcodes.FLOAT_TO_INT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop FLOAT_TO_LONG =
-        new Dop(Opcodes.FLOAT_TO_LONG, Opcodes.FLOAT_TO_LONG,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop FLOAT_TO_DOUBLE =
-        new Dop(Opcodes.FLOAT_TO_DOUBLE, Opcodes.FLOAT_TO_DOUBLE,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop DOUBLE_TO_INT =
-        new Dop(Opcodes.DOUBLE_TO_INT, Opcodes.DOUBLE_TO_INT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop DOUBLE_TO_LONG =
-        new Dop(Opcodes.DOUBLE_TO_LONG, Opcodes.DOUBLE_TO_LONG,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop DOUBLE_TO_FLOAT =
-        new Dop(Opcodes.DOUBLE_TO_FLOAT, Opcodes.DOUBLE_TO_FLOAT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_BYTE =
-        new Dop(Opcodes.INT_TO_BYTE, Opcodes.INT_TO_BYTE,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_CHAR =
-        new Dop(Opcodes.INT_TO_CHAR, Opcodes.INT_TO_CHAR,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop INT_TO_SHORT =
-        new Dop(Opcodes.INT_TO_SHORT, Opcodes.INT_TO_SHORT,
-            Opcodes.NO_NEXT, Form12x.THE_ONE, true);
-
-    public static final Dop ADD_INT =
-        new Dop(Opcodes.ADD_INT, Opcodes.ADD_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SUB_INT =
-        new Dop(Opcodes.SUB_INT, Opcodes.SUB_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop MUL_INT =
-        new Dop(Opcodes.MUL_INT, Opcodes.MUL_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop DIV_INT =
-        new Dop(Opcodes.DIV_INT, Opcodes.DIV_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop REM_INT =
-        new Dop(Opcodes.REM_INT, Opcodes.REM_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AND_INT =
-        new Dop(Opcodes.AND_INT, Opcodes.AND_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop OR_INT =
-        new Dop(Opcodes.OR_INT, Opcodes.OR_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop XOR_INT =
-        new Dop(Opcodes.XOR_INT, Opcodes.XOR_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SHL_INT =
-        new Dop(Opcodes.SHL_INT, Opcodes.SHL_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SHR_INT =
-        new Dop(Opcodes.SHR_INT, Opcodes.SHR_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop USHR_INT =
-        new Dop(Opcodes.USHR_INT, Opcodes.USHR_INT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop ADD_LONG =
-        new Dop(Opcodes.ADD_LONG, Opcodes.ADD_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SUB_LONG =
-        new Dop(Opcodes.SUB_LONG, Opcodes.SUB_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop MUL_LONG =
-        new Dop(Opcodes.MUL_LONG, Opcodes.MUL_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop DIV_LONG =
-        new Dop(Opcodes.DIV_LONG, Opcodes.DIV_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop REM_LONG =
-        new Dop(Opcodes.REM_LONG, Opcodes.REM_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop AND_LONG =
-        new Dop(Opcodes.AND_LONG, Opcodes.AND_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop OR_LONG =
-        new Dop(Opcodes.OR_LONG, Opcodes.OR_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop XOR_LONG =
-        new Dop(Opcodes.XOR_LONG, Opcodes.XOR_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SHL_LONG =
-        new Dop(Opcodes.SHL_LONG, Opcodes.SHL_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SHR_LONG =
-        new Dop(Opcodes.SHR_LONG, Opcodes.SHR_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop USHR_LONG =
-        new Dop(Opcodes.USHR_LONG, Opcodes.USHR_LONG,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop ADD_FLOAT =
-        new Dop(Opcodes.ADD_FLOAT, Opcodes.ADD_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SUB_FLOAT =
-        new Dop(Opcodes.SUB_FLOAT, Opcodes.SUB_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop MUL_FLOAT =
-        new Dop(Opcodes.MUL_FLOAT, Opcodes.MUL_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop DIV_FLOAT =
-        new Dop(Opcodes.DIV_FLOAT, Opcodes.DIV_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop REM_FLOAT =
-        new Dop(Opcodes.REM_FLOAT, Opcodes.REM_FLOAT,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop ADD_DOUBLE =
-        new Dop(Opcodes.ADD_DOUBLE, Opcodes.ADD_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop SUB_DOUBLE =
-        new Dop(Opcodes.SUB_DOUBLE, Opcodes.SUB_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop MUL_DOUBLE =
-        new Dop(Opcodes.MUL_DOUBLE, Opcodes.MUL_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop DIV_DOUBLE =
-        new Dop(Opcodes.DIV_DOUBLE, Opcodes.DIV_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop REM_DOUBLE =
-        new Dop(Opcodes.REM_DOUBLE, Opcodes.REM_DOUBLE,
-            Opcodes.NO_NEXT, Form23x.THE_ONE, true);
-
-    public static final Dop ADD_INT_2ADDR =
-        new Dop(Opcodes.ADD_INT_2ADDR, Opcodes.ADD_INT,
-            Opcodes.ADD_INT, Form12x.THE_ONE, true);
-
-    public static final Dop SUB_INT_2ADDR =
-        new Dop(Opcodes.SUB_INT_2ADDR, Opcodes.SUB_INT,
-            Opcodes.SUB_INT, Form12x.THE_ONE, true);
-
-    public static final Dop MUL_INT_2ADDR =
-        new Dop(Opcodes.MUL_INT_2ADDR, Opcodes.MUL_INT,
-            Opcodes.MUL_INT, Form12x.THE_ONE, true);
-
-    public static final Dop DIV_INT_2ADDR =
-        new Dop(Opcodes.DIV_INT_2ADDR, Opcodes.DIV_INT,
-            Opcodes.DIV_INT, Form12x.THE_ONE, true);
-
-    public static final Dop REM_INT_2ADDR =
-        new Dop(Opcodes.REM_INT_2ADDR, Opcodes.REM_INT,
-            Opcodes.REM_INT, Form12x.THE_ONE, true);
-
-    public static final Dop AND_INT_2ADDR =
-        new Dop(Opcodes.AND_INT_2ADDR, Opcodes.AND_INT,
-            Opcodes.AND_INT, Form12x.THE_ONE, true);
-
-    public static final Dop OR_INT_2ADDR =
-        new Dop(Opcodes.OR_INT_2ADDR, Opcodes.OR_INT,
-            Opcodes.OR_INT, Form12x.THE_ONE, true);
-
-    public static final Dop XOR_INT_2ADDR =
-        new Dop(Opcodes.XOR_INT_2ADDR, Opcodes.XOR_INT,
-            Opcodes.XOR_INT, Form12x.THE_ONE, true);
-
-    public static final Dop SHL_INT_2ADDR =
-        new Dop(Opcodes.SHL_INT_2ADDR, Opcodes.SHL_INT,
-            Opcodes.SHL_INT, Form12x.THE_ONE, true);
-
-    public static final Dop SHR_INT_2ADDR =
-        new Dop(Opcodes.SHR_INT_2ADDR, Opcodes.SHR_INT,
-            Opcodes.SHR_INT, Form12x.THE_ONE, true);
-
-    public static final Dop USHR_INT_2ADDR =
-        new Dop(Opcodes.USHR_INT_2ADDR, Opcodes.USHR_INT,
-            Opcodes.USHR_INT, Form12x.THE_ONE, true);
-
-    public static final Dop ADD_LONG_2ADDR =
-        new Dop(Opcodes.ADD_LONG_2ADDR, Opcodes.ADD_LONG,
-            Opcodes.ADD_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop SUB_LONG_2ADDR =
-        new Dop(Opcodes.SUB_LONG_2ADDR, Opcodes.SUB_LONG,
-            Opcodes.SUB_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop MUL_LONG_2ADDR =
-        new Dop(Opcodes.MUL_LONG_2ADDR, Opcodes.MUL_LONG,
-            Opcodes.MUL_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop DIV_LONG_2ADDR =
-        new Dop(Opcodes.DIV_LONG_2ADDR, Opcodes.DIV_LONG,
-            Opcodes.DIV_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop REM_LONG_2ADDR =
-        new Dop(Opcodes.REM_LONG_2ADDR, Opcodes.REM_LONG,
-            Opcodes.REM_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop AND_LONG_2ADDR =
-        new Dop(Opcodes.AND_LONG_2ADDR, Opcodes.AND_LONG,
-            Opcodes.AND_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop OR_LONG_2ADDR =
-        new Dop(Opcodes.OR_LONG_2ADDR, Opcodes.OR_LONG,
-            Opcodes.OR_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop XOR_LONG_2ADDR =
-        new Dop(Opcodes.XOR_LONG_2ADDR, Opcodes.XOR_LONG,
-            Opcodes.XOR_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop SHL_LONG_2ADDR =
-        new Dop(Opcodes.SHL_LONG_2ADDR, Opcodes.SHL_LONG,
-            Opcodes.SHL_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop SHR_LONG_2ADDR =
-        new Dop(Opcodes.SHR_LONG_2ADDR, Opcodes.SHR_LONG,
-            Opcodes.SHR_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop USHR_LONG_2ADDR =
-        new Dop(Opcodes.USHR_LONG_2ADDR, Opcodes.USHR_LONG,
-            Opcodes.USHR_LONG, Form12x.THE_ONE, true);
-
-    public static final Dop ADD_FLOAT_2ADDR =
-        new Dop(Opcodes.ADD_FLOAT_2ADDR, Opcodes.ADD_FLOAT,
-            Opcodes.ADD_FLOAT, Form12x.THE_ONE, true);
-
-    public static final Dop SUB_FLOAT_2ADDR =
-        new Dop(Opcodes.SUB_FLOAT_2ADDR, Opcodes.SUB_FLOAT,
-            Opcodes.SUB_FLOAT, Form12x.THE_ONE, true);
-
-    public static final Dop MUL_FLOAT_2ADDR =
-        new Dop(Opcodes.MUL_FLOAT_2ADDR, Opcodes.MUL_FLOAT,
-            Opcodes.MUL_FLOAT, Form12x.THE_ONE, true);
-
-    public static final Dop DIV_FLOAT_2ADDR =
-        new Dop(Opcodes.DIV_FLOAT_2ADDR, Opcodes.DIV_FLOAT,
-            Opcodes.DIV_FLOAT, Form12x.THE_ONE, true);
-
-    public static final Dop REM_FLOAT_2ADDR =
-        new Dop(Opcodes.REM_FLOAT_2ADDR, Opcodes.REM_FLOAT,
-            Opcodes.REM_FLOAT, Form12x.THE_ONE, true);
-
-    public static final Dop ADD_DOUBLE_2ADDR =
-        new Dop(Opcodes.ADD_DOUBLE_2ADDR, Opcodes.ADD_DOUBLE,
-            Opcodes.ADD_DOUBLE, Form12x.THE_ONE, true);
-
-    public static final Dop SUB_DOUBLE_2ADDR =
-        new Dop(Opcodes.SUB_DOUBLE_2ADDR, Opcodes.SUB_DOUBLE,
-            Opcodes.SUB_DOUBLE, Form12x.THE_ONE, true);
-
-    public static final Dop MUL_DOUBLE_2ADDR =
-        new Dop(Opcodes.MUL_DOUBLE_2ADDR, Opcodes.MUL_DOUBLE,
-            Opcodes.MUL_DOUBLE, Form12x.THE_ONE, true);
-
-    public static final Dop DIV_DOUBLE_2ADDR =
-        new Dop(Opcodes.DIV_DOUBLE_2ADDR, Opcodes.DIV_DOUBLE,
-            Opcodes.DIV_DOUBLE, Form12x.THE_ONE, true);
-
-    public static final Dop REM_DOUBLE_2ADDR =
-        new Dop(Opcodes.REM_DOUBLE_2ADDR, Opcodes.REM_DOUBLE,
-            Opcodes.REM_DOUBLE, Form12x.THE_ONE, true);
-
-    public static final Dop ADD_INT_LIT16 =
-        new Dop(Opcodes.ADD_INT_LIT16, Opcodes.ADD_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop RSUB_INT =
-        new Dop(Opcodes.RSUB_INT, Opcodes.RSUB_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop MUL_INT_LIT16 =
-        new Dop(Opcodes.MUL_INT_LIT16, Opcodes.MUL_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop DIV_INT_LIT16 =
-        new Dop(Opcodes.DIV_INT_LIT16, Opcodes.DIV_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop REM_INT_LIT16 =
-        new Dop(Opcodes.REM_INT_LIT16, Opcodes.REM_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop AND_INT_LIT16 =
-        new Dop(Opcodes.AND_INT_LIT16, Opcodes.AND_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop OR_INT_LIT16 =
-        new Dop(Opcodes.OR_INT_LIT16, Opcodes.OR_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop XOR_INT_LIT16 =
-        new Dop(Opcodes.XOR_INT_LIT16, Opcodes.XOR_INT,
-            Opcodes.NO_NEXT, Form22s.THE_ONE, true);
-
-    public static final Dop ADD_INT_LIT8 =
-        new Dop(Opcodes.ADD_INT_LIT8, Opcodes.ADD_INT,
-            Opcodes.ADD_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop RSUB_INT_LIT8 =
-        new Dop(Opcodes.RSUB_INT_LIT8, Opcodes.RSUB_INT,
-            Opcodes.RSUB_INT, Form22b.THE_ONE, true);
-
-    public static final Dop MUL_INT_LIT8 =
-        new Dop(Opcodes.MUL_INT_LIT8, Opcodes.MUL_INT,
-            Opcodes.MUL_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop DIV_INT_LIT8 =
-        new Dop(Opcodes.DIV_INT_LIT8, Opcodes.DIV_INT,
-            Opcodes.DIV_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop REM_INT_LIT8 =
-        new Dop(Opcodes.REM_INT_LIT8, Opcodes.REM_INT,
-            Opcodes.REM_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop AND_INT_LIT8 =
-        new Dop(Opcodes.AND_INT_LIT8, Opcodes.AND_INT,
-            Opcodes.AND_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop OR_INT_LIT8 =
-        new Dop(Opcodes.OR_INT_LIT8, Opcodes.OR_INT,
-            Opcodes.OR_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop XOR_INT_LIT8 =
-        new Dop(Opcodes.XOR_INT_LIT8, Opcodes.XOR_INT,
-            Opcodes.XOR_INT_LIT16, Form22b.THE_ONE, true);
-
-    public static final Dop SHL_INT_LIT8 =
-        new Dop(Opcodes.SHL_INT_LIT8, Opcodes.SHL_INT,
-            Opcodes.NO_NEXT, Form22b.THE_ONE, true);
-
-    public static final Dop SHR_INT_LIT8 =
-        new Dop(Opcodes.SHR_INT_LIT8, Opcodes.SHR_INT,
-            Opcodes.NO_NEXT, Form22b.THE_ONE, true);
-
-    public static final Dop USHR_INT_LIT8 =
-        new Dop(Opcodes.USHR_INT_LIT8, Opcodes.USHR_INT,
-            Opcodes.NO_NEXT, Form22b.THE_ONE, true);
-
-    public static final Dop CONST_CLASS_JUMBO =
-        new Dop(Opcodes.CONST_CLASS_JUMBO, Opcodes.CONST_CLASS,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop CHECK_CAST_JUMBO =
-        new Dop(Opcodes.CHECK_CAST_JUMBO, Opcodes.CHECK_CAST,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop INSTANCE_OF_JUMBO =
-        new Dop(Opcodes.INSTANCE_OF_JUMBO, Opcodes.INSTANCE_OF,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop NEW_INSTANCE_JUMBO =
-        new Dop(Opcodes.NEW_INSTANCE_JUMBO, Opcodes.NEW_INSTANCE,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop NEW_ARRAY_JUMBO =
-        new Dop(Opcodes.NEW_ARRAY_JUMBO, Opcodes.NEW_ARRAY,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop FILLED_NEW_ARRAY_JUMBO =
-        new Dop(Opcodes.FILLED_NEW_ARRAY_JUMBO, Opcodes.FILLED_NEW_ARRAY,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    public static final Dop IGET_JUMBO =
-        new Dop(Opcodes.IGET_JUMBO, Opcodes.IGET,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_WIDE_JUMBO =
-        new Dop(Opcodes.IGET_WIDE_JUMBO, Opcodes.IGET_WIDE,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_OBJECT_JUMBO =
-        new Dop(Opcodes.IGET_OBJECT_JUMBO, Opcodes.IGET_OBJECT,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_BOOLEAN_JUMBO =
-        new Dop(Opcodes.IGET_BOOLEAN_JUMBO, Opcodes.IGET_BOOLEAN,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_BYTE_JUMBO =
-        new Dop(Opcodes.IGET_BYTE_JUMBO, Opcodes.IGET_BYTE,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_CHAR_JUMBO =
-        new Dop(Opcodes.IGET_CHAR_JUMBO, Opcodes.IGET_CHAR,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IGET_SHORT_JUMBO =
-        new Dop(Opcodes.IGET_SHORT_JUMBO, Opcodes.IGET_SHORT,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
-    public static final Dop IPUT_JUMBO =
-        new Dop(Opcodes.IPUT_JUMBO, Opcodes.IPUT,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_WIDE_JUMBO =
-        new Dop(Opcodes.IPUT_WIDE_JUMBO, Opcodes.IPUT_WIDE,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_OBJECT_JUMBO =
-        new Dop(Opcodes.IPUT_OBJECT_JUMBO, Opcodes.IPUT_OBJECT,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_BOOLEAN_JUMBO =
-        new Dop(Opcodes.IPUT_BOOLEAN_JUMBO, Opcodes.IPUT_BOOLEAN,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_BYTE_JUMBO =
-        new Dop(Opcodes.IPUT_BYTE_JUMBO, Opcodes.IPUT_BYTE,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_CHAR_JUMBO =
-        new Dop(Opcodes.IPUT_CHAR_JUMBO, Opcodes.IPUT_CHAR,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop IPUT_SHORT_JUMBO =
-        new Dop(Opcodes.IPUT_SHORT_JUMBO, Opcodes.IPUT_SHORT,
-            Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
-    public static final Dop SGET_JUMBO =
-        new Dop(Opcodes.SGET_JUMBO, Opcodes.SGET,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_WIDE_JUMBO =
-        new Dop(Opcodes.SGET_WIDE_JUMBO, Opcodes.SGET_WIDE,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_OBJECT_JUMBO =
-        new Dop(Opcodes.SGET_OBJECT_JUMBO, Opcodes.SGET_OBJECT,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_BOOLEAN_JUMBO =
-        new Dop(Opcodes.SGET_BOOLEAN_JUMBO, Opcodes.SGET_BOOLEAN,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_BYTE_JUMBO =
-        new Dop(Opcodes.SGET_BYTE_JUMBO, Opcodes.SGET_BYTE,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_CHAR_JUMBO =
-        new Dop(Opcodes.SGET_CHAR_JUMBO, Opcodes.SGET_CHAR,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SGET_SHORT_JUMBO =
-        new Dop(Opcodes.SGET_SHORT_JUMBO, Opcodes.SGET_SHORT,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
-    public static final Dop SPUT_JUMBO =
-        new Dop(Opcodes.SPUT_JUMBO, Opcodes.SPUT,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_WIDE_JUMBO =
-        new Dop(Opcodes.SPUT_WIDE_JUMBO, Opcodes.SPUT_WIDE,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_OBJECT_JUMBO =
-        new Dop(Opcodes.SPUT_OBJECT_JUMBO, Opcodes.SPUT_OBJECT,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_BOOLEAN_JUMBO =
-        new Dop(Opcodes.SPUT_BOOLEAN_JUMBO, Opcodes.SPUT_BOOLEAN,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_BYTE_JUMBO =
-        new Dop(Opcodes.SPUT_BYTE_JUMBO, Opcodes.SPUT_BYTE,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_CHAR_JUMBO =
-        new Dop(Opcodes.SPUT_CHAR_JUMBO, Opcodes.SPUT_CHAR,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop SPUT_SHORT_JUMBO =
-        new Dop(Opcodes.SPUT_SHORT_JUMBO, Opcodes.SPUT_SHORT,
-            Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
-    public static final Dop INVOKE_VIRTUAL_JUMBO =
-        new Dop(Opcodes.INVOKE_VIRTUAL_JUMBO, Opcodes.INVOKE_VIRTUAL,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    public static final Dop INVOKE_SUPER_JUMBO =
-        new Dop(Opcodes.INVOKE_SUPER_JUMBO, Opcodes.INVOKE_SUPER,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    public static final Dop INVOKE_DIRECT_JUMBO =
-        new Dop(Opcodes.INVOKE_DIRECT_JUMBO, Opcodes.INVOKE_DIRECT,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    public static final Dop INVOKE_STATIC_JUMBO =
-        new Dop(Opcodes.INVOKE_STATIC_JUMBO, Opcodes.INVOKE_STATIC,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    public static final Dop INVOKE_INTERFACE_JUMBO =
-        new Dop(Opcodes.INVOKE_INTERFACE_JUMBO, Opcodes.INVOKE_INTERFACE,
-            Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
-    // END(dops)
-
-    // Static initialization.
-    static {
-        DOPS = new Dop[Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1];
-
-        set(SPECIAL_FORMAT);
-
-        // BEGIN(dops-init); GENERATED AUTOMATICALLY BY opcode-gen
-        set(NOP);
-        set(MOVE);
-        set(MOVE_FROM16);
-        set(MOVE_16);
-        set(MOVE_WIDE);
-        set(MOVE_WIDE_FROM16);
-        set(MOVE_WIDE_16);
-        set(MOVE_OBJECT);
-        set(MOVE_OBJECT_FROM16);
-        set(MOVE_OBJECT_16);
-        set(MOVE_RESULT);
-        set(MOVE_RESULT_WIDE);
-        set(MOVE_RESULT_OBJECT);
-        set(MOVE_EXCEPTION);
-        set(RETURN_VOID);
-        set(RETURN);
-        set(RETURN_WIDE);
-        set(RETURN_OBJECT);
-        set(CONST_4);
-        set(CONST_16);
-        set(CONST);
-        set(CONST_HIGH16);
-        set(CONST_WIDE_16);
-        set(CONST_WIDE_32);
-        set(CONST_WIDE);
-        set(CONST_WIDE_HIGH16);
-        set(CONST_STRING);
-        set(CONST_STRING_JUMBO);
-        set(CONST_CLASS);
-        set(MONITOR_ENTER);
-        set(MONITOR_EXIT);
-        set(CHECK_CAST);
-        set(INSTANCE_OF);
-        set(ARRAY_LENGTH);
-        set(NEW_INSTANCE);
-        set(NEW_ARRAY);
-        set(FILLED_NEW_ARRAY);
-        set(FILLED_NEW_ARRAY_RANGE);
-        set(FILL_ARRAY_DATA);
-        set(THROW);
-        set(GOTO);
-        set(GOTO_16);
-        set(GOTO_32);
-        set(PACKED_SWITCH);
-        set(SPARSE_SWITCH);
-        set(CMPL_FLOAT);
-        set(CMPG_FLOAT);
-        set(CMPL_DOUBLE);
-        set(CMPG_DOUBLE);
-        set(CMP_LONG);
-        set(IF_EQ);
-        set(IF_NE);
-        set(IF_LT);
-        set(IF_GE);
-        set(IF_GT);
-        set(IF_LE);
-        set(IF_EQZ);
-        set(IF_NEZ);
-        set(IF_LTZ);
-        set(IF_GEZ);
-        set(IF_GTZ);
-        set(IF_LEZ);
-        set(AGET);
-        set(AGET_WIDE);
-        set(AGET_OBJECT);
-        set(AGET_BOOLEAN);
-        set(AGET_BYTE);
-        set(AGET_CHAR);
-        set(AGET_SHORT);
-        set(APUT);
-        set(APUT_WIDE);
-        set(APUT_OBJECT);
-        set(APUT_BOOLEAN);
-        set(APUT_BYTE);
-        set(APUT_CHAR);
-        set(APUT_SHORT);
-        set(IGET);
-        set(IGET_WIDE);
-        set(IGET_OBJECT);
-        set(IGET_BOOLEAN);
-        set(IGET_BYTE);
-        set(IGET_CHAR);
-        set(IGET_SHORT);
-        set(IPUT);
-        set(IPUT_WIDE);
-        set(IPUT_OBJECT);
-        set(IPUT_BOOLEAN);
-        set(IPUT_BYTE);
-        set(IPUT_CHAR);
-        set(IPUT_SHORT);
-        set(SGET);
-        set(SGET_WIDE);
-        set(SGET_OBJECT);
-        set(SGET_BOOLEAN);
-        set(SGET_BYTE);
-        set(SGET_CHAR);
-        set(SGET_SHORT);
-        set(SPUT);
-        set(SPUT_WIDE);
-        set(SPUT_OBJECT);
-        set(SPUT_BOOLEAN);
-        set(SPUT_BYTE);
-        set(SPUT_CHAR);
-        set(SPUT_SHORT);
-        set(INVOKE_VIRTUAL);
-        set(INVOKE_SUPER);
-        set(INVOKE_DIRECT);
-        set(INVOKE_STATIC);
-        set(INVOKE_INTERFACE);
-        set(INVOKE_VIRTUAL_RANGE);
-        set(INVOKE_SUPER_RANGE);
-        set(INVOKE_DIRECT_RANGE);
-        set(INVOKE_STATIC_RANGE);
-        set(INVOKE_INTERFACE_RANGE);
-        set(NEG_INT);
-        set(NOT_INT);
-        set(NEG_LONG);
-        set(NOT_LONG);
-        set(NEG_FLOAT);
-        set(NEG_DOUBLE);
-        set(INT_TO_LONG);
-        set(INT_TO_FLOAT);
-        set(INT_TO_DOUBLE);
-        set(LONG_TO_INT);
-        set(LONG_TO_FLOAT);
-        set(LONG_TO_DOUBLE);
-        set(FLOAT_TO_INT);
-        set(FLOAT_TO_LONG);
-        set(FLOAT_TO_DOUBLE);
-        set(DOUBLE_TO_INT);
-        set(DOUBLE_TO_LONG);
-        set(DOUBLE_TO_FLOAT);
-        set(INT_TO_BYTE);
-        set(INT_TO_CHAR);
-        set(INT_TO_SHORT);
-        set(ADD_INT);
-        set(SUB_INT);
-        set(MUL_INT);
-        set(DIV_INT);
-        set(REM_INT);
-        set(AND_INT);
-        set(OR_INT);
-        set(XOR_INT);
-        set(SHL_INT);
-        set(SHR_INT);
-        set(USHR_INT);
-        set(ADD_LONG);
-        set(SUB_LONG);
-        set(MUL_LONG);
-        set(DIV_LONG);
-        set(REM_LONG);
-        set(AND_LONG);
-        set(OR_LONG);
-        set(XOR_LONG);
-        set(SHL_LONG);
-        set(SHR_LONG);
-        set(USHR_LONG);
-        set(ADD_FLOAT);
-        set(SUB_FLOAT);
-        set(MUL_FLOAT);
-        set(DIV_FLOAT);
-        set(REM_FLOAT);
-        set(ADD_DOUBLE);
-        set(SUB_DOUBLE);
-        set(MUL_DOUBLE);
-        set(DIV_DOUBLE);
-        set(REM_DOUBLE);
-        set(ADD_INT_2ADDR);
-        set(SUB_INT_2ADDR);
-        set(MUL_INT_2ADDR);
-        set(DIV_INT_2ADDR);
-        set(REM_INT_2ADDR);
-        set(AND_INT_2ADDR);
-        set(OR_INT_2ADDR);
-        set(XOR_INT_2ADDR);
-        set(SHL_INT_2ADDR);
-        set(SHR_INT_2ADDR);
-        set(USHR_INT_2ADDR);
-        set(ADD_LONG_2ADDR);
-        set(SUB_LONG_2ADDR);
-        set(MUL_LONG_2ADDR);
-        set(DIV_LONG_2ADDR);
-        set(REM_LONG_2ADDR);
-        set(AND_LONG_2ADDR);
-        set(OR_LONG_2ADDR);
-        set(XOR_LONG_2ADDR);
-        set(SHL_LONG_2ADDR);
-        set(SHR_LONG_2ADDR);
-        set(USHR_LONG_2ADDR);
-        set(ADD_FLOAT_2ADDR);
-        set(SUB_FLOAT_2ADDR);
-        set(MUL_FLOAT_2ADDR);
-        set(DIV_FLOAT_2ADDR);
-        set(REM_FLOAT_2ADDR);
-        set(ADD_DOUBLE_2ADDR);
-        set(SUB_DOUBLE_2ADDR);
-        set(MUL_DOUBLE_2ADDR);
-        set(DIV_DOUBLE_2ADDR);
-        set(REM_DOUBLE_2ADDR);
-        set(ADD_INT_LIT16);
-        set(RSUB_INT);
-        set(MUL_INT_LIT16);
-        set(DIV_INT_LIT16);
-        set(REM_INT_LIT16);
-        set(AND_INT_LIT16);
-        set(OR_INT_LIT16);
-        set(XOR_INT_LIT16);
-        set(ADD_INT_LIT8);
-        set(RSUB_INT_LIT8);
-        set(MUL_INT_LIT8);
-        set(DIV_INT_LIT8);
-        set(REM_INT_LIT8);
-        set(AND_INT_LIT8);
-        set(OR_INT_LIT8);
-        set(XOR_INT_LIT8);
-        set(SHL_INT_LIT8);
-        set(SHR_INT_LIT8);
-        set(USHR_INT_LIT8);
-        set(CONST_CLASS_JUMBO);
-        set(CHECK_CAST_JUMBO);
-        set(INSTANCE_OF_JUMBO);
-        set(NEW_INSTANCE_JUMBO);
-        set(NEW_ARRAY_JUMBO);
-        set(FILLED_NEW_ARRAY_JUMBO);
-        set(IGET_JUMBO);
-        set(IGET_WIDE_JUMBO);
-        set(IGET_OBJECT_JUMBO);
-        set(IGET_BOOLEAN_JUMBO);
-        set(IGET_BYTE_JUMBO);
-        set(IGET_CHAR_JUMBO);
-        set(IGET_SHORT_JUMBO);
-        set(IPUT_JUMBO);
-        set(IPUT_WIDE_JUMBO);
-        set(IPUT_OBJECT_JUMBO);
-        set(IPUT_BOOLEAN_JUMBO);
-        set(IPUT_BYTE_JUMBO);
-        set(IPUT_CHAR_JUMBO);
-        set(IPUT_SHORT_JUMBO);
-        set(SGET_JUMBO);
-        set(SGET_WIDE_JUMBO);
-        set(SGET_OBJECT_JUMBO);
-        set(SGET_BOOLEAN_JUMBO);
-        set(SGET_BYTE_JUMBO);
-        set(SGET_CHAR_JUMBO);
-        set(SGET_SHORT_JUMBO);
-        set(SPUT_JUMBO);
-        set(SPUT_WIDE_JUMBO);
-        set(SPUT_OBJECT_JUMBO);
-        set(SPUT_BOOLEAN_JUMBO);
-        set(SPUT_BYTE_JUMBO);
-        set(SPUT_CHAR_JUMBO);
-        set(SPUT_SHORT_JUMBO);
-        set(INVOKE_VIRTUAL_JUMBO);
-        set(INVOKE_SUPER_JUMBO);
-        set(INVOKE_DIRECT_JUMBO);
-        set(INVOKE_STATIC_JUMBO);
-        set(INVOKE_INTERFACE_JUMBO);
-        // END(dops-init)
-    }
-
-    /**
-     * This class is uninstantiable.
-     */
-    private Dops() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Gets the {@link Dop} for the given opcode value.
-     *
-     * @param opcode {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the
-     * opcode value
-     * @return {@code non-null;} the associated opcode instance
-     */
-    public static Dop get(int opcode) {
-        int idx = opcode - Opcodes.MIN_VALUE;
-
-        try {
-            Dop result = DOPS[idx];
-            if (result != null) {
-                return result;
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Fall through.
-        }
-
-        throw new IllegalArgumentException("bogus opcode");
-    }
-
-    /**
-     * Gets the next {@link Dop} in the instruction fitting chain after the
-     * given instance, if any.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param options {@code non-null;} options, used to determine
-     * which opcodes are potentially off-limits
-     * @return {@code null-ok;} the next opcode in the same family, in the
-     * chain of opcodes to try, or {@code null} if the given opcode is
-     * the last in its chain
-     */
-    public static Dop getNextOrNull(Dop opcode, DexOptions options) {
-        boolean suppressExtendedOpcodes = !options.canUseExtendedOpcodes();
-
-        for (;;) {
-            int nextOpcode = opcode.getNextOpcode();
-
-            if (nextOpcode == Opcodes.NO_NEXT) {
-                return null;
-            }
-
-            opcode = get(nextOpcode);
-
-            if (suppressExtendedOpcodes && Opcodes.isExtended(nextOpcode)) {
-                /*
-                 * Continuing rather than just returning null here
-                 * protects against the possibility that an
-                 * instruction fitting chain might list non-extended
-                 * opcodes after extended ones.
-                 */
-                continue;
-            }
-
-            return opcode;
-        }
-    }
-
-    /**
-     * Puts the given opcode into the table of all ops.
-     *
-     * @param opcode {@code non-null;} the opcode
-     */
-    private static void set(Dop opcode) {
-        int idx = opcode.getOpcode() - Opcodes.MIN_VALUE;
-        DOPS[idx] = opcode;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/FixedSizeInsn.java b/dx/src/main/java/com/android/dx/dex/code/FixedSizeInsn.java
deleted file mode 100644
index faed530..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/FixedSizeInsn.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Base class for instructions which are of a fixed code size and
- * which use {@link InsnFormat} methods to write themselves. This
- * includes most &mdash; but not all &mdash; instructions.
- */
-public abstract class FixedSizeInsn extends DalvInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * <p><b>Note:</b> In the unlikely event that an instruction takes
-     * absolutely no registers (e.g., a {@code nop} or a
-     * no-argument no-result * static method call), then the given
-     * register list may be passed as {@link
-     * RegisterSpecList#EMPTY}.</p>
-     *
-     * @param opcode the opcode; one of the constants from {@link Dops}
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} register list, including a
-     * result register if appropriate (that is, registers may be either
-     * ins or outs)
-     */
-    public FixedSizeInsn(Dop opcode, SourcePosition position,
-                         RegisterSpecList registers) {
-        super(opcode, position, registers);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int codeSize() {
-        return getOpcode().getFormat().codeSize();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void writeTo(AnnotatedOutput out) {
-        getOpcode().getFormat().writeTo(out, this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final DalvInsn withRegisterOffset(int delta) {
-        return withRegisters(getRegisters().withOffset(delta));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final String listingString0(boolean noteIndices) {
-        return getOpcode().getFormat().listingString(this, noteIndices);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/HighRegisterPrefix.java b/dx/src/main/java/com/android/dx/dex/code/HighRegisterPrefix.java
deleted file mode 100644
index 6fab094..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/HighRegisterPrefix.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Combination instruction which turns into a variable number of
- * {@code move*} instructions to move a set of registers into
- * registers starting at {@code 0} sequentially. This is used
- * in translating an instruction whose register requirements cannot
- * be met using a straightforward choice of a single opcode.
- */
-public final class HighRegisterPrefix extends VariableSizeInsn {
-    /** {@code null-ok;} cached instructions, if constructed */
-    private SimpleInsn[] insns;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} source registers
-     */
-    public HighRegisterPrefix(SourcePosition position,
-                              RegisterSpecList registers) {
-        super(position, registers);
-
-        if (registers.size() == 0) {
-            throw new IllegalArgumentException("registers.size() == 0");
-        }
-
-        insns = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        int result = 0;
-
-        calculateInsnsIfNecessary();
-
-        for (SimpleInsn insn : insns) {
-            result += insn.codeSize();
-        }
-
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out) {
-        calculateInsnsIfNecessary();
-
-        for (SimpleInsn insn : insns) {
-            insn.writeTo(out);
-        }
-    }
-
-    /**
-     * Helper for {@link #codeSize} and {@link #writeTo} which sets up
-     * {@link #insns} if not already done.
-     */
-    private void calculateInsnsIfNecessary() {
-        if (insns != null) {
-            return;
-        }
-
-        RegisterSpecList registers = getRegisters();
-        int sz = registers.size();
-
-        insns = new SimpleInsn[sz];
-
-        for (int i = 0, outAt = 0; i < sz; i++) {
-            RegisterSpec src = registers.get(i);
-            insns[i] = moveInsnFor(src, outAt);
-            outAt += src.getCategory();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new HighRegisterPrefix(getPosition(), registers);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        RegisterSpecList registers = getRegisters();
-        int sz = registers.size();
-        StringBuffer sb = new StringBuffer(100);
-
-        for (int i = 0, outAt = 0; i < sz; i++) {
-            RegisterSpec src = registers.get(i);
-            SimpleInsn insn = moveInsnFor(src, outAt);
-
-            if (i != 0) {
-                sb.append('\n');
-            }
-
-            sb.append(insn.listingString0(noteIndices));
-
-            outAt += src.getCategory();
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Returns the proper move instruction for the given source spec
-     * and destination index.
-     *
-     * @param src {@code non-null;} the source register spec
-     * @param destIndex {@code >= 0;} the destination register index
-     * @return {@code non-null;} the appropriate move instruction
-     */
-    private static SimpleInsn moveInsnFor(RegisterSpec src, int destIndex) {
-        return DalvInsn.makeMove(SourcePosition.NO_INFO,
-                RegisterSpec.make(destIndex, src.getType()),
-                src);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/InsnFormat.java b/dx/src/main/java/com/android/dx/dex/code/InsnFormat.java
deleted file mode 100644
index bf9f08e..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/InsnFormat.java
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.cst.CstKnownNull;
-import com.android.dx.rop.cst.CstLiteral64;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.BitSet;
-
-/**
- * Base class for all instruction format handlers. Instruction format
- * handlers know how to translate {@link DalvInsn} instances into
- * streams of code units, as well as human-oriented listing strings
- * representing such translations.
- */
-public abstract class InsnFormat {
-    /**
-     * flag to enable/disable the new extended opcode formats; meant as a
-     * temporary measure until VM support for the salient opcodes is
-     * added. TODO: Remove this declaration when the VM can deal.
-     */
-    public static boolean ALLOW_EXTENDED_OPCODES = true;
-
-    /**
-     * Returns the string form, suitable for inclusion in a listing
-     * dump, of the given instruction. The instruction must be of this
-     * instance's format for proper operation.
-     *
-     * @param insn {@code non-null;} the instruction
-     * @param noteIndices whether to include an explicit notation of
-     * constant pool indices
-     * @return {@code non-null;} the string form
-     */
-    public final String listingString(DalvInsn insn, boolean noteIndices) {
-        String op = insn.getOpcode().getName();
-        String arg = insnArgString(insn);
-        String comment = insnCommentString(insn, noteIndices);
-        StringBuilder sb = new StringBuilder(100);
-
-        sb.append(op);
-
-        if (arg.length() != 0) {
-            sb.append(' ');
-            sb.append(arg);
-        }
-
-        if (comment.length() != 0) {
-            sb.append(" // ");
-            sb.append(comment);
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Returns the string form of the arguments to the given instruction.
-     * The instruction must be of this instance's format. If the instruction
-     * has no arguments, then the result should be {@code ""}, not
-     * {@code null}.
-     *
-     * <p>Subclasses must override this method.</p>
-     *
-     * @param insn {@code non-null;} the instruction
-     * @return {@code non-null;} the string form
-     */
-    public abstract String insnArgString(DalvInsn insn);
-
-    /**
-     * Returns the associated comment for the given instruction, if any.
-     * The instruction must be of this instance's format. If the instruction
-     * has no comment, then the result should be {@code ""}, not
-     * {@code null}.
-     *
-     * <p>Subclasses must override this method.</p>
-     *
-     * @param insn {@code non-null;} the instruction
-     * @param noteIndices whether to include an explicit notation of
-     * constant pool indices
-     * @return {@code non-null;} the string form
-     */
-    public abstract String insnCommentString(DalvInsn insn,
-            boolean noteIndices);
-
-    /**
-     * Gets the code size of instructions that use this format. The
-     * size is a number of 16-bit code units, not bytes. This should
-     * throw an exception if this format is of variable size.
-     *
-     * @return {@code >= 0;} the instruction length in 16-bit code units
-     */
-    public abstract int codeSize();
-
-    /**
-     * Returns whether or not the given instruction's arguments will
-     * fit in this instance's format. This includes such things as
-     * counting register arguments, checking register ranges, and
-     * making sure that additional arguments are of appropriate types
-     * and are in-range. If this format has a branch target but the
-     * instruction's branch offset is unknown, this method will simply
-     * not check the offset.
-     *
-     * <p>Subclasses must override this method.</p>
-     *
-     * @param insn {@code non-null;} the instruction to check
-     * @return {@code true} iff the instruction's arguments are
-     * appropriate for this instance, or {@code false} if not
-     */
-    public abstract boolean isCompatible(DalvInsn insn);
-
-    /**
-     * Returns which of a given instruction's registers will fit in
-     * this instance's format.
-     *
-     * <p>The default implementation of this method always returns
-     * an empty BitSet. Subclasses must override this method if they
-     * have registers.</p>
-     *
-     * @param insn {@code non-null;} the instruction to check
-     * @return {@code non-null;} a BitSet flagging registers in the
-     * register list that are compatible to this format
-     */
-    public BitSet compatibleRegs(DalvInsn insn) {
-        return new BitSet();
-    }
-
-    /**
-     * Returns whether or not the given instruction's branch offset will
-     * fit in this instance's format. This always returns {@code false}
-     * for formats that don't include a branch offset.
-     *
-     * <p>The default implementation of this method always returns
-     * {@code false}. Subclasses must override this method if they
-     * include branch offsets.</p>
-     *
-     * @param insn {@code non-null;} the instruction to check
-     * @return {@code true} iff the instruction's branch offset is
-     * appropriate for this instance, or {@code false} if not
-     */
-    public boolean branchFits(TargetInsn insn) {
-        return false;
-    }
-
-    /**
-     * Writes the code units for the given instruction to the given
-     * output destination. The instruction must be of this instance's format.
-     *
-     * <p>Subclasses must override this method.</p>
-     *
-     * @param out {@code non-null;} the output destination to write to
-     * @param insn {@code non-null;} the instruction to write
-     */
-    public abstract void writeTo(AnnotatedOutput out, DalvInsn insn);
-
-    /**
-     * Helper method to return a register list string.
-     *
-     * @param list {@code non-null;} the list of registers
-     * @return {@code non-null;} the string form
-     */
-    protected static String regListString(RegisterSpecList list) {
-        int sz = list.size();
-        StringBuffer sb = new StringBuffer(sz * 5 + 2);
-
-        sb.append('{');
-
-        for (int i = 0; i < sz; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(list.get(i).regString());
-        }
-
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper method to return a register range string.
-     *
-     * @param list {@code non-null;} the list of registers (which must be
-     * sequential)
-     * @return {@code non-null;} the string form
-     */
-    protected static String regRangeString(RegisterSpecList list) {
-        int size = list.size();
-        StringBuilder sb = new StringBuilder(30);
-
-        sb.append("{");
-
-        switch (size) {
-            case 0: {
-                // Nothing to do.
-                break;
-            }
-            case 1: {
-                sb.append(list.get(0).regString());
-                break;
-            }
-            default: {
-                RegisterSpec lastReg = list.get(size - 1);
-                if (lastReg.getCategory() == 2) {
-                    /*
-                     * Add one to properly represent a list-final
-                     * category-2 register.
-                     */
-                    lastReg = lastReg.withOffset(1);
-                }
-
-                sb.append(list.get(0).regString());
-                sb.append("..");
-                sb.append(lastReg.regString());
-            }
-        }
-
-        sb.append("}");
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper method to return a literal bits argument string.
-     *
-     * @param value the value
-     * @return {@code non-null;} the string form
-     */
-    protected static String literalBitsString(CstLiteralBits value) {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append('#');
-
-        if (value instanceof CstKnownNull) {
-            sb.append("null");
-        } else {
-            sb.append(value.typeName());
-            sb.append(' ');
-            sb.append(value.toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper method to return a literal bits comment string.
-     *
-     * @param value the value
-     * @param width the width of the constant, in bits (used for displaying
-     * the uninterpreted bits; one of: {@code 4 8 16 32 64}
-     * @return {@code non-null;} the comment
-     */
-    protected static String literalBitsComment(CstLiteralBits value,
-            int width) {
-        StringBuffer sb = new StringBuffer(20);
-
-        sb.append("#");
-
-        long bits;
-
-        if (value instanceof CstLiteral64) {
-            bits = ((CstLiteral64) value).getLongBits();
-        } else {
-            bits = value.getIntBits();
-        }
-
-        switch (width) {
-            case 4:  sb.append(Hex.uNibble((int) bits)); break;
-            case 8:  sb.append(Hex.u1((int) bits));      break;
-            case 16: sb.append(Hex.u2((int) bits));      break;
-            case 32: sb.append(Hex.u4((int) bits));      break;
-            case 64: sb.append(Hex.u8(bits));            break;
-            default: {
-                throw new RuntimeException("shouldn't happen");
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper method to return a branch address string.
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @return {@code non-null;} the string form of the instruction's
-     * branch target
-     */
-    protected static String branchString(DalvInsn insn) {
-        TargetInsn ti = (TargetInsn) insn;
-        int address = ti.getTargetAddress();
-
-        return (address == (char) address) ? Hex.u2(address) : Hex.u4(address);
-    }
-
-    /**
-     * Helper method to return the comment for a branch.
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @return {@code non-null;} the comment
-     */
-    protected static String branchComment(DalvInsn insn) {
-        TargetInsn ti = (TargetInsn) insn;
-        int offset = ti.getTargetOffset();
-
-        return (offset == (short) offset) ? Hex.s2(offset) : Hex.s4(offset);
-    }
-
-    /**
-     * Helper method to return the constant string for a {@link CstInsn}
-     * in human form.
-     *
-     * @param insn {@code non-null;} a constant-bearing instruction
-     * @return {@code non-null;} the human string form of the contained
-     * constant
-     */
-    protected static String cstString(DalvInsn insn) {
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        return cst instanceof CstString ? ((CstString) cst).toQuoted() : cst.toHuman();
-    }
-
-    /**
-     * Helper method to return an instruction comment for a constant.
-     *
-     * @param insn {@code non-null;} a constant-bearing instruction
-     * @return {@code non-null;} comment string representing the constant
-     */
-    protected static String cstComment(DalvInsn insn) {
-        CstInsn ci = (CstInsn) insn;
-
-        if (! ci.hasIndex()) {
-            return "";
-        }
-
-        StringBuilder sb = new StringBuilder(20);
-        int index = ci.getIndex();
-
-        sb.append(ci.getConstant().typeName());
-        sb.append('@');
-
-        if (index < 65536) {
-            sb.append(Hex.u2(index));
-        } else {
-            sb.append(Hex.u4(index));
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper method to determine if a signed int value fits in a nibble.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range -8..+7
-     */
-    protected static boolean signedFitsInNibble(int value) {
-        return (value >= -8) && (value <= 7);
-    }
-
-    /**
-     * Helper method to determine if an unsigned int value fits in a nibble.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range 0..0xf
-     */
-    protected static boolean unsignedFitsInNibble(int value) {
-        return value == (value & 0xf);
-    }
-
-    /**
-     * Helper method to determine if a signed int value fits in a byte.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range -0x80..+0x7f
-     */
-    protected static boolean signedFitsInByte(int value) {
-        return (byte) value == value;
-    }
-
-    /**
-     * Helper method to determine if an unsigned int value fits in a byte.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range 0..0xff
-     */
-    protected static boolean unsignedFitsInByte(int value) {
-        return value == (value & 0xff);
-    }
-
-    /**
-     * Helper method to determine if a signed int value fits in a short.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range -0x8000..+0x7fff
-     */
-    protected static boolean signedFitsInShort(int value) {
-        return (short) value == value;
-    }
-
-    /**
-     * Helper method to determine if an unsigned int value fits in a short.
-     *
-     * @param value the value in question
-     * @return {@code true} iff it's in the range 0..0xffff
-     */
-    protected static boolean unsignedFitsInShort(int value) {
-        return value == (value & 0xffff);
-    }
-
-    /**
-     * Helper method to determine if a list of registers are sequential,
-     * including degenerate cases for empty or single-element lists.
-     *
-     * @param list {@code non-null;} the list of registers
-     * @return {@code true} iff the list is sequentially ordered
-     */
-    protected static boolean isRegListSequential(RegisterSpecList list) {
-        int sz = list.size();
-
-        if (sz < 2) {
-            return true;
-        }
-
-        int first = list.get(0).getReg();
-        int next = first;
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec one = list.get(i);
-            if (one.getReg() != next) {
-                return false;
-            }
-            next += one.getCategory();
-        }
-
-        return true;
-    }
-
-    /**
-     * Helper method to extract the callout-argument index from an
-     * appropriate instruction.
-     *
-     * @param insn {@code non-null;} the instruction
-     * @return {@code >= 0;} the callout argument index
-     */
-    protected static int argIndex(DalvInsn insn) {
-        int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue();
-
-        if (arg < 0) {
-            throw new IllegalArgumentException("bogus insn");
-        }
-
-        return arg;
-    }
-
-    /**
-     * Helper method to combine an opcode and a second byte of data into
-     * the appropriate form for emitting into a code buffer.
-     *
-     * @param insn {@code non-null;} the instruction containing the opcode
-     * @param arg {@code 0..255;} arbitrary other byte value
-     * @return combined value
-     */
-    protected static short opcodeUnit(DalvInsn insn, int arg) {
-        if ((arg & 0xff) != arg) {
-            throw new IllegalArgumentException("arg out of range 0..255");
-        }
-
-        int opcode = insn.getOpcode().getOpcode();
-
-        if ((opcode & 0xff) != opcode) {
-            throw new IllegalArgumentException("opcode out of range 0..255");
-        }
-
-        return (short) (opcode | (arg << 8));
-    }
-
-    /**
-     * Helper method to get an extended (16-bit) opcode out of an
-     * instruction, returning it as a code unit. The opcode
-     * <i>must</i> be an extended opcode.
-     *
-     * @param insn {@code non-null;} the instruction containing the
-     * extended opcode
-     * @return the opcode as a code unit
-     */
-    protected static short opcodeUnit(DalvInsn insn) {
-        int opcode = insn.getOpcode().getOpcode();
-
-        if ((opcode < 0xff) || (opcode > 0xffff)) {
-            throw new IllegalArgumentException(
-                "extended opcode out of range 255..65535");
-        }
-
-        return (short) opcode;
-    }
-
-    /**
-     * Helper method to combine two bytes into a code unit.
-     *
-     * @param low {@code 0..255;} low byte
-     * @param high {@code 0..255;} high byte
-     * @return combined value
-     */
-    protected static short codeUnit(int low, int high) {
-        if ((low & 0xff) != low) {
-            throw new IllegalArgumentException("low out of range 0..255");
-        }
-
-        if ((high & 0xff) != high) {
-            throw new IllegalArgumentException("high out of range 0..255");
-        }
-
-        return (short) (low | (high << 8));
-    }
-
-    /**
-     * Helper method to combine four nibbles into a code unit.
-     *
-     * @param n0 {@code 0..15;} low nibble
-     * @param n1 {@code 0..15;} medium-low nibble
-     * @param n2 {@code 0..15;} medium-high nibble
-     * @param n3 {@code 0..15;} high nibble
-     * @return combined value
-     */
-    protected static short codeUnit(int n0, int n1, int n2, int n3) {
-        if ((n0 & 0xf) != n0) {
-            throw new IllegalArgumentException("n0 out of range 0..15");
-        }
-
-        if ((n1 & 0xf) != n1) {
-            throw new IllegalArgumentException("n1 out of range 0..15");
-        }
-
-        if ((n2 & 0xf) != n2) {
-            throw new IllegalArgumentException("n2 out of range 0..15");
-        }
-
-        if ((n3 & 0xf) != n3) {
-            throw new IllegalArgumentException("n3 out of range 0..15");
-        }
-
-        return (short) (n0 | (n1 << 4) | (n2 << 8) | (n3 << 12));
-    }
-
-    /**
-     * Helper method to combine two nibbles into a byte.
-     *
-     * @param low {@code 0..15;} low nibble
-     * @param high {@code 0..15;} high nibble
-     * @return {@code 0..255;} combined value
-     */
-    protected static int makeByte(int low, int high) {
-        if ((low & 0xf) != low) {
-            throw new IllegalArgumentException("low out of range 0..15");
-        }
-
-        if ((high & 0xf) != high) {
-            throw new IllegalArgumentException("high out of range 0..15");
-        }
-
-        return low | (high << 4);
-    }
-
-    /**
-     * Writes one code unit to the given output destination.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0) {
-        out.writeShort(c0);
-    }
-
-    /**
-     * Writes two code units to the given output destination.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, short c1) {
-        out.writeShort(c0);
-        out.writeShort(c1);
-    }
-
-    /**
-     * Writes three code units to the given output destination.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1 code unit to write
-     * @param c2 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, short c1,
-            short c2) {
-        out.writeShort(c0);
-        out.writeShort(c1);
-        out.writeShort(c2);
-    }
-
-    /**
-     * Writes four code units to the given output destination.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1 code unit to write
-     * @param c2 code unit to write
-     * @param c3 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, short c1,
-            short c2, short c3) {
-        out.writeShort(c0);
-        out.writeShort(c1);
-        out.writeShort(c2);
-        out.writeShort(c3);
-    }
-
-    /**
-     * Writes five code units to the given output destination.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1 code unit to write
-     * @param c2 code unit to write
-     * @param c3 code unit to write
-     * @param c4 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, short c1,
-            short c2, short c3, short c4) {
-        out.writeShort(c0);
-        out.writeShort(c1);
-        out.writeShort(c2);
-        out.writeShort(c3);
-        out.writeShort(c4);
-    }
-
-    /**
-     * Writes three code units to the given output destination, where the
-     * second and third are represented as single <code>int</code> and emitted
-     * in little-endian order.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1c2 code unit pair to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, int c1c2) {
-        write(out, c0, (short) c1c2, (short) (c1c2 >> 16));
-    }
-
-    /**
-     * Writes four code units to the given output destination, where the
-     * second and third are represented as single <code>int</code> and emitted
-     * in little-endian order.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1c2 code unit pair to write
-     * @param c3 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, int c1c2,
-            short c3) {
-        write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3);
-    }
-
-    /**
-     * Writes five code units to the given output destination, where the
-     * second and third are represented as single <code>int</code> and emitted
-     * in little-endian order.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1c2 code unit pair to write
-     * @param c3 code unit to write
-     * @param c4 code unit to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, int c1c2,
-            short c3, short c4) {
-        write(out, c0, (short) c1c2, (short) (c1c2 >> 16), c3, c4);
-    }
-
-    /**
-     * Writes five code units to the given output destination, where the
-     * second through fifth are represented as single <code>long</code>
-     * and emitted in little-endian order.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param c0 code unit to write
-     * @param c1c2c3c4 code unit quad to write
-     */
-    protected static void write(AnnotatedOutput out, short c0, long c1c2c3c4) {
-        write(out, c0, (short) c1c2c3c4, (short) (c1c2c3c4 >> 16),
-                (short) (c1c2c3c4 >> 32), (short) (c1c2c3c4 >> 48));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/LocalEnd.java b/dx/src/main/java/com/android/dx/dex/code/LocalEnd.java
deleted file mode 100644
index 1c2bf89..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/LocalEnd.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2009 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Pseudo-instruction which is used to explicitly end the mapping of a
- * register to a named local variable. That is, an instance of this
- * class in an instruction stream indicates that starting with the
- * subsequent instruction, the indicated variable is no longer valid.
- */
-public final class LocalEnd extends ZeroSizeInsn {
-    /**
-     * {@code non-null;} register spec representing the local variable ended
-     * by this instance. <b>Note:</b> Technically, only the register
-     * number needs to be recorded here as the rest of the information
-     * is implicit in the ambient local variable state, but other code
-     * will check the other info for consistency.
-     */
-    private final RegisterSpec local;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param local {@code non-null;} register spec representing the local
-     * variable introduced by this instance
-     */
-    public LocalEnd(SourcePosition position, RegisterSpec local) {
-        super(position);
-
-        if (local == null) {
-            throw new NullPointerException("local == null");
-        }
-
-        this.local = local;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisterOffset(int delta) {
-        return new LocalEnd(getPosition(), local.withOffset(delta));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new LocalEnd(getPosition(), local);
-    }
-
-    /**
-     * Gets the register spec representing the local variable ended
-     * by this instance.
-     *
-     * @return {@code non-null;} the register spec
-     */
-    public RegisterSpec getLocal() {
-        return local;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return local.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        return "local-end " + LocalStart.localString(local);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/LocalList.java b/dx/src/main/java/com/android/dx/dex/code/LocalList.java
deleted file mode 100644
index ab8343a..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/LocalList.java
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.FixedSizeList;
-
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * List of local variables. Each local variable entry indicates a
- * range of code which it is valid for, a register number, a name,
- * and a type.
- */
-public final class LocalList extends FixedSizeList {
-    /** {@code non-null;} empty instance */
-    public static final LocalList EMPTY = new LocalList(0);
-
-    /** whether to run the self-check code */
-    private static final boolean DEBUG = false;
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size {@code >= 0;} the size of the list
-     */
-    public LocalList(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Entry get(int n) {
-        return (Entry) get0(n);
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param entry {@code non-null;} the entry to set at {@code n}
-     */
-    public void set(int n, Entry entry) {
-        set0(n, entry);
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} prefix to attach to each line of output
-     */
-    public void debugPrint(PrintStream out, String prefix) {
-        int sz = size();
-
-        for (int i = 0; i < sz; i++) {
-            out.print(prefix);
-            out.println(get(i));
-        }
-    }
-
-    /**
-     * Disposition of a local entry.
-     */
-    public static enum Disposition {
-        /** local started (introduced) */
-        START,
-
-        /** local ended without being replaced */
-        END_SIMPLY,
-
-        /** local ended because it was directly replaced */
-        END_REPLACED,
-
-        /** local ended because it was moved to a different register */
-        END_MOVED,
-
-        /**
-         * local ended because the previous local clobbered this one
-         * (because it is category-2)
-         */
-        END_CLOBBERED_BY_PREV,
-
-        /**
-         * local ended because the next local clobbered this one
-         * (because this one is a category-2)
-         */
-        END_CLOBBERED_BY_NEXT;
-    }
-
-    /**
-     * Entry in a local list.
-     */
-    public static class Entry implements Comparable<Entry> {
-        /** {@code >= 0;} address */
-        private final int address;
-
-        /** {@code non-null;} disposition of the local */
-        private final Disposition disposition;
-
-        /** {@code non-null;} register spec representing the variable */
-        private final RegisterSpec spec;
-
-        /** {@code non-null;} variable type (derived from {@code spec}) */
-        private final CstType type;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param address {@code >= 0;} address
-         * @param disposition {@code non-null;} disposition of the local
-         * @param spec {@code non-null;} register spec representing
-         * the variable
-         */
-        public Entry(int address, Disposition disposition, RegisterSpec spec) {
-            if (address < 0) {
-                throw new IllegalArgumentException("address < 0");
-            }
-
-            if (disposition == null) {
-                throw new NullPointerException("disposition == null");
-            }
-
-            try {
-                if (spec.getLocalItem() == null) {
-                    throw new NullPointerException(
-                            "spec.getLocalItem() == null");
-                }
-            } catch (NullPointerException ex) {
-                // Elucidate the exception.
-                throw new NullPointerException("spec == null");
-            }
-
-            this.address = address;
-            this.disposition = disposition;
-            this.spec = spec;
-            this.type = CstType.intern(spec.getType());
-        }
-
-        /** {@inheritDoc} */
-        public String toString() {
-            return Integer.toHexString(address) + " " + disposition + " " +
-                spec;
-        }
-
-        /** {@inheritDoc} */
-        public boolean equals(Object other) {
-            if (!(other instanceof Entry)) {
-                return false;
-            }
-
-            return (compareTo((Entry) other) == 0);
-        }
-
-        /**
-         * Compares by (in priority order) address, end then start
-         * disposition (variants of end are all consistered
-         * equivalent), and spec.
-         *
-         * @param other {@code non-null;} entry to compare to
-         * @return {@code -1..1;} standard result of comparison
-         */
-        public int compareTo(Entry other) {
-            if (address < other.address) {
-                return -1;
-            } else if (address > other.address) {
-                return 1;
-            }
-
-            boolean thisIsStart = isStart();
-            boolean otherIsStart = other.isStart();
-
-            if (thisIsStart != otherIsStart) {
-                return thisIsStart ? 1 : -1;
-            }
-
-            return spec.compareTo(other.spec);
-        }
-
-        /**
-         * Gets the address.
-         *
-         * @return {@code >= 0;} the address
-         */
-        public int getAddress() {
-            return address;
-        }
-
-        /**
-         * Gets the disposition.
-         *
-         * @return {@code non-null;} the disposition
-         */
-        public Disposition getDisposition() {
-            return disposition;
-        }
-
-        /**
-         * Gets whether this is a local start. This is just shorthand for
-         * {@code getDisposition() == Disposition.START}.
-         *
-         * @return {@code true} iff this is a start
-         */
-        public boolean isStart() {
-            return disposition == Disposition.START;
-        }
-
-        /**
-         * Gets the variable name.
-         *
-         * @return {@code null-ok;} the variable name
-         */
-        public CstString getName() {
-            return spec.getLocalItem().getName();
-        }
-
-        /**
-         * Gets the variable signature.
-         *
-         * @return {@code null-ok;} the variable signature
-         */
-        public CstString getSignature() {
-            return spec.getLocalItem().getSignature();
-        }
-
-        /**
-         * Gets the variable's type.
-         *
-         * @return {@code non-null;} the type
-         */
-        public CstType getType() {
-            return type;
-        }
-
-        /**
-         * Gets the number of the register holding the variable.
-         *
-         * @return {@code >= 0;} the number of the register holding
-         * the variable
-         */
-        public int getRegister() {
-            return spec.getReg();
-        }
-
-        /**
-         * Gets the RegisterSpec of the register holding the variable.
-         *
-         * @return {@code non-null;} RegisterSpec of the holding register.
-         */
-        public RegisterSpec getRegisterSpec() {
-            return spec;
-        }
-
-        /**
-         * Returns whether or not this instance matches the given spec.
-         *
-         * @param otherSpec {@code non-null;} the spec in question
-         * @return {@code true} iff this instance matches
-         * {@code spec}
-         */
-        public boolean matches(RegisterSpec otherSpec) {
-            return spec.equalsUsingSimpleType(otherSpec);
-        }
-
-        /**
-         * Returns whether or not this instance matches the spec in
-         * the given instance.
-         *
-         * @param other {@code non-null;} another entry
-         * @return {@code true} iff this instance's spec matches
-         * {@code other}
-         */
-        public boolean matches(Entry other) {
-            return matches(other.spec);
-        }
-
-        /**
-         * Returns an instance just like this one but with the disposition
-         * set as given.
-         *
-         * @param disposition {@code non-null;} the new disposition
-         * @return {@code non-null;} an appropriately-constructed instance
-         */
-        public Entry withDisposition(Disposition disposition) {
-            if (disposition == this.disposition) {
-                return this;
-            }
-
-            return new Entry(address, disposition, spec);
-        }
-    }
-
-    /**
-     * Constructs an instance for the given method, based on the given
-     * block order and intermediate local information.
-     *
-     * @param insns {@code non-null;} instructions to convert
-     * @return {@code non-null;} the constructed list
-     */
-    public static LocalList make(DalvInsnList insns) {
-        int sz = insns.size();
-
-        /*
-         * Go through the insn list, looking for all the local
-         * variable pseudoinstructions, splitting out LocalSnapshots
-         * into separate per-variable starts, adding explicit ends
-         * wherever a variable is replaced or moved, and collecting
-         * these and all the other local variable "activity"
-         * together into an output list (without the other insns).
-         *
-         * Note: As of this writing, this method won't be handed any
-         * insn lists that contain local ends, but I (danfuzz) expect
-         * that to change at some point, when we start feeding that
-         * info explicitly into the rop layer rather than only trying
-         * to infer it. So, given that expectation, this code is
-         * written to deal with them.
-         */
-
-        MakeState state = new MakeState(sz);
-
-        for (int i = 0; i < sz; i++) {
-            DalvInsn insn = insns.get(i);
-
-            if (insn instanceof LocalSnapshot) {
-                RegisterSpecSet snapshot =
-                    ((LocalSnapshot) insn).getLocals();
-                state.snapshot(insn.getAddress(), snapshot);
-            } else if (insn instanceof LocalStart) {
-                RegisterSpec local = ((LocalStart) insn).getLocal();
-                state.startLocal(insn.getAddress(), local);
-            } else if (insn instanceof LocalEnd) {
-                RegisterSpec local = ((LocalEnd) insn).getLocal();
-                state.endLocal(insn.getAddress(), local);
-            }
-        }
-
-        LocalList result = state.finish();
-
-        if (DEBUG) {
-            debugVerify(result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Debugging helper that verifies the constraint that a list doesn't
-     * contain any redundant local starts and that local ends that are
-     * due to replacements are properly annotated.
-     */
-    private static void debugVerify(LocalList locals) {
-        try {
-            debugVerify0(locals);
-        } catch (RuntimeException ex) {
-            int sz = locals.size();
-            for (int i = 0; i < sz; i++) {
-                System.err.println(locals.get(i));
-            }
-            throw ex;
-        }
-
-    }
-
-    /**
-     * Helper for {@link #debugVerify} which does most of the work.
-     */
-    private static void debugVerify0(LocalList locals) {
-        int sz = locals.size();
-        Entry[] active = new Entry[65536];
-
-        for (int i = 0; i < sz; i++) {
-            Entry e = locals.get(i);
-            int reg = e.getRegister();
-
-            if (e.isStart()) {
-                Entry already = active[reg];
-
-                if ((already != null) && e.matches(already)) {
-                    throw new RuntimeException("redundant start at " +
-                            Integer.toHexString(e.getAddress()) + ": got " +
-                            e + "; had " + already);
-                }
-
-                active[reg] = e;
-            } else {
-                if (active[reg] == null) {
-                    throw new RuntimeException("redundant end at " +
-                            Integer.toHexString(e.getAddress()));
-                }
-
-                int addr = e.getAddress();
-                boolean foundStart = false;
-
-                for (int j = i + 1; j < sz; j++) {
-                    Entry test = locals.get(j);
-                    if (test.getAddress() != addr) {
-                        break;
-                    }
-                    if (test.getRegisterSpec().getReg() == reg) {
-                        if (test.isStart()) {
-                            if (e.getDisposition()
-                                    != Disposition.END_REPLACED) {
-                                throw new RuntimeException(
-                                        "improperly marked end at " +
-                                        Integer.toHexString(addr));
-                            }
-                            foundStart = true;
-                        } else {
-                            throw new RuntimeException(
-                                    "redundant end at " +
-                                    Integer.toHexString(addr));
-                        }
-                    }
-                }
-
-                if (!foundStart &&
-                        (e.getDisposition() == Disposition.END_REPLACED)) {
-                    throw new RuntimeException(
-                            "improper end replacement claim at " +
-                            Integer.toHexString(addr));
-                }
-
-                active[reg] = null;
-            }
-        }
-    }
-
-    /**
-     * Intermediate state when constructing a local list.
-     */
-    public static class MakeState {
-        /** {@code non-null;} result being collected */
-        private final ArrayList<Entry> result;
-
-        /**
-         * {@code >= 0;} running count of nulled result entries, to help with
-         * sizing the final list
-         */
-        private int nullResultCount;
-
-        /** {@code null-ok;} current register mappings */
-        private RegisterSpecSet regs;
-
-        /** {@code null-ok;} result indices where local ends are stored */
-        private int[] endIndices;
-
-        /** {@code >= 0;} last address seen */
-        private int lastAddress;
-
-        /**
-         * Constructs an instance.
-         */
-        public MakeState(int initialSize) {
-            result = new ArrayList<Entry>(initialSize);
-            nullResultCount = 0;
-            regs = null;
-            endIndices = null;
-            lastAddress = 0;
-        }
-
-        /**
-         * Checks the address and other vitals as a prerequisite to
-         * further processing.
-         *
-         * @param address {@code >= 0;} address about to be processed
-         * @param reg {@code >= 0;} register number about to be processed
-         */
-        private void aboutToProcess(int address, int reg) {
-            boolean first = (endIndices == null);
-
-            if ((address == lastAddress) && !first) {
-                return;
-            }
-
-            if (address < lastAddress) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            if (first || (reg >= endIndices.length)) {
-                /*
-                 * This is the first allocation of the state set and
-                 * index array, or we need to grow. (The latter doesn't
-                 * happen much; in fact, we have only ever observed
-                 * it happening in test cases, never in "real" code.)
-                 */
-                int newSz = reg + 1;
-                RegisterSpecSet newRegs = new RegisterSpecSet(newSz);
-                int[] newEnds = new int[newSz];
-                Arrays.fill(newEnds, -1);
-
-                if (!first) {
-                    newRegs.putAll(regs);
-                    System.arraycopy(endIndices, 0, newEnds, 0,
-                            endIndices.length);
-                }
-
-                regs = newRegs;
-                endIndices = newEnds;
-            }
-        }
-
-        /**
-         * Sets the local state at the given address to the given snapshot.
-         * The first call on this instance must be to this method, so that
-         * the register state can be properly sized.
-         *
-         * @param address {@code >= 0;} the address
-         * @param specs {@code non-null;} spec set representing the locals
-         */
-        public void snapshot(int address, RegisterSpecSet specs) {
-            if (DEBUG) {
-                System.err.printf("%04x snapshot %s\n", address, specs);
-            }
-
-            int sz = specs.getMaxSize();
-            aboutToProcess(address, sz - 1);
-
-            for (int i = 0; i < sz; i++) {
-                RegisterSpec oldSpec = regs.get(i);
-                RegisterSpec newSpec = filterSpec(specs.get(i));
-
-                if (oldSpec == null) {
-                    if (newSpec != null) {
-                        startLocal(address, newSpec);
-                    }
-                } else if (newSpec == null) {
-                    endLocal(address, oldSpec);
-                } else if (! newSpec.equalsUsingSimpleType(oldSpec)) {
-                    endLocal(address, oldSpec);
-                    startLocal(address, newSpec);
-                }
-            }
-
-            if (DEBUG) {
-                System.err.printf("%04x snapshot done\n", address);
-            }
-        }
-
-        /**
-         * Starts a local at the given address.
-         *
-         * @param address {@code >= 0;} the address
-         * @param startedLocal {@code non-null;} spec representing the
-         * started local
-         */
-        public void startLocal(int address, RegisterSpec startedLocal) {
-            if (DEBUG) {
-                System.err.printf("%04x start %s\n", address, startedLocal);
-            }
-
-            int regNum = startedLocal.getReg();
-
-            startedLocal = filterSpec(startedLocal);
-            aboutToProcess(address, regNum);
-
-            RegisterSpec existingLocal = regs.get(regNum);
-
-            if (startedLocal.equalsUsingSimpleType(existingLocal)) {
-                // Silently ignore a redundant start.
-                return;
-            }
-
-            RegisterSpec movedLocal = regs.findMatchingLocal(startedLocal);
-            if (movedLocal != null) {
-                /*
-                 * The same variable was moved from one register to another.
-                 * So add an end for its old location.
-                 */
-                addOrUpdateEnd(address, Disposition.END_MOVED, movedLocal);
-            }
-
-            int endAt = endIndices[regNum];
-
-            if (existingLocal != null) {
-                /*
-                 * There is an existing (but non-matching) local.
-                 * Add an explicit end for it.
-                 */
-                add(address, Disposition.END_REPLACED, existingLocal);
-            } else if (endAt >= 0) {
-                /*
-                 * Look for an end local for the same register at the
-                 * same address. If found, then update it or delete
-                 * it, depending on whether or not it represents the
-                 * same variable as the one being started.
-                 */
-                Entry endEntry = result.get(endAt);
-                if (endEntry.getAddress() == address) {
-                    if (endEntry.matches(startedLocal)) {
-                        /*
-                         * There was already an end local for the same
-                         * variable at the same address. This turns
-                         * out to be superfluous, as we are starting
-                         * up the exact same local. This situation can
-                         * happen when a single local variable got
-                         * somehow "split up" during intermediate
-                         * processing. In any case, rather than represent
-                         * the end-then-start, just remove the old end.
-                         */
-                        result.set(endAt, null);
-                        nullResultCount++;
-                        regs.put(startedLocal);
-                        endIndices[regNum] = -1;
-                        return;
-                    } else {
-                        /*
-                         * There was a different variable ended at the
-                         * same address. Update it to indicate that
-                         * it was ended due to a replacement (rather than
-                         * ending for no particular reason).
-                         */
-                        endEntry = endEntry.withDisposition(
-                                Disposition.END_REPLACED);
-                        result.set(endAt, endEntry);
-                    }
-                }
-            }
-
-            /*
-             * The code above didn't find and remove an unnecessary
-             * local end, so we now have to add one or more entries to
-             * the output to capture the transition.
-             */
-
-            /*
-             * If the local just below (in the register set at reg-1)
-             * is of category-2, then it is ended by this new start.
-             */
-            if (regNum > 0) {
-                RegisterSpec justBelow = regs.get(regNum - 1);
-                if ((justBelow != null) && justBelow.isCategory2()) {
-                    addOrUpdateEnd(address,
-                            Disposition.END_CLOBBERED_BY_NEXT,
-                            justBelow);
-                }
-            }
-
-            /*
-             * Similarly, if this local is category-2, then the local
-             * just above (if any) is ended by the start now being
-             * emitted.
-             */
-            if (startedLocal.isCategory2()) {
-                RegisterSpec justAbove = regs.get(regNum + 1);
-                if (justAbove != null) {
-                    addOrUpdateEnd(address,
-                            Disposition.END_CLOBBERED_BY_PREV,
-                            justAbove);
-                }
-            }
-
-            /*
-             * TODO: Add an end for the same local in a different reg,
-             * if any (that is, if the local migrates from vX to vY,
-             * we should note that as a local end in vX).
-             */
-
-            add(address, Disposition.START, startedLocal);
-        }
-
-        /**
-         * Ends a local at the given address, using the disposition
-         * {@code END_SIMPLY}.
-         *
-         * @param address {@code >= 0;} the address
-         * @param endedLocal {@code non-null;} spec representing the
-         * local being ended
-         */
-        public void endLocal(int address, RegisterSpec endedLocal) {
-            endLocal(address, endedLocal, Disposition.END_SIMPLY);
-        }
-
-        /**
-         * Ends a local at the given address.
-         *
-         * @param address {@code >= 0;} the address
-         * @param endedLocal {@code non-null;} spec representing the
-         * local being ended
-         * @param disposition reason for the end
-         */
-        public void endLocal(int address, RegisterSpec endedLocal,
-                Disposition disposition) {
-            if (DEBUG) {
-                System.err.printf("%04x end %s\n", address, endedLocal);
-            }
-
-            int regNum = endedLocal.getReg();
-
-            endedLocal = filterSpec(endedLocal);
-            aboutToProcess(address, regNum);
-
-            int endAt = endIndices[regNum];
-
-            if (endAt >= 0) {
-                /*
-                 * The local in the given register is already ended.
-                 * Silently return without adding anything to the result.
-                 */
-                return;
-            }
-
-            // Check for start and end at the same address.
-            if (checkForEmptyRange(address, endedLocal)) {
-                return;
-            }
-
-            add(address, disposition, endedLocal);
-        }
-
-        /**
-         * Helper for {@link #endLocal}, which handles the cases where
-         * and end local is issued at the same address as a start local
-         * for the same register. If this case is found, then this
-         * method will remove the start (as the local was never actually
-         * active), update the {@link #endIndices} to be accurate, and
-         * if needed update the newly-active end to reflect an altered
-         * disposition.
-         *
-         * @param address {@code >= 0;} the address
-         * @param endedLocal {@code non-null;} spec representing the
-         * local being ended
-         * @return {@code true} iff this method found the case in question
-         * and adjusted things accordingly
-         */
-        private boolean checkForEmptyRange(int address,
-                RegisterSpec endedLocal) {
-            int at = result.size() - 1;
-            Entry entry;
-
-            // Look for a previous entry at the same address.
-            for (/*at*/; at >= 0; at--) {
-                entry = result.get(at);
-
-                if (entry == null) {
-                    continue;
-                }
-
-                if (entry.getAddress() != address) {
-                    // We didn't find any match at the same address.
-                    return false;
-                }
-
-                if (entry.matches(endedLocal)) {
-                    break;
-                }
-            }
-
-            /*
-             * In fact, we found that the endedLocal had started at the
-             * same address, so do all the requisite cleanup.
-             */
-
-            regs.remove(endedLocal);
-            result.set(at, null);
-            nullResultCount++;
-
-            int regNum = endedLocal.getReg();
-            boolean found = false;
-            entry = null;
-
-            // Now look back further to update where the register ended.
-            for (at--; at >= 0; at--) {
-                entry = result.get(at);
-
-                if (entry == null) {
-                    continue;
-                }
-
-                if (entry.getRegisterSpec().getReg() == regNum) {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (found) {
-                // We found an end for the same register.
-                endIndices[regNum] = at;
-
-                if (entry.getAddress() == address) {
-                    /*
-                     * It's still the same address, so update the
-                     * disposition.
-                     */
-                    result.set(at,
-                            entry.withDisposition(Disposition.END_SIMPLY));
-                }
-            }
-
-            return true;
-        }
-
-        /**
-         * Converts a given spec into the form acceptable for use in a
-         * local list. This, in particular, transforms the "known
-         * null" type into simply {@code Object}. This method needs to
-         * be called for any spec that is on its way into a locals
-         * list.
-         *
-         * <p>This isn't necessarily the cleanest way to achieve the
-         * goal of not representing known nulls in a locals list, but
-         * it gets the job done.</p>
-         *
-         * @param orig {@code null-ok;} the original spec
-         * @return {@code null-ok;} an appropriately modified spec, or the
-         * original if nothing needs to be done
-         */
-        private static RegisterSpec filterSpec(RegisterSpec orig) {
-            if ((orig != null) && (orig.getType() == Type.KNOWN_NULL)) {
-                return orig.withType(Type.OBJECT);
-            }
-
-            return orig;
-        }
-
-        /**
-         * Adds an entry to the result, updating the adjunct tables
-         * accordingly.
-         *
-         * @param address {@code >= 0;} the address
-         * @param disposition {@code non-null;} the disposition
-         * @param spec {@code non-null;} spec representing the local
-         */
-        private void add(int address, Disposition disposition,
-                RegisterSpec spec) {
-            int regNum = spec.getReg();
-
-            result.add(new Entry(address, disposition, spec));
-
-            if (disposition == Disposition.START) {
-                regs.put(spec);
-                endIndices[regNum] = -1;
-            } else {
-                regs.remove(spec);
-                endIndices[regNum] = result.size() - 1;
-            }
-        }
-
-        /**
-         * Adds or updates an end local (changing its disposition). If
-         * this would cause an empty range for a local, this instead
-         * removes the local entirely.
-         *
-         * @param address {@code >= 0;} the address
-         * @param disposition {@code non-null;} the disposition
-         * @param spec {@code non-null;} spec representing the local
-         */
-        private void addOrUpdateEnd(int address, Disposition disposition,
-                RegisterSpec spec) {
-            if (disposition == Disposition.START) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            int regNum = spec.getReg();
-            int endAt = endIndices[regNum];
-
-            if (endAt >= 0) {
-                // There is a previous end.
-                Entry endEntry = result.get(endAt);
-                if ((endEntry.getAddress() == address) &&
-                        endEntry.getRegisterSpec().equals(spec)) {
-                    /*
-                     * The end is for the right address and variable, so
-                     * update it.
-                     */
-                    result.set(endAt, endEntry.withDisposition(disposition));
-                    regs.remove(spec); // TODO: Is this line superfluous?
-                    return;
-                }
-            }
-
-            endLocal(address, spec, disposition);
-        }
-
-        /**
-         * Finishes processing altogether and gets the result.
-         *
-         * @return {@code non-null;} the result list
-         */
-        public LocalList finish() {
-            aboutToProcess(Integer.MAX_VALUE, 0);
-
-            int resultSz = result.size();
-            int finalSz = resultSz - nullResultCount;
-
-            if (finalSz == 0) {
-                return EMPTY;
-            }
-
-            /*
-             * Collect an array of only the non-null entries, and then
-             * sort it to get a consistent order for everything: Local
-             * ends and starts for a given address could come in any
-             * order, but we want ends before starts as well as
-             * registers in order (within ends or starts).
-             */
-
-            Entry[] resultArr = new Entry[finalSz];
-
-            if (resultSz == finalSz) {
-                result.toArray(resultArr);
-            } else {
-                int at = 0;
-                for (Entry e : result) {
-                    if (e != null) {
-                        resultArr[at++] = e;
-                    }
-                }
-            }
-
-            Arrays.sort(resultArr);
-
-            LocalList resultList = new LocalList(finalSz);
-
-            for (int i = 0; i < finalSz; i++) {
-                resultList.set(i, resultArr[i]);
-            }
-
-            resultList.setImmutable();
-            return resultList;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/LocalSnapshot.java b/dx/src/main/java/com/android/dx/dex/code/LocalSnapshot.java
deleted file mode 100644
index baeab4c..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/LocalSnapshot.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Pseudo-instruction which is used to hold a snapshot of the
- * state of local variable name mappings that exists immediately after
- * the instance in an instruction array.
- */
-public final class LocalSnapshot extends ZeroSizeInsn {
-    /** {@code non-null;} local state associated with this instance */
-    private final RegisterSpecSet locals;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param locals {@code non-null;} associated local variable state
-     */
-    public LocalSnapshot(SourcePosition position, RegisterSpecSet locals) {
-        super(position);
-
-        if (locals == null) {
-            throw new NullPointerException("locals == null");
-        }
-
-        this.locals = locals;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisterOffset(int delta) {
-        return new LocalSnapshot(getPosition(), locals.withOffset(delta));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new LocalSnapshot(getPosition(), locals);
-    }
-
-    /**
-     * Gets the local state associated with this instance.
-     *
-     * @return {@code non-null;} the state
-     */
-    public RegisterSpecSet getLocals() {
-        return locals;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return locals.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        int sz = locals.size();
-        int max = locals.getMaxSize();
-        StringBuffer sb = new StringBuffer(100 + sz * 40);
-
-        sb.append("local-snapshot");
-
-        for (int i = 0; i < max; i++) {
-            RegisterSpec spec = locals.get(i);
-            if (spec != null) {
-                sb.append("\n  ");
-                sb.append(LocalStart.localString(spec));
-            }
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/LocalStart.java b/dx/src/main/java/com/android/dx/dex/code/LocalStart.java
deleted file mode 100644
index 9a17c5b..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/LocalStart.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Pseudo-instruction which is used to introduce a new local variable. That
- * is, an instance of this class in an instruction stream indicates that
- * starting with the subsequent instruction, the indicated variable
- * is bound.
- */
-public final class LocalStart extends ZeroSizeInsn {
-    /**
-     * {@code non-null;} register spec representing the local variable introduced
-     * by this instance
-     */
-    private final RegisterSpec local;
-
-    /**
-     * Returns the local variable listing string for a single register spec.
-     *
-     * @param spec {@code non-null;} the spec to convert
-     * @return {@code non-null;} the string form
-     */
-    public static String localString(RegisterSpec spec) {
-        return spec.regString() + ' ' + spec.getLocalItem().toString() + ": " +
-            spec.getTypeBearer().toHuman();
-    }
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param local {@code non-null;} register spec representing the local
-     * variable introduced by this instance
-     */
-    public LocalStart(SourcePosition position, RegisterSpec local) {
-        super(position);
-
-        if (local == null) {
-            throw new NullPointerException("local == null");
-        }
-
-        this.local = local;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisterOffset(int delta) {
-        return new LocalStart(getPosition(), local.withOffset(delta));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new LocalStart(getPosition(), local);
-    }
-
-    /**
-     * Gets the register spec representing the local variable introduced
-     * by this instance.
-     *
-     * @return {@code non-null;} the register spec
-     */
-    public RegisterSpec getLocal() {
-        return local;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return local.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        return "local-start " + localString(local);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/OddSpacer.java b/dx/src/main/java/com/android/dx/dex/code/OddSpacer.java
deleted file mode 100644
index f44f9cc..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/OddSpacer.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Pseudo-instruction which either turns into a {@code nop} or
- * nothingness, in order to make the subsequent instruction have an
- * even address. This is used to align (subsequent) instructions that
- * require it.
- */
-public final class OddSpacer extends VariableSizeInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     */
-    public OddSpacer(SourcePosition position) {
-        super(position, RegisterSpecList.EMPTY);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return (getAddress() & 1);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out) {
-        if (codeSize() != 0) {
-            out.writeShort(InsnFormat.codeUnit(Opcodes.NOP, 0));
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new OddSpacer(getPosition());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        if (codeSize() == 0) {
-            return null;
-        }
-
-        return "nop // spacer";
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/OutputCollector.java b/dx/src/main/java/com/android/dx/dex/code/OutputCollector.java
deleted file mode 100644
index a5e54a8..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/OutputCollector.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.dex.DexOptions;
-
-import java.util.ArrayList;
-
-/**
- * Destination for {@link DalvInsn} instances being output. This class
- * receives and collects instructions in two pieces &mdash; a primary
- * list and a suffix (generally consisting of adjunct data referred to
- * by the primary list, such as switch case tables) &mdash; which it
- * merges and emits back out in the form of a {@link DalvInsnList}
- * instance.
- */
-public final class OutputCollector {
-    /**
-     * {@code non-null;} the associated finisher (which holds the instruction
-     * list in-progress)
-     */
-    private final OutputFinisher finisher;
-
-    /**
-     * {@code null-ok;} suffix for the output, or {@code null} if the suffix
-     * has been appended to the main output (by {@link #appendSuffixToOutput})
-     */
-    private ArrayList<DalvInsn> suffix;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param dexOptions {@code non-null;} options for dex output
-     * @param initialCapacity {@code >= 0;} initial capacity of the output list
-     * @param suffixInitialCapacity {@code >= 0;} initial capacity of the output
-     * suffix
-     * @param regCount {@code >= 0;} register count for the method
-     */
-    public OutputCollector(DexOptions dexOptions, int initialCapacity, int suffixInitialCapacity,
-            int regCount) {
-        this.finisher = new OutputFinisher(dexOptions, initialCapacity, regCount);
-        this.suffix = new ArrayList<DalvInsn>(suffixInitialCapacity);
-    }
-
-    /**
-     * Adds an instruction to the output.
-     *
-     * @param insn {@code non-null;} the instruction to add
-     */
-    public void add(DalvInsn insn) {
-        finisher.add(insn);
-    }
-
-    /**
-     * Reverses a branch which is buried a given number of instructions
-     * backward in the output. It is illegal to call this unless the
-     * indicated instruction really is a reversible branch.
-     *
-     * @param which how many instructions back to find the branch;
-     * {@code 0} is the most recently added instruction,
-     * {@code 1} is the instruction before that, etc.
-     * @param newTarget {@code non-null;} the new target for the reversed branch
-     */
-    public void reverseBranch(int which, CodeAddress newTarget) {
-        finisher.reverseBranch(which, newTarget);
-    }
-
-    /**
-     * Adds an instruction to the output suffix.
-     *
-     * @param insn {@code non-null;} the instruction to add
-     */
-    public void addSuffix(DalvInsn insn) {
-        suffix.add(insn);
-    }
-
-    /**
-     * Gets the results of all the calls on this instance, in the form of
-     * an {@link OutputFinisher}.
-     *
-     * @return {@code non-null;} the output finisher
-     * @throws UnsupportedOperationException if this method has
-     * already been called
-     */
-    public OutputFinisher getFinisher() {
-        if (suffix == null) {
-            throw new UnsupportedOperationException("already processed");
-        }
-
-        appendSuffixToOutput();
-        return finisher;
-    }
-
-    /**
-     * Helper for {@link #getFinisher}, which appends the suffix to
-     * the primary output.
-     */
-    private void appendSuffixToOutput() {
-        int size = suffix.size();
-
-        for (int i = 0; i < size; i++) {
-            finisher.add(suffix.get(i));
-        }
-
-        suffix = null;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/OutputFinisher.java b/dx/src/main/java/com/android/dx/dex/code/OutputFinisher.java
deleted file mode 100644
index 19b5634..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/OutputFinisher.java
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.dex.DexOptions;
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMemberRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Type;
-
-import com.android.dx.util.DexException;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashSet;
-
-/**
- * Processor for instruction lists, which takes a "first cut" of
- * instruction selection as a basis and produces a "final cut" in the
- * form of a {@link DalvInsnList} instance.
- */
-public final class OutputFinisher {
-    /** {@code non-null;} options for dex output */
-    private final DexOptions dexOptions;
-
-    /**
-     * {@code >= 0;} register count for the method, not including any extra
-     * "reserved" registers needed to translate "difficult" instructions
-     */
-    private final int unreservedRegCount;
-
-    /** {@code non-null;} the list of instructions, per se */
-    private ArrayList<DalvInsn> insns;
-
-    /** whether any instruction has position info */
-    private boolean hasAnyPositionInfo;
-
-    /** whether any instruction has local variable info */
-    private boolean hasAnyLocalInfo;
-
-    /**
-     * {@code >= 0;} the count of reserved registers (low-numbered
-     * registers used when expanding instructions that can't be
-     * represented simply); becomes valid after a call to {@link
-     * #massageInstructions}
-     */
-    private int reservedCount;
-
-    /**
-     * Constructs an instance. It initially contains no instructions.
-     *
-     * @param dexOptions {@code non-null;} options for dex output
-     * @param regCount {@code >= 0;} register count for the method
-     * @param initialCapacity {@code >= 0;} initial capacity of the
-     * instructions list
-     */
-    public OutputFinisher(DexOptions dexOptions, int initialCapacity, int regCount) {
-        this.dexOptions = dexOptions;
-        this.unreservedRegCount = regCount;
-        this.insns = new ArrayList<DalvInsn>(initialCapacity);
-        this.reservedCount = -1;
-        this.hasAnyPositionInfo = false;
-        this.hasAnyLocalInfo = false;
-    }
-
-    /**
-     * Returns whether any of the instructions added to this instance
-     * come with position info.
-     *
-     * @return whether any of the instructions added to this instance
-     * come with position info
-     */
-    public boolean hasAnyPositionInfo() {
-        return hasAnyPositionInfo;
-    }
-
-    /**
-     * Returns whether this instance has any local variable information.
-     *
-     * @return whether this instance has any local variable information
-     */
-    public boolean hasAnyLocalInfo() {
-        return hasAnyLocalInfo;
-    }
-
-    /**
-     * Helper for {@link #add} which scrutinizes a single
-     * instruction for local variable information.
-     *
-     * @param insn {@code non-null;} instruction to scrutinize
-     * @return {@code true} iff the instruction refers to any
-     * named locals
-     */
-    private static boolean hasLocalInfo(DalvInsn insn) {
-        if (insn instanceof LocalSnapshot) {
-            RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
-            int size = specs.size();
-            for (int i = 0; i < size; i++) {
-                if (hasLocalInfo(specs.get(i))) {
-                    return true;
-                }
-            }
-        } else if (insn instanceof LocalStart) {
-            RegisterSpec spec = ((LocalStart) insn).getLocal();
-            if (hasLocalInfo(spec)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Helper for {@link #hasAnyLocalInfo} which scrutinizes a single
-     * register spec.
-     *
-     * @param spec {@code non-null;} spec to scrutinize
-     * @return {@code true} iff the spec refers to any
-     * named locals
-     */
-    private static boolean hasLocalInfo(RegisterSpec spec) {
-        return (spec != null)
-            && (spec.getLocalItem().getName() != null);
-    }
-
-    /**
-     * Returns the set of all constants referred to by instructions added
-     * to this instance.
-     *
-     * @return {@code non-null;} the set of constants
-     */
-    public HashSet<Constant> getAllConstants() {
-        HashSet<Constant> result = new HashSet<Constant>(20);
-
-        for (DalvInsn insn : insns) {
-            addConstants(result, insn);
-        }
-
-        return result;
-    }
-
-    /**
-     * Helper for {@link #getAllConstants} which adds all the info for
-     * a single instruction.
-     *
-     * @param result {@code non-null;} result set to add to
-     * @param insn {@code non-null;} instruction to scrutinize
-     */
-    private static void addConstants(HashSet<Constant> result,
-            DalvInsn insn) {
-        if (insn instanceof CstInsn) {
-            Constant cst = ((CstInsn) insn).getConstant();
-            result.add(cst);
-        } else if (insn instanceof LocalSnapshot) {
-            RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
-            int size = specs.size();
-            for (int i = 0; i < size; i++) {
-                addConstants(result, specs.get(i));
-            }
-        } else if (insn instanceof LocalStart) {
-            RegisterSpec spec = ((LocalStart) insn).getLocal();
-            addConstants(result, spec);
-        }
-    }
-
-    /**
-     * Helper for {@link #getAllConstants} which adds all the info for
-     * a single {@code RegisterSpec}.
-     *
-     * @param result {@code non-null;} result set to add to
-     * @param spec {@code null-ok;} register spec to add
-     */
-    private static void addConstants(HashSet<Constant> result,
-            RegisterSpec spec) {
-        if (spec == null) {
-            return;
-        }
-
-        LocalItem local = spec.getLocalItem();
-        CstString name = local.getName();
-        CstString signature = local.getSignature();
-        Type type = spec.getType();
-
-        if (type != Type.KNOWN_NULL) {
-            result.add(CstType.intern(type));
-        }
-
-        if (name != null) {
-            result.add(name);
-        }
-
-        if (signature != null) {
-            result.add(signature);
-        }
-    }
-
-    /**
-     * Adds an instruction to the output.
-     *
-     * @param insn {@code non-null;} the instruction to add
-     */
-    public void add(DalvInsn insn) {
-        insns.add(insn);
-        updateInfo(insn);
-    }
-
-    /**
-     * Inserts an instruction in the output at the given offset.
-     *
-     * @param at {@code >= 0;} what index to insert at
-     * @param insn {@code non-null;} the instruction to insert
-     */
-    public void insert(int at, DalvInsn insn) {
-        insns.add(at, insn);
-        updateInfo(insn);
-    }
-
-    /**
-     * Helper for {@link #add} and {@link #insert},
-     * which updates the position and local info flags.
-     *
-     * @param insn {@code non-null;} an instruction that was just introduced
-     */
-    private void updateInfo(DalvInsn insn) {
-        if (! hasAnyPositionInfo) {
-            SourcePosition pos = insn.getPosition();
-            if (pos.getLine() >= 0) {
-                hasAnyPositionInfo = true;
-            }
-        }
-
-        if (! hasAnyLocalInfo) {
-            if (hasLocalInfo(insn)) {
-                hasAnyLocalInfo = true;
-            }
-        }
-    }
-
-    /**
-     * Reverses a branch which is buried a given number of instructions
-     * backward in the output. It is illegal to call this unless the
-     * indicated instruction really is a reversible branch.
-     *
-     * @param which how many instructions back to find the branch;
-     * {@code 0} is the most recently added instruction,
-     * {@code 1} is the instruction before that, etc.
-     * @param newTarget {@code non-null;} the new target for the
-     * reversed branch
-     */
-    public void reverseBranch(int which, CodeAddress newTarget) {
-        int size = insns.size();
-        int index = size - which - 1;
-        TargetInsn targetInsn;
-
-        try {
-            targetInsn = (TargetInsn) insns.get(index);
-        } catch (IndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("too few instructions");
-        } catch (ClassCastException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("non-reversible instruction");
-        }
-
-        /*
-         * No need to call this.set(), since the format and other info
-         * are the same.
-         */
-        insns.set(index, targetInsn.withNewTargetAndReversed(newTarget));
-    }
-
-    /**
-     * Assigns indices in all instructions that need them, using the
-     * given callback to perform lookups. This should be called before
-     * calling {@link #finishProcessingAndGetList}.
-     *
-     * @param callback {@code non-null;} callback object
-     */
-    public void assignIndices(DalvCode.AssignIndicesCallback callback) {
-        for (DalvInsn insn : insns) {
-            if (insn instanceof CstInsn) {
-                assignIndices((CstInsn) insn, callback);
-            }
-        }
-    }
-
-    /**
-     * Helper for {@link #assignIndices} which does assignment for one
-     * instruction.
-     *
-     * @param insn {@code non-null;} the instruction
-     * @param callback {@code non-null;} the callback
-     */
-    private static void assignIndices(CstInsn insn,
-            DalvCode.AssignIndicesCallback callback) {
-        Constant cst = insn.getConstant();
-        int index = callback.getIndex(cst);
-
-        if (index >= 0) {
-            insn.setIndex(index);
-        }
-
-        if (cst instanceof CstMemberRef) {
-            CstMemberRef member = (CstMemberRef) cst;
-            CstType definer = member.getDefiningClass();
-            index = callback.getIndex(definer);
-            if (index >= 0) {
-                insn.setClassIndex(index);
-            }
-        }
-    }
-
-    /**
-     * Does final processing on this instance and gets the output as
-     * a {@link DalvInsnList}. Final processing consists of:
-     *
-     * <ul>
-     *   <li>optionally renumbering registers (to make room as needed for
-     *   expanded instructions)</li>
-     *   <li>picking a final opcode for each instruction</li>
-     *   <li>rewriting instructions, because of register number,
-     *   constant pool index, or branch target size issues</li>
-     *   <li>assigning final addresses</li>
-     * </ul>
-     *
-     * <p><b>Note:</b> This method may only be called once per instance
-     * of this class.</p>
-     *
-     * @return {@code non-null;} the output list
-     * @throws UnsupportedOperationException if this method has
-     * already been called
-     */
-    public DalvInsnList finishProcessingAndGetList() {
-        if (reservedCount >= 0) {
-            throw new UnsupportedOperationException("already processed");
-        }
-
-        Dop[] opcodes = makeOpcodesArray();
-        reserveRegisters(opcodes);
-        massageInstructions(opcodes);
-        assignAddressesAndFixBranches();
-
-        return DalvInsnList.makeImmutable(insns,
-                reservedCount + unreservedRegCount);
-    }
-
-    /**
-     * Helper for {@link #finishProcessingAndGetList}, which extracts
-     * the opcode out of each instruction into a separate array, to be
-     * further manipulated as things progress.
-     *
-     * @return {@code non-null;} the array of opcodes
-     */
-    private Dop[] makeOpcodesArray() {
-        int size = insns.size();
-        Dop[] result = new Dop[size];
-
-        for (int i = 0; i < size; i++) {
-            result[i] = insns.get(i).getOpcode();
-        }
-
-        return result;
-    }
-
-    /**
-     * Helper for {@link #finishProcessingAndGetList}, which figures
-     * out how many reserved registers are required and then reserving
-     * them. It also updates the given {@code opcodes} array so
-     * as to avoid extra work when constructing the massaged
-     * instruction list.
-     *
-     * @param opcodes {@code non-null;} array of per-instruction
-     * opcode selections
-     */
-    private void reserveRegisters(Dop[] opcodes) {
-        int oldReservedCount = (reservedCount < 0) ? 0 : reservedCount;
-
-        /*
-         * Call calculateReservedCount() and then perform register
-         * reservation, repeatedly until no new reservations happen.
-         */
-        for (;;) {
-            int newReservedCount = calculateReservedCount(opcodes);
-            if (oldReservedCount >= newReservedCount) {
-                break;
-            }
-
-            int reservedDifference = newReservedCount - oldReservedCount;
-            int size = insns.size();
-
-            for (int i = 0; i < size; i++) {
-                /*
-                 * CodeAddress instance identity is used to link
-                 * TargetInsns to their targets, so it is
-                 * inappropriate to make replacements, and they don't
-                 * have registers in any case. Hence, the instanceof
-                 * test below.
-                 */
-                DalvInsn insn = insns.get(i);
-                if (!(insn instanceof CodeAddress)) {
-                    /*
-                     * No need to call this.set() since the format and
-                     * other info are the same.
-                     */
-                    insns.set(i, insn.withRegisterOffset(reservedDifference));
-                }
-            }
-
-            oldReservedCount = newReservedCount;
-        }
-
-        reservedCount = oldReservedCount;
-    }
-
-    /**
-     * Helper for {@link #reserveRegisters}, which does one
-     * pass over the instructions, calculating the number of
-     * registers that need to be reserved. It also updates the
-     * {@code opcodes} list to help avoid extra work in future
-     * register reservation passes.
-     *
-     * @param opcodes {@code non-null;} array of per-instruction
-     * opcode selections
-     * @return {@code >= 0;} the count of reserved registers
-     */
-    private int calculateReservedCount(Dop[] opcodes) {
-        int size = insns.size();
-
-        /*
-         * Potential new value of reservedCount, which gets updated in the
-         * following loop. It starts out with the existing reservedCount
-         * and gets increased if it turns out that additional registers
-         * need to be reserved.
-         */
-        int newReservedCount = reservedCount;
-
-        for (int i = 0; i < size; i++) {
-            DalvInsn insn = insns.get(i);
-            Dop originalOpcode = opcodes[i];
-            Dop newOpcode = findOpcodeForInsn(insn, originalOpcode);
-
-            if (newOpcode == null) {
-                /*
-                 * The instruction will need to be expanded, so find the
-                 * expanded opcode and reserve registers for it.
-                 */
-                Dop expandedOp = findExpandedOpcodeForInsn(insn);
-                BitSet compatRegs = expandedOp.getFormat().compatibleRegs(insn);
-                int reserve = insn.getMinimumRegisterRequirement(compatRegs);
-                if (reserve > newReservedCount) {
-                    newReservedCount = reserve;
-                }
-            } else if (originalOpcode == newOpcode) {
-                continue;
-            }
-
-            opcodes[i] = newOpcode;
-        }
-
-        return newReservedCount;
-    }
-
-    /**
-     * Attempts to fit the given instruction into a specific opcode,
-     * returning the opcode whose format that the instruction fits
-     * into or {@code null} to indicate that the instruction will need
-     * to be expanded. This fitting process starts with the given
-     * opcode as a first "best guess" and then pessimizes from there
-     * if necessary.
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @param guess {@code null-ok;} the current guess as to the best
-     * opcode; {@code null} means that no simple opcode fits
-     * @return {@code null-ok;} a possibly-different opcode; either a
-     * {@code non-null} good fit or {@code null} to indicate that no
-     * simple opcode fits
-     */
-    private Dop findOpcodeForInsn(DalvInsn insn, Dop guess) {
-        /*
-         * Note: The initial guess might be null, meaning that an
-         * earlier call to this method already determined that there
-         * was no possible simple opcode fit.
-         */
-
-        while (guess != null) {
-            if (guess.getFormat().isCompatible(insn)) {
-                break;
-            }
-
-            guess = Dops.getNextOrNull(guess, dexOptions);
-        }
-
-        return guess;
-    }
-
-    /**
-     * Finds the proper opcode for the given instruction, ignoring
-     * register constraints.
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @return {@code non-null;} the opcode that fits
-     */
-    private Dop findExpandedOpcodeForInsn(DalvInsn insn) {
-        Dop result = findOpcodeForInsn(insn.getLowRegVersion(), insn.getOpcode());
-        if (result == null) {
-            throw new DexException("No expanded opcode for " + insn);
-        }
-        return result;
-    }
-
-    /**
-     * Helper for {@link #finishProcessingAndGetList}, which goes
-     * through each instruction in the output, making sure its opcode
-     * can accomodate its arguments. In cases where the opcode is
-     * unable to do so, this replaces the instruction with a larger
-     * instruction with identical semantics that <i>will</i> work.
-     *
-     * <p>This method may also reserve a number of low-numbered
-     * registers, renumbering the instructions' original registers, in
-     * order to have register space available in which to move
-     * very-high registers when expanding instructions into
-     * multi-instruction sequences. This expansion is done when no
-     * simple instruction format can be found for a given instruction that
-     * is able to accomodate that instruction's registers.</p>
-     *
-     * <p>This method ignores issues of branch target size, since
-     * final addresses aren't known at the point that this method is
-     * called.</p>
-     *
-     * @param opcodes {@code non-null;} array of per-instruction
-     * opcode selections
-     */
-    private void massageInstructions(Dop[] opcodes) {
-        if (reservedCount == 0) {
-            /*
-             * The easy common case: No registers were reserved, so we
-             * merely need to replace any instructions whose format
-             * (and hence whose opcode) changed during the reservation
-             * pass, but all instructions will stay at their original
-             * indices, and the instruction list doesn't grow.
-             */
-            int size = insns.size();
-
-            for (int i = 0; i < size; i++) {
-                DalvInsn insn = insns.get(i);
-                Dop originalOpcode = insn.getOpcode();
-                Dop currentOpcode = opcodes[i];
-
-                if (originalOpcode != currentOpcode) {
-                    insns.set(i, insn.withOpcode(currentOpcode));
-                }
-            }
-        } else {
-            /*
-             * The difficult uncommon case: Some instructions have to be
-             * expanded to deal with high registers.
-             */
-            insns = performExpansion(opcodes);
-        }
-    }
-
-    /**
-     * Helper for {@link #massageInstructions}, which constructs a
-     * replacement list, where each {link DalvInsn} instance that
-     * couldn't be represented simply (due to register representation
-     * problems) is expanded into a series of instances that together
-     * perform the proper function.
-     *
-     * @param opcodes {@code non-null;} array of per-instruction
-     * opcode selections
-     * @return {@code non-null;} the replacement list
-     */
-    private ArrayList<DalvInsn> performExpansion(Dop[] opcodes) {
-        int size = insns.size();
-        ArrayList<DalvInsn> result = new ArrayList<DalvInsn>(size * 2);
-
-        for (int i = 0; i < size; i++) {
-            DalvInsn insn = insns.get(i);
-            Dop originalOpcode = insn.getOpcode();
-            Dop currentOpcode = opcodes[i];
-            DalvInsn prefix;
-            DalvInsn suffix;
-
-            if (currentOpcode != null) {
-                // No expansion is necessary.
-                prefix = null;
-                suffix = null;
-            } else {
-                // Expansion is required.
-                currentOpcode = findExpandedOpcodeForInsn(insn);
-                BitSet compatRegs =
-                    currentOpcode.getFormat().compatibleRegs(insn);
-                prefix = insn.expandedPrefix(compatRegs);
-                suffix = insn.expandedSuffix(compatRegs);
-
-                // Expand necessary registers to fit the new format
-                insn = insn.expandedVersion(compatRegs);
-            }
-
-            if (prefix != null) {
-                result.add(prefix);
-            }
-
-            if (currentOpcode != originalOpcode) {
-                insn = insn.withOpcode(currentOpcode);
-            }
-            result.add(insn);
-
-            if (suffix != null) {
-                result.add(suffix);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Helper for {@link #finishProcessingAndGetList}, which assigns
-     * addresses to each instruction, possibly rewriting branches to
-     * fix ones that wouldn't otherwise be able to reach their
-     * targets.
-     */
-    private void assignAddressesAndFixBranches() {
-        for (;;) {
-            assignAddresses();
-            if (!fixBranches()) {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Helper for {@link #assignAddressesAndFixBranches}, which
-     * assigns an address to each instruction, in order.
-     */
-    private void assignAddresses() {
-        int address = 0;
-        int size = insns.size();
-
-        for (int i = 0; i < size; i++) {
-            DalvInsn insn = insns.get(i);
-            insn.setAddress(address);
-            address += insn.codeSize();
-        }
-    }
-
-    /**
-     * Helper for {@link #assignAddressesAndFixBranches}, which checks
-     * the branch target size requirement of each branch instruction
-     * to make sure it fits. For instructions that don't fit, this
-     * rewrites them to use a {@code goto} of some sort. In the
-     * case of a conditional branch that doesn't fit, the sense of the
-     * test is reversed in order to branch around a {@code goto}
-     * to the original target.
-     *
-     * @return whether any branches had to be fixed
-     */
-    private boolean fixBranches() {
-        int size = insns.size();
-        boolean anyFixed = false;
-
-        for (int i = 0; i < size; i++) {
-            DalvInsn insn = insns.get(i);
-            if (!(insn instanceof TargetInsn)) {
-                // This loop only needs to inspect TargetInsns.
-                continue;
-            }
-
-            Dop opcode = insn.getOpcode();
-            TargetInsn target = (TargetInsn) insn;
-
-            if (opcode.getFormat().branchFits(target)) {
-                continue;
-            }
-
-            if (opcode.getFamily() == Opcodes.GOTO) {
-                // It is a goto; widen it if possible.
-                opcode = findOpcodeForInsn(insn, opcode);
-                if (opcode == null) {
-                    /*
-                     * The branch is already maximally large. This should
-                     * only be possible if a method somehow manages to have
-                     * more than 2^31 code units.
-                     */
-                    throw new UnsupportedOperationException("method too long");
-                }
-                insns.set(i, insn.withOpcode(opcode));
-            } else {
-                /*
-                 * It is a conditional: Reverse its sense, and arrange for
-                 * it to branch around an absolute goto to the original
-                 * branch target.
-                 *
-                 * Note: An invariant of the list being processed is
-                 * that every TargetInsn is followed by a CodeAddress.
-                 * Hence, it is always safe to get the next element
-                 * after a TargetInsn and cast it to CodeAddress, as
-                 * is happening a few lines down.
-                 *
-                 * Also note: Size gets incremented by one here, as we
-                 * have -- in the net -- added one additional element
-                 * to the list, so we increment i to match. The added
-                 * and changed elements will be inspected by a repeat
-                 * call to this method after this invocation returns.
-                 */
-                CodeAddress newTarget;
-                try {
-                    newTarget = (CodeAddress) insns.get(i + 1);
-                } catch (IndexOutOfBoundsException ex) {
-                    // The TargetInsn / CodeAddress invariant was violated.
-                    throw new IllegalStateException(
-                            "unpaired TargetInsn (dangling)");
-                } catch (ClassCastException ex) {
-                    // The TargetInsn / CodeAddress invariant was violated.
-                    throw new IllegalStateException("unpaired TargetInsn");
-                }
-                TargetInsn gotoInsn =
-                    new TargetInsn(Dops.GOTO, target.getPosition(),
-                            RegisterSpecList.EMPTY, target.getTarget());
-                insns.set(i, gotoInsn);
-                insns.add(i, target.withNewTargetAndReversed(newTarget));
-                size++;
-                i++;
-            }
-
-            anyFixed = true;
-        }
-
-        return anyFixed;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/PositionList.java b/dx/src/main/java/com/android/dx/dex/code/PositionList.java
deleted file mode 100644
index 1e07e46..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/PositionList.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.FixedSizeList;
-
-/**
- * List of source position entries. This class includes a utility
- * method to extract an instance out of a {@link DalvInsnList}.
- */
-public final class PositionList extends FixedSizeList {
-    /** {@code non-null;} empty instance */
-    public static final PositionList EMPTY = new PositionList(0);
-
-    /**
-     * constant for {@link #make} to indicate that no actual position
-     * information should be returned
-     */
-    public static final int NONE = 1;
-
-    /**
-     * constant for {@link #make} to indicate that only line number
-     * transitions should be returned
-     */
-    public static final int LINES = 2;
-
-    /**
-     * constant for {@link #make} to indicate that only "important" position
-     * information should be returned. This includes block starts and
-     * instructions that might throw.
-     */
-    public static final int IMPORTANT = 3;
-
-    /**
-     * Extracts and returns the source position information out of an
-     * instruction list.
-     *
-     * @param insns {@code non-null;} instructions to convert
-     * @param howMuch how much information should be included; one of the
-     * static constants defined by this class
-     * @return {@code non-null;} the positions list
-     */
-    public static PositionList make(DalvInsnList insns, int howMuch) {
-        switch (howMuch) {
-            case NONE: {
-                return EMPTY;
-            }
-            case LINES:
-            case IMPORTANT: {
-                // Valid.
-                break;
-            }
-            default: {
-                throw new IllegalArgumentException("bogus howMuch");
-            }
-        }
-
-        SourcePosition noInfo = SourcePosition.NO_INFO;
-        SourcePosition cur = noInfo;
-        int sz = insns.size();
-        PositionList.Entry[] arr = new PositionList.Entry[sz];
-        boolean lastWasTarget = false;
-        int at = 0;
-
-        for (int i = 0; i < sz; i++) {
-            DalvInsn insn = insns.get(i);
-
-            if (insn instanceof CodeAddress) {
-                lastWasTarget = true;;
-                continue;
-            }
-
-            SourcePosition pos = insn.getPosition();
-
-            if (pos.equals(noInfo) || pos.sameLine(cur)) {
-                continue;
-            }
-
-            if ((howMuch == IMPORTANT) && !lastWasTarget) {
-                continue;
-            }
-
-            cur = pos;
-            arr[at] = new PositionList.Entry(insn.getAddress(), pos);
-            at++;
-
-            lastWasTarget = false;
-        }
-
-        PositionList result = new PositionList(at);
-        for (int i = 0; i < at; i++) {
-            result.set(i, arr[i]);
-        }
-
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size {@code >= 0;} the size of the list
-     */
-    public PositionList(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Entry get(int n) {
-        return (Entry) get0(n);
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param entry {@code non-null;} the entry to set at {@code n}
-     */
-    public void set(int n, Entry entry) {
-        set0(n, entry);
-    }
-
-    /**
-     * Entry in a position list.
-     */
-    public static class Entry {
-        /** {@code >= 0;} address of this entry */
-        private final int address;
-
-        /** {@code non-null;} corresponding source position information */
-        private final SourcePosition position;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param address {@code >= 0;} address of this entry
-         * @param position {@code non-null;} corresponding source position information
-         */
-        public Entry (int address, SourcePosition position) {
-            if (address < 0) {
-                throw new IllegalArgumentException("address < 0");
-            }
-
-            if (position == null) {
-                throw new NullPointerException("position == null");
-            }
-
-            this.address = address;
-            this.position = position;
-        }
-
-        /**
-         * Gets the address.
-         *
-         * @return {@code >= 0;} the address
-         */
-        public int getAddress() {
-            return address;
-        }
-
-        /**
-         * Gets the source position information.
-         *
-         * @return {@code non-null;} the position information
-         */
-        public SourcePosition getPosition() {
-            return position;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/RopToDop.java b/dx/src/main/java/com/android/dx/dex/code/RopToDop.java
deleted file mode 100644
index 0330113..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/RopToDop.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.ThrowingCstInsn;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Type;
-
-import java.util.HashMap;
-
-/**
- * Translator from rop-level {@link Insn} instances to corresponding
- * {@link Dop} instances.
- */
-public final class RopToDop {
-    /** {@code non-null;} map from all the common rops to dalvik opcodes */
-    private static final HashMap<Rop, Dop> MAP;
-
-    /**
-     * This class is uninstantiable.
-     */
-    private RopToDop() {
-        // This space intentionally left blank.
-    }
-
-    /*
-     * The following comment lists each opcode that should be considered
-     * the "head" of an opcode chain, in terms of the process of fitting
-     * an instruction's arguments to an actual opcode. This list is
-     * automatically generated and may be of use in double-checking the
-     * manually-generated static initialization code for this class.
-     *
-     * TODO: Make opcode-gen produce useful code in this case instead
-     * of just a comment.
-     */
-
-    // BEGIN(first-opcodes); GENERATED AUTOMATICALLY BY opcode-gen
-    //     Opcodes.NOP
-    //     Opcodes.MOVE
-    //     Opcodes.MOVE_WIDE
-    //     Opcodes.MOVE_OBJECT
-    //     Opcodes.MOVE_RESULT
-    //     Opcodes.MOVE_RESULT_WIDE
-    //     Opcodes.MOVE_RESULT_OBJECT
-    //     Opcodes.MOVE_EXCEPTION
-    //     Opcodes.RETURN_VOID
-    //     Opcodes.RETURN
-    //     Opcodes.RETURN_WIDE
-    //     Opcodes.RETURN_OBJECT
-    //     Opcodes.CONST_4
-    //     Opcodes.CONST_WIDE_16
-    //     Opcodes.CONST_STRING
-    //     Opcodes.CONST_CLASS
-    //     Opcodes.MONITOR_ENTER
-    //     Opcodes.MONITOR_EXIT
-    //     Opcodes.CHECK_CAST
-    //     Opcodes.INSTANCE_OF
-    //     Opcodes.ARRAY_LENGTH
-    //     Opcodes.NEW_INSTANCE
-    //     Opcodes.NEW_ARRAY
-    //     Opcodes.FILLED_NEW_ARRAY
-    //     Opcodes.FILL_ARRAY_DATA
-    //     Opcodes.THROW
-    //     Opcodes.GOTO
-    //     Opcodes.PACKED_SWITCH
-    //     Opcodes.SPARSE_SWITCH
-    //     Opcodes.CMPL_FLOAT
-    //     Opcodes.CMPG_FLOAT
-    //     Opcodes.CMPL_DOUBLE
-    //     Opcodes.CMPG_DOUBLE
-    //     Opcodes.CMP_LONG
-    //     Opcodes.IF_EQ
-    //     Opcodes.IF_NE
-    //     Opcodes.IF_LT
-    //     Opcodes.IF_GE
-    //     Opcodes.IF_GT
-    //     Opcodes.IF_LE
-    //     Opcodes.IF_EQZ
-    //     Opcodes.IF_NEZ
-    //     Opcodes.IF_LTZ
-    //     Opcodes.IF_GEZ
-    //     Opcodes.IF_GTZ
-    //     Opcodes.IF_LEZ
-    //     Opcodes.AGET
-    //     Opcodes.AGET_WIDE
-    //     Opcodes.AGET_OBJECT
-    //     Opcodes.AGET_BOOLEAN
-    //     Opcodes.AGET_BYTE
-    //     Opcodes.AGET_CHAR
-    //     Opcodes.AGET_SHORT
-    //     Opcodes.APUT
-    //     Opcodes.APUT_WIDE
-    //     Opcodes.APUT_OBJECT
-    //     Opcodes.APUT_BOOLEAN
-    //     Opcodes.APUT_BYTE
-    //     Opcodes.APUT_CHAR
-    //     Opcodes.APUT_SHORT
-    //     Opcodes.IGET
-    //     Opcodes.IGET_WIDE
-    //     Opcodes.IGET_OBJECT
-    //     Opcodes.IGET_BOOLEAN
-    //     Opcodes.IGET_BYTE
-    //     Opcodes.IGET_CHAR
-    //     Opcodes.IGET_SHORT
-    //     Opcodes.IPUT
-    //     Opcodes.IPUT_WIDE
-    //     Opcodes.IPUT_OBJECT
-    //     Opcodes.IPUT_BOOLEAN
-    //     Opcodes.IPUT_BYTE
-    //     Opcodes.IPUT_CHAR
-    //     Opcodes.IPUT_SHORT
-    //     Opcodes.SGET
-    //     Opcodes.SGET_WIDE
-    //     Opcodes.SGET_OBJECT
-    //     Opcodes.SGET_BOOLEAN
-    //     Opcodes.SGET_BYTE
-    //     Opcodes.SGET_CHAR
-    //     Opcodes.SGET_SHORT
-    //     Opcodes.SPUT
-    //     Opcodes.SPUT_WIDE
-    //     Opcodes.SPUT_OBJECT
-    //     Opcodes.SPUT_BOOLEAN
-    //     Opcodes.SPUT_BYTE
-    //     Opcodes.SPUT_CHAR
-    //     Opcodes.SPUT_SHORT
-    //     Opcodes.INVOKE_VIRTUAL
-    //     Opcodes.INVOKE_SUPER
-    //     Opcodes.INVOKE_DIRECT
-    //     Opcodes.INVOKE_STATIC
-    //     Opcodes.INVOKE_INTERFACE
-    //     Opcodes.NEG_INT
-    //     Opcodes.NOT_INT
-    //     Opcodes.NEG_LONG
-    //     Opcodes.NOT_LONG
-    //     Opcodes.NEG_FLOAT
-    //     Opcodes.NEG_DOUBLE
-    //     Opcodes.INT_TO_LONG
-    //     Opcodes.INT_TO_FLOAT
-    //     Opcodes.INT_TO_DOUBLE
-    //     Opcodes.LONG_TO_INT
-    //     Opcodes.LONG_TO_FLOAT
-    //     Opcodes.LONG_TO_DOUBLE
-    //     Opcodes.FLOAT_TO_INT
-    //     Opcodes.FLOAT_TO_LONG
-    //     Opcodes.FLOAT_TO_DOUBLE
-    //     Opcodes.DOUBLE_TO_INT
-    //     Opcodes.DOUBLE_TO_LONG
-    //     Opcodes.DOUBLE_TO_FLOAT
-    //     Opcodes.INT_TO_BYTE
-    //     Opcodes.INT_TO_CHAR
-    //     Opcodes.INT_TO_SHORT
-    //     Opcodes.ADD_INT_2ADDR
-    //     Opcodes.SUB_INT_2ADDR
-    //     Opcodes.MUL_INT_2ADDR
-    //     Opcodes.DIV_INT_2ADDR
-    //     Opcodes.REM_INT_2ADDR
-    //     Opcodes.AND_INT_2ADDR
-    //     Opcodes.OR_INT_2ADDR
-    //     Opcodes.XOR_INT_2ADDR
-    //     Opcodes.SHL_INT_2ADDR
-    //     Opcodes.SHR_INT_2ADDR
-    //     Opcodes.USHR_INT_2ADDR
-    //     Opcodes.ADD_LONG_2ADDR
-    //     Opcodes.SUB_LONG_2ADDR
-    //     Opcodes.MUL_LONG_2ADDR
-    //     Opcodes.DIV_LONG_2ADDR
-    //     Opcodes.REM_LONG_2ADDR
-    //     Opcodes.AND_LONG_2ADDR
-    //     Opcodes.OR_LONG_2ADDR
-    //     Opcodes.XOR_LONG_2ADDR
-    //     Opcodes.SHL_LONG_2ADDR
-    //     Opcodes.SHR_LONG_2ADDR
-    //     Opcodes.USHR_LONG_2ADDR
-    //     Opcodes.ADD_FLOAT_2ADDR
-    //     Opcodes.SUB_FLOAT_2ADDR
-    //     Opcodes.MUL_FLOAT_2ADDR
-    //     Opcodes.DIV_FLOAT_2ADDR
-    //     Opcodes.REM_FLOAT_2ADDR
-    //     Opcodes.ADD_DOUBLE_2ADDR
-    //     Opcodes.SUB_DOUBLE_2ADDR
-    //     Opcodes.MUL_DOUBLE_2ADDR
-    //     Opcodes.DIV_DOUBLE_2ADDR
-    //     Opcodes.REM_DOUBLE_2ADDR
-    //     Opcodes.ADD_INT_LIT8
-    //     Opcodes.RSUB_INT_LIT8
-    //     Opcodes.MUL_INT_LIT8
-    //     Opcodes.DIV_INT_LIT8
-    //     Opcodes.REM_INT_LIT8
-    //     Opcodes.AND_INT_LIT8
-    //     Opcodes.OR_INT_LIT8
-    //     Opcodes.XOR_INT_LIT8
-    //     Opcodes.SHL_INT_LIT8
-    //     Opcodes.SHR_INT_LIT8
-    //     Opcodes.USHR_INT_LIT8
-    // END(first-opcodes)
-
-    static {
-        /*
-         * Note: The choices made here are to pick the optimistically
-         * smallest Dalvik opcode, and leave it to later processing to
-         * pessimize. See the automatically-generated comment above
-         * for reference.
-         */
-        MAP = new HashMap<Rop, Dop>(400);
-        MAP.put(Rops.NOP,               Dops.NOP);
-        MAP.put(Rops.MOVE_INT,          Dops.MOVE);
-        MAP.put(Rops.MOVE_LONG,         Dops.MOVE_WIDE);
-        MAP.put(Rops.MOVE_FLOAT,        Dops.MOVE);
-        MAP.put(Rops.MOVE_DOUBLE,       Dops.MOVE_WIDE);
-        MAP.put(Rops.MOVE_OBJECT,       Dops.MOVE_OBJECT);
-        MAP.put(Rops.MOVE_PARAM_INT,    Dops.MOVE);
-        MAP.put(Rops.MOVE_PARAM_LONG,   Dops.MOVE_WIDE);
-        MAP.put(Rops.MOVE_PARAM_FLOAT,  Dops.MOVE);
-        MAP.put(Rops.MOVE_PARAM_DOUBLE, Dops.MOVE_WIDE);
-        MAP.put(Rops.MOVE_PARAM_OBJECT, Dops.MOVE_OBJECT);
-
-        /*
-         * Note: No entry for MOVE_EXCEPTION, since it varies by
-         * exception type. (That is, there is no unique instance to
-         * add to the map.)
-         */
-
-        MAP.put(Rops.CONST_INT,         Dops.CONST_4);
-        MAP.put(Rops.CONST_LONG,        Dops.CONST_WIDE_16);
-        MAP.put(Rops.CONST_FLOAT,       Dops.CONST_4);
-        MAP.put(Rops.CONST_DOUBLE,      Dops.CONST_WIDE_16);
-
-        /*
-         * Note: No entry for CONST_OBJECT, since it needs to turn
-         * into either CONST_STRING or CONST_CLASS.
-         */
-
-        /*
-         * TODO: I think the only case of this is for null, and
-         * const/4 should cover that.
-         */
-        MAP.put(Rops.CONST_OBJECT_NOTHROW, Dops.CONST_4);
-
-        MAP.put(Rops.GOTO,                 Dops.GOTO);
-        MAP.put(Rops.IF_EQZ_INT,           Dops.IF_EQZ);
-        MAP.put(Rops.IF_NEZ_INT,           Dops.IF_NEZ);
-        MAP.put(Rops.IF_LTZ_INT,           Dops.IF_LTZ);
-        MAP.put(Rops.IF_GEZ_INT,           Dops.IF_GEZ);
-        MAP.put(Rops.IF_LEZ_INT,           Dops.IF_LEZ);
-        MAP.put(Rops.IF_GTZ_INT,           Dops.IF_GTZ);
-        MAP.put(Rops.IF_EQZ_OBJECT,        Dops.IF_EQZ);
-        MAP.put(Rops.IF_NEZ_OBJECT,        Dops.IF_NEZ);
-        MAP.put(Rops.IF_EQ_INT,            Dops.IF_EQ);
-        MAP.put(Rops.IF_NE_INT,            Dops.IF_NE);
-        MAP.put(Rops.IF_LT_INT,            Dops.IF_LT);
-        MAP.put(Rops.IF_GE_INT,            Dops.IF_GE);
-        MAP.put(Rops.IF_LE_INT,            Dops.IF_LE);
-        MAP.put(Rops.IF_GT_INT,            Dops.IF_GT);
-        MAP.put(Rops.IF_EQ_OBJECT,         Dops.IF_EQ);
-        MAP.put(Rops.IF_NE_OBJECT,         Dops.IF_NE);
-        MAP.put(Rops.SWITCH,               Dops.SPARSE_SWITCH);
-        MAP.put(Rops.ADD_INT,              Dops.ADD_INT_2ADDR);
-        MAP.put(Rops.ADD_LONG,             Dops.ADD_LONG_2ADDR);
-        MAP.put(Rops.ADD_FLOAT,            Dops.ADD_FLOAT_2ADDR);
-        MAP.put(Rops.ADD_DOUBLE,           Dops.ADD_DOUBLE_2ADDR);
-        MAP.put(Rops.SUB_INT,              Dops.SUB_INT_2ADDR);
-        MAP.put(Rops.SUB_LONG,             Dops.SUB_LONG_2ADDR);
-        MAP.put(Rops.SUB_FLOAT,            Dops.SUB_FLOAT_2ADDR);
-        MAP.put(Rops.SUB_DOUBLE,           Dops.SUB_DOUBLE_2ADDR);
-        MAP.put(Rops.MUL_INT,              Dops.MUL_INT_2ADDR);
-        MAP.put(Rops.MUL_LONG,             Dops.MUL_LONG_2ADDR);
-        MAP.put(Rops.MUL_FLOAT,            Dops.MUL_FLOAT_2ADDR);
-        MAP.put(Rops.MUL_DOUBLE,           Dops.MUL_DOUBLE_2ADDR);
-        MAP.put(Rops.DIV_INT,              Dops.DIV_INT_2ADDR);
-        MAP.put(Rops.DIV_LONG,             Dops.DIV_LONG_2ADDR);
-        MAP.put(Rops.DIV_FLOAT,            Dops.DIV_FLOAT_2ADDR);
-        MAP.put(Rops.DIV_DOUBLE,           Dops.DIV_DOUBLE_2ADDR);
-        MAP.put(Rops.REM_INT,              Dops.REM_INT_2ADDR);
-        MAP.put(Rops.REM_LONG,             Dops.REM_LONG_2ADDR);
-        MAP.put(Rops.REM_FLOAT,            Dops.REM_FLOAT_2ADDR);
-        MAP.put(Rops.REM_DOUBLE,           Dops.REM_DOUBLE_2ADDR);
-        MAP.put(Rops.NEG_INT,              Dops.NEG_INT);
-        MAP.put(Rops.NEG_LONG,             Dops.NEG_LONG);
-        MAP.put(Rops.NEG_FLOAT,            Dops.NEG_FLOAT);
-        MAP.put(Rops.NEG_DOUBLE,           Dops.NEG_DOUBLE);
-        MAP.put(Rops.AND_INT,              Dops.AND_INT_2ADDR);
-        MAP.put(Rops.AND_LONG,             Dops.AND_LONG_2ADDR);
-        MAP.put(Rops.OR_INT,               Dops.OR_INT_2ADDR);
-        MAP.put(Rops.OR_LONG,              Dops.OR_LONG_2ADDR);
-        MAP.put(Rops.XOR_INT,              Dops.XOR_INT_2ADDR);
-        MAP.put(Rops.XOR_LONG,             Dops.XOR_LONG_2ADDR);
-        MAP.put(Rops.SHL_INT,              Dops.SHL_INT_2ADDR);
-        MAP.put(Rops.SHL_LONG,             Dops.SHL_LONG_2ADDR);
-        MAP.put(Rops.SHR_INT,              Dops.SHR_INT_2ADDR);
-        MAP.put(Rops.SHR_LONG,             Dops.SHR_LONG_2ADDR);
-        MAP.put(Rops.USHR_INT,             Dops.USHR_INT_2ADDR);
-        MAP.put(Rops.USHR_LONG,            Dops.USHR_LONG_2ADDR);
-        MAP.put(Rops.NOT_INT,              Dops.NOT_INT);
-        MAP.put(Rops.NOT_LONG,             Dops.NOT_LONG);
-
-        MAP.put(Rops.ADD_CONST_INT,        Dops.ADD_INT_LIT8);
-        // Note: No dalvik ops for other types of add_const.
-
-        MAP.put(Rops.SUB_CONST_INT,        Dops.RSUB_INT_LIT8);
-        /*
-         * Note: No dalvik ops for any type of sub_const; instead
-         * there's a *reverse* sub (constant - reg) for ints only.
-         */
-
-        MAP.put(Rops.MUL_CONST_INT,        Dops.MUL_INT_LIT8);
-        // Note: No dalvik ops for other types of mul_const.
-
-        MAP.put(Rops.DIV_CONST_INT,        Dops.DIV_INT_LIT8);
-        // Note: No dalvik ops for other types of div_const.
-
-        MAP.put(Rops.REM_CONST_INT,        Dops.REM_INT_LIT8);
-        // Note: No dalvik ops for other types of rem_const.
-
-        MAP.put(Rops.AND_CONST_INT,        Dops.AND_INT_LIT8);
-        // Note: No dalvik op for and_const_long.
-
-        MAP.put(Rops.OR_CONST_INT,         Dops.OR_INT_LIT8);
-        // Note: No dalvik op for or_const_long.
-
-        MAP.put(Rops.XOR_CONST_INT,        Dops.XOR_INT_LIT8);
-        // Note: No dalvik op for xor_const_long.
-
-        MAP.put(Rops.SHL_CONST_INT,        Dops.SHL_INT_LIT8);
-        // Note: No dalvik op for shl_const_long.
-
-        MAP.put(Rops.SHR_CONST_INT,        Dops.SHR_INT_LIT8);
-        // Note: No dalvik op for shr_const_long.
-
-        MAP.put(Rops.USHR_CONST_INT,       Dops.USHR_INT_LIT8);
-        // Note: No dalvik op for shr_const_long.
-
-        MAP.put(Rops.CMPL_LONG,            Dops.CMP_LONG);
-        MAP.put(Rops.CMPL_FLOAT,           Dops.CMPL_FLOAT);
-        MAP.put(Rops.CMPL_DOUBLE,          Dops.CMPL_DOUBLE);
-        MAP.put(Rops.CMPG_FLOAT,           Dops.CMPG_FLOAT);
-        MAP.put(Rops.CMPG_DOUBLE,          Dops.CMPG_DOUBLE);
-        MAP.put(Rops.CONV_L2I,             Dops.LONG_TO_INT);
-        MAP.put(Rops.CONV_F2I,             Dops.FLOAT_TO_INT);
-        MAP.put(Rops.CONV_D2I,             Dops.DOUBLE_TO_INT);
-        MAP.put(Rops.CONV_I2L,             Dops.INT_TO_LONG);
-        MAP.put(Rops.CONV_F2L,             Dops.FLOAT_TO_LONG);
-        MAP.put(Rops.CONV_D2L,             Dops.DOUBLE_TO_LONG);
-        MAP.put(Rops.CONV_I2F,             Dops.INT_TO_FLOAT);
-        MAP.put(Rops.CONV_L2F,             Dops.LONG_TO_FLOAT);
-        MAP.put(Rops.CONV_D2F,             Dops.DOUBLE_TO_FLOAT);
-        MAP.put(Rops.CONV_I2D,             Dops.INT_TO_DOUBLE);
-        MAP.put(Rops.CONV_L2D,             Dops.LONG_TO_DOUBLE);
-        MAP.put(Rops.CONV_F2D,             Dops.FLOAT_TO_DOUBLE);
-        MAP.put(Rops.TO_BYTE,              Dops.INT_TO_BYTE);
-        MAP.put(Rops.TO_CHAR,              Dops.INT_TO_CHAR);
-        MAP.put(Rops.TO_SHORT,             Dops.INT_TO_SHORT);
-        MAP.put(Rops.RETURN_VOID,          Dops.RETURN_VOID);
-        MAP.put(Rops.RETURN_INT,           Dops.RETURN);
-        MAP.put(Rops.RETURN_LONG,          Dops.RETURN_WIDE);
-        MAP.put(Rops.RETURN_FLOAT,         Dops.RETURN);
-        MAP.put(Rops.RETURN_DOUBLE,        Dops.RETURN_WIDE);
-        MAP.put(Rops.RETURN_OBJECT,        Dops.RETURN_OBJECT);
-        MAP.put(Rops.ARRAY_LENGTH,         Dops.ARRAY_LENGTH);
-        MAP.put(Rops.THROW,                Dops.THROW);
-        MAP.put(Rops.MONITOR_ENTER,        Dops.MONITOR_ENTER);
-        MAP.put(Rops.MONITOR_EXIT,         Dops.MONITOR_EXIT);
-        MAP.put(Rops.AGET_INT,             Dops.AGET);
-        MAP.put(Rops.AGET_LONG,            Dops.AGET_WIDE);
-        MAP.put(Rops.AGET_FLOAT,           Dops.AGET);
-        MAP.put(Rops.AGET_DOUBLE,          Dops.AGET_WIDE);
-        MAP.put(Rops.AGET_OBJECT,          Dops.AGET_OBJECT);
-        MAP.put(Rops.AGET_BOOLEAN,         Dops.AGET_BOOLEAN);
-        MAP.put(Rops.AGET_BYTE,            Dops.AGET_BYTE);
-        MAP.put(Rops.AGET_CHAR,            Dops.AGET_CHAR);
-        MAP.put(Rops.AGET_SHORT,           Dops.AGET_SHORT);
-        MAP.put(Rops.APUT_INT,             Dops.APUT);
-        MAP.put(Rops.APUT_LONG,            Dops.APUT_WIDE);
-        MAP.put(Rops.APUT_FLOAT,           Dops.APUT);
-        MAP.put(Rops.APUT_DOUBLE,          Dops.APUT_WIDE);
-        MAP.put(Rops.APUT_OBJECT,          Dops.APUT_OBJECT);
-        MAP.put(Rops.APUT_BOOLEAN,         Dops.APUT_BOOLEAN);
-        MAP.put(Rops.APUT_BYTE,            Dops.APUT_BYTE);
-        MAP.put(Rops.APUT_CHAR,            Dops.APUT_CHAR);
-        MAP.put(Rops.APUT_SHORT,           Dops.APUT_SHORT);
-        MAP.put(Rops.NEW_INSTANCE,         Dops.NEW_INSTANCE);
-        MAP.put(Rops.CHECK_CAST,           Dops.CHECK_CAST);
-        MAP.put(Rops.INSTANCE_OF,          Dops.INSTANCE_OF);
-
-        MAP.put(Rops.GET_FIELD_LONG,       Dops.IGET_WIDE);
-        MAP.put(Rops.GET_FIELD_FLOAT,      Dops.IGET);
-        MAP.put(Rops.GET_FIELD_DOUBLE,     Dops.IGET_WIDE);
-        MAP.put(Rops.GET_FIELD_OBJECT,     Dops.IGET_OBJECT);
-        /*
-         * Note: No map entries for get_field_* for non-long integral types,
-         * since they need to be handled specially (see dopFor() below).
-         */
-
-        MAP.put(Rops.GET_STATIC_LONG,      Dops.SGET_WIDE);
-        MAP.put(Rops.GET_STATIC_FLOAT,     Dops.SGET);
-        MAP.put(Rops.GET_STATIC_DOUBLE,    Dops.SGET_WIDE);
-        MAP.put(Rops.GET_STATIC_OBJECT,    Dops.SGET_OBJECT);
-        /*
-         * Note: No map entries for get_static* for non-long integral types,
-         * since they need to be handled specially (see dopFor() below).
-         */
-
-        MAP.put(Rops.PUT_FIELD_LONG,       Dops.IPUT_WIDE);
-        MAP.put(Rops.PUT_FIELD_FLOAT,      Dops.IPUT);
-        MAP.put(Rops.PUT_FIELD_DOUBLE,     Dops.IPUT_WIDE);
-        MAP.put(Rops.PUT_FIELD_OBJECT,     Dops.IPUT_OBJECT);
-        /*
-         * Note: No map entries for put_field_* for non-long integral types,
-         * since they need to be handled specially (see dopFor() below).
-         */
-
-        MAP.put(Rops.PUT_STATIC_LONG,      Dops.SPUT_WIDE);
-        MAP.put(Rops.PUT_STATIC_FLOAT,     Dops.SPUT);
-        MAP.put(Rops.PUT_STATIC_DOUBLE,    Dops.SPUT_WIDE);
-        MAP.put(Rops.PUT_STATIC_OBJECT,    Dops.SPUT_OBJECT);
-        /*
-         * Note: No map entries for put_static* for non-long integral types,
-         * since they need to be handled specially (see dopFor() below).
-         */
-
-        /*
-         * Note: No map entries for invoke*, new_array, and
-         * filled_new_array, since they need to be handled specially
-         * (see dopFor() below).
-         */
-    }
-
-    /**
-     * Returns the dalvik opcode appropriate for the given register-based
-     * instruction.
-     *
-     * @param insn {@code non-null;} the original instruction
-     * @return the corresponding dalvik opcode; one of the constants in
-     * {@link Dops}
-     */
-    public static Dop dopFor(Insn insn) {
-        Rop rop = insn.getOpcode();
-
-        /*
-         * First, just try looking up the rop in the MAP of easy
-         * cases.
-         */
-        Dop result = MAP.get(rop);
-        if (result != null) {
-            return result;
-        }
-
-        /*
-         * There was no easy case for the rop, so look up the opcode, and
-         * do something special for each:
-         *
-         * The move_exception, new_array, filled_new_array, and
-         * invoke* opcodes won't be found in MAP, since they'll each
-         * have different source and/or result register types / lists.
-         *
-         * The get* and put* opcodes for (non-long) integral types
-         * aren't in the map, since the type signatures aren't
-         * sufficient to distinguish between the types (the salient
-         * source or result will always be just "int").
-         *
-         * And const instruction need to distinguish between strings and
-         * classes.
-         */
-
-        switch (rop.getOpcode()) {
-            case RegOps.MOVE_EXCEPTION:   return Dops.MOVE_EXCEPTION;
-            case RegOps.INVOKE_STATIC:    return Dops.INVOKE_STATIC;
-            case RegOps.INVOKE_VIRTUAL:   return Dops.INVOKE_VIRTUAL;
-            case RegOps.INVOKE_SUPER:     return Dops.INVOKE_SUPER;
-            case RegOps.INVOKE_DIRECT:    return Dops.INVOKE_DIRECT;
-            case RegOps.INVOKE_INTERFACE: return Dops.INVOKE_INTERFACE;
-            case RegOps.NEW_ARRAY:        return Dops.NEW_ARRAY;
-            case RegOps.FILLED_NEW_ARRAY: return Dops.FILLED_NEW_ARRAY;
-            case RegOps.FILL_ARRAY_DATA:  return Dops.FILL_ARRAY_DATA;
-            case RegOps.MOVE_RESULT: {
-                RegisterSpec resultReg = insn.getResult();
-
-                if (resultReg == null) {
-                    return Dops.NOP;
-                } else {
-                    switch (resultReg.getBasicType()) {
-                        case Type.BT_INT:
-                        case Type.BT_FLOAT:
-                        case Type.BT_BOOLEAN:
-                        case Type.BT_BYTE:
-                        case Type.BT_CHAR:
-                        case Type.BT_SHORT:
-                            return Dops.MOVE_RESULT;
-                        case Type.BT_LONG:
-                        case Type.BT_DOUBLE:
-                            return Dops.MOVE_RESULT_WIDE;
-                        case Type.BT_OBJECT:
-                            return Dops.MOVE_RESULT_OBJECT;
-                        default: {
-                            throw new RuntimeException("Unexpected basic type");
-                        }
-                    }
-                }
-            }
-
-            case RegOps.GET_FIELD: {
-                CstFieldRef ref =
-                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
-                int basicType = ref.getBasicType();
-                switch (basicType) {
-                    case Type.BT_BOOLEAN: return Dops.IGET_BOOLEAN;
-                    case Type.BT_BYTE:    return Dops.IGET_BYTE;
-                    case Type.BT_CHAR:    return Dops.IGET_CHAR;
-                    case Type.BT_SHORT:   return Dops.IGET_SHORT;
-                    case Type.BT_INT:     return Dops.IGET;
-                }
-                break;
-            }
-            case RegOps.PUT_FIELD: {
-                CstFieldRef ref =
-                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
-                int basicType = ref.getBasicType();
-                switch (basicType) {
-                    case Type.BT_BOOLEAN: return Dops.IPUT_BOOLEAN;
-                    case Type.BT_BYTE:    return Dops.IPUT_BYTE;
-                    case Type.BT_CHAR:    return Dops.IPUT_CHAR;
-                    case Type.BT_SHORT:   return Dops.IPUT_SHORT;
-                    case Type.BT_INT:     return Dops.IPUT;
-                }
-                break;
-            }
-            case RegOps.GET_STATIC: {
-                CstFieldRef ref =
-                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
-                int basicType = ref.getBasicType();
-                switch (basicType) {
-                    case Type.BT_BOOLEAN: return Dops.SGET_BOOLEAN;
-                    case Type.BT_BYTE:    return Dops.SGET_BYTE;
-                    case Type.BT_CHAR:    return Dops.SGET_CHAR;
-                    case Type.BT_SHORT:   return Dops.SGET_SHORT;
-                    case Type.BT_INT:     return Dops.SGET;
-                }
-                break;
-            }
-            case RegOps.PUT_STATIC: {
-                CstFieldRef ref =
-                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
-                int basicType = ref.getBasicType();
-                switch (basicType) {
-                    case Type.BT_BOOLEAN: return Dops.SPUT_BOOLEAN;
-                    case Type.BT_BYTE:    return Dops.SPUT_BYTE;
-                    case Type.BT_CHAR:    return Dops.SPUT_CHAR;
-                    case Type.BT_SHORT:   return Dops.SPUT_SHORT;
-                    case Type.BT_INT:     return Dops.SPUT;
-                }
-                break;
-            }
-            case RegOps.CONST: {
-                Constant cst = ((ThrowingCstInsn) insn).getConstant();
-                if (cst instanceof CstType) {
-                    return Dops.CONST_CLASS;
-                } else if (cst instanceof CstString) {
-                    return Dops.CONST_STRING;
-                }
-                break;
-            }
-        }
-
-        throw new RuntimeException("unknown rop: " + rop);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/RopTranslator.java b/dx/src/main/java/com/android/dx/dex/code/RopTranslator.java
deleted file mode 100644
index 3d24c4f..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/RopTranslator.java
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.dex.DexOptions;
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.FillArrayDataInsn;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.LocalVariableInfo;
-import com.android.dx.rop.code.PlainCstInsn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.code.SwitchInsn;
-import com.android.dx.rop.code.ThrowingCstInsn;
-import com.android.dx.rop.code.ThrowingInsn;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.util.Bits;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-
-/**
- * Translator from {@link RopMethod} to {@link DalvCode}. The {@link
- * #translate} method is the thing to call on this class.
- */
-public final class RopTranslator {
-    /** {@code non-null;} options for dex output */
-    private final DexOptions dexOptions;
-
-    /** {@code non-null;} method to translate */
-    private final RopMethod method;
-
-    /**
-     * how much position info to preserve; one of the static
-     * constants in {@link PositionList}
-     */
-    private final int positionInfo;
-
-    /** {@code null-ok;} local variable info to use */
-    private final LocalVariableInfo locals;
-
-    /** {@code non-null;} container for all the address objects for the method */
-    private final BlockAddresses addresses;
-
-    /** {@code non-null;} list of output instructions in-progress */
-    private final OutputCollector output;
-
-    /** {@code non-null;} visitor to use during translation */
-    private final TranslationVisitor translationVisitor;
-
-    /** {@code >= 0;} register count for the method */
-    private final int regCount;
-
-    /** {@code null-ok;} block output order; becomes non-null in {@link #pickOrder} */
-    private int[] order;
-
-    /** size, in register units, of all the parameters to this method */
-    private final int paramSize;
-
-    /**
-     * true if the parameters to this method happen to be in proper order
-     * at the end of the frame (as the optimizer emits them)
-     */
-    private boolean paramsAreInOrder;
-
-    /**
-     * Translates a {@link RopMethod}. This may modify the given
-     * input.
-     *
-     * @param method {@code non-null;} the original method
-     * @param positionInfo how much position info to preserve; one of the
-     * static constants in {@link PositionList}
-     * @param locals {@code null-ok;} local variable information to use
-     * @param paramSize size, in register units, of all the parameters to
-     * this method
-     * @param dexOptions {@code non-null;} options for dex output
-     * @return {@code non-null;} the translated version
-     */
-    public static DalvCode translate(RopMethod method, int positionInfo,
-            LocalVariableInfo locals, int paramSize, DexOptions dexOptions) {
-        RopTranslator translator =
-            new RopTranslator(method, positionInfo, locals, paramSize, dexOptions);
-        return translator.translateAndGetResult();
-    }
-
-    /**
-     * Constructs an instance. This method is private. Use {@link #translate}.
-     *
-     * @param method {@code non-null;} the original method
-     * @param positionInfo how much position info to preserve; one of the
-     * static constants in {@link PositionList}
-     * @param locals {@code null-ok;} local variable information to use
-     * @param paramSize size, in register units, of all the parameters to
-     * this method
-     * @param dexOptions {@code non-null;} options for dex output
-     */
-    private RopTranslator(RopMethod method, int positionInfo, LocalVariableInfo locals,
-            int paramSize, DexOptions dexOptions) {
-        this.dexOptions = dexOptions;
-        this.method = method;
-        this.positionInfo = positionInfo;
-        this.locals = locals;
-        this.addresses = new BlockAddresses(method);
-        this.paramSize = paramSize;
-        this.order = null;
-        this.paramsAreInOrder = calculateParamsAreInOrder(method, paramSize);
-
-        BasicBlockList blocks = method.getBlocks();
-        int bsz = blocks.size();
-
-        /*
-         * Max possible instructions includes three code address
-         * objects per basic block (to the first and last instruction,
-         * and just past the end of the block), and the possibility of
-         * an extra goto at the end of each basic block.
-         */
-        int maxInsns = (bsz * 3) + blocks.getInstructionCount();
-
-        if (locals != null) {
-            /*
-             * If we're tracking locals, then there's could be another
-             * extra instruction per block (for the locals state at the
-             * start of the block) as well as one for each interblock
-             * local introduction.
-             */
-            maxInsns += bsz + locals.getAssignmentCount();
-        }
-
-        /*
-         * If params are not in order, we will need register space
-         * for them before this is all over...
-         */
-        this.regCount = blocks.getRegCount()
-                + (paramsAreInOrder ? 0 : this.paramSize);
-
-        this.output = new OutputCollector(dexOptions, maxInsns, bsz * 3, regCount);
-
-        if (locals != null) {
-            this.translationVisitor =
-                new LocalVariableAwareTranslationVisitor(output, locals);
-        } else {
-            this.translationVisitor = new TranslationVisitor(output);
-        }
-    }
-
-    /**
-     * Checks to see if the move-param instructions that occur in this
-     * method happen to slot the params in an order at the top of the
-     * stack frame that matches dalvik's calling conventions. This will
-     * alway result in "true" for methods that have run through the
-     * SSA optimizer.
-     *
-     * @param paramSize size, in register units, of all the parameters
-     * to this method
-     */
-    private static boolean calculateParamsAreInOrder(RopMethod method,
-            final int paramSize) {
-        final boolean[] paramsAreInOrder = { true };
-        final int initialRegCount = method.getBlocks().getRegCount();
-
-        /*
-         * We almost could just check the first block here, but the
-         * {@code cf} layer will put in a second move-param in a
-         * subsequent block in the case of synchronized methods.
-         */
-        method.getBlocks().forEachInsn(new Insn.BaseVisitor() {
-            @Override
-            public void visitPlainCstInsn(PlainCstInsn insn) {
-                if (insn.getOpcode().getOpcode()== RegOps.MOVE_PARAM) {
-                    int param =
-                        ((CstInteger) insn.getConstant()).getValue();
-
-                    paramsAreInOrder[0] = paramsAreInOrder[0]
-                            && ((initialRegCount - paramSize + param)
-                                == insn.getResult().getReg());
-                }
-            }
-        });
-
-        return paramsAreInOrder[0];
-    }
-
-    /**
-     * Does the translation and returns the result.
-     *
-     * @return {@code non-null;} the result
-     */
-    private DalvCode translateAndGetResult() {
-        pickOrder();
-        outputInstructions();
-
-        StdCatchBuilder catches =
-            new StdCatchBuilder(method, order, addresses);
-
-        return new DalvCode(positionInfo, output.getFinisher(), catches);
-    }
-
-    /**
-     * Performs initial creation of output instructions based on the
-     * original blocks.
-     */
-    private void outputInstructions() {
-        BasicBlockList blocks = method.getBlocks();
-        int[] order = this.order;
-        int len = order.length;
-
-        // Process the blocks in output order.
-        for (int i = 0; i < len; i++) {
-            int nextI = i + 1;
-            int nextLabel = (nextI == order.length) ? -1 : order[nextI];
-            outputBlock(blocks.labelToBlock(order[i]), nextLabel);
-        }
-    }
-
-    /**
-     * Helper for {@link #outputInstructions}, which does the processing
-     * and output of one block.
-     *
-     * @param block {@code non-null;} the block to process and output
-     * @param nextLabel {@code >= -1;} the next block that will be processed, or
-     * {@code -1} if there is no next block
-     */
-    private void outputBlock(BasicBlock block, int nextLabel) {
-        // Append the code address for this block.
-        CodeAddress startAddress = addresses.getStart(block);
-        output.add(startAddress);
-
-        // Append the local variable state for the block.
-        if (locals != null) {
-            RegisterSpecSet starts = locals.getStarts(block);
-            output.add(new LocalSnapshot(startAddress.getPosition(),
-                                         starts));
-        }
-
-        /*
-         * Choose and append an output instruction for each original
-         * instruction.
-         */
-        translationVisitor.setBlock(block, addresses.getLast(block));
-        block.getInsns().forEach(translationVisitor);
-
-        // Insert the block end code address.
-        output.add(addresses.getEnd(block));
-
-        // Set up for end-of-block activities.
-
-        int succ = block.getPrimarySuccessor();
-        Insn lastInsn = block.getLastInsn();
-
-        /*
-         * Check for (and possibly correct for) a non-optimal choice of
-         * which block will get output next.
-         */
-
-        if ((succ >= 0) && (succ != nextLabel)) {
-            /*
-             * The block has a "primary successor" and that primary
-             * successor isn't the next block to be output.
-             */
-            Rop lastRop = lastInsn.getOpcode();
-            if ((lastRop.getBranchingness() == Rop.BRANCH_IF) &&
-                    (block.getSecondarySuccessor() == nextLabel)) {
-                /*
-                 * The block ends with an "if" of some sort, and its
-                 * secondary successor (the "then") is in fact the
-                 * next block to output. So, reverse the sense of
-                 * the test, so that we can just emit the next block
-                 * without an interstitial goto.
-                 */
-                output.reverseBranch(1, addresses.getStart(succ));
-            } else {
-                /*
-                 * Our only recourse is to add a goto here to get the
-                 * flow to be correct.
-                 */
-                TargetInsn insn =
-                    new TargetInsn(Dops.GOTO, lastInsn.getPosition(),
-                            RegisterSpecList.EMPTY,
-                            addresses.getStart(succ));
-                output.add(insn);
-            }
-        }
-    }
-
-    /**
-     * Picks an order for the blocks by doing "trace" analysis.
-     */
-    private void pickOrder() {
-        BasicBlockList blocks = method.getBlocks();
-        int sz = blocks.size();
-        int maxLabel = blocks.getMaxLabel();
-        int[] workSet = Bits.makeBitSet(maxLabel);
-        int[] tracebackSet = Bits.makeBitSet(maxLabel);
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = blocks.get(i);
-            Bits.set(workSet, one.getLabel());
-        }
-
-        int[] order = new int[sz];
-        int at = 0;
-
-        /*
-         * Starting with the designated "first label" (that is, the
-         * first block of the method), add that label to the order,
-         * and then pick its first as-yet unordered successor to
-         * immediately follow it, giving top priority to the primary
-         * (aka default) successor (if any). Keep following successors
-         * until the trace runs out of possibilities. Then, continue
-         * by finding an unordered chain containing the first as-yet
-         * unordered block, and adding it to the order, and so on.
-         */
-        for (int label = method.getFirstLabel();
-             label != -1;
-             label = Bits.findFirst(workSet, 0)) {
-
-            /*
-             * Attempt to trace backward from the chosen block to an
-             * as-yet unordered predecessor which lists the chosen
-             * block as its primary successor, and so on, until we
-             * fail to find such an unordered predecessor. Start the
-             * trace with that block. Note that the first block in the
-             * method has no predecessors, so in that case this loop
-             * will simply terminate with zero iterations and without
-             * picking a new starter block.
-             */
-            traceBack:
-            for (;;) {
-                IntList preds = method.labelToPredecessors(label);
-                int psz = preds.size();
-
-                for (int i = 0; i < psz; i++) {
-                    int predLabel = preds.get(i);
-
-                    if (Bits.get(tracebackSet, predLabel)) {
-                        /*
-                         * We found a predecessor loop; stop tracing back
-                         * from here.
-                         */
-                        break;
-                    }
-
-                    if (!Bits.get(workSet, predLabel)) {
-                        // This one's already ordered.
-                        continue;
-                    }
-
-                    BasicBlock pred = blocks.labelToBlock(predLabel);
-                    if (pred.getPrimarySuccessor() == label) {
-                        // Found one!
-                        label = predLabel;
-                        Bits.set(tracebackSet, label);
-                        continue traceBack;
-                    }
-                }
-
-                // Failed to find a better block to start the trace.
-                break;
-            }
-
-            /*
-             * Trace a path from the chosen block to one of its
-             * unordered successors (hopefully the primary), and so
-             * on, until we run out of unordered successors.
-             */
-            while (label != -1) {
-                Bits.clear(workSet, label);
-                Bits.clear(tracebackSet, label);
-                order[at] = label;
-                at++;
-
-                BasicBlock one = blocks.labelToBlock(label);
-                BasicBlock preferredBlock = blocks.preferredSuccessorOf(one);
-
-                if (preferredBlock == null) {
-                    break;
-                }
-
-                int preferred = preferredBlock.getLabel();
-                int primary = one.getPrimarySuccessor();
-
-                if (Bits.get(workSet, preferred)) {
-                    /*
-                     * Order the current block's preferred successor
-                     * next, as it has yet to be scheduled.
-                     */
-                    label = preferred;
-                } else if ((primary != preferred) && (primary >= 0)
-                        && Bits.get(workSet, primary)) {
-                    /*
-                     * The primary is available, so use that.
-                     */
-                    label = primary;
-                } else {
-                    /*
-                     * There's no obvious candidate, so pick the first
-                     * one that's available, if any.
-                     */
-                    IntList successors = one.getSuccessors();
-                    int ssz = successors.size();
-                    label = -1;
-                    for (int i = 0; i < ssz; i++) {
-                        int candidate = successors.get(i);
-                        if (Bits.get(workSet, candidate)) {
-                            label = candidate;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (at != sz) {
-            // There was a duplicate block label.
-            throw new RuntimeException("shouldn't happen");
-        }
-
-        this.order = order;
-    }
-
-    /**
-     * Gets the complete register list (result and sources) out of a
-     * given rop instruction. For insns that are commutative, have
-     * two register sources, and have a source equal to the result,
-     * place that source first.
-     *
-     * @param insn {@code non-null;} instruction in question
-     * @return {@code non-null;} the instruction's complete register list
-     */
-    private static RegisterSpecList getRegs(Insn insn) {
-        return getRegs(insn, insn.getResult());
-    }
-
-    /**
-     * Gets the complete register list (result and sources) out of a
-     * given rop instruction. For insns that are commutative, have
-     * two register sources, and have a source equal to the result,
-     * place that source first.
-     *
-     * @param insn {@code non-null;} instruction in question
-     * @param resultReg {@code null-ok;} the real result to use (ignore the insn's)
-     * @return {@code non-null;} the instruction's complete register list
-     */
-    private static RegisterSpecList getRegs(Insn insn,
-            RegisterSpec resultReg) {
-        RegisterSpecList regs = insn.getSources();
-
-        if (insn.getOpcode().isCommutative()
-                && (regs.size() == 2)
-                && (resultReg.getReg() == regs.get(1).getReg())) {
-
-            /*
-             * For commutative ops which have two register sources,
-             * if the second source is the same register as the result,
-             * swap the sources so that an opcode of form 12x can be selected
-             * instead of one of form 23x
-             */
-
-            regs = RegisterSpecList.make(regs.get(1), regs.get(0));
-        }
-
-        if (resultReg == null) {
-            return regs;
-        }
-
-        return regs.withFirst(resultReg);
-    }
-
-    /**
-     * Instruction visitor class for doing the instruction translation per se.
-     */
-    private class TranslationVisitor implements Insn.Visitor {
-        /** {@code non-null;} list of output instructions in-progress */
-        private final OutputCollector output;
-
-        /** {@code non-null;} basic block being worked on */
-        private BasicBlock block;
-
-        /**
-         * {@code null-ok;} code address for the salient last instruction of the
-         * block (used before switches and throwing instructions)
-         */
-        private CodeAddress lastAddress;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param output {@code non-null;} destination for instruction output
-         */
-        public TranslationVisitor(OutputCollector output) {
-            this.output = output;
-        }
-
-        /**
-         * Sets the block currently being worked on.
-         *
-         * @param block {@code non-null;} the block
-         * @param lastAddress {@code non-null;} code address for the salient
-         * last instruction of the block
-         */
-        public void setBlock(BasicBlock block, CodeAddress lastAddress) {
-            this.block = block;
-            this.lastAddress = lastAddress;
-        }
-
-        /** {@inheritDoc} */
-        public void visitPlainInsn(PlainInsn insn) {
-            Rop rop = insn.getOpcode();
-            if (rop.getOpcode() == RegOps.MARK_LOCAL) {
-                /*
-                 * Ignore these. They're dealt with by
-                 * the LocalVariableAwareTranslationVisitor
-                 */
-                return;
-            }
-            if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
-                // These get skipped
-                return;
-            }
-
-            SourcePosition pos = insn.getPosition();
-            Dop opcode = RopToDop.dopFor(insn);
-            DalvInsn di;
-
-            switch (rop.getBranchingness()) {
-                case Rop.BRANCH_NONE:
-                case Rop.BRANCH_RETURN:
-                case Rop.BRANCH_THROW: {
-                    di = new SimpleInsn(opcode, pos, getRegs(insn));
-                    break;
-                }
-                case Rop.BRANCH_GOTO: {
-                    /*
-                     * Code in the main translation loop will emit a
-                     * goto if necessary (if the branch isn't to the
-                     * immediately subsequent block).
-                     */
-                    return;
-                }
-                case Rop.BRANCH_IF: {
-                    int target = block.getSuccessors().get(1);
-                    di = new TargetInsn(opcode, pos, getRegs(insn),
-                                        addresses.getStart(target));
-                    break;
-                }
-                default: {
-                    throw new RuntimeException("shouldn't happen");
-                }
-            }
-
-            addOutput(di);
-        }
-
-        /** {@inheritDoc} */
-        public void visitPlainCstInsn(PlainCstInsn insn) {
-            SourcePosition pos = insn.getPosition();
-            Dop opcode = RopToDop.dopFor(insn);
-            Rop rop = insn.getOpcode();
-            int ropOpcode = rop.getOpcode();
-            DalvInsn di;
-
-            if (rop.getBranchingness() != Rop.BRANCH_NONE) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            if (ropOpcode == RegOps.MOVE_PARAM) {
-                if (!paramsAreInOrder) {
-                    /*
-                     * Parameters are not in order at the top of the reg space.
-                     * We need to add moves.
-                     */
-
-                    RegisterSpec dest = insn.getResult();
-                    int param =
-                        ((CstInteger) insn.getConstant()).getValue();
-                    RegisterSpec source =
-                        RegisterSpec.make(regCount - paramSize + param,
-                                dest.getType());
-                    di = new SimpleInsn(opcode, pos,
-                                        RegisterSpecList.make(dest, source));
-                    addOutput(di);
-                }
-            } else {
-                // No moves required for the parameters
-                RegisterSpecList regs = getRegs(insn);
-                di = new CstInsn(opcode, pos, regs, insn.getConstant());
-                addOutput(di);
-            }
-        }
-
-        /** {@inheritDoc} */
-        public void visitSwitchInsn(SwitchInsn insn) {
-            SourcePosition pos = insn.getPosition();
-            IntList cases = insn.getCases();
-            IntList successors = block.getSuccessors();
-            int casesSz = cases.size();
-            int succSz = successors.size();
-            int primarySuccessor = block.getPrimarySuccessor();
-
-            /*
-             * Check the assumptions that the number of cases is one
-             * less than the number of successors and that the last
-             * successor in the list is the primary (in this case, the
-             * default). This test is here to guard against forgetting
-             * to change this code if the way switch instructions are
-             * constructed also gets changed.
-             */
-            if ((casesSz != (succSz - 1)) ||
-                (primarySuccessor != successors.get(casesSz))) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            CodeAddress[] switchTargets = new CodeAddress[casesSz];
-
-            for (int i = 0; i < casesSz; i++) {
-                int label = successors.get(i);
-                switchTargets[i] = addresses.getStart(label);
-            }
-
-            CodeAddress dataAddress = new CodeAddress(pos);
-            SwitchData dataInsn =
-                new SwitchData(pos, lastAddress, cases, switchTargets);
-            Dop opcode = dataInsn.isPacked() ?
-                Dops.PACKED_SWITCH : Dops.SPARSE_SWITCH;
-            TargetInsn switchInsn =
-                new TargetInsn(opcode, pos, getRegs(insn), dataAddress);
-
-            addOutput(lastAddress);
-            addOutput(switchInsn);
-
-            addOutputSuffix(new OddSpacer(pos));
-            addOutputSuffix(dataAddress);
-            addOutputSuffix(dataInsn);
-        }
-
-        /**
-         * Looks forward to the current block's primary successor, returning
-         * the RegisterSpec of the result of the move-result-pseudo at the
-         * top of that block or null if none.
-         *
-         * @return {@code null-ok;} result of move-result-pseudo at the beginning of
-         * primary successor
-         */
-        private RegisterSpec getNextMoveResultPseudo()
-        {
-            int label = block.getPrimarySuccessor();
-
-            if (label < 0) {
-                return null;
-            }
-
-            Insn insn
-                    = method.getBlocks().labelToBlock(label).getInsns().get(0);
-
-            if (insn.getOpcode().getOpcode() != RegOps.MOVE_RESULT_PSEUDO) {
-                return null;
-            } else {
-                return insn.getResult();
-            }
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
-            SourcePosition pos = insn.getPosition();
-            Dop opcode = RopToDop.dopFor(insn);
-            Rop rop = insn.getOpcode();
-            Constant cst = insn.getConstant();
-
-            if (rop.getBranchingness() != Rop.BRANCH_THROW) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            addOutput(lastAddress);
-
-            if (rop.isCallLike()) {
-                RegisterSpecList regs = insn.getSources();
-                DalvInsn di = new CstInsn(opcode, pos, regs, cst);
-
-                addOutput(di);
-            } else {
-                RegisterSpec realResult = getNextMoveResultPseudo();
-
-                RegisterSpecList regs = getRegs(insn, realResult);
-                DalvInsn di;
-
-                boolean hasResult = opcode.hasResult()
-                        || (rop.getOpcode() == RegOps.CHECK_CAST);
-
-                if (hasResult != (realResult != null)) {
-                    throw new RuntimeException(
-                            "Insn with result/move-result-pseudo mismatch " +
-                            insn);
-                }
-
-                if ((rop.getOpcode() == RegOps.NEW_ARRAY) &&
-                    (opcode.getOpcode() != Opcodes.NEW_ARRAY)) {
-                    /*
-                     * It's a type-specific new-array-<primitive>, and
-                     * so it should be turned into a SimpleInsn (no
-                     * constant ref as it's implicit).
-                     */
-                    di = new SimpleInsn(opcode, pos, regs);
-                } else {
-                    /*
-                     * This is the general case for constant-bearing
-                     * instructions.
-                     */
-                    di = new CstInsn(opcode, pos, regs, cst);
-                }
-
-                addOutput(di);
-            }
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingInsn(ThrowingInsn insn) {
-            SourcePosition pos = insn.getPosition();
-            Dop opcode = RopToDop.dopFor(insn);
-            Rop rop = insn.getOpcode();
-            RegisterSpec realResult;
-
-            if (rop.getBranchingness() != Rop.BRANCH_THROW) {
-                throw new RuntimeException("shouldn't happen");
-            }
-
-            realResult = getNextMoveResultPseudo();
-
-            if (opcode.hasResult() != (realResult != null)) {
-                throw new RuntimeException(
-                        "Insn with result/move-result-pseudo mismatch" + insn);
-            }
-
-            addOutput(lastAddress);
-
-            DalvInsn di = new SimpleInsn(opcode, pos,
-                    getRegs(insn, realResult));
-
-            addOutput(di);
-        }
-
-        /** {@inheritDoc} */
-        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
-            SourcePosition pos = insn.getPosition();
-            Constant cst = insn.getConstant();
-            ArrayList<Constant> values = insn.getInitValues();
-            Rop rop = insn.getOpcode();
-
-            if (rop.getBranchingness() != Rop.BRANCH_NONE) {
-                throw new RuntimeException("shouldn't happen");
-            }
-            CodeAddress dataAddress = new CodeAddress(pos);
-            ArrayData dataInsn =
-                new ArrayData(pos, lastAddress, values, cst);
-
-            TargetInsn fillArrayDataInsn =
-                new TargetInsn(Dops.FILL_ARRAY_DATA, pos, getRegs(insn),
-                        dataAddress);
-
-            addOutput(lastAddress);
-            addOutput(fillArrayDataInsn);
-
-            addOutputSuffix(new OddSpacer(pos));
-            addOutputSuffix(dataAddress);
-            addOutputSuffix(dataInsn);
-        }
-
-        /**
-         * Adds to the output.
-         *
-         * @param insn {@code non-null;} instruction to add
-         */
-        protected void addOutput(DalvInsn insn) {
-            output.add(insn);
-        }
-
-        /**
-         * Adds to the output suffix.
-         *
-         * @param insn {@code non-null;} instruction to add
-         */
-        protected void addOutputSuffix(DalvInsn insn) {
-            output.addSuffix(insn);
-        }
-    }
-
-    /**
-     * Instruction visitor class for doing instruction translation with
-     * local variable tracking
-     */
-    private class LocalVariableAwareTranslationVisitor
-            extends TranslationVisitor {
-        /** {@code non-null;} local variable info */
-        private LocalVariableInfo locals;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param output {@code non-null;} destination for instruction output
-         * @param locals {@code non-null;} the local variable info
-         */
-        public LocalVariableAwareTranslationVisitor(OutputCollector output,
-                                                    LocalVariableInfo locals) {
-            super(output);
-            this.locals = locals;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitPlainInsn(PlainInsn insn) {
-            super.visitPlainInsn(insn);
-            addIntroductionIfNecessary(insn);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitPlainCstInsn(PlainCstInsn insn) {
-            super.visitPlainCstInsn(insn);
-            addIntroductionIfNecessary(insn);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitSwitchInsn(SwitchInsn insn) {
-            super.visitSwitchInsn(insn);
-            addIntroductionIfNecessary(insn);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
-            super.visitThrowingCstInsn(insn);
-            addIntroductionIfNecessary(insn);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void visitThrowingInsn(ThrowingInsn insn) {
-            super.visitThrowingInsn(insn);
-            addIntroductionIfNecessary(insn);
-        }
-
-        /**
-         * Adds a {@link LocalStart} to the output if the given
-         * instruction in fact introduces a local variable.
-         *
-         * @param insn {@code non-null;} instruction in question
-         */
-        public void addIntroductionIfNecessary(Insn insn) {
-            RegisterSpec spec = locals.getAssignment(insn);
-
-            if (spec != null) {
-                addOutput(new LocalStart(insn.getPosition(), spec));
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/SimpleInsn.java b/dx/src/main/java/com/android/dx/dex/code/SimpleInsn.java
deleted file mode 100644
index 8cdcc55..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/SimpleInsn.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Instruction which has no extra info beyond the basics provided for in
- * the base class.
- */
-public final class SimpleInsn extends FixedSizeInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param opcode the opcode; one of the constants from {@link Dops}
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} register list, including a
-     * result register if appropriate (that is, registers may be either
-     * ins or outs)
-     */
-    public SimpleInsn(Dop opcode, SourcePosition position,
-                      RegisterSpecList registers) {
-        super(opcode, position, registers);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withOpcode(Dop opcode) {
-        return new SimpleInsn(opcode, getPosition(), getRegisters());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new SimpleInsn(getOpcode(), getPosition(), registers);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        return null;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/StdCatchBuilder.java b/dx/src/main/java/com/android/dx/dex/code/StdCatchBuilder.java
deleted file mode 100644
index 1e7612e..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/StdCatchBuilder.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.code;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-/**
- * Constructor of {@link CatchTable} instances from {@link RopMethod}
- * and associated data.
- */
-public final class StdCatchBuilder implements CatchBuilder {
-    /** the maximum range of a single catch handler, in code units */
-    private static final int MAX_CATCH_RANGE = 65535;
-
-    /** {@code non-null;} method to build the list for */
-    private final RopMethod method;
-
-    /** {@code non-null;} block output order */
-    private final int[] order;
-
-    /** {@code non-null;} address objects for each block */
-    private final BlockAddresses addresses;
-
-    /**
-     * Constructs an instance. It merely holds onto its parameters for
-     * a subsequent call to {@link #build}.
-     *
-     * @param method {@code non-null;} method to build the list for
-     * @param order {@code non-null;} block output order
-     * @param addresses {@code non-null;} address objects for each block
-     */
-    public StdCatchBuilder(RopMethod method, int[] order,
-            BlockAddresses addresses) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        if (order == null) {
-            throw new NullPointerException("order == null");
-        }
-
-        if (addresses == null) {
-            throw new NullPointerException("addresses == null");
-        }
-
-        this.method = method;
-        this.order = order;
-        this.addresses = addresses;
-    }
-
-    /** {@inheritDoc} */
-    public CatchTable build() {
-        return build(method, order, addresses);
-    }
-
-    /** {@inheritDoc} */
-    public boolean hasAnyCatches() {
-        BasicBlockList blocks = method.getBlocks();
-        int size = blocks.size();
-
-        for (int i = 0; i < size; i++) {
-            BasicBlock block = blocks.get(i);
-            TypeList catches = block.getLastInsn().getCatches();
-            if (catches.size() != 0) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public HashSet<Type> getCatchTypes() {
-        HashSet<Type> result = new HashSet<Type>(20);
-        BasicBlockList blocks = method.getBlocks();
-        int size = blocks.size();
-
-        for (int i = 0; i < size; i++) {
-            BasicBlock block = blocks.get(i);
-            TypeList catches = block.getLastInsn().getCatches();
-            int catchSize = catches.size();
-
-            for (int j = 0; j < catchSize; j++) {
-                result.add(catches.getType(j));
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Builds and returns the catch table for a given method.
-     *
-     * @param method {@code non-null;} method to build the list for
-     * @param order {@code non-null;} block output order
-     * @param addresses {@code non-null;} address objects for each block
-     * @return {@code non-null;} the constructed table
-     */
-    public static CatchTable build(RopMethod method, int[] order,
-            BlockAddresses addresses) {
-        int len = order.length;
-        BasicBlockList blocks = method.getBlocks();
-        ArrayList<CatchTable.Entry> resultList =
-            new ArrayList<CatchTable.Entry>(len);
-        CatchHandlerList currentHandlers = CatchHandlerList.EMPTY;
-        BasicBlock currentStartBlock = null;
-        BasicBlock currentEndBlock = null;
-
-        for (int i = 0; i < len; i++) {
-            BasicBlock block = blocks.labelToBlock(order[i]);
-
-            if (!block.canThrow()) {
-                /*
-                 * There is no need to concern ourselves with the
-                 * placement of blocks that can't throw with respect
-                 * to the blocks that *can* throw.
-                 */
-                continue;
-            }
-
-            CatchHandlerList handlers = handlersFor(block, addresses);
-
-            if (currentHandlers.size() == 0) {
-                // This is the start of a new catch range.
-                currentStartBlock = block;
-                currentEndBlock = block;
-                currentHandlers = handlers;
-                continue;
-            }
-
-            if (currentHandlers.equals(handlers)
-                    && rangeIsValid(currentStartBlock, block, addresses)) {
-                /*
-                 * The block we are looking at now has the same handlers
-                 * as the block that started the currently open catch
-                 * range, and adding it to the currently open range won't
-                 * cause it to be too long.
-                 */
-                currentEndBlock = block;
-                continue;
-            }
-
-            /*
-             * The block we are looking at now has incompatible handlers,
-             * so we need to finish off the last entry and start a new
-             * one. Note: We only emit an entry if it has associated handlers.
-             */
-            if (currentHandlers.size() != 0) {
-                CatchTable.Entry entry =
-                    makeEntry(currentStartBlock, currentEndBlock,
-                            currentHandlers, addresses);
-                resultList.add(entry);
-            }
-
-            currentStartBlock = block;
-            currentEndBlock = block;
-            currentHandlers = handlers;
-        }
-
-        if (currentHandlers.size() != 0) {
-            // Emit an entry for the range that was left hanging.
-            CatchTable.Entry entry =
-                makeEntry(currentStartBlock, currentEndBlock,
-                        currentHandlers, addresses);
-            resultList.add(entry);
-        }
-
-        // Construct the final result.
-
-        int resultSz = resultList.size();
-
-        if (resultSz == 0) {
-            return CatchTable.EMPTY;
-        }
-
-        CatchTable result = new CatchTable(resultSz);
-
-        for (int i = 0; i < resultSz; i++) {
-            result.set(i, resultList.get(i));
-        }
-
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Makes the {@link CatchHandlerList} for the given basic block.
-     *
-     * @param block {@code non-null;} block to get entries for
-     * @param addresses {@code non-null;} address objects for each block
-     * @return {@code non-null;} array of entries
-     */
-    private static CatchHandlerList handlersFor(BasicBlock block,
-            BlockAddresses addresses) {
-        IntList successors = block.getSuccessors();
-        int succSize = successors.size();
-        int primary = block.getPrimarySuccessor();
-        TypeList catches = block.getLastInsn().getCatches();
-        int catchSize = catches.size();
-
-        if (catchSize == 0) {
-            return CatchHandlerList.EMPTY;
-        }
-
-        if (((primary == -1) && (succSize != catchSize))
-                || ((primary != -1) &&
-                        ((succSize != (catchSize + 1))
-                                || (primary != successors.get(catchSize))))) {
-            /*
-             * Blocks that throw are supposed to list their primary
-             * successor -- if any -- last in the successors list, but
-             * that constraint appears to be violated here.
-             */
-            throw new RuntimeException(
-                    "shouldn't happen: weird successors list");
-        }
-
-        /*
-         * Reduce the effective catchSize if we spot a catch-all that
-         * isn't at the end.
-         */
-        for (int i = 0; i < catchSize; i++) {
-            Type type = catches.getType(i);
-            if (type.equals(Type.OBJECT)) {
-                catchSize = i + 1;
-                break;
-            }
-        }
-
-        CatchHandlerList result = new CatchHandlerList(catchSize);
-
-        for (int i = 0; i < catchSize; i++) {
-            CstType oneType = new CstType(catches.getType(i));
-            CodeAddress oneHandler = addresses.getStart(successors.get(i));
-            result.set(i, oneType, oneHandler.getAddress());
-        }
-
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Makes a {@link CatchTable#Entry} for the given block range and
-     * handlers.
-     *
-     * @param start {@code non-null;} the start block for the range (inclusive)
-     * @param end {@code non-null;} the start block for the range (also inclusive)
-     * @param handlers {@code non-null;} the handlers for the range
-     * @param addresses {@code non-null;} address objects for each block
-     */
-    private static CatchTable.Entry makeEntry(BasicBlock start,
-            BasicBlock end, CatchHandlerList handlers,
-            BlockAddresses addresses) {
-        /*
-         * We start at the *last* instruction of the start block, since
-         * that's the instruction that can throw...
-         */
-        CodeAddress startAddress = addresses.getLast(start);
-
-        // ...And we end *after* the last instruction of the end block.
-        CodeAddress endAddress = addresses.getEnd(end);
-
-        return new CatchTable.Entry(startAddress.getAddress(),
-                endAddress.getAddress(), handlers);
-    }
-
-    /**
-     * Gets whether the address range for the given two blocks is valid
-     * for a catch handler. This is true as long as the covered range is
-     * under 65536 code units.
-     *
-     * @param start {@code non-null;} the start block for the range (inclusive)
-     * @param end {@code non-null;} the start block for the range (also inclusive)
-     * @param addresses {@code non-null;} address objects for each block
-     * @return {@code true} if the range is valid as a catch range
-     */
-    private static boolean rangeIsValid(BasicBlock start, BasicBlock end,
-            BlockAddresses addresses) {
-        if (start == null) {
-            throw new NullPointerException("start == null");
-        }
-
-        if (end == null) {
-            throw new NullPointerException("end == null");
-        }
-
-        // See above about selection of instructions.
-        int startAddress = addresses.getLast(start).getAddress();
-        int endAddress = addresses.getEnd(end).getAddress();
-
-        return (endAddress - startAddress) <= MAX_CATCH_RANGE;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/SwitchData.java b/dx/src/main/java/com/android/dx/dex/code/SwitchData.java
deleted file mode 100644
index 8fc80b1..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/SwitchData.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.io.Opcodes;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-
-/**
- * Pseudo-instruction which holds switch data. The switch data is
- * a map of values to target addresses, and this class writes the data
- * in either a "packed" or "sparse" form.
- */
-public final class SwitchData extends VariableSizeInsn {
-    /**
-     * {@code non-null;} address representing the instruction that uses this
-     * instance
-     */
-    private final CodeAddress user;
-
-    /** {@code non-null;} sorted list of switch cases (keys) */
-    private final IntList cases;
-
-    /**
-     * {@code non-null;} corresponding list of code addresses; the branch
-     * target for each case
-     */
-    private final CodeAddress[] targets;
-
-    /** whether the output table will be packed (vs. sparse) */
-    private final boolean packed;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param user {@code non-null;} address representing the instruction that
-     * uses this instance
-     * @param cases {@code non-null;} sorted list of switch cases (keys)
-     * @param targets {@code non-null;} corresponding list of code addresses; the
-     * branch target for each case
-     */
-    public SwitchData(SourcePosition position, CodeAddress user,
-                      IntList cases, CodeAddress[] targets) {
-        super(position, RegisterSpecList.EMPTY);
-
-        if (user == null) {
-            throw new NullPointerException("user == null");
-        }
-
-        if (cases == null) {
-            throw new NullPointerException("cases == null");
-        }
-
-        if (targets == null) {
-            throw new NullPointerException("targets == null");
-        }
-
-        int sz = cases.size();
-
-        if (sz != targets.length) {
-            throw new IllegalArgumentException("cases / targets mismatch");
-        }
-
-        if (sz > 65535) {
-            throw new IllegalArgumentException("too many cases");
-        }
-
-        this.user = user;
-        this.cases = cases;
-        this.targets = targets;
-        this.packed = shouldPack(cases);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return packed ? (int) packedCodeSize(cases) :
-            (int) sparseCodeSize(cases);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out) {
-        int baseAddress = user.getAddress();
-        int defaultTarget = Dops.PACKED_SWITCH.getFormat().codeSize();
-        int sz = targets.length;
-
-        if (packed) {
-            int firstCase = (sz == 0) ? 0 : cases.get(0);
-            int lastCase = (sz == 0) ? 0 : cases.get(sz - 1);
-            int outSz = lastCase - firstCase + 1;
-
-            out.writeShort(Opcodes.PACKED_SWITCH_PAYLOAD);
-            out.writeShort(outSz);
-            out.writeInt(firstCase);
-
-            int caseAt = 0;
-            for (int i = 0; i < outSz; i++) {
-                int outCase = firstCase + i;
-                int oneCase = cases.get(caseAt);
-                int relTarget;
-
-                if (oneCase > outCase) {
-                    relTarget = defaultTarget;
-                } else {
-                    relTarget = targets[caseAt].getAddress() - baseAddress;
-                    caseAt++;
-                }
-
-                out.writeInt(relTarget);
-            }
-        } else {
-            out.writeShort(Opcodes.SPARSE_SWITCH_PAYLOAD);
-            out.writeShort(sz);
-
-            for (int i = 0; i < sz; i++) {
-                out.writeInt(cases.get(i));
-            }
-
-            for (int i = 0; i < sz; i++) {
-                int relTarget = targets[i].getAddress() - baseAddress;
-                out.writeInt(relTarget);
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new SwitchData(getPosition(), user, cases, targets);
-    }
-
-    /**
-     * Returns whether or not this instance's data will be output as packed.
-     *
-     * @return {@code true} iff the data is to be packed
-     */
-    public boolean isPacked() {
-        return packed;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        int sz = targets.length;
-        for (int i = 0; i < sz; i++) {
-            sb.append("\n    ");
-            sb.append(cases.get(i));
-            sb.append(": ");
-            sb.append(targets[i]);
-        }
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String listingString0(boolean noteIndices) {
-        int baseAddress = user.getAddress();
-        StringBuffer sb = new StringBuffer(100);
-        int sz = targets.length;
-
-        sb.append(packed ? "packed" : "sparse");
-        sb.append("-switch-payload // for switch @ ");
-        sb.append(Hex.u2(baseAddress));
-
-        for (int i = 0; i < sz; i++) {
-            int absTarget = targets[i].getAddress();
-            int relTarget = absTarget - baseAddress;
-            sb.append("\n  ");
-            sb.append(cases.get(i));
-            sb.append(": ");
-            sb.append(Hex.u4(absTarget));
-            sb.append(" // ");
-            sb.append(Hex.s4(relTarget));
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets the size of a packed table for the given cases, in 16-bit code
-     * units.
-     *
-     * @param cases {@code non-null;} sorted list of cases
-     * @return {@code >= -1;} the packed table size or {@code -1} if the
-     * cases couldn't possibly be represented as a packed table
-     */
-    private static long packedCodeSize(IntList cases) {
-        int sz = cases.size();
-        long low = cases.get(0);
-        long high = cases.get(sz - 1);
-        long result = ((high - low + 1)) * 2 + 4;
-
-        return (result <= 0x7fffffff) ? result : -1;
-    }
-
-    /**
-     * Gets the size of a sparse table for the given cases, in 16-bit code
-     * units.
-     *
-     * @param cases {@code non-null;} sorted list of cases
-     * @return {@code > 0;} the sparse table size
-     */
-    private static long sparseCodeSize(IntList cases) {
-        int sz = cases.size();
-
-        return (sz * 4L) + 2;
-    }
-
-    /**
-     * Determines whether the given list of cases warrant being packed.
-     *
-     * @param cases {@code non-null;} sorted list of cases
-     * @return {@code true} iff the table encoding the cases
-     * should be packed
-     */
-    private static boolean shouldPack(IntList cases) {
-        int sz = cases.size();
-
-        if (sz < 2) {
-            return true;
-        }
-
-        long packedSize = packedCodeSize(cases);
-        long sparseSize = sparseCodeSize(cases);
-
-        /*
-         * We pick the packed representation if it is possible and
-         * would be as small or smaller than 5/4 of the sparse
-         * representation. That is, we accept some size overhead on
-         * the packed representation, since that format is faster to
-         * execute at runtime.
-         */
-        return (packedSize >= 0) && (packedSize <= ((sparseSize * 5) / 4));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/TargetInsn.java b/dx/src/main/java/com/android/dx/dex/code/TargetInsn.java
deleted file mode 100644
index cbb5ff9..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/TargetInsn.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Instruction which has a single branch target.
- */
-public final class TargetInsn extends FixedSizeInsn {
-    /** {@code non-null;} the branch target */
-    private CodeAddress target;
-
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}), and the target is initially
-     * {@code null}.
-     *
-     * @param opcode the opcode; one of the constants from {@link Dops}
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} register list, including a
-     * result register if appropriate (that is, registers may be either
-     * ins or outs)
-     * @param target {@code non-null;} the branch target
-     */
-    public TargetInsn(Dop opcode, SourcePosition position,
-                      RegisterSpecList registers, CodeAddress target) {
-        super(opcode, position, registers);
-
-        if (target == null) {
-            throw new NullPointerException("target == null");
-        }
-
-        this.target = target;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withOpcode(Dop opcode) {
-        return new TargetInsn(opcode, getPosition(), getRegisters(), target);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisters(RegisterSpecList registers) {
-        return new TargetInsn(getOpcode(), getPosition(), registers, target);
-    }
-
-    /**
-     * Returns an instance that is just like this one, except that its
-     * opcode has the opposite sense (as a test; e.g. a
-     * {@code lt} test becomes a {@code ge}), and its branch
-     * target is replaced by the one given, and all set-once values
-     * associated with the class (such as its address) are reset.
-     *
-     * @param target {@code non-null;} the new branch target
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public TargetInsn withNewTargetAndReversed(CodeAddress target) {
-        Dop opcode = getOpcode().getOppositeTest();
-
-        return new TargetInsn(opcode, getPosition(), getRegisters(), target);
-    }
-
-    /**
-     * Gets the unique branch target of this instruction.
-     *
-     * @return {@code non-null;} the branch target
-     */
-    public CodeAddress getTarget() {
-        return target;
-    }
-
-    /**
-     * Gets the target address of this instruction. This is only valid
-     * to call if the target instruction has been assigned an address,
-     * and it is merely a convenient shorthand for
-     * {@code getTarget().getAddress()}.
-     *
-     * @return {@code >= 0;} the target address
-     */
-    public int getTargetAddress() {
-        return target.getAddress();
-    }
-
-    /**
-     * Gets the branch offset of this instruction. This is only valid to
-     * call if both this and the target instruction each has been assigned
-     * an address, and it is merely a convenient shorthand for
-     * {@code getTargetAddress() - getAddress()}.
-     *
-     * @return the branch offset
-     */
-    public int getTargetOffset() {
-        return target.getAddress() - getAddress();
-    }
-
-    /**
-     * Returns whether the target offset is known.
-     *
-     * @return {@code true} if the target offset is known or
-     * {@code false} if not
-     */
-    public boolean hasTargetOffset() {
-        return hasAddress() && target.hasAddress();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String argString() {
-        if (target == null) {
-            return "????";
-        }
-
-        return target.identifierString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/VariableSizeInsn.java b/dx/src/main/java/com/android/dx/dex/code/VariableSizeInsn.java
deleted file mode 100644
index 06b40f7..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/VariableSizeInsn.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-
-/**
- * Pseudo-instruction base class for variable-sized instructions.
- */
-public abstract class VariableSizeInsn extends DalvInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     * @param registers {@code non-null;} source registers
-     */
-    public VariableSizeInsn(SourcePosition position,
-                            RegisterSpecList registers) {
-        super(Dops.SPECIAL_FORMAT, position, registers);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final DalvInsn withOpcode(Dop opcode) {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final DalvInsn withRegisterOffset(int delta) {
-        return withRegisters(getRegisters().withOffset(delta));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/ZeroSizeInsn.java b/dx/src/main/java/com/android/dx/dex/code/ZeroSizeInsn.java
deleted file mode 100644
index 2cc157b..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/ZeroSizeInsn.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Pseudo-instruction base class for zero-size (no code emitted)
- * instructions, which are generally used for tracking metainformation
- * about the code they are adjacent to.
- */
-public abstract class ZeroSizeInsn extends DalvInsn {
-    /**
-     * Constructs an instance. The output address of this instance is initially
-     * unknown ({@code -1}).
-     *
-     * @param position {@code non-null;} source position
-     */
-    public ZeroSizeInsn(SourcePosition position) {
-        super(Dops.SPECIAL_FORMAT, position, RegisterSpecList.EMPTY);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int codeSize() {
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void writeTo(AnnotatedOutput out) {
-        // Nothing to do here, for this class.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final DalvInsn withOpcode(Dop opcode) {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public DalvInsn withRegisterOffset(int delta) {
-        return withRegisters(getRegisters().withOffset(delta));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form10t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form10t.java
deleted file mode 100644
index ced4a64..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form10t.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 10t}. See the instruction format spec
- * for details.
- */
-public final class Form10t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form10t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form10t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        return branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!((insn instanceof TargetInsn) &&
-              (insn.getRegisters().size() == 0))) {
-            return false;
-        }
-
-        TargetInsn ti = (TargetInsn) insn;
-        return ti.hasTargetOffset() ? branchFits(ti) : true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        int offset = insn.getTargetOffset();
-
-        // Note: A zero offset would fit, but it is prohibited by the spec.
-        return (offset != 0) && signedFitsInByte(offset);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out, opcodeUnit(insn, (offset & 0xff)));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form10x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form10x.java
deleted file mode 100644
index 4be3aa0..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form10x.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 10x}. See the instruction format spec
- * for details.
- */
-public final class Form10x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form10x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form10x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        // This format has no arguments.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        return (insn instanceof SimpleInsn) &&
-            (insn.getRegisters().size() == 0);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        write(out, opcodeUnit(insn, 0));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form11n.java b/dx/src/main/java/com/android/dx/dex/code/form/Form11n.java
deleted file mode 100644
index 479af6e..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form11n.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 11n}. See the instruction format spec
- * for details.
- */
-public final class Form11n extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form11n();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form11n() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 4);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInNibble(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        return cb.fitsInInt() && signedFitsInNibble(cb.getIntBits());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out,
-              opcodeUnit(insn, makeByte(regs.get(0).getReg(), value & 0xf)));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form11x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form11x.java
deleted file mode 100644
index 82dda65..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form11x.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 11x}. See the instruction format spec
- * for details.
- */
-public final class Form11x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form11x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form11x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return (insn instanceof SimpleInsn) &&
-            (regs.size() == 1) &&
-            unsignedFitsInByte(regs.get(0).getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        write(out, opcodeUnit(insn, regs.get(0).getReg()));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form12x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form12x.java
deleted file mode 100644
index aabab8a..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form12x.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 12x}. See the instruction format spec
- * for details.
- */
-public final class Form12x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form12x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form12x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-
-        /*
-         * The (sz - 2) and (sz - 1) below makes this code work for
-         * both the two- and three-register ops. (See "case 3" in
-         * isCompatible(), below.)
-         */
-
-        return regs.get(sz - 2).regString() + ", " +
-            regs.get(sz - 1).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!(insn instanceof SimpleInsn)) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        RegisterSpec rs1;
-        RegisterSpec rs2;
-
-        switch (regs.size()) {
-            case 2: {
-                rs1 = regs.get(0);
-                rs2 = regs.get(1);
-                break;
-            }
-            case 3: {
-                /*
-                 * This format is allowed for ops that are effectively
-                 * 3-arg but where the first two args are identical.
-                 */
-                rs1 = regs.get(1);
-                rs2 = regs.get(2);
-                if (rs1.getReg() != regs.get(0).getReg()) {
-                    return false;
-                }
-                break;
-            }
-            default: {
-                return false;
-            }
-        }
-
-        return unsignedFitsInNibble(rs1.getReg()) &&
-            unsignedFitsInNibble(rs2.getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-
-        /*
-         * The (sz - 2) and (sz - 1) below makes this code work for
-         * both the two- and three-register ops. (See "case 3" in
-         * isCompatible(), above.)
-         */
-
-        write(out, opcodeUnit(insn,
-                              makeByte(regs.get(sz - 2).getReg(),
-                                       regs.get(sz - 1).getReg())));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form20t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form20t.java
deleted file mode 100644
index a19ed28..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form20t.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 20t}. See the instruction format spec
- * for details.
- */
-public final class Form20t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form20t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form20t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        return branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!((insn instanceof TargetInsn) &&
-              (insn.getRegisters().size() == 0))) {
-            return false;
-        }
-
-        TargetInsn ti = (TargetInsn) insn;
-        return ti.hasTargetOffset() ? branchFits(ti) : true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        int offset = insn.getTargetOffset();
-
-        // Note: A zero offset would fit, but it is prohibited by the spec.
-        return (offset != 0) && signedFitsInShort(offset);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out, opcodeUnit(insn, 0), (short) offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form21c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form21c.java
deleted file mode 100644
index 0335dc7..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form21c.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 21c}. See the instruction format spec
- * for details.
- */
-public final class Form21c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form21c();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form21c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        RegisterSpec reg;
-
-        switch (regs.size()) {
-            case 1: {
-                reg = regs.get(0);
-                break;
-            }
-            case 2: {
-                /*
-                 * This format is allowed for ops that are effectively
-                 * 2-arg but where the two args are identical.
-                 */
-                reg = regs.get(0);
-                if (reg.getReg() != regs.get(1).getReg()) {
-                    return false;
-                }
-                break;
-            }
-            default: {
-                return false;
-            }
-        }
-
-        if (!unsignedFitsInByte(reg.getReg())) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        int cpi = ci.getIndex();
-        Constant cst = ci.getConstant();
-
-        if (! unsignedFitsInShort(cpi)) {
-            return false;
-        }
-
-        return (cst instanceof CstType) ||
-            (cst instanceof CstFieldRef) ||
-            (cst instanceof CstString);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-        BitSet bits = new BitSet(sz);
-        boolean compat = unsignedFitsInByte(regs.get(0).getReg());
-
-        if (sz == 1) {
-            bits.set(0, compat);
-        } else {
-            if (regs.get(0).getReg() == regs.get(1).getReg()) {
-                bits.set(0, compat);
-                bits.set(1, compat);
-            }
-        }
-
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              (short) cpi);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form21h.java b/dx/src/main/java/com/android/dx/dex/code/form/Form21h.java
deleted file mode 100644
index 02cc0fd..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form21h.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 21h}. See the instruction format spec
- * for details.
- */
-public final class Form21h extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form21h();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form21h() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return
-            literalBitsComment(value,
-                    (regs.get(0).getCategory() == 1) ? 32 : 64);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        // Where the high bits are depends on the category of the target.
-        if (regs.get(0).getCategory() == 1) {
-            int bits = cb.getIntBits();
-            return ((bits & 0xffff) == 0);
-        } else {
-            long bits = cb.getLongBits();
-            return ((bits & 0xffffffffffffL) == 0);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits cb = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        short bits;
-
-        // Where the high bits are depends on the category of the target.
-        if (regs.get(0).getCategory() == 1) {
-            bits = (short) (cb.getIntBits() >>> 16);
-        } else {
-            bits = (short) (cb.getLongBits() >>> 48);
-        }
-
-        write(out, opcodeUnit(insn, regs.get(0).getReg()), bits);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form21s.java b/dx/src/main/java/com/android/dx/dex/code/form/Form21s.java
deleted file mode 100644
index 9264ec0..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form21s.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 21s}. See the instruction format spec
- * for details.
- */
-public final class Form21s extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form21s();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form21s() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 16);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              (short) value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form21t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form21t.java
deleted file mode 100644
index 8adb668..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form21t.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 21t}. See the instruction format spec
- * for details.
- */
-public final class Form21t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form21t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form21t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        if (!((insn instanceof TargetInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        TargetInsn ti = (TargetInsn) insn;
-        return ti.hasTargetOffset() ? branchFits(ti) : true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        int offset = insn.getTargetOffset();
-
-        // Note: A zero offset would fit, but it is prohibited by the spec.
-        return (offset != 0) && signedFitsInShort(offset);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              (short) offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form22b.java b/dx/src/main/java/com/android/dx/dex/code/form/Form22b.java
deleted file mode 100644
index e5a8b5d..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form22b.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 22b}. See the instruction format spec
- * for details.
- */
-public final class Form22b extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form22b();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form22b() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 8);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInByte(regs.get(0).getReg()) &&
-              unsignedFitsInByte(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        return cb.fitsInInt() && signedFitsInByte(cb.getIntBits());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              codeUnit(regs.get(1).getReg(), value & 0xff));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form22c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form22c.java
deleted file mode 100644
index 5ffdb86..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form22c.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 22c}. See the instruction format spec
- * for details.
- */
-public final class Form22c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form22c();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form22c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInNibble(regs.get(0).getReg()) &&
-              unsignedFitsInNibble(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        int cpi = ci.getIndex();
-
-        if (! unsignedFitsInShort(cpi)) {
-            return false;
-        }
-
-        Constant cst = ci.getConstant();
-        return (cst instanceof CstType) ||
-            (cst instanceof CstFieldRef);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-
-        write(out,
-              opcodeUnit(insn,
-                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),
-              (short) cpi);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form22s.java b/dx/src/main/java/com/android/dx/dex/code/form/Form22s.java
deleted file mode 100644
index 03d180a..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form22s.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 22s}. See the instruction format spec
- * for details.
- */
-public final class Form22s extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form22s();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form22s() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + regs.get(1).regString()
-            + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 16);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInNibble(regs.get(0).getReg()) &&
-              unsignedFitsInNibble(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out,
-              opcodeUnit(insn,
-                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),
-              (short) value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form22t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form22t.java
deleted file mode 100644
index 15ce0f8..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form22t.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 22t}. See the instruction format spec
- * for details.
- */
-public final class Form22t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form22t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form22t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        if (!((insn instanceof TargetInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInNibble(regs.get(0).getReg()) &&
-              unsignedFitsInNibble(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        TargetInsn ti = (TargetInsn) insn;
-        return ti.hasTargetOffset() ? branchFits(ti) : true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInNibble(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInNibble(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        int offset = insn.getTargetOffset();
-
-        // Note: A zero offset would fit, but it is prohibited by the spec.
-        return (offset != 0) && signedFitsInShort(offset);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out,
-              opcodeUnit(insn,
-                         makeByte(regs.get(0).getReg(), regs.get(1).getReg())),
-              (short) offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form22x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form22x.java
deleted file mode 100644
index 01eec0b..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form22x.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 22x}. See the instruction format spec
- * for details.
- */
-public final class Form22x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form22x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form22x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        return (insn instanceof SimpleInsn) &&
-            (regs.size() == 2) &&
-            unsignedFitsInByte(regs.get(0).getReg()) &&
-            unsignedFitsInShort(regs.get(1).getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              (short) regs.get(1).getReg());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form23x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form23x.java
deleted file mode 100644
index 9164482..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form23x.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 23x}. See the instruction format spec
- * for details.
- */
-public final class Form23x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form23x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form23x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + regs.get(2).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        return (insn instanceof SimpleInsn) &&
-            (regs.size() == 3) &&
-            unsignedFitsInByte(regs.get(0).getReg()) &&
-            unsignedFitsInByte(regs.get(1).getReg()) &&
-            unsignedFitsInByte(regs.get(2).getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(3);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
-        bits.set(2, unsignedFitsInByte(regs.get(2).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        write(out,
-              opcodeUnit(insn, regs.get(0).getReg()),
-              codeUnit(regs.get(1).getReg(), regs.get(2).getReg()));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form30t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form30t.java
deleted file mode 100644
index 86a3e82..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form30t.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 30t}. See the instruction format spec
- * for details.
- */
-public final class Form30t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form30t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form30t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        return branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!((insn instanceof TargetInsn) &&
-              (insn.getRegisters().size() == 0))) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out, opcodeUnit(insn, 0), offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form31c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form31c.java
deleted file mode 100644
index 3295fda..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form31c.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 31c}. See the instruction format spec
- * for details.
- */
-public final class Form31c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form31c();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form31c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        RegisterSpec reg;
-
-        switch (regs.size()) {
-            case 1: {
-                reg = regs.get(0);
-                break;
-            }
-            case 2: {
-                /*
-                 * This format is allowed for ops that are effectively
-                 * 2-arg but where the two args are identical.
-                 */
-                reg = regs.get(0);
-                if (reg.getReg() != regs.get(1).getReg()) {
-                    return false;
-                }
-                break;
-            }
-            default: {
-                return false;
-            }
-        }
-
-        if (!unsignedFitsInByte(reg.getReg())) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        return (cst instanceof CstType) ||
-            (cst instanceof CstFieldRef) ||
-            (cst instanceof CstString);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-        BitSet bits = new BitSet(sz);
-        boolean compat = unsignedFitsInByte(regs.get(0).getReg());
-
-        if (sz == 1) {
-            bits.set(0, compat);
-        } else {
-            if (regs.get(0).getReg() == regs.get(1).getReg()) {
-                bits.set(0, compat);
-                bits.set(1, compat);
-            }
-        }
-
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-
-        write(out, opcodeUnit(insn, regs.get(0).getReg()), cpi);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form31i.java b/dx/src/main/java/com/android/dx/dex/code/form/Form31i.java
deleted file mode 100644
index b52341d..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form31i.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 31i}. See the instruction format spec
- * for details.
- */
-public final class Form31i extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form31i();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form31i() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 32);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        return ((CstLiteralBits) cst).fitsInInt();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out, opcodeUnit(insn, regs.get(0).getReg()), value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form31t.java b/dx/src/main/java/com/android/dx/dex/code/form/Form31t.java
deleted file mode 100644
index 1999bba..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form31t.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.TargetInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 31t}. See the instruction format spec
- * for details.
- */
-public final class Form31t extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form31t();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form31t() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + branchString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        return branchComment(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        if (!((insn instanceof TargetInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean branchFits(TargetInsn insn) {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int offset = ((TargetInsn) insn).getTargetOffset();
-
-        write(out, opcodeUnit(insn, regs.get(0).getReg()), offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form32s.java b/dx/src/main/java/com/android/dx/dex/code/form/Form32s.java
deleted file mode 100644
index e081470..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form32s.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2010 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 32s}. See the instruction format spec
- * for details.
- */
-public final class Form32s extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form32s();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form32s() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + regs.get(1).regString()
-            + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 16);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (! ALLOW_EXTENDED_OPCODES) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInByte(regs.get(0).getReg()) &&
-              unsignedFitsInByte(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!(cst instanceof CstLiteralBits)) {
-            return false;
-        }
-
-        CstLiteralBits cb = (CstLiteralBits) cst;
-
-        return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int value =
-            ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
-        write(out,
-                opcodeUnit(insn),
-                codeUnit(regs.get(0).getReg(), regs.get(1).getReg()),
-                (short) value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form32x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form32x.java
deleted file mode 100644
index abed0e9..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form32x.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 32x}. See the instruction format spec
- * for details.
- */
-public final class Form32x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form32x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form32x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return (insn instanceof SimpleInsn) &&
-            (regs.size() == 2) &&
-            unsignedFitsInShort(regs.get(0).getReg()) &&
-            unsignedFitsInShort(regs.get(1).getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInShort(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-
-        write(out,
-              opcodeUnit(insn, 0),
-              (short) regs.get(0).getReg(),
-              (short) regs.get(1).getReg());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form33x.java b/dx/src/main/java/com/android/dx/dex/code/form/Form33x.java
deleted file mode 100644
index 9a569a0..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form33x.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 33x}. See the instruction format spec
- * for details.
- */
-public final class Form33x extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form33x();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form33x() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + regs.get(2).regString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        // This format has no comment.
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (! ALLOW_EXTENDED_OPCODES) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-
-        return (insn instanceof SimpleInsn) &&
-            (regs.size() == 3) &&
-            unsignedFitsInByte(regs.get(0).getReg()) &&
-            unsignedFitsInByte(regs.get(1).getReg()) &&
-            unsignedFitsInShort(regs.get(2).getReg());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(3);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
-        bits.set(2, unsignedFitsInShort(regs.get(2).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        write(out,
-                opcodeUnit(insn),
-                codeUnit(regs.get(0).getReg(), regs.get(1).getReg()),
-                (short) regs.get(2).getReg());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form35c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form35c.java
deleted file mode 100644
index b9c12c6..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form35c.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 35c}. See the instruction format spec
- * for details.
- */
-public final class Form35c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form35c();
-
-    /** Maximal number of operands */
-    private static final int MAX_NUM_OPS = 5;
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form35c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = explicitize(insn.getRegisters());
-        return regListString(regs) + ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        int cpi = ci.getIndex();
-
-        if (! unsignedFitsInShort(cpi)) {
-            return false;
-        }
-
-        Constant cst = ci.getConstant();
-        if (!((cst instanceof CstMethodRef) ||
-              (cst instanceof CstType))) {
-            return false;
-        }
-
-        RegisterSpecList regs = ci.getRegisters();
-        return (wordCount(regs) >= 0);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-        BitSet bits = new BitSet(sz);
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec reg = regs.get(i);
-            /*
-             * The check below adds (category - 1) to the register, to
-             * account for the fact that the second half of a
-             * category-2 register has to be represented explicitly in
-             * the result.
-             */
-            bits.set(i, unsignedFitsInNibble(reg.getReg() +
-                                             reg.getCategory() - 1));
-        }
-
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        int cpi = ((CstInsn) insn).getIndex();
-        RegisterSpecList regs = explicitize(insn.getRegisters());
-        int sz = regs.size();
-        int r0 = (sz > 0) ? regs.get(0).getReg() : 0;
-        int r1 = (sz > 1) ? regs.get(1).getReg() : 0;
-        int r2 = (sz > 2) ? regs.get(2).getReg() : 0;
-        int r3 = (sz > 3) ? regs.get(3).getReg() : 0;
-        int r4 = (sz > 4) ? regs.get(4).getReg() : 0;
-
-        write(out,
-              opcodeUnit(insn,
-                         makeByte(r4, sz)), // encode the fifth operand here
-              (short) cpi,
-              codeUnit(r0, r1, r2, r3));
-    }
-
-    /**
-     * Gets the number of words required for the given register list, where
-     * category-2 values count as two words. Return {@code -1} if the
-     * list requires more than five words or contains registers that need
-     * more than a nibble to identify them.
-     *
-     * @param regs {@code non-null;} the register list in question
-     * @return {@code >= -1;} the number of words required, or {@code -1}
-     * if the list couldn't possibly fit in this format
-     */
-    private static int wordCount(RegisterSpecList regs) {
-        int sz = regs.size();
-
-        if (sz > MAX_NUM_OPS) {
-            // It can't possibly fit.
-            return -1;
-        }
-
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec one = regs.get(i);
-            result += one.getCategory();
-            /*
-             * The check below adds (category - 1) to the register, to
-             * account for the fact that the second half of a
-             * category-2 register has to be represented explicitly in
-             * the result.
-             */
-            if (!unsignedFitsInNibble(one.getReg() + one.getCategory() - 1)) {
-                return -1;
-            }
-        }
-
-        return (result <= MAX_NUM_OPS) ? result : -1;
-    }
-
-    /**
-     * Returns a register list which is equivalent to the given one,
-     * except that it splits category-2 registers into two explicit
-     * entries. This returns the original list if no modification is
-     * required
-     *
-     * @param orig {@code non-null;} the original list
-     * @return {@code non-null;} the list with the described transformation
-     */
-    private static RegisterSpecList explicitize(RegisterSpecList orig) {
-        int wordCount = wordCount(orig);
-        int sz = orig.size();
-
-        if (wordCount == sz) {
-            return orig;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(wordCount);
-        int wordAt = 0;
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec one = orig.get(i);
-            result.set(wordAt, one);
-            if (one.getCategory() == 2) {
-                result.set(wordAt + 1,
-                           RegisterSpec.make(one.getReg() + 1, Type.VOID));
-                wordAt += 2;
-            } else {
-                wordAt++;
-            }
-        }
-
-        result.setImmutable();
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form3rc.java b/dx/src/main/java/com/android/dx/dex/code/form/Form3rc.java
deleted file mode 100644
index 1727af5..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form3rc.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 3rc}. See the instruction format spec
- * for details.
- */
-public final class Form3rc extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form3rc();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form3rc() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        return regRangeString(insn.getRegisters()) + ", " +
-            cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        int cpi = ci.getIndex();
-        Constant cst = ci.getConstant();
-
-        if (! unsignedFitsInShort(cpi)) {
-            return false;
-        }
-
-        if (!((cst instanceof CstMethodRef) ||
-              (cst instanceof CstType))) {
-            return false;
-        }
-
-        RegisterSpecList regs = ci.getRegisters();
-        int sz = regs.size();
-
-        return (regs.size() == 0) ||
-            (isRegListSequential(regs) &&
-             unsignedFitsInShort(regs.get(0).getReg()) &&
-             unsignedFitsInByte(regs.getWordCount()));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-        int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();
-        int count = regs.getWordCount();
-
-        write(out, opcodeUnit(insn, count), (short) cpi, (short) firstReg);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form41c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form41c.java
deleted file mode 100644
index 24067bc..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form41c.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2010 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 41c}. See the instruction format spec
- * for details.
- */
-public final class Form41c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form41c();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form41c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 4;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (! ALLOW_EXTENDED_OPCODES) {
-            return false;
-        }
-
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        RegisterSpec reg;
-
-        switch (regs.size()) {
-            case 1: {
-                reg = regs.get(0);
-                break;
-            }
-            case 2: {
-                /*
-                 * This format is allowed for ops that are effectively
-                 * 2-arg but where the two args are identical.
-                 */
-                reg = regs.get(0);
-                if (reg.getReg() != regs.get(1).getReg()) {
-                    return false;
-                }
-                break;
-            }
-            default: {
-                return false;
-            }
-        }
-
-        if (!unsignedFitsInShort(reg.getReg())) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        return (cst instanceof CstType) ||
-            (cst instanceof CstFieldRef);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int sz = regs.size();
-        BitSet bits = new BitSet(sz);
-        boolean compat = unsignedFitsInByte(regs.get(0).getReg());
-
-        if (sz == 1) {
-            bits.set(0, compat);
-        } else {
-            if (regs.get(0).getReg() == regs.get(1).getReg()) {
-                bits.set(0, compat);
-                bits.set(1, compat);
-            }
-        }
-
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-
-        write(out, opcodeUnit(insn), cpi, (short) regs.get(0).getReg());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form51l.java b/dx/src/main/java/com/android/dx/dex/code/form/Form51l.java
deleted file mode 100644
index 4dc7bcd..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form51l.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteral64;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 51l}. See the instruction format spec
- * for details.
- */
-public final class Form51l extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form51l();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form51l() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
-        return regs.get(0).regString() + ", " + literalBitsString(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-        return literalBitsComment(value, 64);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 5;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 1) &&
-              unsignedFitsInByte(regs.get(0).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        return (cst instanceof CstLiteral64);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(1);
-
-        bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        long value =
-            ((CstLiteral64) ((CstInsn) insn).getConstant()).getLongBits();
-
-        write(out, opcodeUnit(insn, regs.get(0).getReg()), value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form52c.java b/dx/src/main/java/com/android/dx/dex/code/form/Form52c.java
deleted file mode 100644
index acd2124..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form52c.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 52c}. See the instruction format spec
- * for details.
- */
-public final class Form52c extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form52c();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form52c() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        return regs.get(0).regString() + ", " + regs.get(1).regString() +
-            ", " + cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 5;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (! ALLOW_EXTENDED_OPCODES) {
-            return false;
-        }
-
-        RegisterSpecList regs = insn.getRegisters();
-        if (!((insn instanceof CstInsn) &&
-              (regs.size() == 2) &&
-              unsignedFitsInShort(regs.get(0).getReg()) &&
-              unsignedFitsInShort(regs.get(1).getReg()))) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        return (cst instanceof CstType) ||
-            (cst instanceof CstFieldRef);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BitSet compatibleRegs(DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        BitSet bits = new BitSet(2);
-
-        bits.set(0, unsignedFitsInShort(regs.get(0).getReg()));
-        bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-
-        write(out,
-                opcodeUnit(insn),
-                cpi,
-                (short) regs.get(0).getReg(),
-                (short) regs.get(1).getReg());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/Form5rc.java b/dx/src/main/java/com/android/dx/dex/code/form/Form5rc.java
deleted file mode 100644
index 0c54702..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/Form5rc.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 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.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 5rc}. See the instruction format spec
- * for details.
- */
-public final class Form5rc extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new Form5rc();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private Form5rc() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        return regRangeString(insn.getRegisters()) + ", " +
-            cstString(insn);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        if (noteIndices) {
-            return cstComment(insn);
-        } else {
-            return "";
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        return 5;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        if (! ALLOW_EXTENDED_OPCODES) {
-            return false;
-        }
-
-        if (!(insn instanceof CstInsn)) {
-            return false;
-        }
-
-        CstInsn ci = (CstInsn) insn;
-        Constant cst = ci.getConstant();
-
-        if (!((cst instanceof CstMethodRef) ||
-              (cst instanceof CstType))) {
-            return false;
-        }
-
-        RegisterSpecList regs = ci.getRegisters();
-        int sz = regs.size();
-
-        return (regs.size() == 0) ||
-            (isRegListSequential(regs) &&
-             unsignedFitsInShort(regs.get(0).getReg()) &&
-             unsignedFitsInShort(regs.getWordCount()));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        RegisterSpecList regs = insn.getRegisters();
-        int cpi = ((CstInsn) insn).getIndex();
-        int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();
-        int count = regs.getWordCount();
-
-        write(out, opcodeUnit(insn), cpi, (short) count, (short) firstReg);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/code/form/SpecialFormat.java b/dx/src/main/java/com/android/dx/dex/code/form/SpecialFormat.java
deleted file mode 100644
index 87091b5..0000000
--- a/dx/src/main/java/com/android/dx/dex/code/form/SpecialFormat.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format for nonstandard format instructions, which aren't
- * generally real instructions but do end up appearing in instruction
- * lists. Most of the overridden methods on this class end up throwing
- * exceptions, as code should know (implicitly or explicitly) to avoid
- * using this class. The one exception is {@link #isCompatible}, which
- * always returns {@code true}.
- */
-public final class SpecialFormat extends InsnFormat {
-    /** {@code non-null;} unique instance of this class */
-    public static final InsnFormat THE_ONE = new SpecialFormat();
-
-    /**
-     * Constructs an instance. This class is not publicly
-     * instantiable. Use {@link #THE_ONE}.
-     */
-    private SpecialFormat() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnArgString(DalvInsn insn) {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int codeSize() {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCompatible(DalvInsn insn) {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
-        throw new RuntimeException("unsupported");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/AnnotationItem.java b/dx/src/main/java/com/android/dx/dex/file/AnnotationItem.java
deleted file mode 100644
index 1d92247..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/AnnotationItem.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotation;
-import com.android.dx.rop.annotation.AnnotationVisibility;
-import com.android.dx.rop.annotation.NameValuePair;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * Single annotation, which consists of a type and a set of name-value
- * element pairs.
- */
-public final class AnnotationItem extends OffsettedItem {
-    /** annotation visibility constant: visible at build time only */
-    private static final int VISIBILITY_BUILD = 0;
-
-    /** annotation visibility constant: visible at runtime */
-    private static final int VISIBILITY_RUNTIME = 1;
-
-    /** annotation visibility constant: visible at runtime only to system */
-    private static final int VISIBILITY_SYSTEM = 2;
-
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 1;
-
-    /** {@code non-null;} unique instance of {@link #TypeIdSorter} */
-    private static final TypeIdSorter TYPE_ID_SORTER = new TypeIdSorter();
-
-    /** {@code non-null;} the annotation to represent */
-    private final Annotation annotation;
-
-    /**
-     * {@code null-ok;} type reference for the annotation type; set during
-     * {@link #addContents}
-     */
-    private TypeIdItem type;
-
-    /**
-     * {@code null-ok;} encoded form, ready for writing to a file; set during
-     * {@link #place0}
-     */
-    private byte[] encodedForm;
-
-    /**
-     * Comparator that sorts (outer) instances by type id index.
-     */
-    private static class TypeIdSorter implements Comparator<AnnotationItem> {
-        /** {@inheritDoc} */
-        public int compare(AnnotationItem item1, AnnotationItem item2) {
-            int index1 = item1.type.getIndex();
-            int index2 = item2.type.getIndex();
-
-            if (index1 < index2) {
-                return -1;
-            } else if (index1 > index2) {
-                return 1;
-            }
-
-            return 0;
-        }
-    }
-
-    /**
-     * Sorts an array of instances, in place, by type id index,
-     * ignoring all other aspects of the elements. This is only valid
-     * to use after type id indices are known.
-     *
-     * @param array {@code non-null;} array to sort
-     */
-    public static void sortByTypeIdIndex(AnnotationItem[] array) {
-        Arrays.sort(array, TYPE_ID_SORTER);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param annotation {@code non-null;} annotation to represent
-     */
-    public AnnotationItem(Annotation annotation) {
-        /*
-         * The write size isn't known up-front because (the variable-lengthed)
-         * leb128 type is used to represent some things.
-         */
-        super(ALIGNMENT, -1);
-
-        if (annotation == null) {
-            throw new NullPointerException("annotation == null");
-        }
-
-        this.annotation = annotation;
-        this.type = null;
-        this.encodedForm = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_ANNOTATION_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return annotation.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(OffsettedItem other) {
-        AnnotationItem otherAnnotation = (AnnotationItem) other;
-
-        return annotation.compareTo(otherAnnotation.annotation);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return annotation.toHuman();
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        type = file.getTypeIds().intern(annotation.getType());
-        ValueEncoder.addContents(file, annotation);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // Encode the data and note the size.
-
-        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
-        ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);
-
-        encoder.writeAnnotation(annotation, false);
-        encodedForm = out.toByteArray();
-
-        // Add one for the visibility byte in front of the encoded annotation.
-        setWriteSize(encodedForm.length + 1);
-    }
-
-    /**
-     * Write a (listing file) annotation for this instance to the given
-     * output, that consumes no bytes of output. This is for annotating
-     * a reference to this instance at the point of the reference.
-     *
-     * @param out {@code non-null;} where to output to
-     * @param prefix {@code non-null;} prefix for each line of output
-     */
-    public void annotateTo(AnnotatedOutput out, String prefix) {
-        out.annotate(0, prefix + "visibility: " +
-                annotation.getVisibility().toHuman());
-        out.annotate(0, prefix + "type: " + annotation.getType().toHuman());
-
-        for (NameValuePair pair : annotation.getNameValuePairs()) {
-            CstString name = pair.getName();
-            Constant value = pair.getValue();
-
-            out.annotate(0, prefix + name.toHuman() + ": " +
-                    ValueEncoder.constantToHuman(value));
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        AnnotationVisibility visibility = annotation.getVisibility();
-
-        if (annotates) {
-            out.annotate(0, offsetString() + " annotation");
-            out.annotate(1, "  visibility: VISBILITY_" + visibility);
-        }
-
-        switch (visibility) {
-            case BUILD:   out.writeByte(VISIBILITY_BUILD); break;
-            case RUNTIME: out.writeByte(VISIBILITY_RUNTIME); break;
-            case SYSTEM:  out.writeByte(VISIBILITY_SYSTEM); break;
-            default: {
-                // EMBEDDED shouldn't appear at the top level.
-                throw new RuntimeException("shouldn't happen");
-            }
-        }
-
-        if (annotates) {
-            /*
-             * The output is to be annotated, so redo the work previously
-             * done by place0(), except this time annotations will actually
-             * get emitted.
-             */
-            ValueEncoder encoder = new ValueEncoder(file, out);
-            encoder.writeAnnotation(annotation, true);
-        } else {
-            out.write(encodedForm);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/AnnotationSetItem.java b/dx/src/main/java/com/android/dx/dex/file/AnnotationSetItem.java
deleted file mode 100644
index 2187700..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/AnnotationSetItem.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.annotation.Annotation;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Set of annotations, where no annotation type appears more than once.
- */
-public final class AnnotationSetItem extends OffsettedItem {
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 4;
-
-    /** the size of an entry int the set: one {@code uint} */
-    private static final int ENTRY_WRITE_SIZE = 4;
-
-    /** {@code non-null;} the set of annotations */
-    private final Annotations annotations;
-
-    /**
-     * {@code non-null;} set of annotations as individual items in an array.
-     * <b>Note:</b> The contents have to get sorted by type id before
-     * writing.
-     */
-    private final AnnotationItem[] items;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param annotations {@code non-null;} set of annotations
-     */
-    public AnnotationSetItem(Annotations annotations) {
-        super(ALIGNMENT, writeSize(annotations));
-
-        this.annotations = annotations;
-        this.items = new AnnotationItem[annotations.size()];
-
-        int at = 0;
-        for (Annotation a : annotations.getAnnotations()) {
-            items[at] = new AnnotationItem(a);
-            at++;
-        }
-    }
-
-    /**
-     * Gets the write size for the given set.
-     *
-     * @param annotations {@code non-null;} the set
-     * @return {@code > 0;} the write size
-     */
-    private static int writeSize(Annotations annotations) {
-        // This includes an int size at the start of the list.
-
-        try {
-            return (annotations.size() * ENTRY_WRITE_SIZE) + 4;
-        } catch (NullPointerException ex) {
-            // Elucidate the exception.
-            throw new NullPointerException("list == null");
-        }
-    }
-
-    /**
-     * Gets the underlying annotations of this instance
-     *
-     * @return {@code non-null;} the annotations
-     */
-    public Annotations getAnnotations() {
-        return annotations;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return annotations.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(OffsettedItem other) {
-        AnnotationSetItem otherSet = (AnnotationSetItem) other;
-
-        return annotations.compareTo(otherSet.annotations);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_ANNOTATION_SET_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return annotations.toString();
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MixedItemSection byteData = file.getByteData();
-        int size = items.length;
-
-        for (int i = 0; i < size; i++) {
-            items[i] = byteData.intern(items[i]);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // Sort the array to be in type id index order.
-        AnnotationItem.sortByTypeIdIndex(items);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        int size = items.length;
-
-        if (annotates) {
-            out.annotate(0, offsetString() + " annotation set");
-            out.annotate(4, "  size: " + Hex.u4(size));
-        }
-
-        out.writeInt(size);
-
-        for (int i = 0; i < size; i++) {
-            AnnotationItem item = items[i];
-            int offset = item.getAbsoluteOffset();
-
-            if (annotates) {
-                out.annotate(4, "  entries[" + Integer.toHexString(i) + "]: " +
-                        Hex.u4(offset));
-                items[i].annotateTo(out, "    ");
-            }
-
-            out.writeInt(offset);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/AnnotationSetRefItem.java b/dx/src/main/java/com/android/dx/dex/file/AnnotationSetRefItem.java
deleted file mode 100644
index 53072d8..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/AnnotationSetRefItem.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Indirect reference to an {@link AnnotationSetItem}.
- */
-public final class AnnotationSetRefItem extends OffsettedItem {
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 4;
-
-    /** write size of this class, in bytes */
-    private static final int WRITE_SIZE = 4;
-
-    /** {@code non-null;} the annotation set to refer to */
-    private AnnotationSetItem annotations;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param annotations {@code non-null;} the annotation set to refer to
-     */
-    public AnnotationSetRefItem(AnnotationSetItem annotations) {
-        super(ALIGNMENT, WRITE_SIZE);
-
-        if (annotations == null) {
-            throw new NullPointerException("annotations == null");
-        }
-
-        this.annotations = annotations;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_ANNOTATION_SET_REF_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MixedItemSection wordData = file.getWordData();
-
-        annotations = wordData.intern(annotations);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return annotations.toHuman();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        int annotationsOff = annotations.getAbsoluteOffset();
-
-        if (out.annotates()) {
-            out.annotate(4, "  annotations_off: " + Hex.u4(annotationsOff));
-        }
-
-        out.writeInt(annotationsOff);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/AnnotationUtils.java b/dx/src/main/java/com/android/dx/dex/file/AnnotationUtils.java
deleted file mode 100644
index 350ed9a..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/AnnotationUtils.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotation;
-import com.android.dx.rop.annotation.NameValuePair;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstAnnotation;
-import com.android.dx.rop.cst.CstArray;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.cst.CstKnownNull;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-
-import java.util.ArrayList;
-
-import static com.android.dx.rop.annotation.AnnotationVisibility.*;
-
-/**
- * Utility class for dealing with annotations.
- */
-public final class AnnotationUtils {
-    /** {@code non-null;} type for {@code AnnotationDefault} annotations */
-    private static final CstType ANNOTATION_DEFAULT_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/AnnotationDefault;"));
-
-    /** {@code non-null;} type for {@code EnclosingClass} annotations */
-    private static final CstType ENCLOSING_CLASS_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/EnclosingClass;"));
-
-    /** {@code non-null;} type for {@code EnclosingMethod} annotations */
-    private static final CstType ENCLOSING_METHOD_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/EnclosingMethod;"));
-
-    /** {@code non-null;} type for {@code InnerClass} annotations */
-    private static final CstType INNER_CLASS_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/InnerClass;"));
-
-    /** {@code non-null;} type for {@code MemberClasses} annotations */
-    private static final CstType MEMBER_CLASSES_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/MemberClasses;"));
-
-    /** {@code non-null;} type for {@code Signature} annotations */
-    private static final CstType SIGNATURE_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/Signature;"));
-
-    /** {@code non-null;} type for {@code Throws} annotations */
-    private static final CstType THROWS_TYPE =
-        CstType.intern(Type.intern("Ldalvik/annotation/Throws;"));
-
-    /** {@code non-null;} the UTF-8 constant {@code "accessFlags"} */
-    private static final CstString ACCESS_FLAGS_STRING = new CstString("accessFlags");
-
-    /** {@code non-null;} the UTF-8 constant {@code "name"} */
-    private static final CstString NAME_STRING = new CstString("name");
-
-    /** {@code non-null;} the UTF-8 constant {@code "value"} */
-    private static final CstString VALUE_STRING = new CstString("value");
-
-    /**
-     * This class is uninstantiable.
-     */
-    private AnnotationUtils() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Constructs a standard {@code AnnotationDefault} annotation.
-     *
-     * @param defaults {@code non-null;} the defaults, itself as an annotation
-     * @return {@code non-null;} the constructed annotation
-     */
-    public static Annotation makeAnnotationDefault(Annotation defaults) {
-        Annotation result = new Annotation(ANNOTATION_DEFAULT_TYPE, SYSTEM);
-
-        result.put(new NameValuePair(VALUE_STRING, new CstAnnotation(defaults)));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code EnclosingClass} annotation.
-     *
-     * @param clazz {@code non-null;} the enclosing class
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeEnclosingClass(CstType clazz) {
-        Annotation result = new Annotation(ENCLOSING_CLASS_TYPE, SYSTEM);
-
-        result.put(new NameValuePair(VALUE_STRING, clazz));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code EnclosingMethod} annotation.
-     *
-     * @param method {@code non-null;} the enclosing method
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeEnclosingMethod(CstMethodRef method) {
-        Annotation result = new Annotation(ENCLOSING_METHOD_TYPE, SYSTEM);
-
-        result.put(new NameValuePair(VALUE_STRING, method));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code InnerClass} annotation.
-     *
-     * @param name {@code null-ok;} the original name of the class, or
-     * {@code null} to represent an anonymous class
-     * @param accessFlags the original access flags
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeInnerClass(CstString name, int accessFlags) {
-        Annotation result = new Annotation(INNER_CLASS_TYPE, SYSTEM);
-        Constant nameCst = (name != null) ? name : CstKnownNull.THE_ONE;
-
-        result.put(new NameValuePair(NAME_STRING, nameCst));
-        result.put(new NameValuePair(ACCESS_FLAGS_STRING,
-                        CstInteger.make(accessFlags)));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code MemberClasses} annotation.
-     *
-     * @param types {@code non-null;} the list of (the types of) the member classes
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeMemberClasses(TypeList types) {
-        CstArray array = makeCstArray(types);
-        Annotation result = new Annotation(MEMBER_CLASSES_TYPE, SYSTEM);
-        result.put(new NameValuePair(VALUE_STRING, array));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code Signature} annotation.
-     *
-     * @param signature {@code non-null;} the signature string
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeSignature(CstString signature) {
-        Annotation result = new Annotation(SIGNATURE_TYPE, SYSTEM);
-
-        /*
-         * Split the string into pieces that are likely to be common
-         * across many signatures and the rest of the file.
-         */
-
-        String raw = signature.getString();
-        int rawLength = raw.length();
-        ArrayList<String> pieces = new ArrayList<String>(20);
-
-        for (int at = 0; at < rawLength; /*at*/) {
-            char c = raw.charAt(at);
-            int endAt = at + 1;
-            if (c == 'L') {
-                // Scan to ';' or '<'. Consume ';' but not '<'.
-                while (endAt < rawLength) {
-                    c = raw.charAt(endAt);
-                    if (c == ';') {
-                        endAt++;
-                        break;
-                    } else if (c == '<') {
-                        break;
-                    }
-                    endAt++;
-                }
-            } else {
-                // Scan to 'L' without consuming it.
-                while (endAt < rawLength) {
-                    c = raw.charAt(endAt);
-                    if (c == 'L') {
-                        break;
-                    }
-                    endAt++;
-                }
-            }
-
-            pieces.add(raw.substring(at, endAt));
-            at = endAt;
-        }
-
-        int size = pieces.size();
-        CstArray.List list = new CstArray.List(size);
-
-        for (int i = 0; i < size; i++) {
-            list.set(i, new CstString(pieces.get(i)));
-        }
-
-        list.setImmutable();
-
-        result.put(new NameValuePair(VALUE_STRING, new CstArray(list)));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs a standard {@code Throws} annotation.
-     *
-     * @param types {@code non-null;} the list of thrown types
-     * @return {@code non-null;} the annotation
-     */
-    public static Annotation makeThrows(TypeList types) {
-        CstArray array = makeCstArray(types);
-        Annotation result = new Annotation(THROWS_TYPE, SYSTEM);
-        result.put(new NameValuePair(VALUE_STRING, array));
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Converts a {@link TypeList} to a {@link CstArray}.
-     *
-     * @param types {@code non-null;} the type list
-     * @return {@code non-null;} the corresponding array constant
-     */
-    private static CstArray makeCstArray(TypeList types) {
-        int size = types.size();
-        CstArray.List list = new CstArray.List(size);
-
-        for (int i = 0; i < size; i++) {
-            list.set(i, CstType.intern(types.getType(i)));
-        }
-
-        list.setImmutable();
-        return new CstArray(list);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/AnnotationsDirectoryItem.java b/dx/src/main/java/com/android/dx/dex/file/AnnotationsDirectoryItem.java
deleted file mode 100644
index 972d4e6..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/AnnotationsDirectoryItem.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.annotation.AnnotationsList;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Per-class directory of annotations.
- */
-public final class AnnotationsDirectoryItem extends OffsettedItem {
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 4;
-
-    /** write size of this class's header, in bytes */
-    private static final int HEADER_SIZE = 16;
-
-    /** write size of a list element, in bytes */
-    private static final int ELEMENT_SIZE = 8;
-
-    /** {@code null-ok;} the class-level annotations, if any */
-    private AnnotationSetItem classAnnotations;
-
-    /** {@code null-ok;} the annotated fields, if any */
-    private ArrayList<FieldAnnotationStruct> fieldAnnotations;
-
-    /** {@code null-ok;} the annotated methods, if any */
-    private ArrayList<MethodAnnotationStruct> methodAnnotations;
-
-    /** {@code null-ok;} the annotated parameters, if any */
-    private ArrayList<ParameterAnnotationStruct> parameterAnnotations;
-
-    /**
-     * Constructs an empty instance.
-     */
-    public AnnotationsDirectoryItem() {
-        super(ALIGNMENT, -1);
-
-        classAnnotations = null;
-        fieldAnnotations = null;
-        methodAnnotations = null;
-        parameterAnnotations = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
-    }
-
-    /**
-     * Returns whether this item is empty (has no contents).
-     *
-     * @return {@code true} if this item is empty, or {@code false}
-     * if not
-     */
-    public boolean isEmpty() {
-        return (classAnnotations == null) &&
-            (fieldAnnotations == null) &&
-            (methodAnnotations == null) &&
-            (parameterAnnotations == null);
-    }
-
-    /**
-     * Returns whether this item is a candidate for interning. The only
-     * interning candidates are ones that <i>only</i> have a non-null
-     * set of class annotations, with no other lists.
-     *
-     * @return {@code true} if this is an interning candidate, or
-     * {@code false} if not
-     */
-    public boolean isInternable() {
-        return (classAnnotations != null) &&
-            (fieldAnnotations == null) &&
-            (methodAnnotations == null) &&
-            (parameterAnnotations == null);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        if (classAnnotations == null) {
-            return 0;
-        }
-
-        return classAnnotations.hashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p><b>Note:</b>: This throws an exception if this item is not
-     * internable.</p>
-     *
-     * @see #isInternable
-     */
-    @Override
-    public int compareTo0(OffsettedItem other) {
-        if (! isInternable()) {
-            throw new UnsupportedOperationException("uninternable instance");
-        }
-
-        AnnotationsDirectoryItem otherDirectory =
-            (AnnotationsDirectoryItem) other;
-        return classAnnotations.compareTo(otherDirectory.classAnnotations);
-    }
-
-    /**
-     * Sets the direct annotations on this instance. These are annotations
-     * made on the class, per se, as opposed to on one of its members.
-     * It is only valid to call this method at most once per instance.
-     *
-     * @param annotations {@code non-null;} annotations to set for this class
-     */
-    public void setClassAnnotations(Annotations annotations) {
-        if (annotations == null) {
-            throw new NullPointerException("annotations == null");
-        }
-
-        if (classAnnotations != null) {
-            throw new UnsupportedOperationException(
-                    "class annotations already set");
-        }
-
-        classAnnotations = new AnnotationSetItem(annotations);
-    }
-
-    /**
-     * Adds a field annotations item to this instance.
-     *
-     * @param field {@code non-null;} field in question
-     * @param annotations {@code non-null;} associated annotations to add
-     */
-    public void addFieldAnnotations(CstFieldRef field,
-            Annotations annotations) {
-        if (fieldAnnotations == null) {
-            fieldAnnotations = new ArrayList<FieldAnnotationStruct>();
-        }
-
-        fieldAnnotations.add(new FieldAnnotationStruct(field,
-                        new AnnotationSetItem(annotations)));
-    }
-
-    /**
-     * Adds a method annotations item to this instance.
-     *
-     * @param method {@code non-null;} method in question
-     * @param annotations {@code non-null;} associated annotations to add
-     */
-    public void addMethodAnnotations(CstMethodRef method,
-            Annotations annotations) {
-        if (methodAnnotations == null) {
-            methodAnnotations = new ArrayList<MethodAnnotationStruct>();
-        }
-
-        methodAnnotations.add(new MethodAnnotationStruct(method,
-                        new AnnotationSetItem(annotations)));
-    }
-
-    /**
-     * Adds a parameter annotations item to this instance.
-     *
-     * @param method {@code non-null;} method in question
-     * @param list {@code non-null;} associated list of annotation sets to add
-     */
-    public void addParameterAnnotations(CstMethodRef method,
-            AnnotationsList list) {
-        if (parameterAnnotations == null) {
-            parameterAnnotations = new ArrayList<ParameterAnnotationStruct>();
-        }
-
-        parameterAnnotations.add(new ParameterAnnotationStruct(method, list));
-    }
-
-    /**
-     * Gets the method annotations for a given method, if any. This is
-     * meant for use by debugging / dumping code.
-     *
-     * @param method {@code non-null;} the method
-     * @return {@code null-ok;} the method annotations, if any
-     */
-    public Annotations getMethodAnnotations(CstMethodRef method) {
-        if (methodAnnotations == null) {
-            return null;
-        }
-
-        for (MethodAnnotationStruct item : methodAnnotations) {
-            if (item.getMethod().equals(method)) {
-                return item.getAnnotations();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Gets the parameter annotations for a given method, if any. This is
-     * meant for use by debugging / dumping code.
-     *
-     * @param method {@code non-null;} the method
-     * @return {@code null-ok;} the parameter annotations, if any
-     */
-    public AnnotationsList getParameterAnnotations(CstMethodRef method) {
-        if (parameterAnnotations == null) {
-            return null;
-        }
-
-        for (ParameterAnnotationStruct item : parameterAnnotations) {
-            if (item.getMethod().equals(method)) {
-                return item.getAnnotationsList();
-            }
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MixedItemSection wordData = file.getWordData();
-
-        if (classAnnotations != null) {
-            classAnnotations = wordData.intern(classAnnotations);
-        }
-
-        if (fieldAnnotations != null) {
-            for (FieldAnnotationStruct item : fieldAnnotations) {
-                item.addContents(file);
-            }
-        }
-
-        if (methodAnnotations != null) {
-            for (MethodAnnotationStruct item : methodAnnotations) {
-                item.addContents(file);
-            }
-        }
-
-        if (parameterAnnotations != null) {
-            for (ParameterAnnotationStruct item : parameterAnnotations) {
-                item.addContents(file);
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        throw new RuntimeException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // We just need to set the write size here.
-
-        int elementCount = listSize(fieldAnnotations)
-            + listSize(methodAnnotations) + listSize(parameterAnnotations);
-        setWriteSize(HEADER_SIZE + (elementCount * ELEMENT_SIZE));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations);
-        int fieldsSize = listSize(fieldAnnotations);
-        int methodsSize = listSize(methodAnnotations);
-        int parametersSize = listSize(parameterAnnotations);
-
-        if (annotates) {
-            out.annotate(0, offsetString() + " annotations directory");
-            out.annotate(4, "  class_annotations_off: " + Hex.u4(classOff));
-            out.annotate(4, "  fields_size:           " +
-                    Hex.u4(fieldsSize));
-            out.annotate(4, "  methods_size:          " +
-                    Hex.u4(methodsSize));
-            out.annotate(4, "  parameters_size:       " +
-                    Hex.u4(parametersSize));
-        }
-
-        out.writeInt(classOff);
-        out.writeInt(fieldsSize);
-        out.writeInt(methodsSize);
-        out.writeInt(parametersSize);
-
-        if (fieldsSize != 0) {
-            Collections.sort(fieldAnnotations);
-            if (annotates) {
-                out.annotate(0, "  fields:");
-            }
-            for (FieldAnnotationStruct item : fieldAnnotations) {
-                item.writeTo(file, out);
-            }
-        }
-
-        if (methodsSize != 0) {
-            Collections.sort(methodAnnotations);
-            if (annotates) {
-                out.annotate(0, "  methods:");
-            }
-            for (MethodAnnotationStruct item : methodAnnotations) {
-                item.writeTo(file, out);
-            }
-        }
-
-        if (parametersSize != 0) {
-            Collections.sort(parameterAnnotations);
-            if (annotates) {
-                out.annotate(0, "  parameters:");
-            }
-            for (ParameterAnnotationStruct item : parameterAnnotations) {
-                item.writeTo(file, out);
-            }
-        }
-    }
-
-    /**
-     * Gets the list size of the given list, or {@code 0} if given
-     * {@code null}.
-     *
-     * @param list {@code null-ok;} the list in question
-     * @return {@code >= 0;} its size
-     */
-    private static int listSize(ArrayList<?> list) {
-        if (list == null) {
-            return 0;
-        }
-
-        return list.size();
-    }
-
-    /**
-     * Prints out the contents of this instance, in a debugging-friendly
-     * way. This is meant to be called from {@link ClassDefItem#debugPrint}.
-     *
-     * @param out {@code non-null;} where to output to
-     */
-    /*package*/ void debugPrint(PrintWriter out) {
-        if (classAnnotations != null) {
-            out.println("  class annotations: " + classAnnotations);
-        }
-
-        if (fieldAnnotations != null) {
-            out.println("  field annotations:");
-            for (FieldAnnotationStruct item : fieldAnnotations) {
-                out.println("    " + item.toHuman());
-            }
-        }
-
-        if (methodAnnotations != null) {
-            out.println("  method annotations:");
-            for (MethodAnnotationStruct item : methodAnnotations) {
-                out.println("    " + item.toHuman());
-            }
-        }
-
-        if (parameterAnnotations != null) {
-            out.println("  parameter annotations:");
-            for (ParameterAnnotationStruct item : parameterAnnotations) {
-                out.println("    " + item.toHuman());
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/CatchStructs.java b/dx/src/main/java/com/android/dx/dex/file/CatchStructs.java
deleted file mode 100644
index 8b0f1bd..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/CatchStructs.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.dex.code.CatchHandlerList;
-import com.android.dx.dex.code.CatchTable;
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.io.PrintWriter;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * List of exception handlers (tuples of covered range, catch type,
- * handler address) for a particular piece of code. Instances of this
- * class correspond to a {@code try_item[]} and a
- * {@code catch_handler_item[]}.
- */
-public final class CatchStructs {
-    /**
-     * the size of a {@code try_item}: a {@code uint}
-     * and two {@code ushort}s
-     */
-    private static final int TRY_ITEM_WRITE_SIZE = 4 + (2 * 2);
-
-    /** {@code non-null;} code that contains the catches */
-    private final DalvCode code;
-
-    /**
-     * {@code null-ok;} the underlying table; set in
-     * {@link #finishProcessingIfNecessary}
-     */
-    private CatchTable table;
-
-    /**
-     * {@code null-ok;} the encoded handler list, if calculated; set in
-     * {@link #encode}
-     */
-    private byte[] encodedHandlers;
-
-    /**
-     * length of the handlers header (encoded size), if known; used for
-     * annotation
-     */
-    private int encodedHandlerHeaderSize;
-
-    /**
-     * {@code null-ok;} map from handler lists to byte offsets, if calculated; set in
-     * {@link #encode}
-     */
-    private TreeMap<CatchHandlerList, Integer> handlerOffsets;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param code {@code non-null;} code that contains the catches
-     */
-    public CatchStructs(DalvCode code) {
-        this.code = code;
-        this.table = null;
-        this.encodedHandlers = null;
-        this.encodedHandlerHeaderSize = 0;
-        this.handlerOffsets = null;
-    }
-
-    /**
-     * Finish processing the catches, if necessary.
-     */
-    private void finishProcessingIfNecessary() {
-        if (table == null) {
-            table = code.getCatches();
-        }
-    }
-
-    /**
-     * Gets the size of the tries list, in entries.
-     *
-     * @return {@code >= 0;} the tries list size
-     */
-    public int triesSize() {
-        finishProcessingIfNecessary();
-        return table.size();
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} prefix to attach to each line of output
-     */
-    public void debugPrint(PrintWriter out, String prefix) {
-        annotateEntries(prefix, out, null);
-    }
-
-    /**
-     * Encodes the handler lists.
-     *
-     * @param file {@code non-null;} file this instance is part of
-     */
-    public void encode(DexFile file) {
-        finishProcessingIfNecessary();
-
-        TypeIdsSection typeIds = file.getTypeIds();
-        int size = table.size();
-
-        handlerOffsets = new TreeMap<CatchHandlerList, Integer>();
-
-        /*
-         * First add a map entry for each unique list. The tree structure
-         * will ensure they are sorted when we reiterate later.
-         */
-        for (int i = 0; i < size; i++) {
-            handlerOffsets.put(table.get(i).getHandlers(), null);
-        }
-
-        if (handlerOffsets.size() > 65535) {
-            throw new UnsupportedOperationException(
-                    "too many catch handlers");
-        }
-
-        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
-
-        // Write out the handlers "header" consisting of its size in entries.
-        encodedHandlerHeaderSize =
-            out.writeUleb128(handlerOffsets.size());
-
-        // Now write the lists out in order, noting the offset of each.
-        for (Map.Entry<CatchHandlerList, Integer> mapping :
-                 handlerOffsets.entrySet()) {
-            CatchHandlerList list = mapping.getKey();
-            int listSize = list.size();
-            boolean catchesAll = list.catchesAll();
-
-            // Set the offset before we do any writing.
-            mapping.setValue(out.getCursor());
-
-            if (catchesAll) {
-                // A size <= 0 means that the list ends with a catch-all.
-                out.writeSleb128(-(listSize - 1));
-                listSize--;
-            } else {
-                out.writeSleb128(listSize);
-            }
-
-            for (int i = 0; i < listSize; i++) {
-                CatchHandlerList.Entry entry = list.get(i);
-                out.writeUleb128(
-                        typeIds.indexOf(entry.getExceptionType()));
-                out.writeUleb128(entry.getHandler());
-            }
-
-            if (catchesAll) {
-                out.writeUleb128(list.get(listSize).getHandler());
-            }
-        }
-
-        encodedHandlers = out.toByteArray();
-    }
-
-    /**
-     * Gets the write size of this instance, in bytes.
-     *
-     * @return {@code >= 0;} the write size
-     */
-    public int writeSize() {
-        return (triesSize() * TRY_ITEM_WRITE_SIZE) +
-                + encodedHandlers.length;
-    }
-
-    /**
-     * Writes this instance to the given stream.
-     *
-     * @param file {@code non-null;} file this instance is part of
-     * @param out {@code non-null;} where to write to
-     */
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        finishProcessingIfNecessary();
-
-        if (out.annotates()) {
-            annotateEntries("  ", null, out);
-        }
-
-        int tableSize = table.size();
-        for (int i = 0; i < tableSize; i++) {
-            CatchTable.Entry one = table.get(i);
-            int start = one.getStart();
-            int end = one.getEnd();
-            int insnCount = end - start;
-
-            if (insnCount >= 65536) {
-                throw new UnsupportedOperationException(
-                        "bogus exception range: " + Hex.u4(start) + ".." +
-                        Hex.u4(end));
-            }
-
-            out.writeInt(start);
-            out.writeShort(insnCount);
-            out.writeShort(handlerOffsets.get(one.getHandlers()));
-        }
-
-        out.write(encodedHandlers);
-    }
-
-    /**
-     * Helper method to annotate or simply print the exception handlers.
-     * Only one of {@code printTo} or {@code annotateTo} should
-     * be non-null.
-     *
-     * @param prefix {@code non-null;} prefix for each line
-     * @param printTo {@code null-ok;} where to print to
-     * @param annotateTo {@code null-ok;} where to consume bytes and annotate to
-     */
-    private void annotateEntries(String prefix, PrintWriter printTo,
-            AnnotatedOutput annotateTo) {
-        finishProcessingIfNecessary();
-
-        boolean consume = (annotateTo != null);
-        int amt1 = consume ? 6 : 0;
-        int amt2 = consume ? 2 : 0;
-        int size = table.size();
-        String subPrefix = prefix + "  ";
-
-        if (consume) {
-            annotateTo.annotate(0, prefix + "tries:");
-        } else {
-            printTo.println(prefix + "tries:");
-        }
-
-        for (int i = 0; i < size; i++) {
-            CatchTable.Entry entry = table.get(i);
-            CatchHandlerList handlers = entry.getHandlers();
-            String s1 = subPrefix + "try " + Hex.u2or4(entry.getStart())
-                + ".." + Hex.u2or4(entry.getEnd());
-            String s2 = handlers.toHuman(subPrefix, "");
-
-            if (consume) {
-                annotateTo.annotate(amt1, s1);
-                annotateTo.annotate(amt2, s2);
-            } else {
-                printTo.println(s1);
-                printTo.println(s2);
-            }
-        }
-
-        if (! consume) {
-            // Only emit the handler lists if we are consuming bytes.
-            return;
-        }
-
-        annotateTo.annotate(0, prefix + "handlers:");
-        annotateTo.annotate(encodedHandlerHeaderSize,
-                subPrefix + "size: " + Hex.u2(handlerOffsets.size()));
-
-        int lastOffset = 0;
-        CatchHandlerList lastList = null;
-
-        for (Map.Entry<CatchHandlerList, Integer> mapping :
-                 handlerOffsets.entrySet()) {
-            CatchHandlerList list = mapping.getKey();
-            int offset = mapping.getValue();
-
-            if (lastList != null) {
-                annotateAndConsumeHandlers(lastList, lastOffset,
-                        offset - lastOffset, subPrefix, printTo, annotateTo);
-            }
-
-            lastList = list;
-            lastOffset = offset;
-        }
-
-        annotateAndConsumeHandlers(lastList, lastOffset,
-                encodedHandlers.length - lastOffset,
-                subPrefix, printTo, annotateTo);
-    }
-
-    /**
-     * Helper for {@link #annotateEntries} to annotate a catch handler list
-     * while consuming it.
-     *
-     * @param handlers {@code non-null;} handlers to annotate
-     * @param offset {@code >= 0;} the offset of this handler
-     * @param size {@code >= 1;} the number of bytes the handlers consume
-     * @param prefix {@code non-null;} prefix for each line
-     * @param printTo {@code null-ok;} where to print to
-     * @param annotateTo {@code non-null;} where to annotate to
-     */
-    private static void annotateAndConsumeHandlers(CatchHandlerList handlers,
-            int offset, int size, String prefix, PrintWriter printTo,
-            AnnotatedOutput annotateTo) {
-        String s = handlers.toHuman(prefix, Hex.u2(offset) + ": ");
-
-        if (printTo != null) {
-            printTo.println(s);
-        }
-
-        annotateTo.annotate(size, s);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ClassDataItem.java b/dx/src/main/java/com/android/dx/dex/file/ClassDataItem.java
deleted file mode 100644
index e9ae18b..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ClassDataItem.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstArray;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.Zeroes;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Writers;
-
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-
-/**
- * Representation of all the parts of a Dalvik class that are generally
- * "inflated" into an in-memory representation at runtime. Instances of
- * this class are represented in a compact streamable form in a
- * {@code dex} file, as opposed to a random-access form.
- */
-public final class ClassDataItem extends OffsettedItem {
-    /** {@code non-null;} what class this data is for, just for listing generation */
-    private final CstType thisClass;
-
-    /** {@code non-null;} list of static fields */
-    private final ArrayList<EncodedField> staticFields;
-
-    /** {@code non-null;} list of initial values for static fields */
-    private final HashMap<EncodedField, Constant> staticValues;
-
-    /** {@code non-null;} list of instance fields */
-    private final ArrayList<EncodedField> instanceFields;
-
-    /** {@code non-null;} list of direct methods */
-    private final ArrayList<EncodedMethod> directMethods;
-
-    /** {@code non-null;} list of virtual methods */
-    private final ArrayList<EncodedMethod> virtualMethods;
-
-    /** {@code null-ok;} static initializer list; set in {@link #addContents} */
-    private CstArray staticValuesConstant;
-
-    /**
-     * {@code null-ok;} encoded form, ready for writing to a file; set during
-     * {@link #place0}
-     */
-    private byte[] encodedForm;
-
-    /**
-     * Constructs an instance. Its sets of members are initially
-     * empty.
-     *
-     * @param thisClass {@code non-null;} what class this data is for, just
-     * for listing generation
-     */
-    public ClassDataItem(CstType thisClass) {
-        super(1, -1);
-
-        if (thisClass == null) {
-            throw new NullPointerException("thisClass == null");
-        }
-
-        this.thisClass = thisClass;
-        this.staticFields = new ArrayList<EncodedField>(20);
-        this.staticValues = new HashMap<EncodedField, Constant>(40);
-        this.instanceFields = new ArrayList<EncodedField>(20);
-        this.directMethods = new ArrayList<EncodedMethod>(20);
-        this.virtualMethods = new ArrayList<EncodedMethod>(20);
-        this.staticValuesConstant = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_CLASS_DATA_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return toString();
-    }
-
-    /**
-     * Returns whether this instance is empty.
-     *
-     * @return {@code true} if this instance is empty or
-     * {@code false} if at least one element has been added to it
-     */
-    public boolean isEmpty() {
-        return staticFields.isEmpty() && instanceFields.isEmpty()
-            && directMethods.isEmpty() && virtualMethods.isEmpty();
-    }
-
-    /**
-     * Adds a static field.
-     *
-     * @param field {@code non-null;} the field to add
-     * @param value {@code null-ok;} initial value for the field, if any
-     */
-    public void addStaticField(EncodedField field, Constant value) {
-        if (field == null) {
-            throw new NullPointerException("field == null");
-        }
-
-        if (staticValuesConstant != null) {
-            throw new UnsupportedOperationException(
-                    "static fields already sorted");
-        }
-
-        staticFields.add(field);
-        staticValues.put(field, value);
-    }
-
-    /**
-     * Adds an instance field.
-     *
-     * @param field {@code non-null;} the field to add
-     */
-    public void addInstanceField(EncodedField field) {
-        if (field == null) {
-            throw new NullPointerException("field == null");
-        }
-
-        instanceFields.add(field);
-    }
-
-    /**
-     * Adds a direct ({@code static} and/or {@code private}) method.
-     *
-     * @param method {@code non-null;} the method to add
-     */
-    public void addDirectMethod(EncodedMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        directMethods.add(method);
-    }
-
-    /**
-     * Adds a virtual method.
-     *
-     * @param method {@code non-null;} the method to add
-     */
-    public void addVirtualMethod(EncodedMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        virtualMethods.add(method);
-    }
-
-    /**
-     * Gets all the methods in this class. The returned list is not linked
-     * in any way to the underlying lists contained in this instance, but
-     * the objects contained in the list are shared.
-     *
-     * @return {@code non-null;} list of all methods
-     */
-    public ArrayList<EncodedMethod> getMethods() {
-        int sz = directMethods.size() + virtualMethods.size();
-        ArrayList<EncodedMethod> result = new ArrayList<EncodedMethod>(sz);
-
-        result.addAll(directMethods);
-        result.addAll(virtualMethods);
-
-        return result;
-    }
-
-
-    /**
-     * Prints out the contents of this instance, in a debugging-friendly
-     * way.
-     *
-     * @param out {@code non-null;} where to output to
-     * @param verbose whether to be verbose with the output
-     */
-    public void debugPrint(Writer out, boolean verbose) {
-        PrintWriter pw = Writers.printWriterFor(out);
-
-        int sz = staticFields.size();
-        for (int i = 0; i < sz; i++) {
-            pw.println("  sfields[" + i + "]: " + staticFields.get(i));
-        }
-
-        sz = instanceFields.size();
-        for (int i = 0; i < sz; i++) {
-            pw.println("  ifields[" + i + "]: " + instanceFields.get(i));
-        }
-
-        sz = directMethods.size();
-        for (int i = 0; i < sz; i++) {
-            pw.println("  dmeths[" + i + "]:");
-            directMethods.get(i).debugPrint(pw, verbose);
-        }
-
-        sz = virtualMethods.size();
-        for (int i = 0; i < sz; i++) {
-            pw.println("  vmeths[" + i + "]:");
-            virtualMethods.get(i).debugPrint(pw, verbose);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        if (!staticFields.isEmpty()) {
-            getStaticValuesConstant(); // Force the fields to be sorted.
-            for (EncodedField field : staticFields) {
-                field.addContents(file);
-            }
-        }
-
-        if (!instanceFields.isEmpty()) {
-            Collections.sort(instanceFields);
-            for (EncodedField field : instanceFields) {
-                field.addContents(file);
-            }
-        }
-
-        if (!directMethods.isEmpty()) {
-            Collections.sort(directMethods);
-            for (EncodedMethod method : directMethods) {
-                method.addContents(file);
-            }
-        }
-
-        if (!virtualMethods.isEmpty()) {
-            Collections.sort(virtualMethods);
-            for (EncodedMethod method : virtualMethods) {
-                method.addContents(file);
-            }
-        }
-    }
-
-    /**
-     * Gets a {@link CstArray} corresponding to {@link #staticValues} if
-     * it contains any non-zero non-{@code null} values.
-     *
-     * @return {@code null-ok;} the corresponding constant or {@code null} if
-     * there are no values to encode
-     */
-    public CstArray getStaticValuesConstant() {
-        if ((staticValuesConstant == null) && (staticFields.size() != 0)) {
-            staticValuesConstant = makeStaticValuesConstant();
-        }
-
-        return staticValuesConstant;
-    }
-
-    /**
-     * Gets a {@link CstArray} corresponding to {@link #staticValues} if
-     * it contains any non-zero non-{@code null} values.
-     *
-     * @return {@code null-ok;} the corresponding constant or {@code null} if
-     * there are no values to encode
-     */
-    private CstArray makeStaticValuesConstant() {
-        // First sort the statics into their final order.
-        Collections.sort(staticFields);
-
-        /*
-         * Get the size of staticValues minus any trailing zeros/nulls (both
-         * nulls per se as well as instances of CstKnownNull).
-         */
-
-        int size = staticFields.size();
-        while (size > 0) {
-            EncodedField field = staticFields.get(size - 1);
-            Constant cst = staticValues.get(field);
-            if (cst instanceof CstLiteralBits) {
-                // Note: CstKnownNull extends CstLiteralBits.
-                if (((CstLiteralBits) cst).getLongBits() != 0) {
-                    break;
-                }
-            } else if (cst != null) {
-                break;
-            }
-            size--;
-        }
-
-        if (size == 0) {
-            return null;
-        }
-
-        // There is something worth encoding, so build up a result.
-
-        CstArray.List list = new CstArray.List(size);
-        for (int i = 0; i < size; i++) {
-            EncodedField field = staticFields.get(i);
-            Constant cst = staticValues.get(field);
-            if (cst == null) {
-                cst = Zeroes.zeroFor(field.getRef().getType());
-            }
-            list.set(i, cst);
-        }
-        list.setImmutable();
-
-        return new CstArray(list);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // Encode the data and note the size.
-
-        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
-
-        encodeOutput(addedTo.getFile(), out);
-        encodedForm = out.toByteArray();
-        setWriteSize(encodedForm.length);
-    }
-
-    /**
-     * Writes out the encoded form of this instance.
-     *
-     * @param file {@code non-null;} file this instance is part of
-     * @param out {@code non-null;} where to write to
-     */
-    private void encodeOutput(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-
-        if (annotates) {
-            out.annotate(0, offsetString() + " class data for " +
-                    thisClass.toHuman());
-        }
-
-        encodeSize(file, out, "static_fields", staticFields.size());
-        encodeSize(file, out, "instance_fields", instanceFields.size());
-        encodeSize(file, out, "direct_methods", directMethods.size());
-        encodeSize(file, out, "virtual_methods", virtualMethods.size());
-
-        encodeList(file, out, "static_fields", staticFields);
-        encodeList(file, out, "instance_fields", instanceFields);
-        encodeList(file, out, "direct_methods", directMethods);
-        encodeList(file, out, "virtual_methods", virtualMethods);
-
-        if (annotates) {
-            out.endAnnotation();
-        }
-    }
-
-    /**
-     * Helper for {@link #encodeOutput}, which writes out the given
-     * size value, annotating it as well (if annotations are enabled).
-     *
-     * @param file {@code non-null;} file this instance is part of
-     * @param out {@code non-null;} where to write to
-     * @param label {@code non-null;} the label for the purposes of annotation
-     * @param size {@code >= 0;} the size to write
-     */
-    private static void encodeSize(DexFile file, AnnotatedOutput out,
-            String label, int size) {
-        if (out.annotates()) {
-            out.annotate(String.format("  %-21s %08x", label + "_size:",
-                            size));
-        }
-
-        out.writeUleb128(size);
-    }
-
-    /**
-     * Helper for {@link #encodeOutput}, which writes out the given
-     * list. It also annotates the items (if any and if annotations
-     * are enabled).
-     *
-     * @param file {@code non-null;} file this instance is part of
-     * @param out {@code non-null;} where to write to
-     * @param label {@code non-null;} the label for the purposes of annotation
-     * @param list {@code non-null;} the list in question
-     */
-    private static void encodeList(DexFile file, AnnotatedOutput out,
-            String label, ArrayList<? extends EncodedMember> list) {
-        int size = list.size();
-        int lastIndex = 0;
-
-        if (size == 0) {
-            return;
-        }
-
-        if (out.annotates()) {
-            out.annotate(0, "  " + label + ":");
-        }
-
-        for (int i = 0; i < size; i++) {
-            lastIndex = list.get(i).encode(file, out, lastIndex, i);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-
-        if (annotates) {
-            /*
-             * The output is to be annotated, so redo the work previously
-             * done by place0(), except this time annotations will actually
-             * get emitted.
-             */
-            encodeOutput(file, out);
-        } else {
-            out.write(encodedForm);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ClassDefItem.java b/dx/src/main/java/com/android/dx/dex/file/ClassDefItem.java
deleted file mode 100644
index df3945a..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ClassDefItem.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.SizeOf;
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.annotation.AnnotationsList;
-import com.android.dx.rop.code.AccessFlags;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstArray;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.Writers;
-
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-
-/**
- * Representation of a Dalvik class, which is basically a set of
- * members (fields or methods) along with a few more pieces of
- * information.
- */
-public final class ClassDefItem extends IndexedItem {
-
-    /** {@code non-null;} type constant for this class */
-    private final CstType thisClass;
-
-    /** access flags */
-    private final int accessFlags;
-
-    /**
-     * {@code null-ok;} superclass or {@code null} if this class is a/the
-     * root class
-     */
-    private final CstType superclass;
-
-    /** {@code null-ok;} list of implemented interfaces */
-    private TypeListItem interfaces;
-
-    /** {@code null-ok;} source file name or {@code null} if unknown */
-    private final CstString sourceFile;
-
-    /** {@code non-null;} associated class data object */
-    private final ClassDataItem classData;
-
-    /**
-     * {@code null-ok;} item wrapper for the static values, initialized
-     * in {@link #addContents}
-     */
-    private EncodedArrayItem staticValuesItem;
-
-    /** {@code non-null;} annotations directory */
-    private AnnotationsDirectoryItem annotationsDirectory;
-
-    /**
-     * Constructs an instance. Its sets of members and annotations are
-     * initially empty.
-     *
-     * @param thisClass {@code non-null;} type constant for this class
-     * @param accessFlags access flags
-     * @param superclass {@code null-ok;} superclass or {@code null} if
-     * this class is a/the root class
-     * @param interfaces {@code non-null;} list of implemented interfaces
-     * @param sourceFile {@code null-ok;} source file name or
-     * {@code null} if unknown
-     */
-    public ClassDefItem(CstType thisClass, int accessFlags,
-            CstType superclass, TypeList interfaces, CstString sourceFile) {
-        if (thisClass == null) {
-            throw new NullPointerException("thisClass == null");
-        }
-
-        /*
-         * TODO: Maybe check accessFlags and superclass, at
-         * least for easily-checked stuff?
-         */
-
-        if (interfaces == null) {
-            throw new NullPointerException("interfaces == null");
-        }
-
-        this.thisClass = thisClass;
-        this.accessFlags = accessFlags;
-        this.superclass = superclass;
-        this.interfaces =
-            (interfaces.size() == 0) ? null :  new TypeListItem(interfaces);
-        this.sourceFile = sourceFile;
-        this.classData = new ClassDataItem(thisClass);
-        this.staticValuesItem = null;
-        this.annotationsDirectory = new AnnotationsDirectoryItem();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_CLASS_DEF_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.CLASS_DEF_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        MixedItemSection byteData = file.getByteData();
-        MixedItemSection wordData = file.getWordData();
-        MixedItemSection typeLists = file.getTypeLists();
-        StringIdsSection stringIds = file.getStringIds();
-
-        typeIds.intern(thisClass);
-
-        if (!classData.isEmpty()) {
-            MixedItemSection classDataSection = file.getClassData();
-            classDataSection.add(classData);
-
-            CstArray staticValues = classData.getStaticValuesConstant();
-            if (staticValues != null) {
-                staticValuesItem =
-                    byteData.intern(new EncodedArrayItem(staticValues));
-            }
-        }
-
-        if (superclass != null) {
-            typeIds.intern(superclass);
-        }
-
-        if (interfaces != null) {
-            interfaces = typeLists.intern(interfaces);
-        }
-
-        if (sourceFile != null) {
-            stringIds.intern(sourceFile);
-        }
-
-        if (! annotationsDirectory.isEmpty()) {
-            if (annotationsDirectory.isInternable()) {
-                annotationsDirectory = wordData.intern(annotationsDirectory);
-            } else {
-                wordData.add(annotationsDirectory);
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        TypeIdsSection typeIds = file.getTypeIds();
-        int classIdx = typeIds.indexOf(thisClass);
-        int superIdx = (superclass == null) ? -1 :
-            typeIds.indexOf(superclass);
-        int interOff = OffsettedItem.getAbsoluteOffsetOr0(interfaces);
-        int annoOff = annotationsDirectory.isEmpty() ? 0 :
-            annotationsDirectory.getAbsoluteOffset();
-        int sourceFileIdx = (sourceFile == null) ? -1 :
-            file.getStringIds().indexOf(sourceFile);
-        int dataOff = classData.isEmpty()? 0 : classData.getAbsoluteOffset();
-        int staticValuesOff =
-            OffsettedItem.getAbsoluteOffsetOr0(staticValuesItem);
-
-        if (annotates) {
-            out.annotate(0, indexString() + ' ' + thisClass.toHuman());
-            out.annotate(4, "  class_idx:           " + Hex.u4(classIdx));
-            out.annotate(4, "  access_flags:        " +
-                         AccessFlags.classString(accessFlags));
-            out.annotate(4, "  superclass_idx:      " + Hex.u4(superIdx) +
-                         " // " + ((superclass == null) ? "<none>" :
-                          superclass.toHuman()));
-            out.annotate(4, "  interfaces_off:      " + Hex.u4(interOff));
-            if (interOff != 0) {
-                TypeList list = interfaces.getList();
-                int sz = list.size();
-                for (int i = 0; i < sz; i++) {
-                    out.annotate(0, "    " + list.getType(i).toHuman());
-                }
-            }
-            out.annotate(4, "  source_file_idx:     " + Hex.u4(sourceFileIdx) +
-                         " // " + ((sourceFile == null) ? "<none>" :
-                          sourceFile.toHuman()));
-            out.annotate(4, "  annotations_off:     " + Hex.u4(annoOff));
-            out.annotate(4, "  class_data_off:      " + Hex.u4(dataOff));
-            out.annotate(4, "  static_values_off:   " +
-                    Hex.u4(staticValuesOff));
-        }
-
-        out.writeInt(classIdx);
-        out.writeInt(accessFlags);
-        out.writeInt(superIdx);
-        out.writeInt(interOff);
-        out.writeInt(sourceFileIdx);
-        out.writeInt(annoOff);
-        out.writeInt(dataOff);
-        out.writeInt(staticValuesOff);
-    }
-
-    /**
-     * Gets the constant corresponding to this class.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public CstType getThisClass() {
-        return thisClass;
-    }
-
-    /**
-     * Gets the access flags.
-     *
-     * @return the access flags
-     */
-    public int getAccessFlags() {
-        return accessFlags;
-    }
-
-    /**
-     * Gets the superclass.
-     *
-     * @return {@code null-ok;} the superclass or {@code null} if
-     * this class is a/the root class
-     */
-    public CstType getSuperclass() {
-        return superclass;
-    }
-
-    /**
-     * Gets the list of interfaces implemented.
-     *
-     * @return {@code non-null;} the interfaces list
-     */
-    public TypeList getInterfaces() {
-        if (interfaces == null) {
-            return StdTypeList.EMPTY;
-        }
-
-        return interfaces.getList();
-    }
-
-    /**
-     * Gets the source file name.
-     *
-     * @return {@code null-ok;} the source file name or {@code null} if unknown
-     */
-    public CstString getSourceFile() {
-        return sourceFile;
-    }
-
-    /**
-     * Adds a static field.
-     *
-     * @param field {@code non-null;} the field to add
-     * @param value {@code null-ok;} initial value for the field, if any
-     */
-    public void addStaticField(EncodedField field, Constant value) {
-        classData.addStaticField(field, value);
-    }
-
-    /**
-     * Adds an instance field.
-     *
-     * @param field {@code non-null;} the field to add
-     */
-    public void addInstanceField(EncodedField field) {
-        classData.addInstanceField(field);
-    }
-
-    /**
-     * Adds a direct ({@code static} and/or {@code private}) method.
-     *
-     * @param method {@code non-null;} the method to add
-     */
-    public void addDirectMethod(EncodedMethod method) {
-        classData.addDirectMethod(method);
-    }
-
-    /**
-     * Adds a virtual method.
-     *
-     * @param method {@code non-null;} the method to add
-     */
-    public void addVirtualMethod(EncodedMethod method) {
-        classData.addVirtualMethod(method);
-    }
-
-    /**
-     * Gets all the methods in this class. The returned list is not linked
-     * in any way to the underlying lists contained in this instance, but
-     * the objects contained in the list are shared.
-     *
-     * @return {@code non-null;} list of all methods
-     */
-    public ArrayList<EncodedMethod> getMethods() {
-        return classData.getMethods();
-    }
-
-    /**
-     * Sets the direct annotations on this class. These are annotations
-     * made on the class, per se, as opposed to on one of its members.
-     * It is only valid to call this method at most once per instance.
-     *
-     * @param annotations {@code non-null;} annotations to set for this class
-     */
-    public void setClassAnnotations(Annotations annotations) {
-        annotationsDirectory.setClassAnnotations(annotations);
-    }
-
-    /**
-     * Adds a field annotations item to this class.
-     *
-     * @param field {@code non-null;} field in question
-     * @param annotations {@code non-null;} associated annotations to add
-     */
-    public void addFieldAnnotations(CstFieldRef field,
-            Annotations annotations) {
-        annotationsDirectory.addFieldAnnotations(field, annotations);
-    }
-
-    /**
-     * Adds a method annotations item to this class.
-     *
-     * @param method {@code non-null;} method in question
-     * @param annotations {@code non-null;} associated annotations to add
-     */
-    public void addMethodAnnotations(CstMethodRef method,
-            Annotations annotations) {
-        annotationsDirectory.addMethodAnnotations(method, annotations);
-    }
-
-    /**
-     * Adds a parameter annotations item to this class.
-     *
-     * @param method {@code non-null;} method in question
-     * @param list {@code non-null;} associated list of annotation sets to add
-     */
-    public void addParameterAnnotations(CstMethodRef method,
-            AnnotationsList list) {
-        annotationsDirectory.addParameterAnnotations(method, list);
-    }
-
-    /**
-     * Gets the method annotations for a given method, if any. This is
-     * meant for use by debugging / dumping code.
-     *
-     * @param method {@code non-null;} the method
-     * @return {@code null-ok;} the method annotations, if any
-     */
-    public Annotations getMethodAnnotations(CstMethodRef method) {
-        return annotationsDirectory.getMethodAnnotations(method);
-    }
-
-    /**
-     * Gets the parameter annotations for a given method, if any. This is
-     * meant for use by debugging / dumping code.
-     *
-     * @param method {@code non-null;} the method
-     * @return {@code null-ok;} the parameter annotations, if any
-     */
-    public AnnotationsList getParameterAnnotations(CstMethodRef method) {
-        return annotationsDirectory.getParameterAnnotations(method);
-    }
-
-    /**
-     * Prints out the contents of this instance, in a debugging-friendly
-     * way.
-     *
-     * @param out {@code non-null;} where to output to
-     * @param verbose whether to be verbose with the output
-     */
-    public void debugPrint(Writer out, boolean verbose) {
-        PrintWriter pw = Writers.printWriterFor(out);
-
-        pw.println(getClass().getName() + " {");
-        pw.println("  accessFlags: " + Hex.u2(accessFlags));
-        pw.println("  superclass: " + superclass);
-        pw.println("  interfaces: " +
-                ((interfaces == null) ? "<none>" : interfaces));
-        pw.println("  sourceFile: " +
-                ((sourceFile == null) ? "<none>" : sourceFile.toQuoted()));
-
-        classData.debugPrint(out, verbose);
-        annotationsDirectory.debugPrint(pw);
-
-        pw.println("}");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ClassDefsSection.java b/dx/src/main/java/com/android/dx/dex/file/ClassDefsSection.java
deleted file mode 100644
index 1ca391f..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ClassDefsSection.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Class definitions list section of a {@code .dex} file.
- */
-public final class ClassDefsSection extends UniformItemSection {
-    /**
-     * {@code non-null;} map from type constants for classes to {@link
-     * ClassDefItem} instances that define those classes
-     */
-    private final TreeMap<Type, ClassDefItem> classDefs;
-
-    /** {@code null-ok;} ordered list of classes; set in {@link #orderItems} */
-    private ArrayList<ClassDefItem> orderedDefs;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public ClassDefsSection(DexFile file) {
-        super("class_defs", file, 4);
-
-        classDefs = new TreeMap<Type, ClassDefItem>();
-        orderedDefs = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        if (orderedDefs != null) {
-            return orderedDefs;
-        }
-
-        return classDefs.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        throwIfNotPrepared();
-
-        Type type = ((CstType) cst).getClassType();
-        IndexedItem result = classDefs.get(type);
-
-        if (result == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = classDefs.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (out.annotates()) {
-            out.annotate(4, "class_defs_size: " + Hex.u4(sz));
-            out.annotate(4, "class_defs_off:  " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Adds an element to this instance. It is illegal to attempt to add more
-     * than one class with the same name.
-     *
-     * @param clazz {@code non-null;} the class def to add
-     */
-    public void add(ClassDefItem clazz) {
-        Type type;
-
-        try {
-            type = clazz.getThisClass().getClassType();
-        } catch (NullPointerException ex) {
-            // Elucidate the exception.
-            throw new NullPointerException("clazz == null");
-        }
-
-        throwIfPrepared();
-
-        if (classDefs.get(type) != null) {
-            throw new IllegalArgumentException("already added: " + type);
-        }
-
-        classDefs.put(type, clazz);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        int sz = classDefs.size();
-        int idx = 0;
-
-        orderedDefs = new ArrayList<ClassDefItem>(sz);
-
-        /*
-         * Iterate over all the classes, recursively assigning an
-         * index to each, implicitly skipping the ones that have
-         * already been assigned by the time this (top-level)
-         * iteration reaches them.
-         */
-        for (Type type : classDefs.keySet()) {
-            idx = orderItems0(type, idx, sz - idx);
-        }
-    }
-
-    /**
-     * Helper for {@link #orderItems}, which recursively assigns indices
-     * to classes.
-     *
-     * @param type {@code null-ok;} type ref to assign, if any
-     * @param idx {@code >= 0;} the next index to assign
-     * @param maxDepth maximum recursion depth; if negative, this will
-     * throw an exception indicating class definition circularity
-     * @return {@code >= 0;} the next index to assign
-     */
-    private int orderItems0(Type type, int idx, int maxDepth) {
-        ClassDefItem c = classDefs.get(type);
-
-        if ((c == null) || (c.hasIndex())) {
-            return idx;
-        }
-
-        if (maxDepth < 0) {
-            throw new RuntimeException("class circularity with " + type);
-        }
-
-        maxDepth--;
-
-        CstType superclassCst = c.getSuperclass();
-        if (superclassCst != null) {
-            Type superclass = superclassCst.getClassType();
-            idx = orderItems0(superclass, idx, maxDepth);
-        }
-
-        TypeList interfaces = c.getInterfaces();
-        int sz = interfaces.size();
-        for (int i = 0; i < sz; i++) {
-            idx = orderItems0(interfaces.getType(i), idx, maxDepth);
-        }
-
-        c.setIndex(idx);
-        orderedDefs.add(c);
-        return idx + 1;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/CodeItem.java b/dx/src/main/java/com/android/dx/dex/file/CodeItem.java
deleted file mode 100644
index a47f68a..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/CodeItem.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.CatchTable;
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.DalvInsnList;
-import com.android.dx.dex.code.LocalList;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMemberRef;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-import com.android.dx.util.Hex;
-
-import java.io.PrintWriter;
-import java.util.HashSet;
-
-/**
- * Representation of all the parts needed for concrete methods in a
- * {@code dex} file.
- */
-public final class CodeItem extends OffsettedItem {
-    /** file alignment of this class, in bytes */
-    private static final int ALIGNMENT = 4;
-
-    /** write size of the header of this class, in bytes */
-    private static final int HEADER_SIZE = 16;
-
-    /** {@code non-null;} method that this code implements */
-    private final CstMethodRef ref;
-
-    /** {@code non-null;} the bytecode instructions and associated data */
-    private final DalvCode code;
-
-    /** {@code null-ok;} the catches, if needed; set in {@link #addContents} */
-    private CatchStructs catches;
-
-    /** whether this instance is for a {@code static} method */
-    private final boolean isStatic;
-
-    /**
-     * {@code non-null;} list of possibly-thrown exceptions; just used in
-     * generating debugging output (listings)
-     */
-    private final TypeList throwsList;
-
-    /**
-     * {@code null-ok;} the debug info or {@code null} if there is none;
-     * set in {@link #addContents}
-     */
-    private DebugInfoItem debugInfo;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ref {@code non-null;} method that this code implements
-     * @param code {@code non-null;} the underlying code
-     * @param isStatic whether this instance is for a {@code static}
-     * method
-     * @param throwsList {@code non-null;} list of possibly-thrown exceptions,
-     * just used in generating debugging output (listings)
-     */
-    public CodeItem(CstMethodRef ref, DalvCode code, boolean isStatic,
-            TypeList throwsList) {
-        super(ALIGNMENT, -1);
-
-        if (ref == null) {
-            throw new NullPointerException("ref == null");
-        }
-
-        if (code == null) {
-            throw new NullPointerException("code == null");
-        }
-
-        if (throwsList == null) {
-            throw new NullPointerException("throwsList == null");
-        }
-
-        this.ref = ref;
-        this.code = code;
-        this.isStatic = isStatic;
-        this.throwsList = throwsList;
-        this.catches = null;
-        this.debugInfo = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_CODE_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MixedItemSection byteData = file.getByteData();
-        TypeIdsSection typeIds = file.getTypeIds();
-
-        if (code.hasPositions() || code.hasLocals()) {
-            debugInfo = new DebugInfoItem(code, isStatic, ref);
-            byteData.add(debugInfo);
-        }
-
-        if (code.hasAnyCatches()) {
-            for (Type type : code.getCatchTypes()) {
-                typeIds.intern(type);
-            }
-            catches = new CatchStructs(code);
-        }
-
-        for (Constant c : code.getInsnConstants()) {
-            file.internIfAppropriate(c);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "CodeItem{" + toHuman() + "}";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return ref.toHuman();
-    }
-
-    /**
-     * Gets the reference to the method this instance implements.
-     *
-     * @return {@code non-null;} the method reference
-     */
-    public CstMethodRef getRef() {
-        return ref;
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} per-line prefix to use
-     * @param verbose whether to be verbose with the output
-     */
-    public void debugPrint(PrintWriter out, String prefix, boolean verbose) {
-        out.println(ref.toHuman() + ":");
-
-        DalvInsnList insns = code.getInsns();
-        out.println("regs: " + Hex.u2(getRegistersSize()) +
-                "; ins: " + Hex.u2(getInsSize()) + "; outs: " +
-                Hex.u2(getOutsSize()));
-
-        insns.debugPrint(out, prefix, verbose);
-
-        String prefix2 = prefix + "  ";
-
-        if (catches != null) {
-            out.print(prefix);
-            out.println("catches");
-            catches.debugPrint(out, prefix2);
-        }
-
-        if (debugInfo != null) {
-            out.print(prefix);
-            out.println("debug info");
-            debugInfo.debugPrint(out, prefix2);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        final DexFile file = addedTo.getFile();
-        int catchesSize;
-
-        /*
-         * In order to get the catches and insns, all the code's
-         * constants need to be assigned indices.
-         */
-        code.assignIndices(new DalvCode.AssignIndicesCallback() {
-                public int getIndex(Constant cst) {
-                    IndexedItem item = file.findItemOrNull(cst);
-                    if (item == null) {
-                        return -1;
-                    }
-                    return item.getIndex();
-                }
-            });
-
-        if (catches != null) {
-            catches.encode(file);
-            catchesSize = catches.writeSize();
-        } else {
-            catchesSize = 0;
-        }
-
-        /*
-         * The write size includes the header, two bytes per code
-         * unit, post-code padding if necessary, and however much
-         * space the catches need.
-         */
-
-        int insnsSize = code.getInsns().codeSize();
-        if ((insnsSize & 1) != 0) {
-            insnsSize++;
-        }
-
-        setWriteSize(HEADER_SIZE + (insnsSize * 2) + catchesSize);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        int regSz = getRegistersSize();
-        int outsSz = getOutsSize();
-        int insSz = getInsSize();
-        int insnsSz = code.getInsns().codeSize();
-        boolean needPadding = (insnsSz & 1) != 0;
-        int triesSz = (catches == null) ? 0 : catches.triesSize();
-        int debugOff = (debugInfo == null) ? 0 : debugInfo.getAbsoluteOffset();
-
-        if (annotates) {
-            out.annotate(0, offsetString() + ' ' + ref.toHuman());
-            out.annotate(2, "  registers_size: " + Hex.u2(regSz));
-            out.annotate(2, "  ins_size:       " + Hex.u2(insSz));
-            out.annotate(2, "  outs_size:      " + Hex.u2(outsSz));
-            out.annotate(2, "  tries_size:     " + Hex.u2(triesSz));
-            out.annotate(4, "  debug_off:      " + Hex.u4(debugOff));
-            out.annotate(4, "  insns_size:     " + Hex.u4(insnsSz));
-
-            // This isn't represented directly here, but it is useful to see.
-            int size = throwsList.size();
-            if (size != 0) {
-                out.annotate(0, "  throws " + StdTypeList.toHuman(throwsList));
-            }
-        }
-
-        out.writeShort(regSz);
-        out.writeShort(insSz);
-        out.writeShort(outsSz);
-        out.writeShort(triesSz);
-        out.writeInt(debugOff);
-        out.writeInt(insnsSz);
-
-        writeCodes(file, out);
-
-        if (catches != null) {
-            if (needPadding) {
-                if (annotates) {
-                    out.annotate(2, "  padding: 0");
-                }
-                out.writeShort(0);
-            }
-
-            catches.writeTo(file, out);
-        }
-
-        if (annotates) {
-            /*
-             * These are pointed at in the code header (above), but it's less
-             * distracting to expand on them at the bottom of the code.
-             */
-            if (debugInfo != null) {
-                out.annotate(0, "  debug info");
-                debugInfo.annotateTo(file, out, "    ");
-            }
-        }
-    }
-
-    /**
-     * Helper for {@link #writeTo0} which writes out the actual bytecode.
-     *
-     * @param file {@code non-null;} file we are part of
-     * @param out {@code non-null;} where to write to
-     */
-    private void writeCodes(DexFile file, AnnotatedOutput out) {
-        DalvInsnList insns = code.getInsns();
-
-        try {
-            insns.writeTo(out);
-        } catch (RuntimeException ex) {
-            throw ExceptionWithContext.withContext(ex, "...while writing " +
-                    "instructions for " + ref.toHuman());
-        }
-    }
-
-    /**
-     * Get the in registers count.
-     *
-     * @return the count
-     */
-    private int getInsSize() {
-        return ref.getParameterWordCount(isStatic);
-    }
-
-    /**
-     * Get the out registers count.
-     *
-     * @return the count
-     */
-    private int getOutsSize() {
-        return code.getInsns().getOutsSize();
-    }
-
-    /**
-     * Get the total registers count.
-     *
-     * @return the count
-     */
-    private int getRegistersSize() {
-        return code.getInsns().getRegistersSize();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/DebugInfoConstants.java b/dx/src/main/java/com/android/dx/dex/file/DebugInfoConstants.java
deleted file mode 100644
index 78b6b04..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/DebugInfoConstants.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-/**
- * Constants for the dex debug info state machine format.
- */
-public interface DebugInfoConstants {
-
-    /*
-     * normal opcodes
-     */
-
-    /**
-     * Terminates a debug info sequence for a method.<p>
-     * Args: none
-     *
-     */
-    static final int DBG_END_SEQUENCE = 0x00;
-
-    /**
-     * Advances the program counter/address register without emitting
-     * a positions entry.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; amount to advance pc by
-     * </ol>
-     */
-    static final int DBG_ADVANCE_PC = 0x01;
-
-    /**
-     * Advances the line register without emitting
-     * a positions entry.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Signed LEB128 &mdash; amount to change line register by.
-     * </ol>
-     */
-    static final int DBG_ADVANCE_LINE = 0x02;
-
-    /**
-     * Introduces a local variable at the current address.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; register that will contain local.
-     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of local name.
-     * <li>Unsigned LEB128 &mdash; type index (shifted by 1) of type.
-     * </ol>
-     */
-    static final int DBG_START_LOCAL = 0x03;
-
-    /**
-     * Introduces a local variable at the current address with a type
-     * signature specified.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; register that will contain local.
-     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of local name.
-     * <li>Unsigned LEB128 &mdash; type index (shifted by 1) of type.
-     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of
-     * type signature.
-     * </ol>
-     */
-    static final int DBG_START_LOCAL_EXTENDED = 0x04;
-
-    /**
-     * Marks a currently-live local variable as out of scope at the
-     * current address.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; register that contained local
-     * </ol>
-     */
-    static final int DBG_END_LOCAL = 0x05;
-
-    /**
-     * Re-introduces a local variable at the current address. The name
-     * and type are the same as the last local that was live in the specified
-     * register.<p>
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; register to re-start.
-     * </ol>
-     */
-    static final int DBG_RESTART_LOCAL = 0x06;
-
-
-    /**
-     * Sets the "prologue_end" state machine register, indicating that the
-     * next position entry that is added should be considered the end of
-     * a method prologue (an appropriate place for a method breakpoint).<p>
-     *
-     * The prologue_end register is cleared by any special
-     * ({@code >= OPCODE_BASE}) opcode.
-     */
-    static final int DBG_SET_PROLOGUE_END = 0x07;
-
-    /**
-     * Sets the "epilogue_begin" state machine register, indicating that the
-     * next position entry that is added should be considered the beginning of
-     * a method epilogue (an appropriate place to suspend execution before
-     * method exit).<p>
-     *
-     * The epilogue_begin register is cleared by any special
-     * ({@code >= OPCODE_BASE}) opcode.
-     */
-    static final int DBG_SET_EPILOGUE_BEGIN = 0x08;
-
-    /**
-     * Sets the current file that that line numbers refer to. All subsequent
-     * line number entries make reference to this source file name, instead
-     * of the default name specified in code_item.
-     *
-     * Args:
-     * <ol>
-     * <li>Unsigned LEB128 &mdash; string index (shifted by 1) of source
-     * file name.
-     * </ol>
-     */
-    static final int DBG_SET_FILE = 0x09;
-
-    /* IF YOU ADD A NEW OPCODE, increase OPCODE_BASE */
-
-    /*
-     * "special opcode" configuration, essentially what's found in
-     * the line number program header in DWARFv3, Section 6.2.4
-     */
-
-    /** the smallest value a special opcode can take */
-    static final int DBG_FIRST_SPECIAL = 0x0a;
-    static final int DBG_LINE_BASE = -4;
-    static final int DBG_LINE_RANGE = 15;
-    // MIN_INSN_LENGTH is always 1
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/DebugInfoDecoder.java b/dx/src/main/java/com/android/dx/dex/file/DebugInfoDecoder.java
deleted file mode 100644
index 9fb4845..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/DebugInfoDecoder.java
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.dex.code.DalvInsnList;
-import com.android.dx.dex.code.LocalList;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.ByteArrayByteInput;
-import com.android.dx.util.ByteInput;
-import com.android.dx.util.ExceptionWithContext;
-
-import com.android.dx.util.Leb128Utils;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.android.dx.dex.file.DebugInfoConstants.*;
-
-/**
- * A decoder for the dex debug info state machine format.
- * This code exists mostly as a reference implementation and test for
- * for the {@code DebugInfoEncoder}
- */
-public class DebugInfoDecoder {
-    /** encoded debug info */
-    private final byte[] encoded;
-
-    /** positions decoded */
-    private final ArrayList<PositionEntry> positions;
-
-    /** locals decoded */
-    private final ArrayList<LocalEntry> locals;
-
-    /** size of code block in code units */
-    private final int codesize;
-
-    /** indexed by register, the last local variable live in a reg */
-    private final LocalEntry[] lastEntryForReg;
-
-    /** method descriptor of method this debug info is for */
-    private final Prototype desc;
-
-    /** true if method is static */
-    private final boolean isStatic;
-
-    /** dex file this debug info will be stored in */
-    private final DexFile file;
-
-    /**
-     * register size, in register units, of the register space
-     * used by this method
-     */
-    private final int regSize;
-
-    /** current decoding state: line number */
-    private int line = 1;
-
-    /** current decoding state: bytecode address */
-    private int address = 0;
-
-    /** string index of the string "this" */
-    private final int thisStringIdx;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param encoded encoded debug info
-     * @param codesize size of code block in code units
-     * @param regSize register size, in register units, of the register space
-     * used by this method
-     * @param isStatic true if method is static
-     * @param ref method descriptor of method this debug info is for
-     * @param file dex file this debug info will be stored in
-     */
-    DebugInfoDecoder(byte[] encoded, int codesize, int regSize,
-            boolean isStatic, CstMethodRef ref, DexFile file) {
-        if (encoded == null) {
-            throw new NullPointerException("encoded == null");
-        }
-
-        this.encoded = encoded;
-        this.isStatic = isStatic;
-        this.desc = ref.getPrototype();
-        this.file = file;
-        this.regSize = regSize;
-
-        positions = new ArrayList<PositionEntry>();
-        locals = new ArrayList<LocalEntry>();
-        this.codesize = codesize;
-        lastEntryForReg = new LocalEntry[regSize];
-
-        int idx = -1;
-
-        try {
-            idx = file.getStringIds().indexOf(new CstString("this"));
-        } catch (IllegalArgumentException ex) {
-            /*
-             * Silently tolerate not finding "this". It just means that
-             * no method has local variable info that looks like
-             * a standard instance method.
-             */
-        }
-
-        thisStringIdx = idx;
-    }
-
-    /**
-     * An entry in the resulting postions table
-     */
-    static private class PositionEntry {
-        /** bytecode address */
-        public int address;
-
-        /** line number */
-        public int line;
-
-        public PositionEntry(int address, int line) {
-            this.address = address;
-            this.line = line;
-        }
-    }
-
-    /**
-     * An entry in the resulting locals table
-     */
-    static private class LocalEntry {
-        /** address of event */
-        public int address;
-
-        /** {@code true} iff it's a local start */
-        public boolean isStart;
-
-        /** register number */
-        public int reg;
-
-        /** index of name in strings table */
-        public int nameIndex;
-
-        /** index of type in types table */
-        public int typeIndex;
-
-        /** index of type signature in strings table */
-        public int signatureIndex;
-
-        public LocalEntry(int address, boolean isStart, int reg, int nameIndex,
-                int typeIndex, int signatureIndex) {
-            this.address        = address;
-            this.isStart        = isStart;
-            this.reg            = reg;
-            this.nameIndex      = nameIndex;
-            this.typeIndex      = typeIndex;
-            this.signatureIndex = signatureIndex;
-        }
-
-        public String toString() {
-            return String.format("[%x %s v%d %04x %04x %04x]",
-                    address, isStart ? "start" : "end", reg,
-                    nameIndex, typeIndex, signatureIndex);
-        }
-    }
-
-    /**
-     * Gets the decoded positions list.
-     * Valid after calling {@code decode}.
-     *
-     * @return positions list in ascending address order.
-     */
-    public List<PositionEntry> getPositionList() {
-        return positions;
-    }
-
-    /**
-     * Gets the decoded locals list, in ascending start-address order.
-     * Valid after calling {@code decode}.
-     *
-     * @return locals list in ascending address order.
-     */
-    public List<LocalEntry> getLocals() {
-        return locals;
-    }
-
-    /**
-     * Decodes the debug info sequence.
-     */
-    public void decode() {
-        try {
-            decode0();
-        } catch (Exception ex) {
-            throw ExceptionWithContext.withContext(ex,
-                    "...while decoding debug info");
-        }
-    }
-
-    /**
-     * Reads a string index. String indicies are offset by 1, and a 0 value
-     * in the stream (-1 as returned by this method) means "null"
-     *
-     * @return index into file's string ids table, -1 means null
-     * @throws IOException
-     */
-    private int readStringIndex(ByteInput bs) throws IOException {
-        int offsetIndex = Leb128Utils.readUnsignedLeb128(bs);
-
-        return offsetIndex - 1;
-    }
-
-    /**
-     * Gets the register that begins the method's parameter range (including
-     * the 'this' parameter for non-static methods). The range continues until
-     * {@code regSize}
-     *
-     * @return register as noted above.
-     */
-    private int getParamBase() {
-        return regSize
-                - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1);
-    }
-
-    private void decode0() throws IOException {
-        ByteInput bs = new ByteArrayByteInput(encoded);
-
-        line = Leb128Utils.readUnsignedLeb128(bs);
-        int szParams = Leb128Utils.readUnsignedLeb128(bs);
-        StdTypeList params = desc.getParameterTypes();
-        int curReg = getParamBase();
-
-        if (szParams != params.size()) {
-            throw new RuntimeException(
-                    "Mismatch between parameters_size and prototype");
-        }
-
-        if (!isStatic) {
-            // Start off with implicit 'this' entry
-            LocalEntry thisEntry =
-                new LocalEntry(0, true, curReg, thisStringIdx, 0, 0);
-            locals.add(thisEntry);
-            lastEntryForReg[curReg] = thisEntry;
-            curReg++;
-        }
-
-        for (int i = 0; i < szParams; i++) {
-            Type paramType = params.getType(i);
-            LocalEntry le;
-
-            int nameIdx = readStringIndex(bs);
-
-            if (nameIdx == -1) {
-                /*
-                 * Unnamed parameter; often but not always filled in by an
-                 * extended start op after the prologue
-                 */
-                le = new LocalEntry(0, true, curReg, -1, 0, 0);
-            } else {
-                // TODO: Final 0 should be idx of paramType.getDescriptor().
-                le = new LocalEntry(0, true, curReg, nameIdx, 0, 0);
-            }
-
-            locals.add(le);
-            lastEntryForReg[curReg] = le;
-            curReg += paramType.getCategory();
-        }
-
-        for (;;) {
-            int opcode = bs.readByte() & 0xff;
-
-            switch (opcode) {
-                case DBG_START_LOCAL: {
-                    int reg = Leb128Utils.readUnsignedLeb128(bs);
-                    int nameIdx = readStringIndex(bs);
-                    int typeIdx = readStringIndex(bs);
-                    LocalEntry le = new LocalEntry(
-                            address, true, reg, nameIdx, typeIdx, 0);
-
-                    locals.add(le);
-                    lastEntryForReg[reg] = le;
-                }
-                break;
-
-                case DBG_START_LOCAL_EXTENDED: {
-                    int reg = Leb128Utils.readUnsignedLeb128(bs);
-                    int nameIdx = readStringIndex(bs);
-                    int typeIdx = readStringIndex(bs);
-                    int sigIdx = readStringIndex(bs);
-                    LocalEntry le = new LocalEntry(
-                            address, true, reg, nameIdx, typeIdx, sigIdx);
-
-                    locals.add(le);
-                    lastEntryForReg[reg] = le;
-                }
-                break;
-
-                case DBG_RESTART_LOCAL: {
-                    int reg = Leb128Utils.readUnsignedLeb128(bs);
-                    LocalEntry prevle;
-                    LocalEntry le;
-
-                    try {
-                        prevle = lastEntryForReg[reg];
-
-                        if (prevle.isStart) {
-                            throw new RuntimeException("nonsensical "
-                                    + "RESTART_LOCAL on live register v"
-                                    + reg);
-                        }
-
-                        le = new LocalEntry(address, true, reg,
-                                prevle.nameIndex, prevle.typeIndex, 0);
-                    } catch (NullPointerException ex) {
-                        throw new RuntimeException(
-                                "Encountered RESTART_LOCAL on new v" + reg);
-                    }
-
-                    locals.add(le);
-                    lastEntryForReg[reg] = le;
-                }
-                break;
-
-                case DBG_END_LOCAL: {
-                    int reg = Leb128Utils.readUnsignedLeb128(bs);
-                    LocalEntry prevle;
-                    LocalEntry le;
-
-                    try {
-                        prevle = lastEntryForReg[reg];
-
-                        if (!prevle.isStart) {
-                            throw new RuntimeException("nonsensical "
-                                    + "END_LOCAL on dead register v" + reg);
-                        }
-
-                        le = new LocalEntry(address, false, reg,
-                                prevle.nameIndex, prevle.typeIndex,
-                                prevle.signatureIndex);
-                    } catch (NullPointerException ex) {
-                        throw new RuntimeException(
-                                "Encountered END_LOCAL on new v" + reg);
-                    }
-
-                    locals.add(le);
-                    lastEntryForReg[reg] = le;
-                }
-                break;
-
-                case DBG_END_SEQUENCE:
-                    // all done
-                return;
-
-                case DBG_ADVANCE_PC:
-                    address += Leb128Utils.readUnsignedLeb128(bs);
-                break;
-
-                case DBG_ADVANCE_LINE:
-                    line += Leb128Utils.readSignedLeb128(bs);
-                break;
-
-                case DBG_SET_PROLOGUE_END:
-                    //TODO do something with this.
-                break;
-
-                case DBG_SET_EPILOGUE_BEGIN:
-                    //TODO do something with this.
-                break;
-
-                case DBG_SET_FILE:
-                    //TODO do something with this.
-                break;
-
-                default:
-                    if (opcode < DBG_FIRST_SPECIAL) {
-                        throw new RuntimeException(
-                                "Invalid extended opcode encountered "
-                                        + opcode);
-                    }
-
-                    int adjopcode = opcode - DBG_FIRST_SPECIAL;
-
-                    address += adjopcode / DBG_LINE_RANGE;
-                    line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
-
-                    positions.add(new PositionEntry(address, line));
-                break;
-
-            }
-        }
-    }
-
-    /**
-     * Validates an encoded debug info stream against data used to encode it,
-     * throwing an exception if they do not match. Used to validate the
-     * encoder.
-     *
-     * @param info encoded debug info
-     * @param file {@code non-null;} file to refer to during decoding
-     * @param ref {@code non-null;} method whose info is being decoded
-     * @param code {@code non-null;} original code object that was encoded
-     * @param isStatic whether the method is static
-     */
-    public static void validateEncode(byte[] info, DexFile file,
-            CstMethodRef ref, DalvCode code, boolean isStatic) {
-        PositionList pl = code.getPositions();
-        LocalList ll = code.getLocals();
-        DalvInsnList insns = code.getInsns();
-        int codeSize = insns.codeSize();
-        int countRegisters = insns.getRegistersSize();
-
-        try {
-            validateEncode0(info, codeSize, countRegisters,
-                    isStatic, ref, file, pl, ll);
-        } catch (RuntimeException ex) {
-            System.err.println("instructions:");
-            insns.debugPrint(System.err, "  ", true);
-            System.err.println("local list:");
-            ll.debugPrint(System.err, "  ");
-            throw ExceptionWithContext.withContext(ex,
-                    "while processing " + ref.toHuman());
-        }
-    }
-
-    private static void validateEncode0(byte[] info, int codeSize,
-            int countRegisters, boolean isStatic, CstMethodRef ref,
-            DexFile file, PositionList pl, LocalList ll) {
-        DebugInfoDecoder decoder
-                = new DebugInfoDecoder(info, codeSize, countRegisters,
-                    isStatic, ref, file);
-
-        decoder.decode();
-
-        /*
-         * Go through the decoded position entries, matching up
-         * with original entries.
-         */
-
-        List<PositionEntry> decodedEntries = decoder.getPositionList();
-
-        if (decodedEntries.size() != pl.size()) {
-            throw new RuntimeException(
-                    "Decoded positions table not same size was "
-                    + decodedEntries.size() + " expected " + pl.size());
-        }
-
-        for (PositionEntry entry : decodedEntries) {
-            boolean found = false;
-            for (int i = pl.size() - 1; i >= 0; i--) {
-                PositionList.Entry ple = pl.get(i);
-
-                if (entry.line == ple.getPosition().getLine()
-                        && entry.address == ple.getAddress()) {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found) {
-                throw new RuntimeException ("Could not match position entry: "
-                        + entry.address + ", " + entry.line);
-            }
-        }
-
-        /*
-         * Go through the original local list, in order, matching up
-         * with decoded entries.
-         */
-
-        List<LocalEntry> decodedLocals = decoder.getLocals();
-        int thisStringIdx = decoder.thisStringIdx;
-        int decodedSz = decodedLocals.size();
-        int paramBase = decoder.getParamBase();
-
-        /*
-         * Preflight to fill in any parameters that were skipped in
-         * the prologue (including an implied "this") but then
-         * identified by full signature.
-         */
-        for (int i = 0; i < decodedSz; i++) {
-            LocalEntry entry = decodedLocals.get(i);
-            int idx = entry.nameIndex;
-
-            if ((idx < 0) || (idx == thisStringIdx)) {
-                for (int j = i + 1; j < decodedSz; j++) {
-                    LocalEntry e2 = decodedLocals.get(j);
-                    if (e2.address != 0) {
-                        break;
-                    }
-                    if ((entry.reg == e2.reg) && e2.isStart) {
-                        decodedLocals.set(i, e2);
-                        decodedLocals.remove(j);
-                        decodedSz--;
-                        break;
-                    }
-                }
-            }
-        }
-
-        int origSz = ll.size();
-        int decodeAt = 0;
-        boolean problem = false;
-
-        for (int i = 0; i < origSz; i++) {
-            LocalList.Entry origEntry = ll.get(i);
-
-            if (origEntry.getDisposition()
-                    == LocalList.Disposition.END_REPLACED) {
-                /*
-                 * The encoded list doesn't represent replacements, so
-                 * ignore them for the sake of comparison.
-                 */
-                continue;
-            }
-
-            LocalEntry decodedEntry;
-
-            do {
-                decodedEntry = decodedLocals.get(decodeAt);
-                if (decodedEntry.nameIndex >= 0) {
-                    break;
-                }
-                /*
-                 * A negative name index means this is an anonymous
-                 * parameter, and we shouldn't expect to see it in the
-                 * original list. So, skip it.
-                 */
-                decodeAt++;
-            } while (decodeAt < decodedSz);
-
-            int decodedAddress = decodedEntry.address;
-
-            if (decodedEntry.reg != origEntry.getRegister()) {
-                System.err.println("local register mismatch at orig " + i +
-                        " / decoded " + decodeAt);
-                problem = true;
-                break;
-            }
-
-            if (decodedEntry.isStart != origEntry.isStart()) {
-                System.err.println("local start/end mismatch at orig " + i +
-                        " / decoded " + decodeAt);
-                problem = true;
-                break;
-            }
-
-            /*
-             * The secondary check here accounts for the fact that a
-             * parameter might not be marked as starting at 0 in the
-             * original list.
-             */
-            if ((decodedAddress != origEntry.getAddress())
-                    && !((decodedAddress == 0)
-                            && (decodedEntry.reg >= paramBase))) {
-                System.err.println("local address mismatch at orig " + i +
-                        " / decoded " + decodeAt);
-                problem = true;
-                break;
-            }
-
-            decodeAt++;
-        }
-
-        if (problem) {
-            System.err.println("decoded locals:");
-            for (LocalEntry e : decodedLocals) {
-                System.err.println("  " + e);
-            }
-            throw new RuntimeException("local table problem");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/DebugInfoEncoder.java b/dx/src/main/java/com/android/dx/dex/file/DebugInfoEncoder.java
deleted file mode 100644
index ae87fc3..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/DebugInfoEncoder.java
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.code.LocalList;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.BitSet;
-
-import static com.android.dx.dex.file.DebugInfoConstants.*;
-
-/**
- * An encoder for the dex debug info state machine format. The format
- * for each method enrty is as follows:
- * <ol>
- * <li> signed LEB128: initial value for line register.
- * <li> n instances of signed LEB128: string indicies (offset by 1)
- * for each method argument in left-to-right order
- * with {@code this} excluded. A value of '0' indicates "no name"
- * <li> A sequence of special or normal opcodes as defined in
- * {@code DebugInfoConstants}.
- * <li> A single terminating {@code OP_END_SEQUENCE}
- * </ol>
- */
-public final class DebugInfoEncoder {
-    private static final boolean DEBUG = false;
-
-    /** {@code null-ok;} positions (line numbers) to encode */
-    private final PositionList positions;
-
-    /** {@code null-ok;} local variables to encode */
-    private final LocalList locals;
-
-    private final ByteArrayAnnotatedOutput output;
-    private final DexFile file;
-    private final int codeSize;
-    private final int regSize;
-
-    private final Prototype desc;
-    private final boolean isStatic;
-
-    /** current encoding state: bytecode address */
-    private int address = 0;
-
-    /** current encoding state: line number */
-    private int line = 1;
-
-    /**
-     * if non-null: the output to write annotations to. No normal
-     * output is written to this.
-     */
-    private AnnotatedOutput annotateTo;
-
-    /** if non-null: another possible output for annotations */
-    private PrintWriter debugPrint;
-
-    /** if non-null: the prefix for each annotation or debugPrint line */
-    private String prefix;
-
-    /** true if output should be consumed during annotation */
-    private boolean shouldConsume;
-
-    /** indexed by register; last local alive in register */
-    private final LocalList.Entry[] lastEntryForReg;
-
-    /**
-     * Creates an instance.
-     *
-     * @param positions {@code null-ok;} positions (line numbers) to encode
-     * @param locals {@code null-ok;} local variables to encode
-     * @param file {@code null-ok;} may only be {@code null} if simply using
-     * this class to do a debug print
-     * @param codeSize
-     * @param regSize
-     * @param isStatic
-     * @param ref
-     */
-    public DebugInfoEncoder(PositionList positions, LocalList locals,
-            DexFile file, int codeSize, int regSize,
-            boolean isStatic, CstMethodRef ref) {
-        this.positions = positions;
-        this.locals = locals;
-        this.file = file;
-        this.desc = ref.getPrototype();
-        this.isStatic = isStatic;
-        this.codeSize = codeSize;
-        this.regSize = regSize;
-
-        output = new ByteArrayAnnotatedOutput();
-        lastEntryForReg = new LocalList.Entry[regSize];
-    }
-
-    /**
-     * Annotates or writes a message to the {@code debugPrint} writer
-     * if applicable.
-     *
-     * @param length the number of bytes associated with this message
-     * @param message the message itself
-     */
-    private void annotate(int length, String message) {
-        if (prefix != null) {
-            message = prefix + message;
-        }
-
-        if (annotateTo != null) {
-            annotateTo.annotate(shouldConsume ? length : 0, message);
-        }
-
-        if (debugPrint != null) {
-            debugPrint.println(message);
-        }
-    }
-
-    /**
-     * Converts this (PositionList, LocalList) pair into a state machine
-     * sequence.
-     *
-     * @return {@code non-null;} encoded byte sequence without padding and
-     * terminated with a {@code 0x00} byte
-     */
-    public byte[] convert() {
-        try {
-            byte[] ret;
-            ret = convert0();
-
-            if (DEBUG) {
-                for (int i = 0 ; i < ret.length; i++) {
-                    System.err.printf("byte %02x\n", (0xff & ret[i]));
-                }
-            }
-
-            return ret;
-        } catch (IOException ex) {
-            throw ExceptionWithContext
-                    .withContext(ex, "...while encoding debug info");
-        }
-    }
-
-    /**
-     * Converts and produces annotations on a stream. Does not write
-     * actual bits to the {@code AnnotatedOutput}.
-     *
-     * @param prefix {@code null-ok;} prefix to attach to each line of output
-     * @param debugPrint {@code null-ok;} if specified, an alternate output for
-     * annotations
-     * @param out {@code null-ok;} if specified, where annotations should go
-     * @param consume whether to claim to have consumed output for
-     * {@code out}
-     * @return {@code non-null;} encoded output
-     */
-    public byte[] convertAndAnnotate(String prefix, PrintWriter debugPrint,
-            AnnotatedOutput out, boolean consume) {
-        this.prefix = prefix;
-        this.debugPrint = debugPrint;
-        annotateTo = out;
-        shouldConsume = consume;
-
-        byte[] result = convert();
-
-        return result;
-    }
-
-    private byte[] convert0() throws IOException {
-        ArrayList<PositionList.Entry> sortedPositions = buildSortedPositions();
-        ArrayList<LocalList.Entry> methodArgs = extractMethodArguments();
-
-        emitHeader(sortedPositions, methodArgs);
-
-        // TODO: Make this mark be the actual prologue end.
-        output.writeByte(DBG_SET_PROLOGUE_END);
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(1, String.format("%04x: prologue end",address));
-        }
-
-        int positionsSz = sortedPositions.size();
-        int localsSz = locals.size();
-
-        // Current index in sortedPositions
-        int curPositionIdx = 0;
-        // Current index in locals
-        int curLocalIdx = 0;
-
-        for (;;) {
-            /*
-             * Emit any information for the current address.
-             */
-
-            curLocalIdx = emitLocalsAtAddress(curLocalIdx);
-            curPositionIdx =
-                emitPositionsAtAddress(curPositionIdx, sortedPositions);
-
-            /*
-             * Figure out what the next important address is.
-             */
-
-            int nextAddrL = Integer.MAX_VALUE; // local variable
-            int nextAddrP = Integer.MAX_VALUE; // position (line number)
-
-            if (curLocalIdx < localsSz) {
-                nextAddrL = locals.get(curLocalIdx).getAddress();
-            }
-
-            if (curPositionIdx < positionsSz) {
-                nextAddrP = sortedPositions.get(curPositionIdx).getAddress();
-            }
-
-            int next = Math.min(nextAddrP, nextAddrL);
-
-            // No next important address == done.
-            if (next == Integer.MAX_VALUE) {
-                break;
-            }
-
-            /*
-             * If the only work remaining are local ends at the end of the
-             * block, stop here. Those are implied anyway.
-             */
-            if (next == codeSize
-                    && nextAddrL == Integer.MAX_VALUE
-                    && nextAddrP == Integer.MAX_VALUE) {
-                break;
-            }
-
-            if (next == nextAddrP) {
-                // Combined advance PC + position entry
-                emitPosition(sortedPositions.get(curPositionIdx++));
-            } else {
-                emitAdvancePc(next - address);
-            }
-        }
-
-        emitEndSequence();
-
-        return output.toByteArray();
-    }
-
-    /**
-     * Emits all local variable activity that occurs at the current
-     * {@link #address} starting at the given index into {@code
-     * locals} and including all subsequent activity at the same
-     * address.
-     *
-     * @param curLocalIdx Current index in locals
-     * @return new value for {@code curLocalIdx}
-     * @throws IOException
-     */
-    private int emitLocalsAtAddress(int curLocalIdx)
-            throws IOException {
-        int sz = locals.size();
-
-        // TODO: Don't emit ends implied by starts.
-
-        while ((curLocalIdx < sz)
-                && (locals.get(curLocalIdx).getAddress() == address)) {
-            LocalList.Entry entry = locals.get(curLocalIdx++);
-            int reg = entry.getRegister();
-            LocalList.Entry prevEntry = lastEntryForReg[reg];
-
-            if (entry == prevEntry) {
-                /*
-                 * Here we ignore locals entries for parameters,
-                 * which have already been represented and placed in the
-                 * lastEntryForReg array.
-                 */
-                continue;
-            }
-
-            // At this point we have a new entry one way or another.
-            lastEntryForReg[reg] = entry;
-
-            if (entry.isStart()) {
-                if ((prevEntry != null) && entry.matches(prevEntry)) {
-                    /*
-                     * The previous local in this register has the same
-                     * name and type as the one being introduced now, so
-                     * use the more efficient "restart" form.
-                     */
-                    if (prevEntry.isStart()) {
-                        /*
-                         * We should never be handed a start when a
-                         * a matching local is already active.
-                         */
-                        throw new RuntimeException("shouldn't happen");
-                    }
-                    emitLocalRestart(entry);
-                } else {
-                    emitLocalStart(entry);
-                }
-            } else {
-                /*
-                 * Only emit a local end if it is *not* due to a direct
-                 * replacement. Direct replacements imply an end of the
-                 * previous local in the same register.
-                 *
-                 * TODO: Make sure the runtime can deal with implied
-                 * local ends from category-2 interactions, and when so,
-                 * also stop emitting local ends for those cases.
-                 */
-                if (entry.getDisposition()
-                        != LocalList.Disposition.END_REPLACED) {
-                    emitLocalEnd(entry);
-                }
-            }
-        }
-
-        return curLocalIdx;
-    }
-
-    /**
-     * Emits all positions that occur at the current {@code address}
-     *
-     * @param curPositionIdx Current index in sortedPositions
-     * @param sortedPositions positions, sorted by ascending address
-     * @return new value for {@code curPositionIdx}
-     * @throws IOException
-     */
-    private int emitPositionsAtAddress(int curPositionIdx,
-            ArrayList<PositionList.Entry> sortedPositions)
-            throws IOException {
-        int positionsSz = sortedPositions.size();
-        while ((curPositionIdx < positionsSz)
-                && (sortedPositions.get(curPositionIdx).getAddress()
-                        == address)) {
-            emitPosition(sortedPositions.get(curPositionIdx++));
-        }
-        return curPositionIdx;
-    }
-
-    /**
-     * Emits the header sequence, which consists of LEB128-encoded initial
-     * line number and string indicies for names of all non-"this" arguments.
-     *
-     * @param sortedPositions positions, sorted by ascending address
-     * @param methodArgs local list entries for method argumens arguments,
-     * in left-to-right order omitting "this"
-     * @throws IOException
-     */
-    private void emitHeader(ArrayList<PositionList.Entry> sortedPositions,
-            ArrayList<LocalList.Entry> methodArgs) throws IOException {
-        boolean annotate = (annotateTo != null) || (debugPrint != null);
-        int mark = output.getCursor();
-
-        // Start by initializing the line number register.
-        if (sortedPositions.size() > 0) {
-            PositionList.Entry entry = sortedPositions.get(0);
-            line = entry.getPosition().getLine();
-        }
-        output.writeUleb128(line);
-
-        if (annotate) {
-            annotate(output.getCursor() - mark, "line_start: " + line);
-        }
-
-        int curParam = getParamBase();
-        // paramTypes will not include 'this'
-        StdTypeList paramTypes = desc.getParameterTypes();
-        int szParamTypes = paramTypes.size();
-
-        /*
-         * Initialize lastEntryForReg to have an initial
-         * entry for the 'this' pointer.
-         */
-        if (!isStatic) {
-            for (LocalList.Entry arg : methodArgs) {
-                if (curParam == arg.getRegister()) {
-                    lastEntryForReg[curParam] = arg;
-                    break;
-                }
-            }
-            curParam++;
-        }
-
-        // Write out the number of parameter entries that will follow.
-        mark = output.getCursor();
-        output.writeUleb128(szParamTypes);
-
-        if (annotate) {
-            annotate(output.getCursor() - mark,
-                    String.format("parameters_size: %04x", szParamTypes));
-        }
-
-        /*
-         * Then emit the string indicies of all the method parameters.
-         * Note that 'this', if applicable, is excluded.
-         */
-        for (int i = 0; i < szParamTypes; i++) {
-            Type pt = paramTypes.get(i);
-            LocalList.Entry found = null;
-
-            mark = output.getCursor();
-
-            for (LocalList.Entry arg : methodArgs) {
-                if (curParam == arg.getRegister()) {
-                    found = arg;
-
-                    if (arg.getSignature() != null) {
-                        /*
-                         * Parameters with signatures will be re-emitted
-                         * in complete as LOCAL_START_EXTENDED's below.
-                         */
-                        emitStringIndex(null);
-                    } else {
-                        emitStringIndex(arg.getName());
-                    }
-                    lastEntryForReg[curParam] = arg;
-
-                    break;
-                }
-            }
-
-            if (found == null) {
-                /*
-                 * Emit a null symbol for "unnamed." This is common
-                 * for, e.g., synthesized methods and inner-class
-                 * this$0 arguments.
-                 */
-                emitStringIndex(null);
-            }
-
-            if (annotate) {
-                String parameterName
-                        = (found == null || found.getSignature() != null)
-                                ? "<unnamed>" : found.getName().toHuman();
-                annotate(output.getCursor() - mark,
-                        "parameter " + parameterName + " "
-                                + RegisterSpec.PREFIX + curParam);
-            }
-
-            curParam += pt.getCategory();
-        }
-
-        /*
-         * If anything emitted above has a type signature, emit it again as
-         * a LOCAL_RESTART_EXTENDED
-         */
-
-        for (LocalList.Entry arg : lastEntryForReg) {
-            if (arg == null) {
-                continue;
-            }
-
-            CstString signature = arg.getSignature();
-
-            if (signature != null) {
-                emitLocalStartExtended(arg);
-            }
-        }
-    }
-
-    /**
-     * Builds a list of position entries, sorted by ascending address.
-     *
-     * @return A sorted positions list
-     */
-    private ArrayList<PositionList.Entry> buildSortedPositions() {
-        int sz = (positions == null) ? 0 : positions.size();
-        ArrayList<PositionList.Entry> result = new ArrayList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            result.add(positions.get(i));
-        }
-
-        // Sort ascending by address.
-        Collections.sort (result, new Comparator<PositionList.Entry>() {
-            public int compare (PositionList.Entry a, PositionList.Entry b) {
-                return a.getAddress() - b.getAddress();
-            }
-
-            public boolean equals (Object obj) {
-               return obj == this;
-            }
-        });
-        return result;
-    }
-
-    /**
-     * Gets the register that begins the method's parameter range (including
-     * the 'this' parameter for non-static methods). The range continues until
-     * {@code regSize}
-     *
-     * @return register as noted above
-     */
-    private int getParamBase() {
-        return regSize
-                - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1);
-    }
-
-    /**
-     * Extracts method arguments from a locals list. These will be collected
-     * from the input list and sorted by ascending register in the
-     * returned list.
-     *
-     * @return list of non-{@code this} method argument locals,
-     * sorted by ascending register
-     */
-    private ArrayList<LocalList.Entry> extractMethodArguments() {
-        ArrayList<LocalList.Entry> result
-                = new ArrayList(desc.getParameterTypes().size());
-        int argBase = getParamBase();
-        BitSet seen = new BitSet(regSize - argBase);
-        int sz = locals.size();
-
-        for (int i = 0; i < sz; i++) {
-            LocalList.Entry e = locals.get(i);
-            int reg = e.getRegister();
-
-            if (reg < argBase) {
-                continue;
-            }
-
-            // only the lowest-start-address entry is included.
-            if (seen.get(reg - argBase)) {
-                continue;
-            }
-
-            seen.set(reg - argBase);
-            result.add(e);
-        }
-
-        // Sort by ascending register.
-        Collections.sort(result, new Comparator<LocalList.Entry>() {
-            public int compare(LocalList.Entry a, LocalList.Entry b) {
-                return a.getRegister() - b.getRegister();
-            }
-
-            public boolean equals(Object obj) {
-               return obj == this;
-            }
-        });
-
-        return result;
-    }
-
-    /**
-     * Returns a string representation of this LocalList entry that is
-     * appropriate for emitting as an annotation.
-     *
-     * @param e {@code non-null;} entry
-     * @return {@code non-null;} annotation string
-     */
-    private String entryAnnotationString(LocalList.Entry e) {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(RegisterSpec.PREFIX);
-        sb.append(e.getRegister());
-        sb.append(' ');
-
-        CstString name = e.getName();
-        if (name == null) {
-            sb.append("null");
-        } else {
-            sb.append(name.toHuman());
-        }
-        sb.append(' ');
-
-        CstType type = e.getType();
-        if (type == null) {
-            sb.append("null");
-        } else {
-            sb.append(type.toHuman());
-        }
-
-        CstString signature = e.getSignature();
-
-        if (signature != null) {
-            sb.append(' ');
-            sb.append(signature.toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Emits a {@link DebugInfoConstants#DBG_RESTART_LOCAL DBG_RESTART_LOCAL}
-     * sequence.
-     *
-     * @param entry entry associated with this restart
-     * @throws IOException
-     */
-    private void emitLocalRestart(LocalList.Entry entry)
-            throws IOException {
-
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_RESTART_LOCAL);
-        emitUnsignedLeb128(entry.getRegister());
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("%04x: +local restart %s",
-                            address, entryAnnotationString(entry)));
-        }
-
-        if (DEBUG) {
-            System.err.println("emit local restart");
-        }
-    }
-
-    /**
-     * Emits a string index as an unsigned LEB128. The actual value written
-     * is shifted by 1, so that the '0' value is reserved for "null". The
-     * null symbol is used in some cases by the parameter name list
-     * at the beginning of the sequence.
-     *
-     * @param string {@code null-ok;} string to emit
-     * @throws IOException
-     */
-    private void emitStringIndex(CstString string) throws IOException {
-        if ((string == null) || (file == null)) {
-            output.writeUleb128(0);
-        } else {
-            output.writeUleb128(
-                    1 + file.getStringIds().indexOf(string));
-        }
-
-        if (DEBUG) {
-            System.err.printf("Emit string %s\n",
-                    string == null ? "<null>" : string.toQuoted());
-        }
-    }
-
-    /**
-     * Emits a type index as an unsigned LEB128. The actual value written
-     * is shifted by 1, so that the '0' value is reserved for "null".
-     *
-     * @param type {@code null-ok;} type to emit
-     * @throws IOException
-     */
-    private void emitTypeIndex(CstType type) throws IOException {
-        if ((type == null) || (file == null)) {
-            output.writeUleb128(0);
-        } else {
-            output.writeUleb128(
-                    1 + file.getTypeIds().indexOf(type));
-        }
-
-        if (DEBUG) {
-            System.err.printf("Emit type %s\n",
-                    type == null ? "<null>" : type.toHuman());
-        }
-    }
-
-    /**
-     * Emits a {@link DebugInfoConstants#DBG_START_LOCAL DBG_START_LOCAL} or
-     * {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED
-     * DBG_START_LOCAL_EXTENDED} sequence.
-     *
-     * @param entry entry to emit
-     * @throws IOException
-     */
-    private void emitLocalStart(LocalList.Entry entry)
-        throws IOException {
-
-        if (entry.getSignature() != null) {
-            emitLocalStartExtended(entry);
-            return;
-        }
-
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_START_LOCAL);
-
-        emitUnsignedLeb128(entry.getRegister());
-        emitStringIndex(entry.getName());
-        emitTypeIndex(entry.getType());
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("%04x: +local %s", address,
-                            entryAnnotationString(entry)));
-        }
-
-        if (DEBUG) {
-            System.err.println("emit local start");
-        }
-    }
-
-    /**
-     * Emits a {@link DebugInfoConstants#DBG_START_LOCAL_EXTENDED
-     * DBG_START_LOCAL_EXTENDED} sequence.
-     *
-     * @param entry entry to emit
-     * @throws IOException
-     */
-    private void emitLocalStartExtended(LocalList.Entry entry)
-        throws IOException {
-
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_START_LOCAL_EXTENDED);
-
-        emitUnsignedLeb128(entry.getRegister());
-        emitStringIndex(entry.getName());
-        emitTypeIndex(entry.getType());
-        emitStringIndex(entry.getSignature());
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("%04x: +localx %s", address,
-                            entryAnnotationString(entry)));
-        }
-
-        if (DEBUG) {
-            System.err.println("emit local start");
-        }
-    }
-
-    /**
-     * Emits a {@link DebugInfoConstants#DBG_END_LOCAL DBG_END_LOCAL} sequence.
-     *
-     * @param entry {@code entry non-null;} entry associated with end.
-     * @throws IOException
-     */
-    private void emitLocalEnd(LocalList.Entry entry)
-            throws IOException {
-
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_END_LOCAL);
-        output.writeUleb128(entry.getRegister());
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("%04x: -local %s", address,
-                            entryAnnotationString(entry)));
-        }
-
-        if (DEBUG) {
-            System.err.println("emit local end");
-        }
-    }
-
-    /**
-     * Emits the necessary byte sequences to emit the given position table
-     * entry. This will typically be a single special opcode, although
-     * it may also require DBG_ADVANCE_PC or DBG_ADVANCE_LINE.
-     *
-     * @param entry position entry to emit.
-     * @throws IOException
-     */
-    private void emitPosition(PositionList.Entry entry)
-            throws IOException {
-
-        SourcePosition pos = entry.getPosition();
-        int newLine = pos.getLine();
-        int newAddress = entry.getAddress();
-
-        int opcode;
-
-        int deltaLines = newLine - line;
-        int deltaAddress = newAddress - address;
-
-        if (deltaAddress < 0) {
-            throw new RuntimeException(
-                    "Position entries must be in ascending address order");
-        }
-
-        if ((deltaLines < DBG_LINE_BASE)
-                || (deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1))) {
-            emitAdvanceLine(deltaLines);
-            deltaLines = 0;
-        }
-
-        opcode = computeOpcode (deltaLines, deltaAddress);
-
-        if ((opcode & ~0xff) > 0) {
-            emitAdvancePc(deltaAddress);
-            deltaAddress = 0;
-            opcode = computeOpcode (deltaLines, deltaAddress);
-
-            if ((opcode & ~0xff) > 0) {
-                emitAdvanceLine(deltaLines);
-                deltaLines = 0;
-                opcode = computeOpcode (deltaLines, deltaAddress);
-            }
-        }
-
-        output.writeByte(opcode);
-
-        line += deltaLines;
-        address += deltaAddress;
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(1,
-                    String.format("%04x: line %d", address, line));
-        }
-    }
-
-    /**
-     * Computes a special opcode that will encode the given position change.
-     * If the return value is > 0xff, then the request cannot be fulfilled.
-     * Essentially the same as described in "DWARF Debugging Format Version 3"
-     * section 6.2.5.1.
-     *
-     * @param deltaLines {@code >= DBG_LINE_BASE, <= DBG_LINE_BASE +
-     * DBG_LINE_RANGE;} the line change to encode
-     * @param deltaAddress {@code >= 0;} the address change to encode
-     * @return {@code <= 0xff} if in range, otherwise parameters are out
-     * of range
-     */
-    private static int computeOpcode(int deltaLines, int deltaAddress) {
-        if (deltaLines < DBG_LINE_BASE
-                || deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1)) {
-
-            throw new RuntimeException("Parameter out of range");
-        }
-
-        return (deltaLines - DBG_LINE_BASE)
-            + (DBG_LINE_RANGE * deltaAddress) + DBG_FIRST_SPECIAL;
-    }
-
-    /**
-     * Emits an {@link DebugInfoConstants#DBG_ADVANCE_LINE DBG_ADVANCE_LINE}
-     * sequence.
-     *
-     * @param deltaLines amount to change line number register by
-     * @throws IOException
-     */
-    private void emitAdvanceLine(int deltaLines) throws IOException {
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_ADVANCE_LINE);
-        output.writeSleb128(deltaLines);
-        line += deltaLines;
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("line = %d", line));
-        }
-
-        if (DEBUG) {
-            System.err.printf("Emitting advance_line for %d\n", deltaLines);
-        }
-    }
-
-    /**
-     * Emits an  {@link DebugInfoConstants#DBG_ADVANCE_PC DBG_ADVANCE_PC}
-     * sequence.
-     *
-     * @param deltaAddress {@code >= 0;} amount to change program counter by
-     * @throws IOException
-     */
-    private void emitAdvancePc(int deltaAddress) throws IOException {
-        int mark = output.getCursor();
-
-        output.writeByte(DBG_ADVANCE_PC);
-        output.writeUleb128(deltaAddress);
-        address += deltaAddress;
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(output.getCursor() - mark,
-                    String.format("%04x: advance pc", address));
-        }
-
-        if (DEBUG) {
-            System.err.printf("Emitting advance_pc for %d\n", deltaAddress);
-        }
-    }
-
-    /**
-     * Emits an unsigned LEB128 value.
-     *
-     * @param n {@code >= 0;} value to emit. Note that, although this can
-     * represent integers larger than Integer.MAX_VALUE, we currently don't
-     * allow that.
-     * @throws IOException
-     */
-    private void emitUnsignedLeb128(int n) throws IOException {
-        // We'll never need the top end of the unsigned range anyway.
-        if (n < 0) {
-            throw new RuntimeException(
-                    "Signed value where unsigned required: " + n);
-        }
-
-        output.writeUleb128(n);
-    }
-
-    /**
-     * Emits the {@link DebugInfoConstants#DBG_END_SEQUENCE DBG_END_SEQUENCE}
-     * bytecode.
-     */
-    private void emitEndSequence() {
-        output.writeByte(DBG_END_SEQUENCE);
-
-        if (annotateTo != null || debugPrint != null) {
-            annotate(1, "end sequence");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/DebugInfoItem.java b/dx/src/main/java/com/android/dx/dex/file/DebugInfoItem.java
deleted file mode 100644
index 09b2712..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/DebugInfoItem.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.dex.code.DalvInsnList;
-import com.android.dx.dex.code.LocalList;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-
-import java.io.PrintWriter;
-
-public class DebugInfoItem extends OffsettedItem {
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 1;
-
-    private static final boolean ENABLE_ENCODER_SELF_CHECK = false;
-
-    /** {@code non-null;} the code this item represents */
-    private final DalvCode code;
-
-    private byte[] encoded;
-
-    private final boolean isStatic;
-    private final CstMethodRef ref;
-
-    public DebugInfoItem(DalvCode code, boolean isStatic, CstMethodRef ref) {
-        // We don't know the write size yet.
-        super (ALIGNMENT, -1);
-
-        if (code == null) {
-            throw new NullPointerException("code == null");
-        }
-
-        this.code = code;
-        this.isStatic = isStatic;
-        this.ref = ref;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_DEBUG_INFO_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        // No contents to add.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // Encode the data and note the size.
-
-        try {
-            encoded = encode(addedTo.getFile(), null, null, null, false);
-            setWriteSize(encoded.length);
-        } catch (RuntimeException ex) {
-            throw ExceptionWithContext.withContext(ex,
-                    "...while placing debug info for " + ref.toHuman());
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        throw new RuntimeException("unsupported");
-    }
-
-    /**
-     * Writes annotations for the elements of this list, as
-     * zero-length. This is meant to be used for dumping this instance
-     * directly after a code dump (with the real local list actually
-     * existing elsewhere in the output).
-     *
-     * @param file {@code non-null;} the file to use for referencing other sections
-     * @param out {@code non-null;} where to annotate to
-     * @param prefix {@code null-ok;} prefix to attach to each line of output
-     */
-    public void annotateTo(DexFile file, AnnotatedOutput out, String prefix) {
-        encode(file, prefix, null, out, false);
-    }
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param prefix {@code non-null;} prefix to attach to each line of output
-     */
-    public void debugPrint(PrintWriter out, String prefix) {
-        encode(null, prefix, out, null, false);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        if (out.annotates()) {
-            /*
-             * Re-run the encoder to generate the annotations,
-             * but write the bits from the original encode
-             */
-
-            out.annotate(offsetString() + " debug info");
-            encode(file, null, null, out, true);
-        }
-
-        out.write(encoded);
-    }
-
-    /**
-     * Performs debug info encoding.
-     *
-     * @param file {@code null-ok;} file to refer to during encoding
-     * @param prefix {@code null-ok;} prefix to attach to each line of output
-     * @param debugPrint {@code null-ok;} if specified, an alternate output for
-     * annotations
-     * @param out {@code null-ok;} if specified, where annotations should go
-     * @param consume whether to claim to have consumed output for
-     * {@code out}
-     * @return {@code non-null;} the encoded array
-     */
-    private byte[] encode(DexFile file, String prefix, PrintWriter debugPrint,
-            AnnotatedOutput out, boolean consume) {
-        byte[] result = encode0(file, prefix, debugPrint, out, consume);
-
-        if (ENABLE_ENCODER_SELF_CHECK && (file != null)) {
-            try {
-                DebugInfoDecoder.validateEncode(result, file, ref, code,
-                        isStatic);
-            } catch (RuntimeException ex) {
-                // Reconvert, annotating to System.err.
-                encode0(file, "", new PrintWriter(System.err, true), null,
-                        false);
-                throw ex;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Helper for {@link #encode} to do most of the work.
-     *
-     * @param file {@code null-ok;} file to refer to during encoding
-     * @param prefix {@code null-ok;} prefix to attach to each line of output
-     * @param debugPrint {@code null-ok;} if specified, an alternate output for
-     * annotations
-     * @param out {@code null-ok;} if specified, where annotations should go
-     * @param consume whether to claim to have consumed output for
-     * {@code out}
-     * @return {@code non-null;} the encoded array
-     */
-    private byte[] encode0(DexFile file, String prefix, PrintWriter debugPrint,
-            AnnotatedOutput out, boolean consume) {
-        PositionList positions = code.getPositions();
-        LocalList locals = code.getLocals();
-        DalvInsnList insns = code.getInsns();
-        int codeSize = insns.codeSize();
-        int regSize = insns.getRegistersSize();
-
-        DebugInfoEncoder encoder =
-            new DebugInfoEncoder(positions, locals,
-                    file, codeSize, regSize, isStatic, ref);
-
-        byte[] result;
-
-        if ((debugPrint == null) && (out == null)) {
-            result = encoder.convert();
-        } else {
-            result = encoder.convertAndAnnotate(prefix, debugPrint, out,
-                    consume);
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/DexFile.java b/dx/src/main/java/com/android/dx/dex/file/DexFile.java
deleted file mode 100644
index 6a9882c..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/DexFile.java
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.DexFormat;
-import com.android.dx.dex.DexOptions;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstBaseMethodRef;
-import com.android.dx.rop.cst.CstEnumRef;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.security.DigestException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.zip.Adler32;
-
-import static com.android.dx.dex.file.MixedItemSection.SortType;
-
-/**
- * Representation of an entire {@code .dex} (Dalvik EXecutable)
- * file, which itself consists of a set of Dalvik classes.
- */
-public final class DexFile {
-    /** options controlling the creation of the file */
-    private DexOptions dexOptions;
-
-    /** {@code non-null;} word data section */
-    private final MixedItemSection wordData;
-
-    /**
-     * {@code non-null;} type lists section. This is word data, but separating
-     * it from {@link #wordData} helps break what would otherwise be a
-     * circular dependency between the that and {@link #protoIds}.
-     */
-    private final MixedItemSection typeLists;
-
-    /**
-     * {@code non-null;} map section. The map needs to be in a section by itself
-     * for the self-reference mechanics to work in a reasonably
-     * straightforward way. See {@link MapItem#addMap} for more detail.
-     */
-    private final MixedItemSection map;
-
-    /** {@code non-null;} string data section */
-    private final MixedItemSection stringData;
-
-    /** {@code non-null;} string identifiers section */
-    private final StringIdsSection stringIds;
-
-    /** {@code non-null;} type identifiers section */
-    private final TypeIdsSection typeIds;
-
-    /** {@code non-null;} prototype identifiers section */
-    private final ProtoIdsSection protoIds;
-
-    /** {@code non-null;} field identifiers section */
-    private final FieldIdsSection fieldIds;
-
-    /** {@code non-null;} method identifiers section */
-    private final MethodIdsSection methodIds;
-
-    /** {@code non-null;} class definitions section */
-    private final ClassDefsSection classDefs;
-
-    /** {@code non-null;} class data section */
-    private final MixedItemSection classData;
-
-    /** {@code non-null;} byte data section */
-    private final MixedItemSection byteData;
-
-    /** {@code non-null;} file header */
-    private final HeaderSection header;
-
-    /**
-     * {@code non-null;} array of sections in the order they will appear in the
-     * final output file
-     */
-    private final Section[] sections;
-
-    /** {@code >= -1;} total file size or {@code -1} if unknown */
-    private int fileSize;
-
-    /** {@code >= 40;} maximum width of the file dump */
-    private int dumpWidth;
-
-    /**
-     * Constructs an instance. It is initially empty.
-     */
-    public DexFile(DexOptions dexOptions) {
-        this.dexOptions = dexOptions;
-
-        header = new HeaderSection(this);
-        typeLists = new MixedItemSection(null, this, 4, SortType.NONE);
-        wordData = new MixedItemSection("word_data", this, 4, SortType.TYPE);
-        stringData =
-            new MixedItemSection("string_data", this, 1, SortType.INSTANCE);
-        classData = new MixedItemSection(null, this, 1, SortType.NONE);
-        byteData = new MixedItemSection("byte_data", this, 1, SortType.TYPE);
-        stringIds = new StringIdsSection(this);
-        typeIds = new TypeIdsSection(this);
-        protoIds = new ProtoIdsSection(this);
-        fieldIds = new FieldIdsSection(this);
-        methodIds = new MethodIdsSection(this);
-        classDefs = new ClassDefsSection(this);
-        map = new MixedItemSection("map", this, 4, SortType.NONE);
-
-        /*
-         * This is the list of sections in the order they appear in
-         * the final output.
-         */
-        sections = new Section[] {
-            header, stringIds, typeIds, protoIds, fieldIds, methodIds,
-            classDefs, wordData, typeLists, stringData, byteData,
-            classData, map };
-
-        fileSize = -1;
-        dumpWidth = 79;
-    }
-
-    /**
-     * Returns true if this dex doesn't contain any class defs.
-     */
-    public boolean isEmpty() {
-        return classDefs.items().isEmpty();
-    }
-
-    /**
-     * Gets the dex-creation options object.
-     */
-    public DexOptions getDexOptions() {
-        return dexOptions;
-    }
-
-    /**
-     * Adds a class to this instance. It is illegal to attempt to add more
-     * than one class with the same name.
-     *
-     * @param clazz {@code non-null;} the class to add
-     */
-    public void add(ClassDefItem clazz) {
-        classDefs.add(clazz);
-    }
-
-    /**
-     * Gets the class definition with the given name, if any.
-     *
-     * @param name {@code non-null;} the class name to look for
-     * @return {@code null-ok;} the class with the given name, or {@code null}
-     * if there is no such class
-     */
-    public ClassDefItem getClassOrNull(String name) {
-        try {
-            Type type = Type.internClassName(name);
-            return (ClassDefItem) classDefs.get(new CstType(type));
-        } catch (IllegalArgumentException ex) {
-            // Translate exception, per contract.
-            return null;
-        }
-    }
-
-    /**
-     * Writes the contents of this instance as either a binary or a
-     * human-readable form, or both.
-     *
-     * @param out {@code null-ok;} where to write to
-     * @param humanOut {@code null-ok;} where to write human-oriented output to
-     * @param verbose whether to be verbose when writing human-oriented output
-     */
-    public void writeTo(OutputStream out, Writer humanOut, boolean verbose)
-        throws IOException {
-        boolean annotate = (humanOut != null);
-        ByteArrayAnnotatedOutput result = toDex0(annotate, verbose);
-
-        if (out != null) {
-            out.write(result.getArray());
-        }
-
-        if (annotate) {
-            result.writeAnnotationsTo(humanOut);
-        }
-    }
-
-    /**
-     * Returns the contents of this instance as a {@code .dex} file,
-     * in {@code byte[]} form.
-     *
-     * @param humanOut {@code null-ok;} where to write human-oriented output to
-     * @param verbose whether to be verbose when writing human-oriented output
-     * @return {@code non-null;} a {@code .dex} file for this instance
-     */
-    public byte[] toDex(Writer humanOut, boolean verbose)
-        throws IOException {
-        boolean annotate = (humanOut != null);
-        ByteArrayAnnotatedOutput result = toDex0(annotate, verbose);
-
-        if (annotate) {
-            result.writeAnnotationsTo(humanOut);
-        }
-
-        return result.getArray();
-    }
-
-    /**
-     * Sets the maximum width of the human-oriented dump of the instance.
-     *
-     * @param dumpWidth {@code >= 40;} the width
-     */
-    public void setDumpWidth(int dumpWidth) {
-        if (dumpWidth < 40) {
-            throw new IllegalArgumentException("dumpWidth < 40");
-        }
-
-        this.dumpWidth = dumpWidth;
-    }
-
-    /**
-     * Gets the total file size, if known.
-     *
-     * <p>This is package-scope in order to allow
-     * the {@link HeaderSection} to set itself up properly.</p>
-     *
-     * @return {@code >= 0;} the total file size
-     * @throws RuntimeException thrown if the file size is not yet known
-     */
-    /*package*/ int getFileSize() {
-        if (fileSize < 0) {
-            throw new RuntimeException("file size not yet known");
-        }
-
-        return fileSize;
-    }
-
-    /**
-     * Gets the string data section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the string data section
-     */
-    /*package*/ MixedItemSection getStringData() {
-        return stringData;
-    }
-
-    /**
-     * Gets the word data section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the word data section
-     */
-    /*package*/ MixedItemSection getWordData() {
-        return wordData;
-    }
-
-    /**
-     * Gets the type lists section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the word data section
-     */
-    /*package*/ MixedItemSection getTypeLists() {
-        return typeLists;
-    }
-
-    /**
-     * Gets the map section.
-     *
-     * <p>This is package-scope in order to allow the header section
-     * to query it.</p>
-     *
-     * @return {@code non-null;} the map section
-     */
-    /*package*/ MixedItemSection getMap() {
-        return map;
-    }
-
-    /**
-     * Gets the string identifiers section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the string identifiers section
-     */
-    /*package*/ StringIdsSection getStringIds() {
-        return stringIds;
-    }
-
-    /**
-     * Gets the class definitions section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the class definitions section
-     */
-    /*package*/ ClassDefsSection getClassDefs() {
-        return classDefs;
-    }
-
-    /**
-     * Gets the class data section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the class data section
-     */
-    /*package*/ MixedItemSection getClassData() {
-        return classData;
-    }
-
-    /**
-     * Gets the type identifiers section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the class identifiers section
-     */
-    /*package*/ TypeIdsSection getTypeIds() {
-        return typeIds;
-    }
-
-    /**
-     * Gets the prototype identifiers section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the prototype identifiers section
-     */
-    /*package*/ ProtoIdsSection getProtoIds() {
-        return protoIds;
-    }
-
-    /**
-     * Gets the field identifiers section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the field identifiers section
-     */
-    /*package*/ FieldIdsSection getFieldIds() {
-        return fieldIds;
-    }
-
-    /**
-     * Gets the method identifiers section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the method identifiers section
-     */
-    /*package*/ MethodIdsSection getMethodIds() {
-        return methodIds;
-    }
-
-    /**
-     * Gets the byte data section.
-     *
-     * <p>This is package-scope in order to allow
-     * the various {@link Item} instances to add items to the
-     * instance.</p>
-     *
-     * @return {@code non-null;} the byte data section
-     */
-    /*package*/ MixedItemSection getByteData() {
-        return byteData;
-    }
-
-    /**
-     * Gets the first section of the file that is to be considered
-     * part of the data section.
-     *
-     * <p>This is package-scope in order to allow the header section
-     * to query it.</p>
-     *
-     * @return {@code non-null;} the section
-     */
-    /*package*/ Section getFirstDataSection() {
-        return wordData;
-    }
-
-    /**
-     * Gets the last section of the file that is to be considered
-     * part of the data section.
-     *
-     * <p>This is package-scope in order to allow the header section
-     * to query it.</p>
-     *
-     * @return {@code non-null;} the section
-     */
-    /*package*/ Section getLastDataSection() {
-        return map;
-    }
-
-    /**
-     * Interns the given constant in the appropriate section of this
-     * instance, or do nothing if the given constant isn't the sort
-     * that should be interned.
-     *
-     * @param cst {@code non-null;} constant to possibly intern
-     */
-    /*package*/ void internIfAppropriate(Constant cst) {
-        if (cst instanceof CstString) {
-            stringIds.intern((CstString) cst);
-        } else if (cst instanceof CstType) {
-            typeIds.intern((CstType) cst);
-        } else if (cst instanceof CstBaseMethodRef) {
-            methodIds.intern((CstBaseMethodRef) cst);
-        } else if (cst instanceof CstFieldRef) {
-            fieldIds.intern((CstFieldRef) cst);
-        } else if (cst instanceof CstEnumRef) {
-            fieldIds.intern(((CstEnumRef) cst).getFieldRef());
-        } else if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-    }
-
-    /**
-     * Gets the {@link IndexedItem} corresponding to the given constant,
-     * if it is a constant that has such a correspondence, or return
-     * {@code null} if it isn't such a constant. This will throw
-     * an exception if the given constant <i>should</i> have been found
-     * but wasn't.
-     *
-     * @param cst {@code non-null;} the constant to look up
-     * @return {@code null-ok;} its corresponding item, if it has a corresponding
-     * item, or {@code null} if it's not that sort of constant
-     */
-    /*package*/ IndexedItem findItemOrNull(Constant cst) {
-        IndexedItem item;
-
-        if (cst instanceof CstString) {
-            return stringIds.get(cst);
-        } else if (cst instanceof CstType) {
-            return typeIds.get(cst);
-        } else if (cst instanceof CstBaseMethodRef) {
-            return methodIds.get(cst);
-        } else if (cst instanceof CstFieldRef) {
-            return fieldIds.get(cst);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the contents of this instance as a {@code .dex} file,
-     * in a {@link ByteArrayAnnotatedOutput} instance.
-     *
-     * @param annotate whether or not to keep annotations
-     * @param verbose if annotating, whether to be verbose
-     * @return {@code non-null;} a {@code .dex} file for this instance
-     */
-    private ByteArrayAnnotatedOutput toDex0(boolean annotate,
-            boolean verbose) {
-        /*
-         * The following is ordered so that the prepare() calls which
-         * add items happen before the calls to the sections that get
-         * added to.
-         */
-
-        classDefs.prepare();
-        classData.prepare();
-        wordData.prepare();
-        byteData.prepare();
-        methodIds.prepare();
-        fieldIds.prepare();
-        protoIds.prepare();
-        typeLists.prepare();
-        typeIds.prepare();
-        stringIds.prepare();
-        stringData.prepare();
-        header.prepare();
-
-        // Place the sections within the file.
-
-        int count = sections.length;
-        int offset = 0;
-
-        for (int i = 0; i < count; i++) {
-            Section one = sections[i];
-            int placedAt = one.setFileOffset(offset);
-            if (placedAt < offset) {
-                throw new RuntimeException("bogus placement for section " + i);
-            }
-
-            try {
-                if (one == map) {
-                    /*
-                     * Inform the map of all the sections, and add it
-                     * to the file. This can only be done after all
-                     * the other items have been sorted and placed.
-                     */
-                    MapItem.addMap(sections, map);
-                    map.prepare();
-                }
-
-                if (one instanceof MixedItemSection) {
-                    /*
-                     * Place the items of a MixedItemSection that just
-                     * got placed.
-                     */
-                    ((MixedItemSection) one).placeItems();
-                }
-
-                offset = placedAt + one.writeSize();
-            } catch (RuntimeException ex) {
-                throw ExceptionWithContext.withContext(ex,
-                        "...while writing section " + i);
-            }
-        }
-
-        // Write out all the sections.
-
-        fileSize = offset;
-        byte[] barr = new byte[fileSize];
-        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(barr);
-
-        if (annotate) {
-            out.enableAnnotations(dumpWidth, verbose);
-        }
-
-        for (int i = 0; i < count; i++) {
-            try {
-                Section one = sections[i];
-                int zeroCount = one.getFileOffset() - out.getCursor();
-                if (zeroCount < 0) {
-                    throw new ExceptionWithContext("excess write of " +
-                            (-zeroCount));
-                }
-                out.writeZeroes(one.getFileOffset() - out.getCursor());
-                one.writeTo(out);
-            } catch (RuntimeException ex) {
-                ExceptionWithContext ec;
-                if (ex instanceof ExceptionWithContext) {
-                    ec = (ExceptionWithContext) ex;
-                } else {
-                    ec = new ExceptionWithContext(ex);
-                }
-                ec.addContext("...while writing section " + i);
-                throw ec;
-            }
-        }
-
-        if (out.getCursor() != fileSize) {
-            throw new RuntimeException("foreshortened write");
-        }
-
-        // Perform final bookkeeping.
-
-        calcSignature(barr);
-        calcChecksum(barr);
-
-        if (annotate) {
-            wordData.writeIndexAnnotation(out, ItemType.TYPE_CODE_ITEM,
-                    "\nmethod code index:\n\n");
-            getStatistics().writeAnnotation(out);
-            out.finishAnnotating();
-        }
-
-        return out;
-    }
-
-    /**
-     * Generates and returns statistics for all the items in the file.
-     *
-     * @return {@code non-null;} the statistics
-     */
-    public Statistics getStatistics() {
-        Statistics stats = new Statistics();
-
-        for (Section s : sections) {
-            stats.addAll(s);
-        }
-
-        return stats;
-    }
-
-    /**
-     * Calculates the signature for the {@code .dex} file in the
-     * given array, and modify the array to contain it.
-     *
-     * @param bytes {@code non-null;} the bytes of the file
-     */
-    private static void calcSignature(byte[] bytes) {
-        MessageDigest md;
-
-        try {
-            md = MessageDigest.getInstance("SHA-1");
-        } catch (NoSuchAlgorithmException ex) {
-            throw new RuntimeException(ex);
-        }
-
-        md.update(bytes, 32, bytes.length - 32);
-
-        try {
-            int amt = md.digest(bytes, 12, 20);
-            if (amt != 20) {
-                throw new RuntimeException("unexpected digest write: " + amt +
-                                           " bytes");
-            }
-        } catch (DigestException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Calculates the checksum for the {@code .dex} file in the
-     * given array, and modify the array to contain it.
-     *
-     * @param bytes {@code non-null;} the bytes of the file
-     */
-    private static void calcChecksum(byte[] bytes) {
-        Adler32 a32 = new Adler32();
-
-        a32.update(bytes, 12, bytes.length - 12);
-
-        int sum = (int) a32.getValue();
-
-        bytes[8]  = (byte) sum;
-        bytes[9]  = (byte) (sum >> 8);
-        bytes[10] = (byte) (sum >> 16);
-        bytes[11] = (byte) (sum >> 24);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/EncodedArrayItem.java b/dx/src/main/java/com/android/dx/dex/file/EncodedArrayItem.java
deleted file mode 100644
index 3d05ab3..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/EncodedArrayItem.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.cst.CstArray;
-import com.android.dx.util.ByteArrayAnnotatedOutput;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Encoded array of constant values.
- */
-public final class EncodedArrayItem extends OffsettedItem {
-    /** the required alignment for instances of this class */
-    private static final int ALIGNMENT = 1;
-
-    /** {@code non-null;} the array to represent */
-    private final CstArray array;
-
-    /**
-     * {@code null-ok;} encoded form, ready for writing to a file; set during
-     * {@link #place0}
-     */
-    private byte[] encodedForm;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param array {@code non-null;} array to represent
-     */
-    public EncodedArrayItem(CstArray array) {
-        /*
-         * The write size isn't known up-front because (the variable-lengthed)
-         * leb128 type is used to represent some things.
-         */
-        super(ALIGNMENT, -1);
-
-        if (array == null) {
-            throw new NullPointerException("array == null");
-        }
-
-        this.array = array;
-        this.encodedForm = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_ENCODED_ARRAY_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return array.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(OffsettedItem other) {
-        EncodedArrayItem otherArray = (EncodedArrayItem) other;
-
-        return array.compareTo(otherArray.array);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return array.toHuman();
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        ValueEncoder.addContents(file, array);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        // Encode the data and note the size.
-
-        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
-        ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);
-
-        encoder.writeArray(array, false);
-        encodedForm = out.toByteArray();
-        setWriteSize(encodedForm.length);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-
-        if (annotates) {
-            out.annotate(0, offsetString() + " encoded array");
-
-            /*
-             * The output is to be annotated, so redo the work previously
-             * done by place0(), except this time annotations will actually
-             * get emitted.
-             */
-            ValueEncoder encoder = new ValueEncoder(file, out);
-            encoder.writeArray(array, true);
-        } else {
-            out.write(encodedForm);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/EncodedField.java b/dx/src/main/java/com/android/dx/dex/file/EncodedField.java
deleted file mode 100644
index fdfa5d2..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/EncodedField.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.code.AccessFlags;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.Leb128Utils;
-
-import java.io.PrintWriter;
-
-/**
- * Representation of a field of a class, of any sort.
- */
-public final class EncodedField extends EncodedMember
-        implements Comparable<EncodedField> {
-    /** {@code non-null;} constant for the field */
-    private final CstFieldRef field;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param field {@code non-null;} constant for the field
-     * @param accessFlags access flags
-     */
-    public EncodedField(CstFieldRef field, int accessFlags) {
-        super(accessFlags);
-
-        if (field == null) {
-            throw new NullPointerException("field == null");
-        }
-
-        /*
-         * TODO: Maybe check accessFlags, at least for
-         * easily-checked stuff?
-         */
-
-        this.field = field;
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        return field.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof EncodedField)) {
-            return false;
-        }
-
-        return compareTo((EncodedField) other) == 0;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p><b>Note:</b> This compares the method constants only,
-     * ignoring any associated code, because it should never be the
-     * case that two different items with the same method constant
-     * ever appear in the same list (or same file, even).</p>
-     */
-    public int compareTo(EncodedField other) {
-        return field.compareTo(other.field);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append(getClass().getName());
-        sb.append('{');
-        sb.append(Hex.u2(getAccessFlags()));
-        sb.append(' ');
-        sb.append(field);
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        FieldIdsSection fieldIds = file.getFieldIds();
-        fieldIds.intern(field);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public CstString getName() {
-        return field.getNat().getName();
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return field.toHuman();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void debugPrint(PrintWriter out, boolean verbose) {
-        // TODO: Maybe put something better here?
-        out.println(toString());
-    }
-
-    /**
-     * Gets the constant for the field.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public CstFieldRef getRef() {
-        return field;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int encode(DexFile file, AnnotatedOutput out,
-            int lastIndex, int dumpSeq) {
-        int fieldIdx = file.getFieldIds().indexOf(field);
-        int diff = fieldIdx - lastIndex;
-        int accessFlags = getAccessFlags();
-
-        if (out.annotates()) {
-            out.annotate(0, String.format("  [%x] %s", dumpSeq,
-                            field.toHuman()));
-            out.annotate(Leb128Utils.unsignedLeb128Size(diff),
-                    "    field_idx:    " + Hex.u4(fieldIdx));
-            out.annotate(Leb128Utils.unsignedLeb128Size(accessFlags),
-                    "    access_flags: " +
-                    AccessFlags.fieldString(accessFlags));
-        }
-
-        out.writeUleb128(diff);
-        out.writeUleb128(accessFlags);
-
-        return fieldIdx;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/EncodedMember.java b/dx/src/main/java/com/android/dx/dex/file/EncodedMember.java
deleted file mode 100644
index 6277646..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/EncodedMember.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ToHuman;
-
-import java.io.PrintWriter;
-
-/**
- * Representation of a member (field or method) of a class, for the
- * purposes of encoding it inside a {@link ClassDataItem}.
- */
-public abstract class EncodedMember implements ToHuman {
-    /** access flags */
-    private final int accessFlags;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param accessFlags access flags for the member
-     */
-    public EncodedMember(int accessFlags) {
-        this.accessFlags = accessFlags;
-    }
-
-    /**
-     * Gets the access flags.
-     *
-     * @return the access flags
-     */
-    public final int getAccessFlags() {
-        return accessFlags;
-    }
-
-    /**
-     * Gets the name.
-     *
-     * @return {@code non-null;} the name
-     */
-    public abstract CstString getName();
-
-    /**
-     * Does a human-friendly dump of this instance.
-     *
-     * @param out {@code non-null;} where to dump
-     * @param verbose whether to be verbose with the output
-     */
-    public abstract void debugPrint(PrintWriter out, boolean verbose);
-
-    /**
-     * Populates a {@link DexFile} with items from within this instance.
-     *
-     * @param file {@code non-null;} the file to populate
-     */
-    public abstract void addContents(DexFile file);
-
-    /**
-     * Encodes this instance to the given output.
-     *
-     * @param file {@code non-null;} file this instance is part of
-     * @param out {@code non-null;} where to write to
-     * @param lastIndex {@code >= 0;} the previous member index value encoded, or
-     * {@code 0} if this is the first element to encode
-     * @param dumpSeq {@code >= 0;} sequence number of this instance for
-     * annotation purposes
-     * @return {@code >= 0;} the member index value that was encoded
-     */
-    public abstract int encode(DexFile file, AnnotatedOutput out,
-            int lastIndex, int dumpSeq);
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/EncodedMethod.java b/dx/src/main/java/com/android/dx/dex/file/EncodedMethod.java
deleted file mode 100644
index c3f71b7..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/EncodedMethod.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.rop.code.AccessFlags;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.Leb128Utils;
-
-import java.io.PrintWriter;
-
-/**
- * Class that representats a method of a class.
- */
-public final class EncodedMethod extends EncodedMember
-        implements Comparable<EncodedMethod> {
-    /** {@code non-null;} constant for the method */
-    private final CstMethodRef method;
-
-    /**
-     * {@code null-ok;} code for the method, if the method is neither
-     * {@code abstract} nor {@code native}
-     */
-    private final CodeItem code;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} constant for the method
-     * @param accessFlags access flags
-     * @param code {@code null-ok;} code for the method, if it is neither
-     * {@code abstract} nor {@code native}
-     * @param throwsList {@code non-null;} list of possibly-thrown exceptions,
-     * just used in generating debugging output (listings)
-     */
-    public EncodedMethod(CstMethodRef method, int accessFlags,
-            DalvCode code, TypeList throwsList) {
-        super(accessFlags);
-
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        this.method = method;
-
-        if (code == null) {
-            this.code = null;
-        } else {
-            boolean isStatic = (accessFlags & AccessFlags.ACC_STATIC) != 0;
-            this.code = new CodeItem(method, code, isStatic, throwsList);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof EncodedMethod)) {
-            return false;
-        }
-
-        return compareTo((EncodedMethod) other) == 0;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p><b>Note:</b> This compares the method constants only,
-     * ignoring any associated code, because it should never be the
-     * case that two different items with the same method constant
-     * ever appear in the same list (or same file, even).</p>
-     */
-    public int compareTo(EncodedMethod other) {
-        return method.compareTo(other.method);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append(getClass().getName());
-        sb.append('{');
-        sb.append(Hex.u2(getAccessFlags()));
-        sb.append(' ');
-        sb.append(method);
-
-        if (code != null) {
-            sb.append(' ');
-            sb.append(code);
-        }
-
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        MethodIdsSection methodIds = file.getMethodIds();
-        MixedItemSection wordData = file.getWordData();
-
-        methodIds.intern(method);
-
-        if (code != null) {
-            wordData.add(code);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public final String toHuman() {
-        return method.toHuman();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final CstString getName() {
-        return method.getNat().getName();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void debugPrint(PrintWriter out, boolean verbose) {
-        if (code == null) {
-            out.println(getRef().toHuman() + ": abstract or native");
-        } else {
-            code.debugPrint(out, "  ", verbose);
-        }
-    }
-
-    /**
-     * Gets the constant for the method.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public final CstMethodRef getRef() {
-        return method;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int encode(DexFile file, AnnotatedOutput out,
-            int lastIndex, int dumpSeq) {
-        int methodIdx = file.getMethodIds().indexOf(method);
-        int diff = methodIdx - lastIndex;
-        int accessFlags = getAccessFlags();
-        int codeOff = OffsettedItem.getAbsoluteOffsetOr0(code);
-        boolean hasCode = (codeOff != 0);
-        boolean shouldHaveCode = (accessFlags &
-                (AccessFlags.ACC_ABSTRACT | AccessFlags.ACC_NATIVE)) == 0;
-
-        /*
-         * Verify that code appears if and only if a method is
-         * declared to have it.
-         */
-        if (hasCode != shouldHaveCode) {
-            throw new UnsupportedOperationException(
-                    "code vs. access_flags mismatch");
-        }
-
-        if (out.annotates()) {
-            out.annotate(0, String.format("  [%x] %s", dumpSeq,
-                            method.toHuman()));
-            out.annotate(Leb128Utils.unsignedLeb128Size(diff),
-                    "    method_idx:   " + Hex.u4(methodIdx));
-            out.annotate(Leb128Utils.unsignedLeb128Size(accessFlags),
-                    "    access_flags: " +
-                    AccessFlags.methodString(accessFlags));
-            out.annotate(Leb128Utils.unsignedLeb128Size(codeOff),
-                    "    code_off:     " + Hex.u4(codeOff));
-        }
-
-        out.writeUleb128(diff);
-        out.writeUleb128(accessFlags);
-        out.writeUleb128(codeOff);
-
-        return methodIdx;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/FieldAnnotationStruct.java b/dx/src/main/java/com/android/dx/dex/file/FieldAnnotationStruct.java
deleted file mode 100644
index f363d41..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/FieldAnnotationStruct.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.ToHuman;
-
-/**
- * Association of a field and its annotations.
- */
-public final class FieldAnnotationStruct
-        implements ToHuman, Comparable<FieldAnnotationStruct> {
-    /** {@code non-null;} the field in question */
-    private final CstFieldRef field;
-
-    /** {@code non-null;} the associated annotations */
-    private AnnotationSetItem annotations;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param field {@code non-null;} the field in question
-     * @param annotations {@code non-null;} the associated annotations
-     */
-    public FieldAnnotationStruct(CstFieldRef field,
-            AnnotationSetItem annotations) {
-        if (field == null) {
-            throw new NullPointerException("field == null");
-        }
-
-        if (annotations == null) {
-            throw new NullPointerException("annotations == null");
-        }
-
-        this.field = field;
-        this.annotations = annotations;
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        return field.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof FieldAnnotationStruct)) {
-            return false;
-        }
-
-        return field.equals(((FieldAnnotationStruct) other).field);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(FieldAnnotationStruct other) {
-        return field.compareTo(other.field);
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        FieldIdsSection fieldIds = file.getFieldIds();
-        MixedItemSection wordData = file.getWordData();
-
-        fieldIds.intern(field);
-        annotations = wordData.intern(annotations);
-    }
-
-    /** {@inheritDoc} */
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int fieldIdx = file.getFieldIds().indexOf(field);
-        int annotationsOff = annotations.getAbsoluteOffset();
-
-        if (out.annotates()) {
-            out.annotate(0, "    " + field.toHuman());
-            out.annotate(4, "      field_idx:       " + Hex.u4(fieldIdx));
-            out.annotate(4, "      annotations_off: " +
-                    Hex.u4(annotationsOff));
-        }
-
-        out.writeInt(fieldIdx);
-        out.writeInt(annotationsOff);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return field.toHuman() + ": " + annotations;
-    }
-
-    /**
-     * Gets the field this item is for.
-     *
-     * @return {@code non-null;} the field
-     */
-    public CstFieldRef getField() {
-        return field;
-    }
-
-    /**
-     * Gets the associated annotations.
-     *
-     * @return {@code non-null;} the annotations
-     */
-    public Annotations getAnnotations() {
-        return annotations.getAnnotations();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/FieldIdItem.java b/dx/src/main/java/com/android/dx/dex/file/FieldIdItem.java
deleted file mode 100644
index ecb1d3d..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/FieldIdItem.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstFieldRef;
-
-/**
- * Representation of a field reference inside a Dalvik file.
- */
-public final class FieldIdItem extends MemberIdItem {
-    /**
-     * Constructs an instance.
-     *
-     * @param field {@code non-null;} the constant for the field
-     */
-    public FieldIdItem(CstFieldRef field) {
-        super(field);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_FIELD_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        super.addContents(file);
-
-        TypeIdsSection typeIds = file.getTypeIds();
-        typeIds.intern(getFieldRef().getType());
-    }
-
-    /**
-     * Gets the field constant.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public CstFieldRef getFieldRef() {
-        return (CstFieldRef) getRef();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int getTypoidIdx(DexFile file) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        return typeIds.indexOf(getFieldRef().getType());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String getTypoidName() {
-        return "type_idx";
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/FieldIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/FieldIdsSection.java
deleted file mode 100644
index c320731..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/FieldIdsSection.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Field refs list section of a {@code .dex} file.
- */
-public final class FieldIdsSection extends MemberIdsSection {
-    /**
-     * {@code non-null;} map from field constants to {@link
-     * FieldIdItem} instances
-     */
-    private final TreeMap<CstFieldRef, FieldIdItem> fieldIds;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public FieldIdsSection(DexFile file) {
-        super("field_ids", file);
-
-        fieldIds = new TreeMap<CstFieldRef, FieldIdItem>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return fieldIds.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        throwIfNotPrepared();
-
-        IndexedItem result = fieldIds.get((CstFieldRef) cst);
-
-        if (result == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = fieldIds.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (out.annotates()) {
-            out.annotate(4, "field_ids_size:  " + Hex.u4(sz));
-            out.annotate(4, "field_ids_off:   " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param field {@code non-null;} the reference to intern
-     * @return {@code non-null;} the interned reference
-     */
-    public FieldIdItem intern(CstFieldRef field) {
-        if (field == null) {
-            throw new NullPointerException("field == null");
-        }
-
-        throwIfPrepared();
-
-        FieldIdItem result = fieldIds.get(field);
-
-        if (result == null) {
-            result = new FieldIdItem(field);
-            fieldIds.put(field, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the index of the given reference, which must have been added
-     * to this instance.
-     *
-     * @param ref {@code non-null;} the reference to look up
-     * @return {@code >= 0;} the reference's index
-     */
-    public int indexOf(CstFieldRef ref) {
-        if (ref == null) {
-            throw new NullPointerException("ref == null");
-        }
-
-        throwIfNotPrepared();
-
-        FieldIdItem item = fieldIds.get(ref);
-
-        if (item == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return item.getIndex();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/HeaderItem.java b/dx/src/main/java/com/android/dx/dex/file/HeaderItem.java
deleted file mode 100644
index 3816eb8..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/HeaderItem.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.DexFormat;
-import com.android.dx.dex.SizeOf;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * File header section of a {@code .dex} file.
- */
-public final class HeaderItem extends IndexedItem {
-    /**
-     * Constructs an instance.
-     */
-    public HeaderItem() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_HEADER_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.HEADER_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        // Nothing to do here.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int mapOff = file.getMap().getFileOffset();
-        Section firstDataSection = file.getFirstDataSection();
-        Section lastDataSection = file.getLastDataSection();
-        int dataOff = firstDataSection.getFileOffset();
-        int dataSize = lastDataSection.getFileOffset() +
-            lastDataSection.writeSize() - dataOff;
-
-        String magic = file.getDexOptions().getMagic();
-
-        if (out.annotates()) {
-            out.annotate(8, "magic: " + new CstString(magic).toQuoted());
-            out.annotate(4, "checksum");
-            out.annotate(20, "signature");
-            out.annotate(4, "file_size:       " +
-                         Hex.u4(file.getFileSize()));
-            out.annotate(4, "header_size:     " + Hex.u4(SizeOf.HEADER_ITEM));
-            out.annotate(4, "endian_tag:      " + Hex.u4(DexFormat.ENDIAN_TAG));
-            out.annotate(4, "link_size:       0");
-            out.annotate(4, "link_off:        0");
-            out.annotate(4, "map_off:         " + Hex.u4(mapOff));
-        }
-
-        // Write the magic number.
-        for (int i = 0; i < 8; i++) {
-            out.writeByte(magic.charAt(i));
-        }
-
-        // Leave space for the checksum and signature.
-        out.writeZeroes(24);
-
-        out.writeInt(file.getFileSize());
-        out.writeInt(SizeOf.HEADER_ITEM);
-        out.writeInt(DexFormat.ENDIAN_TAG);
-
-        /*
-         * Write zeroes for the link size and data, as the output
-         * isn't a staticly linked file.
-         */
-        out.writeZeroes(8);
-
-        out.writeInt(mapOff);
-
-        // Write out each section's respective header part.
-        file.getStringIds().writeHeaderPart(out);
-        file.getTypeIds().writeHeaderPart(out);
-        file.getProtoIds().writeHeaderPart(out);
-        file.getFieldIds().writeHeaderPart(out);
-        file.getMethodIds().writeHeaderPart(out);
-        file.getClassDefs().writeHeaderPart(out);
-
-        if (out.annotates()) {
-            out.annotate(4, "data_size:       " + Hex.u4(dataSize));
-            out.annotate(4, "data_off:        " + Hex.u4(dataOff));
-        }
-
-        out.writeInt(dataSize);
-        out.writeInt(dataOff);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/HeaderSection.java b/dx/src/main/java/com/android/dx/dex/file/HeaderSection.java
deleted file mode 100644
index 21da488..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/HeaderSection.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * File header section of a {@code .dex} file.
- */
-public final class HeaderSection extends UniformItemSection {
-    /** {@code non-null;} the list of the one item in the section */
-    private final List<HeaderItem> list;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public HeaderSection(DexFile file) {
-        super(null, file, 4);
-
-        HeaderItem item = new HeaderItem();
-        item.setIndex(0);
-
-        this.list = Collections.singletonList(item);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return list;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        // Nothing to do here.
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/IdItem.java b/dx/src/main/java/com/android/dx/dex/file/IdItem.java
deleted file mode 100644
index 1bd2b5f..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/IdItem.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstType;
-
-/**
- * Representation of a reference to an item inside a Dalvik file.
- */
-public abstract class IdItem extends IndexedItem {
-    /**
-     * {@code non-null;} the type constant for the defining class of
-     * the reference
-     */
-    private final CstType type;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param type {@code non-null;} the type constant for the defining
-     * class of the reference
-     */
-    public IdItem(CstType type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        this.type = type;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        typeIds.intern(type);
-    }
-
-    /**
-     * Gets the type constant for the defining class of the
-     * reference.
-     *
-     * @return {@code non-null;} the type constant
-     */
-    public final CstType getDefiningClass() {
-        return type;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/IndexedItem.java b/dx/src/main/java/com/android/dx/dex/file/IndexedItem.java
deleted file mode 100644
index 9ba4783..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/IndexedItem.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-/**
- * An item in a Dalvik file which is referenced by index.
- */
-public abstract class IndexedItem extends Item {
-    /** {@code >= -1;} assigned index of the item, or {@code -1} if not
-     * yet assigned */
-    private int index;
-
-    /**
-     * Constructs an instance. The index is initially unassigned.
-     */
-    public IndexedItem() {
-        index = -1;
-    }
-
-    /**
-     * Gets whether or not this instance has been assigned an index.
-     *
-     * @return {@code true} iff this instance has been assigned an index
-     */
-    public final boolean hasIndex() {
-        return (index >= 0);
-    }
-
-    /**
-     * Gets the item index.
-     *
-     * @return {@code >= 0;} the index
-     * @throws RuntimeException thrown if the item index is not yet assigned
-     */
-    public final int getIndex() {
-        if (index < 0) {
-            throw new RuntimeException("index not yet set");
-        }
-
-        return index;
-    }
-
-    /**
-     * Sets the item index. This method may only ever be called once
-     * per instance, and this will throw a {@code RuntimeException} if
-     * called a second (or subsequent) time.
-     *
-     * @param index {@code >= 0;} the item index
-     */
-    public final void setIndex(int index) {
-        if (this.index != -1) {
-            throw new RuntimeException("index already set");
-        }
-
-        this.index = index;
-    }
-
-    /**
-     * Gets the index of this item as a string, suitable for including in
-     * annotations.
-     *
-     * @return {@code non-null;} the index string
-     */
-    public final String indexString() {
-        return '[' + Integer.toHexString(index) + ']';
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/Item.java b/dx/src/main/java/com/android/dx/dex/file/Item.java
deleted file mode 100644
index cf2b380..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/Item.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Base class for any structurally-significant and (potentially)
- * repeated piece of a Dalvik file.
- */
-public abstract class Item {
-    /**
-     * Constructs an instance.
-     */
-    public Item() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Returns the item type for this instance.
-     *
-     * @return {@code non-null;} the item type
-     */
-    public abstract ItemType itemType();
-
-    /**
-     * Returns the human name for the particular type of item this
-     * instance is.
-     *
-     * @return {@code non-null;} the name
-     */
-    public final String typeName() {
-        return itemType().toHuman();
-    }
-
-    /**
-     * Gets the size of this instance when written, in bytes.
-     *
-     * @return {@code >= 0;} the write size
-     */
-    public abstract int writeSize();
-
-    /**
-     * Populates a {@link DexFile} with items from within this instance.
-     * This will <i>not</i> add an item to the file for this instance itself
-     * (which should have been done by whatever refers to this instance).
-     *
-     * <p><b>Note:</b> Subclasses must override this to do something
-     * appropriate.</p>
-     *
-     * @param file {@code non-null;} the file to populate
-     */
-    public abstract void addContents(DexFile file);
-
-    /**
-     * Writes the representation of this instance to the given data section,
-     * using the given {@link DexFile} to look things up as needed.
-     * If this instance keeps track of its offset, then this method will
-     * note the written offset and will also throw an exception if this
-     * instance has already been written.
-     *
-     * @param file {@code non-null;} the file to use for reference
-     * @param out {@code non-null;} where to write to
-     */
-    public abstract void writeTo(DexFile file, AnnotatedOutput out);
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ItemType.java b/dx/src/main/java/com/android/dx/dex/file/ItemType.java
deleted file mode 100644
index 2fe97ab..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ItemType.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.util.ToHuman;
-
-/**
- * Enumeration of all the top-level item types.
- */
-public enum ItemType implements ToHuman {
-    TYPE_HEADER_ITEM(               0x0000, "header_item"),
-    TYPE_STRING_ID_ITEM(            0x0001, "string_id_item"),
-    TYPE_TYPE_ID_ITEM(              0x0002, "type_id_item"),
-    TYPE_PROTO_ID_ITEM(             0x0003, "proto_id_item"),
-    TYPE_FIELD_ID_ITEM(             0x0004, "field_id_item"),
-    TYPE_METHOD_ID_ITEM(            0x0005, "method_id_item"),
-    TYPE_CLASS_DEF_ITEM(            0x0006, "class_def_item"),
-    TYPE_MAP_LIST(                  0x1000, "map_list"),
-    TYPE_TYPE_LIST(                 0x1001, "type_list"),
-    TYPE_ANNOTATION_SET_REF_LIST(   0x1002, "annotation_set_ref_list"),
-    TYPE_ANNOTATION_SET_ITEM(       0x1003, "annotation_set_item"),
-    TYPE_CLASS_DATA_ITEM(           0x2000, "class_data_item"),
-    TYPE_CODE_ITEM(                 0x2001, "code_item"),
-    TYPE_STRING_DATA_ITEM(          0x2002, "string_data_item"),
-    TYPE_DEBUG_INFO_ITEM(           0x2003, "debug_info_item"),
-    TYPE_ANNOTATION_ITEM(           0x2004, "annotation_item"),
-    TYPE_ENCODED_ARRAY_ITEM(        0x2005, "encoded_array_item"),
-    TYPE_ANNOTATIONS_DIRECTORY_ITEM(0x2006, "annotations_directory_item"),
-    TYPE_MAP_ITEM(                  -1,     "map_item"),
-    TYPE_TYPE_ITEM(                 -1,     "type_item"),
-    TYPE_EXCEPTION_HANDLER_ITEM(    -1,     "exception_handler_item"),
-    TYPE_ANNOTATION_SET_REF_ITEM(   -1,     "annotation_set_ref_item");
-
-    /** value when represented in a {@link MapItem} */
-    private final int mapValue;
-
-    /** {@code non-null;} name of the type */
-    private final String typeName;
-
-    /** {@code non-null;} the short human name */
-    private final String humanName;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param mapValue value when represented in a {@link MapItem}
-     * @param typeName {@code non-null;} name of the type
-     */
-    private ItemType(int mapValue, String typeName) {
-        this.mapValue = mapValue;
-        this.typeName = typeName;
-
-        // Make the human name.
-        String human = typeName;
-        if (human.endsWith("_item")) {
-            human = human.substring(0, human.length() - 5);
-        }
-        this.humanName = human.replace('_', ' ');
-    }
-
-    /**
-     * Gets the map value.
-     *
-     * @return the map value
-     */
-    public int getMapValue() {
-        return mapValue;
-    }
-
-    /**
-     * Gets the type name.
-     *
-     * @return {@code non-null;} the type name
-     */
-    public String getTypeName() {
-        return typeName;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return humanName;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MapItem.java b/dx/src/main/java/com/android/dx/dex/file/MapItem.java
deleted file mode 100644
index d78dc91..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MapItem.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.ArrayList;
-
-/**
- * Class that represents a map item.
- */
-public final class MapItem extends OffsettedItem {
-    /** file alignment of this class, in bytes */
-    private static final int ALIGNMENT = 4;
-
-    /** write size of this class, in bytes: three {@code uint}s */
-    private static final int WRITE_SIZE = (4 * 3);
-
-    /** {@code non-null;} item type this instance covers */
-    private final ItemType type;
-
-    /** {@code non-null;} section this instance covers */
-    private final Section section;
-
-    /**
-     * {@code null-ok;} first item covered or {@code null} if this is
-     * a self-reference
-     */
-    private final Item firstItem;
-
-    /**
-     * {@code null-ok;} last item covered or {@code null} if this is
-     * a self-reference
-     */
-    private final Item lastItem;
-
-    /**
-     * {@code > 0;} count of items covered; {@code 1} if this
-     * is a self-reference
-     */
-    private final int itemCount;
-
-    /**
-     * Constructs a list item with instances of this class representing
-     * the contents of the given array of sections, adding it to the
-     * given map section.
-     *
-     * @param sections {@code non-null;} the sections
-     * @param mapSection {@code non-null;} the section that the resulting map
-     * should be added to; it should be empty on entry to this method
-     */
-    public static void addMap(Section[] sections,
-            MixedItemSection mapSection) {
-        if (sections == null) {
-            throw new NullPointerException("sections == null");
-        }
-
-        if (mapSection.items().size() != 0) {
-            throw new IllegalArgumentException(
-                    "mapSection.items().size() != 0");
-        }
-
-        ArrayList<MapItem> items = new ArrayList<MapItem>(50);
-
-        for (Section section : sections) {
-            ItemType currentType = null;
-            Item firstItem = null;
-            Item lastItem = null;
-            int count = 0;
-
-            for (Item item : section.items()) {
-                ItemType type = item.itemType();
-                if (type != currentType) {
-                    if (count != 0) {
-                        items.add(new MapItem(currentType, section,
-                                        firstItem, lastItem, count));
-                    }
-                    currentType = type;
-                    firstItem = item;
-                    count = 0;
-                }
-                lastItem = item;
-                count++;
-            }
-
-            if (count != 0) {
-                // Add a MapItem for the final items in the section.
-                items.add(new MapItem(currentType, section,
-                                firstItem, lastItem, count));
-            } else if (section == mapSection) {
-                // Add a MapItem for the self-referential section.
-                items.add(new MapItem(mapSection));
-            }
-        }
-
-        mapSection.add(
-                new UniformListItem<MapItem>(ItemType.TYPE_MAP_LIST, items));
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param type {@code non-null;} item type this instance covers
-     * @param section {@code non-null;} section this instance covers
-     * @param firstItem {@code non-null;} first item covered
-     * @param lastItem {@code non-null;} last item covered
-     * @param itemCount {@code > 0;} count of items covered
-     */
-    private MapItem(ItemType type, Section section, Item firstItem,
-            Item lastItem, int itemCount) {
-        super(ALIGNMENT, WRITE_SIZE);
-
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        if (section == null) {
-            throw new NullPointerException("section == null");
-        }
-
-        if (firstItem == null) {
-            throw new NullPointerException("firstItem == null");
-        }
-
-        if (lastItem == null) {
-            throw new NullPointerException("lastItem == null");
-        }
-
-        if (itemCount <= 0) {
-            throw new IllegalArgumentException("itemCount <= 0");
-        }
-
-        this.type = type;
-        this.section = section;
-        this.firstItem = firstItem;
-        this.lastItem = lastItem;
-        this.itemCount = itemCount;
-    }
-
-    /**
-     * Constructs a self-referential instance. This instance is meant to
-     * represent the section containing the {@code map_list}.
-     *
-     * @param section {@code non-null;} section this instance covers
-     */
-    private MapItem(Section section) {
-        super(ALIGNMENT, WRITE_SIZE);
-
-        if (section == null) {
-            throw new NullPointerException("section == null");
-        }
-
-        this.type = ItemType.TYPE_MAP_LIST;
-        this.section = section;
-        this.firstItem = null;
-        this.lastItem = null;
-        this.itemCount = 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_MAP_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append(getClass().getName());
-        sb.append('{');
-        sb.append(section.toString());
-        sb.append(' ');
-        sb.append(type.toHuman());
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        // We have nothing to add.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final String toHuman() {
-        return toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        int value = type.getMapValue();
-        int offset;
-
-        if (firstItem == null) {
-            offset = section.getFileOffset();
-        } else {
-            offset = section.getAbsoluteItemOffset(firstItem);
-        }
-
-        if (out.annotates()) {
-            out.annotate(0, offsetString() + ' ' + type.getTypeName() +
-                    " map");
-            out.annotate(2, "  type:   " + Hex.u2(value) + " // " +
-                    type.toString());
-            out.annotate(2, "  unused: 0");
-            out.annotate(4, "  size:   " + Hex.u4(itemCount));
-            out.annotate(4, "  offset: " + Hex.u4(offset));
-        }
-
-        out.writeShort(value);
-        out.writeShort(0); // unused
-        out.writeInt(itemCount);
-        out.writeInt(offset);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MemberIdItem.java b/dx/src/main/java/com/android/dx/dex/file/MemberIdItem.java
deleted file mode 100644
index 08a3123..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MemberIdItem.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstMemberRef;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.dex.SizeOf;
-
-/**
- * Representation of a member (field or method) reference inside a
- * Dalvik file.
- */
-public abstract class MemberIdItem extends IdItem {
-    /** {@code non-null;} the constant for the member */
-    private final CstMemberRef cst;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param cst {@code non-null;} the constant for the member
-     */
-    public MemberIdItem(CstMemberRef cst) {
-        super(cst.getDefiningClass());
-
-        this.cst = cst;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.MEMBER_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        super.addContents(file);
-
-        StringIdsSection stringIds = file.getStringIds();
-        stringIds.intern(getRef().getNat().getName());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void writeTo(DexFile file, AnnotatedOutput out) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        StringIdsSection stringIds = file.getStringIds();
-        CstNat nat = cst.getNat();
-        int classIdx = typeIds.indexOf(getDefiningClass());
-        int nameIdx = stringIds.indexOf(nat.getName());
-        int typoidIdx = getTypoidIdx(file);
-
-        if (out.annotates()) {
-            out.annotate(0, indexString() + ' ' + cst.toHuman());
-            out.annotate(2, "  class_idx: " + Hex.u2(classIdx));
-            out.annotate(2, String.format("  %-10s %s", getTypoidName() + ':',
-                            Hex.u2(typoidIdx)));
-            out.annotate(4, "  name_idx:  " + Hex.u4(nameIdx));
-        }
-
-        out.writeShort(classIdx);
-        out.writeShort(typoidIdx);
-        out.writeInt(nameIdx);
-    }
-
-    /**
-     * Returns the index of the type-like thing associated with
-     * this item, in order that it may be written out. Subclasses must
-     * override this to get whatever it is they need to store.
-     *
-     * @param file {@code non-null;} the file being written
-     * @return the index in question
-     */
-    protected abstract int getTypoidIdx(DexFile file);
-
-    /**
-     * Returns the field name of the type-like thing associated with
-     * this item, for listing-generating purposes. Subclasses must override
-     * this.
-     *
-     * @return {@code non-null;} the name in question
-     */
-    protected abstract String getTypoidName();
-
-    /**
-     * Gets the member constant.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public final CstMemberRef getRef() {
-        return cst;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MemberIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/MemberIdsSection.java
deleted file mode 100644
index ec39b75..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MemberIdsSection.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.DexException;
-
-/**
- * Member (field or method) refs list section of a {@code .dex} file.
- */
-public abstract class MemberIdsSection extends UniformItemSection {
-    /** The largest addressable member is 0xffff, in the dex spec as field@CCCC or meth@CCCC. */
-    private static final int MAX_MEMBERS = 0x10000;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param name {@code null-ok;} the name of this instance, for annotation
-     * purposes
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public MemberIdsSection(String name, DexFile file) {
-        super(name, file, 4);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        int idx = 0;
-
-        if (items().size() > MAX_MEMBERS) {
-            String memberType = this instanceof MethodIdsSection ? "methods" : "fields";
-            throw new DexException("Too many " + memberType + ": " + items().size()
-                    + "; max is " + MAX_MEMBERS);
-        }
-
-        for (Object i : items()) {
-            ((MemberIdItem) i).setIndex(idx);
-            idx++;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MethodAnnotationStruct.java b/dx/src/main/java/com/android/dx/dex/file/MethodAnnotationStruct.java
deleted file mode 100644
index 38f7ce4..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MethodAnnotationStruct.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.ToHuman;
-
-/**
- * Association of a method and its annotations.
- */
-public final class MethodAnnotationStruct
-        implements ToHuman, Comparable<MethodAnnotationStruct> {
-    /** {@code non-null;} the method in question */
-    private final CstMethodRef method;
-
-    /** {@code non-null;} the associated annotations */
-    private AnnotationSetItem annotations;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the method in question
-     * @param annotations {@code non-null;} the associated annotations
-     */
-    public MethodAnnotationStruct(CstMethodRef method,
-            AnnotationSetItem annotations) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        if (annotations == null) {
-            throw new NullPointerException("annotations == null");
-        }
-
-        this.method = method;
-        this.annotations = annotations;
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        return method.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof MethodAnnotationStruct)) {
-            return false;
-        }
-
-        return method.equals(((MethodAnnotationStruct) other).method);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(MethodAnnotationStruct other) {
-        return method.compareTo(other.method);
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MethodIdsSection methodIds = file.getMethodIds();
-        MixedItemSection wordData = file.getWordData();
-
-        methodIds.intern(method);
-        annotations = wordData.intern(annotations);
-    }
-
-    /** {@inheritDoc} */
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int methodIdx = file.getMethodIds().indexOf(method);
-        int annotationsOff = annotations.getAbsoluteOffset();
-
-        if (out.annotates()) {
-            out.annotate(0, "    " + method.toHuman());
-            out.annotate(4, "      method_idx:      " + Hex.u4(methodIdx));
-            out.annotate(4, "      annotations_off: " +
-                    Hex.u4(annotationsOff));
-        }
-
-        out.writeInt(methodIdx);
-        out.writeInt(annotationsOff);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return method.toHuman() + ": " + annotations;
-    }
-
-    /**
-     * Gets the method this item is for.
-     *
-     * @return {@code non-null;} the method
-     */
-    public CstMethodRef getMethod() {
-        return method;
-    }
-
-    /**
-     * Gets the associated annotations.
-     *
-     * @return {@code non-null;} the annotations
-     */
-    public Annotations getAnnotations() {
-        return annotations.getAnnotations();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MethodIdItem.java b/dx/src/main/java/com/android/dx/dex/file/MethodIdItem.java
deleted file mode 100644
index f2ff4f9..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MethodIdItem.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstBaseMethodRef;
-
-/**
- * Representation of a method reference inside a Dalvik file.
- */
-public final class MethodIdItem extends MemberIdItem {
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the constant for the method
-     */
-    public MethodIdItem(CstBaseMethodRef method) {
-        super(method);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_METHOD_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        super.addContents(file);
-
-        ProtoIdsSection protoIds = file.getProtoIds();
-        protoIds.intern(getMethodRef().getPrototype());
-    }
-
-    /**
-     * Gets the method constant.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public CstBaseMethodRef getMethodRef() {
-        return (CstBaseMethodRef) getRef();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int getTypoidIdx(DexFile file) {
-        ProtoIdsSection protoIds = file.getProtoIds();
-        return protoIds.indexOf(getMethodRef().getPrototype());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String getTypoidName() {
-        return "proto_idx";
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MethodIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/MethodIdsSection.java
deleted file mode 100644
index fa0cd3c..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MethodIdsSection.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstBaseMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Method refs list section of a {@code .dex} file.
- */
-public final class MethodIdsSection extends MemberIdsSection {
-    /**
-     * {@code non-null;} map from method constants to {@link
-     * MethodIdItem} instances
-     */
-    private final TreeMap<CstBaseMethodRef, MethodIdItem> methodIds;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public MethodIdsSection(DexFile file) {
-        super("method_ids", file);
-
-        methodIds = new TreeMap<CstBaseMethodRef, MethodIdItem>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return methodIds.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        throwIfNotPrepared();
-
-        IndexedItem result = methodIds.get((CstBaseMethodRef) cst);
-
-        if (result == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = methodIds.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (out.annotates()) {
-            out.annotate(4, "method_ids_size: " + Hex.u4(sz));
-            out.annotate(4, "method_ids_off:  " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param method {@code non-null;} the reference to intern
-     * @return {@code non-null;} the interned reference
-     */
-    public MethodIdItem intern(CstBaseMethodRef method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        throwIfPrepared();
-
-        MethodIdItem result = methodIds.get(method);
-
-        if (result == null) {
-            result = new MethodIdItem(method);
-            methodIds.put(method, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the index of the given reference, which must have been added
-     * to this instance.
-     *
-     * @param ref {@code non-null;} the reference to look up
-     * @return {@code >= 0;} the reference's index
-     */
-    public int indexOf(CstBaseMethodRef ref) {
-        if (ref == null) {
-            throw new NullPointerException("ref == null");
-        }
-
-        throwIfNotPrepared();
-
-        MethodIdItem item = methodIds.get(ref);
-
-        if (item == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return item.getIndex();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/MixedItemSection.java b/dx/src/main/java/com/android/dx/dex/file/MixedItemSection.java
deleted file mode 100644
index b885306..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/MixedItemSection.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-import com.android.dx.util.Hex;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-
-/**
- * A section of a {@code .dex} file which consists of a sequence of
- * {@link OffsettedItem} objects, which may each be of a different concrete
- * class and/or size.
- *
- * <b>Note:</b> It is invalid for an item in an instance of this class to
- * have a larger alignment requirement than the alignment of this instance.
- */
-public final class MixedItemSection extends Section {
-    static enum SortType {
-        /** no sorting */
-        NONE,
-
-        /** sort by type only */
-        TYPE,
-
-        /** sort in class-major order, with instances sorted per-class */
-        INSTANCE;
-    };
-
-    /** {@code non-null;} sorter which sorts instances by type */
-    private static final Comparator<OffsettedItem> TYPE_SORTER =
-        new Comparator<OffsettedItem>() {
-        public int compare(OffsettedItem item1, OffsettedItem item2) {
-            ItemType type1 = item1.itemType();
-            ItemType type2 = item2.itemType();
-            return type1.compareTo(type2);
-        }
-    };
-
-    /** {@code non-null;} the items in this part */
-    private final ArrayList<OffsettedItem> items;
-
-    /** {@code non-null;} items that have been explicitly interned */
-    private final HashMap<OffsettedItem, OffsettedItem> interns;
-
-    /** {@code non-null;} how to sort the items */
-    private final SortType sort;
-
-    /**
-     * {@code >= -1;} the current size of this part, in bytes, or {@code -1}
-     * if not yet calculated
-     */
-    private int writeSize;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param name {@code null-ok;} the name of this instance, for annotation
-     * purposes
-     * @param file {@code non-null;} file that this instance is part of
-     * @param alignment {@code > 0;} alignment requirement for the final output;
-     * must be a power of 2
-     * @param sort how the items should be sorted in the final output
-     */
-    public MixedItemSection(String name, DexFile file, int alignment,
-            SortType sort) {
-        super(name, file, alignment);
-
-        this.items = new ArrayList<OffsettedItem>(100);
-        this.interns = new HashMap<OffsettedItem, OffsettedItem>(100);
-        this.sort = sort;
-        this.writeSize = -1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return items;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        throwIfNotPrepared();
-        return writeSize;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getAbsoluteItemOffset(Item item) {
-        OffsettedItem oi = (OffsettedItem) item;
-        return oi.getAbsoluteOffset();
-    }
-
-    /**
-     * Gets the size of this instance, in items.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int size() {
-        return items.size();
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        if (writeSize == -1) {
-            throw new RuntimeException("write size not yet set");
-        }
-
-        int sz = writeSize;
-        int offset = (sz == 0) ? 0 : getFileOffset();
-        String name = getName();
-
-        if (name == null) {
-            name = "<unnamed>";
-        }
-
-        int spaceCount = 15 - name.length();
-        char[] spaceArr = new char[spaceCount];
-        Arrays.fill(spaceArr, ' ');
-        String spaces = new String(spaceArr);
-
-        if (out.annotates()) {
-            out.annotate(4, name + "_size:" + spaces + Hex.u4(sz));
-            out.annotate(4, name + "_off: " + spaces + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Adds an item to this instance. This will in turn tell the given item
-     * that it has been added to this instance. It is invalid to add the
-     * same item to more than one instance, nor to add the same items
-     * multiple times to a single instance.
-     *
-     * @param item {@code non-null;} the item to add
-     */
-    public void add(OffsettedItem item) {
-        throwIfPrepared();
-
-        try {
-            if (item.getAlignment() > getAlignment()) {
-                throw new IllegalArgumentException(
-                        "incompatible item alignment");
-            }
-        } catch (NullPointerException ex) {
-            // Elucidate the exception.
-            throw new NullPointerException("item == null");
-        }
-
-        items.add(item);
-    }
-
-    /**
-     * Interns an item in this instance, returning the interned instance
-     * (which may not be the one passed in). This will add the item if no
-     * equal item has been added.
-     *
-     * @param item {@code non-null;} the item to intern
-     * @return {@code non-null;} the equivalent interned instance
-     */
-    public <T extends OffsettedItem> T intern(T item) {
-        throwIfPrepared();
-
-        OffsettedItem result = interns.get(item);
-
-        if (result != null) {
-            return (T) result;
-        }
-
-        add(item);
-        interns.put(item, item);
-        return item;
-    }
-
-    /**
-     * Gets an item which was previously interned.
-     *
-     * @param item {@code non-null;} the item to look for
-     * @return {@code non-null;} the equivalent already-interned instance
-     */
-    public <T extends OffsettedItem> T get(T item) {
-        throwIfNotPrepared();
-
-        OffsettedItem result = interns.get(item);
-
-        if (result != null) {
-            return (T) result;
-        }
-
-        throw new NoSuchElementException(item.toString());
-    }
-
-    /**
-     * Writes an index of contents of the items in this instance of the
-     * given type. If there are none, this writes nothing. If there are any,
-     * then the index is preceded by the given intro string.
-     *
-     * @param out {@code non-null;} where to write to
-     * @param itemType {@code non-null;} the item type of interest
-     * @param intro {@code non-null;} the introductory string for non-empty indices
-     */
-    public void writeIndexAnnotation(AnnotatedOutput out, ItemType itemType,
-            String intro) {
-        throwIfNotPrepared();
-
-        TreeMap<String, OffsettedItem> index =
-            new TreeMap<String, OffsettedItem>();
-
-        for (OffsettedItem item : items) {
-            if (item.itemType() == itemType) {
-                String label = item.toHuman();
-                index.put(label, item);
-            }
-        }
-
-        if (index.size() == 0) {
-            return;
-        }
-
-        out.annotate(0, intro);
-
-        for (Map.Entry<String, OffsettedItem> entry : index.entrySet()) {
-            String label = entry.getKey();
-            OffsettedItem item = entry.getValue();
-            out.annotate(0, item.offsetString() + ' ' + label + '\n');
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void prepare0() {
-        DexFile file = getFile();
-
-        /*
-         * It's okay for new items to be added as a result of an
-         * addContents() call; we just have to deal with the possibility.
-         */
-
-        int i = 0;
-        for (;;) {
-            int sz = items.size();
-            if (i >= sz) {
-                break;
-            }
-
-            for (/*i*/; i < sz; i++) {
-                OffsettedItem one = items.get(i);
-                one.addContents(file);
-            }
-        }
-    }
-
-    /**
-     * Places all the items in this instance at particular offsets. This
-     * will call {@link OffsettedItem#place} on each item. If an item
-     * does not know its write size before the call to {@code place},
-     * it is that call which is responsible for setting the write size.
-     * This method may only be called once per instance; subsequent calls
-     * will throw an exception.
-     */
-    public void placeItems() {
-        throwIfNotPrepared();
-
-        switch (sort) {
-            case INSTANCE: {
-                Collections.sort(items);
-                break;
-            }
-            case TYPE: {
-                Collections.sort(items, TYPE_SORTER);
-                break;
-            }
-        }
-
-        int sz = items.size();
-        int outAt = 0;
-        for (int i = 0; i < sz; i++) {
-            OffsettedItem one = items.get(i);
-            try {
-                int placedAt = one.place(this, outAt);
-
-                if (placedAt < outAt) {
-                    throw new RuntimeException("bogus place() result for " +
-                            one);
-                }
-
-                outAt = placedAt + one.writeSize();
-            } catch (RuntimeException ex) {
-                throw ExceptionWithContext.withContext(ex,
-                        "...while placing " + one);
-            }
-        }
-
-        writeSize = outAt;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(AnnotatedOutput out) {
-        boolean annotates = out.annotates();
-        boolean first = true;
-        DexFile file = getFile();
-        int at = 0;
-
-        for (OffsettedItem one : items) {
-            if (annotates) {
-                if (first) {
-                    first = false;
-                } else {
-                    out.annotate(0, "\n");
-                }
-            }
-
-            int alignMask = one.getAlignment() - 1;
-            int writeAt = (at + alignMask) & ~alignMask;
-
-            if (at != writeAt) {
-                out.writeZeroes(writeAt - at);
-                at = writeAt;
-            }
-
-            one.writeTo(file, out);
-            at += one.writeSize();
-        }
-
-        if (at != writeSize) {
-            throw new RuntimeException("output size mismatch");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/OffsettedItem.java b/dx/src/main/java/com/android/dx/dex/file/OffsettedItem.java
deleted file mode 100644
index 7721470..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/OffsettedItem.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ExceptionWithContext;
-
-/**
- * An item in a Dalvik file which is referenced by absolute offset.
- */
-public abstract class OffsettedItem extends Item
-        implements Comparable<OffsettedItem> {
-    /** {@code > 0;} alignment requirement */
-    private final int alignment;
-
-    /** {@code >= -1;} the size of this instance when written, in bytes, or
-     * {@code -1} if not yet known */
-    private int writeSize;
-
-    /**
-     * {@code null-ok;} section the item was added to, or {@code null} if
-     * not yet added
-     */
-    private Section addedTo;
-
-    /**
-     * {@code >= -1;} assigned offset of the item from the start of its section,
-     * or {@code -1} if not yet assigned
-     */
-    private int offset;
-
-    /**
-     * Gets the absolute offset of the given item, returning {@code 0}
-     * if handed {@code null}.
-     *
-     * @param item {@code null-ok;} the item in question
-     * @return {@code >= 0;} the item's absolute offset, or {@code 0}
-     * if {@code item == null}
-     */
-    public static int getAbsoluteOffsetOr0(OffsettedItem item) {
-        if (item == null) {
-            return 0;
-        }
-
-        return item.getAbsoluteOffset();
-    }
-
-    /**
-     * Constructs an instance. The offset is initially unassigned.
-     *
-     * @param alignment {@code > 0;} output alignment requirement; must be a
-     * power of 2
-     * @param writeSize {@code >= -1;} the size of this instance when written,
-     * in bytes, or {@code -1} if not immediately known
-     */
-    public OffsettedItem(int alignment, int writeSize) {
-        Section.validateAlignment(alignment);
-
-        if (writeSize < -1) {
-            throw new IllegalArgumentException("writeSize < -1");
-        }
-
-        this.alignment = alignment;
-        this.writeSize = writeSize;
-        this.addedTo = null;
-        this.offset = -1;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Comparisons for this class are defined to be type-major (if the
-     * types don't match then the objects are not equal), with
-     * {@link #compareTo0} deciding same-type comparisons.
-     */
-    @Override
-    public final boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        OffsettedItem otherItem = (OffsettedItem) other;
-        ItemType thisType = itemType();
-        ItemType otherType = otherItem.itemType();
-
-        if (thisType != otherType) {
-            return false;
-        }
-
-        return (compareTo0(otherItem) == 0);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Comparisons for this class are defined to be class-major (if the
-     * classes don't match then the objects are not equal), with
-     * {@link #compareTo0} deciding same-class comparisons.
-     */
-    public final int compareTo(OffsettedItem other) {
-        if (this == other) {
-            return 0;
-        }
-
-        ItemType thisType = itemType();
-        ItemType otherType = other.itemType();
-
-        if (thisType != otherType) {
-            return thisType.compareTo(otherType);
-        }
-
-        return compareTo0(other);
-    }
-
-    /**
-     * Sets the write size of this item. This may only be called once
-     * per instance, and only if the size was unknown upon instance
-     * creation.
-     *
-     * @param writeSize {@code > 0;} the write size, in bytes
-     */
-    public final void setWriteSize(int writeSize) {
-        if (writeSize < 0) {
-            throw new IllegalArgumentException("writeSize < 0");
-        }
-
-        if (this.writeSize >= 0) {
-            throw new UnsupportedOperationException("writeSize already set");
-        }
-
-        this.writeSize = writeSize;
-    }
-
-    /** {@inheritDoc}
-     *
-     * @throws UnsupportedOperationException thrown if the write size
-     * is not yet known
-     */
-    @Override
-    public final int writeSize() {
-        if (writeSize < 0) {
-            throw new UnsupportedOperationException("writeSize is unknown");
-        }
-
-        return writeSize;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void writeTo(DexFile file, AnnotatedOutput out) {
-        out.alignTo(alignment);
-
-        try {
-            if (writeSize < 0) {
-                throw new UnsupportedOperationException(
-                        "writeSize is unknown");
-            }
-            out.assertCursor(getAbsoluteOffset());
-        } catch (RuntimeException ex) {
-            throw ExceptionWithContext.withContext(ex,
-                    "...while writing " + this);
-        }
-
-        writeTo0(file, out);
-    }
-
-    /**
-     * Gets the relative item offset. The offset is from the start of
-     * the section which the instance was written to.
-     *
-     * @return {@code >= 0;} the offset
-     * @throws RuntimeException thrown if the offset is not yet known
-     */
-    public final int getRelativeOffset() {
-        if (offset < 0) {
-            throw new RuntimeException("offset not yet known");
-        }
-
-        return offset;
-    }
-
-    /**
-     * Gets the absolute item offset. The offset is from the start of
-     * the file which the instance was written to.
-     *
-     * @return {@code >= 0;} the offset
-     * @throws RuntimeException thrown if the offset is not yet known
-     */
-    public final int getAbsoluteOffset() {
-        if (offset < 0) {
-            throw new RuntimeException("offset not yet known");
-        }
-
-        return addedTo.getAbsoluteOffset(offset);
-    }
-
-    /**
-     * Indicates that this item has been added to the given section at
-     * the given offset. It is only valid to call this method once per
-     * instance.
-     *
-     * @param addedTo {@code non-null;} the section this instance has
-     * been added to
-     * @param offset {@code >= 0;} the desired offset from the start of the
-     * section where this instance was placed
-     * @return {@code >= 0;} the offset that this instance should be placed at
-     * in order to meet its alignment constraint
-     */
-    public final int place(Section addedTo, int offset) {
-        if (addedTo == null) {
-            throw new NullPointerException("addedTo == null");
-        }
-
-        if (offset < 0) {
-            throw new IllegalArgumentException("offset < 0");
-        }
-
-        if (this.addedTo != null) {
-            throw new RuntimeException("already written");
-        }
-
-        int mask = alignment - 1;
-        offset = (offset + mask) & ~mask;
-
-        this.addedTo = addedTo;
-        this.offset = offset;
-
-        place0(addedTo, offset);
-
-        return offset;
-    }
-
-    /**
-     * Gets the alignment requirement of this instance. An instance should
-     * only be written when so aligned.
-     *
-     * @return {@code > 0;} the alignment requirement; must be a power of 2
-     */
-    public final int getAlignment() {
-        return alignment;
-    }
-
-    /**
-     * Gets the absolute offset of this item as a string, suitable for
-     * including in annotations.
-     *
-     * @return {@code non-null;} the offset string
-     */
-    public final String offsetString() {
-        return '[' + Integer.toHexString(getAbsoluteOffset()) + ']';
-    }
-
-    /**
-     * Gets a short human-readable string representing this instance.
-     *
-     * @return {@code non-null;} the human form
-     */
-    public abstract String toHuman();
-
-    /**
-     * Compares this instance to another which is guaranteed to be of
-     * the same class. The default implementation of this method is to
-     * throw an exception (unsupported operation). If a particular
-     * class needs to actually sort, then it should override this
-     * method.
-     *
-     * @param other {@code non-null;} instance to compare to
-     * @return {@code -1}, {@code 0}, or {@code 1}, depending
-     * on the sort order of this instance and the other
-     */
-    protected int compareTo0(OffsettedItem other) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /**
-     * Does additional work required when placing an instance. The
-     * default implementation of this method is a no-op. If a
-     * particular class needs to do something special, then it should
-     * override this method. In particular, if this instance did not
-     * know its write size up-front, then this method is responsible
-     * for setting it.
-     *
-     * @param addedTo {@code non-null;} the section this instance has been added to
-     * @param offset {@code >= 0;} the offset from the start of the
-     * section where this instance was placed
-     */
-    protected void place0(Section addedTo, int offset) {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Performs the actual write of the contents of this instance to
-     * the given data section. This is called by {@link #writeTo},
-     * which will have taken care of ensuring alignment.
-     *
-     * @param file {@code non-null;} the file to use for reference
-     * @param out {@code non-null;} where to write to
-     */
-    protected abstract void writeTo0(DexFile file, AnnotatedOutput out);
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ParameterAnnotationStruct.java b/dx/src/main/java/com/android/dx/dex/file/ParameterAnnotationStruct.java
deleted file mode 100644
index 078c219..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ParameterAnnotationStruct.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotations;
-import com.android.dx.rop.annotation.AnnotationsList;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import com.android.dx.util.ToHuman;
-
-import java.util.ArrayList;
-
-/**
- * Association of a method and its parameter annotations.
- */
-public final class ParameterAnnotationStruct
-        implements ToHuman, Comparable<ParameterAnnotationStruct> {
-    /** {@code non-null;} the method in question */
-    private final CstMethodRef method;
-
-    /** {@code non-null;} the associated annotations list */
-    private final AnnotationsList annotationsList;
-
-    /** {@code non-null;} the associated annotations list, as an item */
-    private final UniformListItem<AnnotationSetRefItem> annotationsItem;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the method in question
-     * @param annotationsList {@code non-null;} the associated annotations list
-     */
-    public ParameterAnnotationStruct(CstMethodRef method,
-            AnnotationsList annotationsList) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        if (annotationsList == null) {
-            throw new NullPointerException("annotationsList == null");
-        }
-
-        this.method = method;
-        this.annotationsList = annotationsList;
-
-        /*
-         * Construct an item for the annotations list. TODO: This
-         * requires way too much copying; fix it.
-         */
-
-        int size = annotationsList.size();
-        ArrayList<AnnotationSetRefItem> arrayList = new
-            ArrayList<AnnotationSetRefItem>(size);
-
-        for (int i = 0; i < size; i++) {
-            Annotations annotations = annotationsList.get(i);
-            AnnotationSetItem item = new AnnotationSetItem(annotations);
-            arrayList.add(new AnnotationSetRefItem(item));
-        }
-
-        this.annotationsItem = new UniformListItem<AnnotationSetRefItem>(
-                ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList);
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        return method.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof ParameterAnnotationStruct)) {
-            return false;
-        }
-
-        return method.equals(((ParameterAnnotationStruct) other).method);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(ParameterAnnotationStruct other) {
-        return method.compareTo(other.method);
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        MethodIdsSection methodIds = file.getMethodIds();
-        MixedItemSection wordData = file.getWordData();
-
-        methodIds.intern(method);
-        wordData.add(annotationsItem);
-    }
-
-    /** {@inheritDoc} */
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int methodIdx = file.getMethodIds().indexOf(method);
-        int annotationsOff = annotationsItem.getAbsoluteOffset();
-
-        if (out.annotates()) {
-            out.annotate(0, "    " + method.toHuman());
-            out.annotate(4, "      method_idx:      " + Hex.u4(methodIdx));
-            out.annotate(4, "      annotations_off: " +
-                    Hex.u4(annotationsOff));
-        }
-
-        out.writeInt(methodIdx);
-        out.writeInt(annotationsOff);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(method.toHuman());
-        sb.append(": ");
-
-        boolean first = true;
-        for (AnnotationSetRefItem item : annotationsItem.getItems()) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            sb.append(item.toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets the method this item is for.
-     *
-     * @return {@code non-null;} the method
-     */
-    public CstMethodRef getMethod() {
-        return method;
-    }
-
-    /**
-     * Gets the associated annotations list.
-     *
-     * @return {@code non-null;} the annotations list
-     */
-    public AnnotationsList getAnnotationsList() {
-        return annotationsList;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ProtoIdItem.java b/dx/src/main/java/com/android/dx/dex/file/ProtoIdItem.java
deleted file mode 100644
index 235a8c8..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ProtoIdItem.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.dex.SizeOf;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Representation of a method prototype reference inside a Dalvik file.
- */
-public final class ProtoIdItem extends IndexedItem {
-    /** {@code non-null;} the wrapped prototype */
-    private final Prototype prototype;
-
-    /** {@code non-null;} the short-form of the prototype */
-    private final CstString shortForm;
-
-    /**
-     * {@code null-ok;} the list of parameter types or {@code null} if this
-     * prototype has no parameters
-     */
-    private TypeListItem parameterTypes;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param prototype {@code non-null;} the constant for the prototype
-     */
-    public ProtoIdItem(Prototype prototype) {
-        if (prototype == null) {
-            throw new NullPointerException("prototype == null");
-        }
-
-        this.prototype = prototype;
-        this.shortForm = makeShortForm(prototype);
-
-        StdTypeList parameters = prototype.getParameterTypes();
-        this.parameterTypes = (parameters.size() == 0) ? null
-            : new TypeListItem(parameters);
-    }
-
-    /**
-     * Creates the short-form of the given prototype.
-     *
-     * @param prototype {@code non-null;} the prototype
-     * @return {@code non-null;} the short form
-     */
-    private static CstString makeShortForm(Prototype prototype) {
-        StdTypeList parameters = prototype.getParameterTypes();
-        int size = parameters.size();
-        StringBuilder sb = new StringBuilder(size + 1);
-
-        sb.append(shortFormCharFor(prototype.getReturnType()));
-
-        for (int i = 0; i < size; i++) {
-            sb.append(shortFormCharFor(parameters.getType(i)));
-        }
-
-        return new CstString(sb.toString());
-    }
-
-    /**
-     * Gets the short-form character for the given type.
-     *
-     * @param type {@code non-null;} the type
-     * @return the corresponding short-form character
-     */
-    private static char shortFormCharFor(Type type) {
-        char descriptorChar = type.getDescriptor().charAt(0);
-
-        if (descriptorChar == '[') {
-            return 'L';
-        }
-
-        return descriptorChar;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_PROTO_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.PROTO_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        StringIdsSection stringIds = file.getStringIds();
-        TypeIdsSection typeIds = file.getTypeIds();
-        MixedItemSection typeLists = file.getTypeLists();
-
-        typeIds.intern(prototype.getReturnType());
-        stringIds.intern(shortForm);
-
-        if (parameterTypes != null) {
-            parameterTypes = typeLists.intern(parameterTypes);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int shortyIdx = file.getStringIds().indexOf(shortForm);
-        int returnIdx = file.getTypeIds().indexOf(prototype.getReturnType());
-        int paramsOff = OffsettedItem.getAbsoluteOffsetOr0(parameterTypes);
-
-        if (out.annotates()) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(prototype.getReturnType().toHuman());
-            sb.append(" proto(");
-
-            StdTypeList params = prototype.getParameterTypes();
-            int size = params.size();
-
-            for (int i = 0; i < size; i++) {
-                if (i != 0) {
-                    sb.append(", ");
-                }
-                sb.append(params.getType(i).toHuman());
-            }
-
-            sb.append(")");
-            out.annotate(0, indexString() + ' ' + sb.toString());
-            out.annotate(4, "  shorty_idx:      " + Hex.u4(shortyIdx) +
-                    " // " + shortForm.toQuoted());
-            out.annotate(4, "  return_type_idx: " + Hex.u4(returnIdx) +
-                    " // " + prototype.getReturnType().toHuman());
-            out.annotate(4, "  parameters_off:  " + Hex.u4(paramsOff));
-        }
-
-        out.writeInt(shortyIdx);
-        out.writeInt(returnIdx);
-        out.writeInt(paramsOff);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ProtoIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/ProtoIdsSection.java
deleted file mode 100644
index dc6e8ad..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ProtoIdsSection.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Proto (method prototype) identifiers list section of a
- * {@code .dex} file.
- */
-public final class ProtoIdsSection extends UniformItemSection {
-    /**
-     * {@code non-null;} map from method prototypes to {@link ProtoIdItem} instances
-     */
-    private final TreeMap<Prototype, ProtoIdItem> protoIds;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public ProtoIdsSection(DexFile file) {
-        super("proto_ids", file, 4);
-
-        protoIds = new TreeMap<Prototype, ProtoIdItem>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return protoIds.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = protoIds.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (sz > 65536) {
-            throw new UnsupportedOperationException("too many proto ids");
-        }
-
-        if (out.annotates()) {
-            out.annotate(4, "proto_ids_size:  " + Hex.u4(sz));
-            out.annotate(4, "proto_ids_off:   " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param prototype {@code non-null;} the prototype to intern
-     * @return {@code non-null;} the interned reference
-     */
-    public ProtoIdItem intern(Prototype prototype) {
-        if (prototype == null) {
-            throw new NullPointerException("prototype == null");
-        }
-
-        throwIfPrepared();
-
-        ProtoIdItem result = protoIds.get(prototype);
-
-        if (result == null) {
-            result = new ProtoIdItem(prototype);
-            protoIds.put(prototype, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the index of the given prototype, which must have
-     * been added to this instance.
-     *
-     * @param prototype {@code non-null;} the prototype to look up
-     * @return {@code >= 0;} the reference's index
-     */
-    public int indexOf(Prototype prototype) {
-        if (prototype == null) {
-            throw new NullPointerException("prototype == null");
-        }
-
-        throwIfNotPrepared();
-
-        ProtoIdItem item = protoIds.get(prototype);
-
-        if (item == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return item.getIndex();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        int idx = 0;
-
-        for (Object i : items()) {
-            ((ProtoIdItem) i).setIndex(idx);
-            idx++;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/Section.java b/dx/src/main/java/com/android/dx/dex/file/Section.java
deleted file mode 100644
index 3f04216..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/Section.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.Collection;
-
-/**
- * A section of a {@code .dex} file. Each section consists of a list
- * of items of some sort or other.
- */
-public abstract class Section {
-    /** {@code null-ok;} name of this part, for annotation purposes */
-    private final String name;
-
-    /** {@code non-null;} file that this instance is part of */
-    private final DexFile file;
-
-    /** {@code > 0;} alignment requirement for the final output;
-     * must be a power of 2 */
-    private final int alignment;
-
-    /** {@code >= -1;} offset from the start of the file to this part, or
-     * {@code -1} if not yet known */
-    private int fileOffset;
-
-    /** whether {@link #prepare} has been called successfully on this
-     * instance */
-    private boolean prepared;
-
-    /**
-     * Validates an alignment.
-     *
-     * @param alignment the alignment
-     * @throws IllegalArgumentException thrown if {@code alignment}
-     * isn't a positive power of 2
-     */
-    public static void validateAlignment(int alignment) {
-        if ((alignment <= 0) ||
-            (alignment & (alignment - 1)) != 0) {
-            throw new IllegalArgumentException("invalid alignment");
-        }
-    }
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param name {@code null-ok;} the name of this instance, for annotation
-     * purposes
-     * @param file {@code non-null;} file that this instance is part of
-     * @param alignment {@code > 0;} alignment requirement for the final output;
-     * must be a power of 2
-     */
-    public Section(String name, DexFile file, int alignment) {
-        if (file == null) {
-            throw new NullPointerException("file == null");
-        }
-
-        validateAlignment(alignment);
-
-        this.name = name;
-        this.file = file;
-        this.alignment = alignment;
-        this.fileOffset = -1;
-        this.prepared = false;
-    }
-
-    /**
-     * Gets the file that this instance is part of.
-     *
-     * @return {@code non-null;} the file
-     */
-    public final DexFile getFile() {
-        return file;
-    }
-
-    /**
-     * Gets the alignment for this instance's final output.
-     *
-     * @return {@code > 0;} the alignment
-     */
-    public final int getAlignment() {
-        return alignment;
-    }
-
-    /**
-     * Gets the offset from the start of the file to this part. This
-     * throws an exception if the offset has not yet been set.
-     *
-     * @return {@code >= 0;} the file offset
-     */
-    public final int getFileOffset() {
-        if (fileOffset < 0) {
-            throw new RuntimeException("fileOffset not set");
-        }
-
-        return fileOffset;
-    }
-
-    /**
-     * Sets the file offset. It is only valid to call this method once
-     * once per instance.
-     *
-     * @param fileOffset {@code >= 0;} the desired offset from the start of the
-     * file where this for this instance
-     * @return {@code >= 0;} the offset that this instance should be placed at
-     * in order to meet its alignment constraint
-     */
-    public final int setFileOffset(int fileOffset) {
-        if (fileOffset < 0) {
-            throw new IllegalArgumentException("fileOffset < 0");
-        }
-
-        if (this.fileOffset >= 0) {
-            throw new RuntimeException("fileOffset already set");
-        }
-
-        int mask = alignment - 1;
-        fileOffset = (fileOffset + mask) & ~mask;
-
-        this.fileOffset = fileOffset;
-
-        return fileOffset;
-    }
-
-    /**
-     * Writes this instance to the given raw data object.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    public final void writeTo(AnnotatedOutput out) {
-        throwIfNotPrepared();
-        align(out);
-
-        int cursor = out.getCursor();
-
-        if (fileOffset < 0) {
-            fileOffset = cursor;
-        } else if (fileOffset != cursor) {
-            throw new RuntimeException("alignment mismatch: for " + this +
-                                       ", at " + cursor +
-                                       ", but expected " + fileOffset);
-        }
-
-        if (out.annotates()) {
-            if (name != null) {
-                out.annotate(0, "\n" + name + ":");
-            } else if (cursor != 0) {
-                out.annotate(0, "\n");
-            }
-        }
-
-        writeTo0(out);
-    }
-
-    /**
-     * Returns the absolute file offset, given an offset from the
-     * start of this instance's output. This is only valid to call
-     * once this instance has been assigned a file offset (via {@link
-     * #setFileOffset}).
-     *
-     * @param relative {@code >= 0;} the relative offset
-     * @return {@code >= 0;} the corresponding absolute file offset
-     */
-    public final int getAbsoluteOffset(int relative) {
-        if (relative < 0) {
-            throw new IllegalArgumentException("relative < 0");
-        }
-
-        if (fileOffset < 0) {
-            throw new RuntimeException("fileOffset not yet set");
-        }
-
-        return fileOffset + relative;
-    }
-
-    /**
-     * Returns the absolute file offset of the given item which must
-     * be contained in this section. This is only valid to call
-     * once this instance has been assigned a file offset (via {@link
-     * #setFileOffset}).
-     *
-     * <p><b>Note:</b> Subclasses must implement this as appropriate for
-     * their contents.</p>
-     *
-     * @param item {@code non-null;} the item in question
-     * @return {@code >= 0;} the item's absolute file offset
-     */
-    public abstract int getAbsoluteItemOffset(Item item);
-
-    /**
-     * Prepares this instance for writing. This performs any necessary
-     * prerequisites, including particularly adding stuff to other
-     * sections. This method may only be called once per instance;
-     * subsequent calls will throw an exception.
-     */
-    public final void prepare() {
-        throwIfPrepared();
-        prepare0();
-        prepared = true;
-    }
-
-    /**
-     * Gets the collection of all the items in this section.
-     * It is not valid to attempt to change the returned list.
-     *
-     * @return {@code non-null;} the items
-     */
-    public abstract Collection<? extends Item> items();
-
-    /**
-     * Does the main work of {@link #prepare}.
-     */
-    protected abstract void prepare0();
-
-    /**
-     * Gets the size of this instance when output, in bytes.
-     *
-     * @return {@code >= 0;} the size of this instance, in bytes
-     */
-    public abstract int writeSize();
-
-    /**
-     * Throws an exception if {@link #prepare} has not been
-     * called on this instance.
-     */
-    protected final void throwIfNotPrepared() {
-        if (!prepared) {
-            throw new RuntimeException("not prepared");
-        }
-    }
-
-    /**
-     * Throws an exception if {@link #prepare} has already been called
-     * on this instance.
-     */
-    protected final void throwIfPrepared() {
-        if (prepared) {
-            throw new RuntimeException("already prepared");
-        }
-    }
-
-    /**
-     * Aligns the output of the given data to the alignment of this instance.
-     *
-     * @param out {@code non-null;} the output to align
-     */
-    protected final void align(AnnotatedOutput out) {
-        out.alignTo(alignment);
-    }
-
-    /**
-     * Writes this instance to the given raw data object. This gets
-     * called by {@link #writeTo} after aligning the cursor of
-     * {@code out} and verifying that either the assigned file
-     * offset matches the actual cursor {@code out} or that the
-     * file offset was not previously assigned, in which case it gets
-     * assigned to {@code out}'s cursor.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    protected abstract void writeTo0(AnnotatedOutput out);
-
-    /**
-     * Returns the name of this section, for annotation purposes.
-     *
-     * @return {@code null-ok;} name of this part, for annotation purposes
-     */
-    protected final String getName() {
-        return name;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/Statistics.java b/dx/src/main/java/com/android/dx/dex/file/Statistics.java
deleted file mode 100644
index 62e1832..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/Statistics.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.TreeMap;
-
-/**
- * Statistics about the contents of a file.
- */
-public final class Statistics {
-    /** {@code non-null;} data about each type of item */
-    private final HashMap<String, Data> dataMap;
-
-    /**
-     * Constructs an instance.
-     */
-    public Statistics() {
-        dataMap = new HashMap<String, Data>(50);
-    }
-
-    /**
-     * Adds the given item to the statistics.
-     *
-     * @param item {@code non-null;} the item to add
-     */
-    public void add(Item item) {
-        String typeName = item.typeName();
-        Data data = dataMap.get(typeName);
-
-        if (data == null) {
-            dataMap.put(typeName, new Data(item, typeName));
-        } else {
-            data.add(item);
-        }
-    }
-
-    /**
-     * Adds the given list of items to the statistics.
-     *
-     * @param list {@code non-null;} the list of items to add
-     */
-    public void addAll(Section list) {
-        Collection<? extends Item> items = list.items();
-        for (Item item : items) {
-            add(item);
-        }
-    }
-
-    /**
-     * Writes the statistics as an annotation.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    public final void writeAnnotation(AnnotatedOutput out) {
-        if (dataMap.size() == 0) {
-            return;
-        }
-
-        out.annotate(0, "\nstatistics:\n");
-
-        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();
-
-        for (Data data : dataMap.values()) {
-            sortedData.put(data.name, data);
-        }
-
-        for (Data data : sortedData.values()) {
-            data.writeAnnotation(out);
-        }
-    }
-
-    public String toHuman() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("Statistics:\n");
-
-        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();
-
-        for (Data data : dataMap.values()) {
-            sortedData.put(data.name, data);
-        }
-
-        for (Data data : sortedData.values()) {
-            sb.append(data.toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Statistical data about a particular class.
-     */
-    private static class Data {
-        /** {@code non-null;} name to use as a label */
-        private final String name;
-
-        /** {@code >= 0;} number of instances */
-        private int count;
-
-        /** {@code >= 0;} total size of instances in bytes */
-        private int totalSize;
-
-        /** {@code >= 0;} largest size of any individual item */
-        private int largestSize;
-
-        /** {@code >= 0;} smallest size of any individual item */
-        private int smallestSize;
-
-        /**
-         * Constructs an instance for the given item.
-         *
-         * @param item {@code non-null;} item in question
-         * @param name {@code non-null;} type name to use
-         */
-        public Data(Item item, String name) {
-            int size = item.writeSize();
-
-            this.name = name;
-            this.count = 1;
-            this.totalSize = size;
-            this.largestSize = size;
-            this.smallestSize = size;
-        }
-
-        /**
-         * Incorporates a new item. This assumes the type name matches.
-         *
-         * @param item {@code non-null;} item to incorporate
-         */
-        public void add(Item item) {
-            int size = item.writeSize();
-
-            count++;
-            totalSize += size;
-
-            if (size > largestSize) {
-                largestSize = size;
-            }
-
-            if (size < smallestSize) {
-                smallestSize = size;
-            }
-        }
-
-        /**
-         * Writes this instance as an annotation.
-         *
-         * @param out {@code non-null;} where to write to
-         */
-        public void writeAnnotation(AnnotatedOutput out) {
-            out.annotate(toHuman());
-        }
-
-        /**
-         * Generates a human-readable string for this data item.
-         *
-         * @return string for human consumption.
-         */
-        public String toHuman() {
-            StringBuilder sb = new StringBuilder();
-
-            sb.append("  " + name + ": " +
-                         count + " item" + (count == 1 ? "" : "s") + "; " +
-                         totalSize + " bytes total\n");
-
-            if (smallestSize == largestSize) {
-                sb.append("    " + smallestSize + " bytes/item\n");
-            } else {
-                int average = totalSize / count;
-                sb.append("    " + smallestSize + ".." + largestSize +
-                             " bytes/item; average " + average + "\n");
-            }
-
-            return sb.toString();
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/StringDataItem.java b/dx/src/main/java/com/android/dx/dex/file/StringDataItem.java
deleted file mode 100644
index e85a823..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/StringDataItem.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.ByteArray;
-import com.android.dx.util.Hex;
-import com.android.dx.util.Leb128Utils;
-
-/**
- * Representation of string data for a particular string, in a Dalvik file.
- */
-public final class StringDataItem extends OffsettedItem {
-    /** {@code non-null;} the string value */
-    private final CstString value;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param value {@code non-null;} the string value
-     */
-    public StringDataItem(CstString value) {
-        super(1, writeSize(value));
-
-        this.value = value;
-    }
-
-    /**
-     * Gets the write size for a given value.
-     *
-     * @param value {@code non-null;} the string value
-     * @return {@code >= 2}; the write size, in bytes
-     */
-    private static int writeSize(CstString value) {
-        int utf16Size = value.getUtf16Size();
-
-        // The +1 is for the '\0' termination byte.
-        return Leb128Utils.unsignedLeb128Size(utf16Size)
-            + value.getUtf8Size() + 1;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_STRING_DATA_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        // Nothing to do here.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo0(DexFile file, AnnotatedOutput out) {
-        ByteArray bytes = value.getBytes();
-        int utf16Size = value.getUtf16Size();
-
-        if (out.annotates()) {
-            out.annotate(Leb128Utils.unsignedLeb128Size(utf16Size),
-                    "utf16_size: " + Hex.u4(utf16Size));
-            out.annotate(bytes.size() + 1, value.toQuoted());
-        }
-
-        out.writeUleb128(utf16Size);
-        out.write(bytes);
-        out.writeByte(0);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        return value.toQuoted();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(OffsettedItem other) {
-        StringDataItem otherData = (StringDataItem) other;
-
-        return value.compareTo(otherData.value);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/StringIdItem.java b/dx/src/main/java/com/android/dx/dex/file/StringIdItem.java
deleted file mode 100644
index 533427d..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/StringIdItem.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.SizeOf;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Representation of a string inside a Dalvik file.
- */
-public final class StringIdItem
-        extends IndexedItem implements Comparable {
-    /** {@code non-null;} the string value */
-    private final CstString value;
-
-    /** {@code null-ok;} associated string data object, if known */
-    private StringDataItem data;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param value {@code non-null;} the string value
-     */
-    public StringIdItem(CstString value) {
-        if (value == null) {
-            throw new NullPointerException("value == null");
-        }
-
-        this.value = value;
-        this.data = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof StringIdItem)) {
-            return false;
-        }
-
-        StringIdItem otherString = (StringIdItem) other;
-        return value.equals(otherString.value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return value.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(Object other) {
-        StringIdItem otherString = (StringIdItem) other;
-        return value.compareTo(otherString.value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_STRING_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.STRING_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        if (data == null) {
-            // The string data hasn't yet been added, so add it.
-            MixedItemSection stringData = file.getStringData();
-            data = new StringDataItem(value);
-            stringData.add(data);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        int dataOff = data.getAbsoluteOffset();
-
-        if (out.annotates()) {
-            out.annotate(0, indexString() + ' ' + value.toQuoted(100));
-            out.annotate(4, "  string_data_off: " + Hex.u4(dataOff));
-        }
-
-        out.writeInt(dataOff);
-    }
-
-    /**
-     * Gets the string value.
-     *
-     * @return {@code non-null;} the value
-     */
-    public CstString getValue() {
-        return value;
-    }
-
-    /**
-     * Gets the associated data object for this instance, if known.
-     *
-     * @return {@code null-ok;} the associated data object or {@code null}
-     * if not yet known
-     */
-    public StringDataItem getData() {
-        return data;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/StringIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/StringIdsSection.java
deleted file mode 100644
index 2f7c40b..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/StringIdsSection.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Strings list section of a {@code .dex} file.
- */
-public final class StringIdsSection
-        extends UniformItemSection {
-    /**
-     * {@code non-null;} map from string constants to {@link
-     * StringIdItem} instances
-     */
-    private final TreeMap<CstString, StringIdItem> strings;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public StringIdsSection(DexFile file) {
-        super("string_ids", file, 4);
-
-        strings = new TreeMap<CstString, StringIdItem>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return strings.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        throwIfNotPrepared();
-
-        IndexedItem result = strings.get((CstString) cst);
-
-        if (result == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = strings.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (out.annotates()) {
-            out.annotate(4, "string_ids_size: " + Hex.u4(sz));
-            out.annotate(4, "string_ids_off:  " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param string {@code non-null;} the string to intern, as a regular Java
-     * {@code String}
-     * @return {@code non-null;} the interned string
-     */
-    public StringIdItem intern(String string) {
-        return intern(new StringIdItem(new CstString(string)));
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param string {@code non-null;} the string to intern, as a constant
-     * @return {@code non-null;} the interned string
-     */
-    public StringIdItem intern(CstString string) {
-        return intern(new StringIdItem(string));
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param string {@code non-null;} the string to intern
-     * @return {@code non-null;} the interned string
-     */
-    public StringIdItem intern(StringIdItem string) {
-        if (string == null) {
-            throw new NullPointerException("string == null");
-        }
-
-        throwIfPrepared();
-
-        CstString value = string.getValue();
-        StringIdItem already = strings.get(value);
-
-        if (already != null) {
-            return already;
-        }
-
-        strings.put(value, string);
-        return string;
-    }
-
-    /**
-     * Interns the components of a name-and-type into this instance.
-     *
-     * @param nat {@code non-null;} the name-and-type
-     */
-    public void intern(CstNat nat) {
-        intern(nat.getName());
-        intern(nat.getDescriptor());
-    }
-
-    /**
-     * Gets the index of the given string, which must have been added
-     * to this instance.
-     *
-     * @param string {@code non-null;} the string to look up
-     * @return {@code >= 0;} the string's index
-     */
-    public int indexOf(CstString string) {
-        if (string == null) {
-            throw new NullPointerException("string == null");
-        }
-
-        throwIfNotPrepared();
-
-        StringIdItem s = strings.get(string);
-
-        if (s == null) {
-            throw new IllegalArgumentException("not found");
-        }
-
-        return s.getIndex();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        int idx = 0;
-
-        for (StringIdItem s : strings.values()) {
-            s.setIndex(idx);
-            idx++;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/TypeIdItem.java b/dx/src/main/java/com/android/dx/dex/file/TypeIdItem.java
deleted file mode 100644
index 04be2a1..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/TypeIdItem.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.dex.SizeOf;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Representation of a type reference inside a Dalvik file.
- */
-public final class TypeIdItem extends IdItem {
-    /**
-     * Constructs an instance.
-     *
-     * @param type {@code non-null;} the constant for the type
-     */
-    public TypeIdItem(CstType type) {
-        super(type);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_TYPE_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int writeSize() {
-        return SizeOf.TYPE_ID_ITEM;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        file.getStringIds().intern(getDefiningClass().getDescriptor());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeTo(DexFile file, AnnotatedOutput out) {
-        CstType type = getDefiningClass();
-        CstString descriptor = type.getDescriptor();
-        int idx = file.getStringIds().indexOf(descriptor);
-
-        if (out.annotates()) {
-            out.annotate(0, indexString() + ' ' + descriptor.toHuman());
-            out.annotate(4, "  descriptor_idx: " + Hex.u4(idx));
-        }
-
-        out.writeInt(idx);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/TypeIdsSection.java b/dx/src/main/java/com/android/dx/dex/file/TypeIdsSection.java
deleted file mode 100644
index bcc8250..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/TypeIdsSection.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.Collection;
-import java.util.TreeMap;
-
-/**
- * Type identifiers list section of a {@code .dex} file.
- */
-public final class TypeIdsSection extends UniformItemSection {
-    /**
-     * {@code non-null;} map from types to {@link TypeIdItem} instances
-     */
-    private final TreeMap<Type, TypeIdItem> typeIds;
-
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param file {@code non-null;} file that this instance is part of
-     */
-    public TypeIdsSection(DexFile file) {
-        super("type_ids", file, 4);
-
-        typeIds = new TreeMap<Type, TypeIdItem>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<? extends Item> items() {
-        return typeIds.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public IndexedItem get(Constant cst) {
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        throwIfNotPrepared();
-
-        Type type = ((CstType) cst).getClassType();
-        IndexedItem result = typeIds.get(type);
-
-        if (result == null) {
-            throw new IllegalArgumentException("not found: " + cst);
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes the portion of the file header that refers to this instance.
-     *
-     * @param out {@code non-null;} where to write
-     */
-    public void writeHeaderPart(AnnotatedOutput out) {
-        throwIfNotPrepared();
-
-        int sz = typeIds.size();
-        int offset = (sz == 0) ? 0 : getFileOffset();
-
-        if (sz > 65536) {
-            throw new UnsupportedOperationException("too many type ids");
-        }
-
-        if (out.annotates()) {
-            out.annotate(4, "type_ids_size:   " + Hex.u4(sz));
-            out.annotate(4, "type_ids_off:    " + Hex.u4(offset));
-        }
-
-        out.writeInt(sz);
-        out.writeInt(offset);
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param type {@code non-null;} the type to intern
-     * @return {@code non-null;} the interned reference
-     */
-    public TypeIdItem intern(Type type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        throwIfPrepared();
-
-        TypeIdItem result = typeIds.get(type);
-
-        if (result == null) {
-            result = new TypeIdItem(new CstType(type));
-            typeIds.put(type, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Interns an element into this instance.
-     *
-     * @param type {@code non-null;} the type to intern
-     * @return {@code non-null;} the interned reference
-     */
-    public TypeIdItem intern(CstType type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        throwIfPrepared();
-
-        Type typePerSe = type.getClassType();
-        TypeIdItem result = typeIds.get(typePerSe);
-
-        if (result == null) {
-            result = new TypeIdItem(type);
-            typeIds.put(typePerSe, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the index of the given type, which must have
-     * been added to this instance.
-     *
-     * @param type {@code non-null;} the type to look up
-     * @return {@code >= 0;} the reference's index
-     */
-    public int indexOf(Type type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        throwIfNotPrepared();
-
-        TypeIdItem item = typeIds.get(type);
-
-        if (item == null) {
-            throw new IllegalArgumentException("not found: " + type);
-        }
-
-        return item.getIndex();
-    }
-
-    /**
-     * Gets the index of the given type, which must have
-     * been added to this instance.
-     *
-     * @param type {@code non-null;} the type to look up
-     * @return {@code >= 0;} the reference's index
-     */
-    public int indexOf(CstType type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        return indexOf(type.getClassType());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void orderItems() {
-        int idx = 0;
-
-        for (Object i : items()) {
-            ((TypeIdItem) i).setIndex(idx);
-            idx++;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/TypeListItem.java b/dx/src/main/java/com/android/dx/dex/file/TypeListItem.java
deleted file mode 100644
index b815dd3..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/TypeListItem.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-/**
- * Representation of a list of class references.
- */
-public final class TypeListItem extends OffsettedItem {
-    /** alignment requirement */
-    private static final int ALIGNMENT = 4;
-
-    /** element size in bytes */
-    private static final int ELEMENT_SIZE = 2;
-
-    /** header size in bytes */
-    private static final int HEADER_SIZE = 4;
-
-    /** {@code non-null;} the actual list */
-    private final TypeList list;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param list {@code non-null;} the actual list
-     */
-    public TypeListItem(TypeList list) {
-        super(ALIGNMENT, (list.size() * ELEMENT_SIZE) + HEADER_SIZE);
-
-        this.list = list;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return StdTypeList.hashContents(list);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return ItemType.TYPE_TYPE_LIST;
-    }
-
-    /** {@inheritDoc} */
-    public void addContents(DexFile file) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        int sz = list.size();
-
-        for (int i = 0; i < sz; i++) {
-            typeIds.intern(list.getType(i));
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toHuman() {
-        throw new RuntimeException("unsupported");
-    }
-
-    /**
-     * Gets the underlying list.
-     *
-     * @return {@code non-null;} the list
-     */
-    public TypeList getList() {
-        return list;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        int sz = list.size();
-
-        if (out.annotates()) {
-            out.annotate(0, offsetString() + " type_list");
-            out.annotate(HEADER_SIZE, "  size: " + Hex.u4(sz));
-            for (int i = 0; i < sz; i++) {
-                Type one = list.getType(i);
-                int idx = typeIds.indexOf(one);
-                out.annotate(ELEMENT_SIZE,
-                             "  " + Hex.u2(idx) + " // " + one.toHuman());
-            }
-        }
-
-        out.writeInt(sz);
-
-        for (int i = 0; i < sz; i++) {
-            out.writeShort(typeIds.indexOf(list.getType(i)));
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(OffsettedItem other) {
-        TypeList thisList = this.list;
-        TypeList otherList = ((TypeListItem) other).list;
-
-        return StdTypeList.compareContents(thisList, otherList);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/UniformItemSection.java b/dx/src/main/java/com/android/dx/dex/file/UniformItemSection.java
deleted file mode 100644
index d8c09ab..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/UniformItemSection.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.Collection;
-
-/**
- * A section of a {@code .dex} file which consists of a sequence of
- * {@link Item} objects. Each of the items must have the same size in
- * the output.
- */
-public abstract class UniformItemSection extends Section {
-    /**
-     * Constructs an instance. The file offset is initially unknown.
-     *
-     * @param name {@code null-ok;} the name of this instance, for annotation
-     * purposes
-     * @param file {@code non-null;} file that this instance is part of
-     * @param alignment {@code > 0;} alignment requirement for the final output;
-     * must be a power of 2
-     */
-    public UniformItemSection(String name, DexFile file, int alignment) {
-        super(name, file, alignment);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int writeSize() {
-        Collection<? extends Item> items = items();
-        int sz = items.size();
-
-        if (sz == 0) {
-            return 0;
-        }
-
-        // Since each item has to be the same size, we can pick any.
-        return sz * items.iterator().next().writeSize();
-    }
-
-    /**
-     * Gets the item corresponding to the given {@link Constant}. This
-     * will throw an exception if the constant is not found, including
-     * if this instance isn't the sort that maps constants to {@link
-     * IndexedItem} instances.
-     *
-     * @param cst {@code non-null;} constant to look for
-     * @return {@code non-null;} the corresponding item found in this instance
-     */
-    public abstract IndexedItem get(Constant cst);
-
-    /** {@inheritDoc} */
-    @Override
-    protected final void prepare0() {
-        DexFile file = getFile();
-
-        orderItems();
-
-        for (Item one : items()) {
-            one.addContents(file);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final void writeTo0(AnnotatedOutput out) {
-        DexFile file = getFile();
-        int alignment = getAlignment();
-
-        for (Item one : items()) {
-            one.writeTo(file, out);
-            out.alignTo(alignment);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int getAbsoluteItemOffset(Item item) {
-        /*
-         * Since all items must be the same size, we can use the size
-         * of the one we're given to calculate its offset.
-         */
-        IndexedItem ii = (IndexedItem) item;
-        int relativeOffset = ii.getIndex() * ii.writeSize();
-
-        return getAbsoluteOffset(relativeOffset);
-    }
-
-    /**
-     * Alters or picks the order for items in this instance if desired,
-     * so that subsequent calls to {@link #items} will yield a
-     * so-ordered collection. If the items in this instance are indexed,
-     * then this method should also assign indices.
-     */
-    protected abstract void orderItems();
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/UniformListItem.java b/dx/src/main/java/com/android/dx/dex/file/UniformListItem.java
deleted file mode 100644
index 88919c7..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/UniformListItem.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2007 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.dex.file;
-
-import com.android.dx.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Class that represents a contiguous list of uniform items. Each
- * item in the list, in particular, must have the same write size and
- * alignment.
- *
- * <p>This class inherits its alignment from its items, bumped up to
- * {@code 4} if the items have a looser alignment requirement. If
- * it is more than {@code 4}, then there will be a gap after the
- * output list size (which is four bytes) and before the first item.</p>
- *
- * @param <T> type of element contained in an instance
- */
-public final class UniformListItem<T extends OffsettedItem>
-        extends OffsettedItem {
-    /** the size of the list header */
-    private static final int HEADER_SIZE = 4;
-
-    /** {@code non-null;} the item type */
-    private final ItemType itemType;
-
-    /** {@code non-null;} the contents */
-    private final List<T> items;
-
-    /**
-     * Constructs an instance. It is illegal to modify the given list once
-     * it is used to construct an instance of this class.
-     *
-     * @param itemType {@code non-null;} the type of the item
-     * @param items {@code non-null and non-empty;} list of items to represent
-     */
-    public UniformListItem(ItemType itemType, List<T> items) {
-        super(getAlignment(items), writeSize(items));
-
-        if (itemType == null) {
-            throw new NullPointerException("itemType == null");
-        }
-
-        this.items = items;
-        this.itemType = itemType;
-    }
-
-    /**
-     * Helper for {@link #UniformListItem}, which returns the alignment
-     * requirement implied by the given list. See the header comment for
-     * more details.
-     *
-     * @param items {@code non-null;} list of items being represented
-     * @return {@code >= 4;} the alignment requirement
-     */
-    private static int getAlignment(List<? extends OffsettedItem> items) {
-        try {
-            // Since they all must have the same alignment, any one will do.
-            return Math.max(HEADER_SIZE, items.get(0).getAlignment());
-        } catch (IndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("items.size() == 0");
-        } catch (NullPointerException ex) {
-            // Translate the exception.
-            throw new NullPointerException("items == null");
-        }
-    }
-
-    /**
-     * Calculates the write size for the given list.
-     *
-     * @param items {@code non-null;} the list in question
-     * @return {@code >= 0;} the write size
-     */
-    private static int writeSize(List<? extends OffsettedItem> items) {
-        /*
-         * This class assumes all included items are the same size,
-         * an assumption which is verified in place0().
-         */
-        OffsettedItem first = items.get(0);
-        return (items.size() * first.writeSize()) + getAlignment(items);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public ItemType itemType() {
-        return itemType;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append(getClass().getName());
-        sb.append(items);
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addContents(DexFile file) {
-        for (OffsettedItem i : items) {
-            i.addContents(file);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final String toHuman() {
-        StringBuffer sb = new StringBuffer(100);
-        boolean first = true;
-
-        sb.append("{");
-
-        for (OffsettedItem i : items) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            sb.append(i.toHuman());
-        }
-
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     * Gets the underlying list of items.
-     *
-     * @return {@code non-null;} the list
-     */
-    public final List<T> getItems() {
-        return items;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void place0(Section addedTo, int offset) {
-        offset += headerSize();
-
-        boolean first = true;
-        int theSize = -1;
-        int theAlignment = -1;
-
-        for (OffsettedItem i : items) {
-            int size = i.writeSize();
-            if (first) {
-                theSize = size;
-                theAlignment = i.getAlignment();
-                first = false;
-            } else {
-                if (size != theSize) {
-                    throw new UnsupportedOperationException(
-                            "item size mismatch");
-                }
-                if (i.getAlignment() != theAlignment) {
-                    throw new UnsupportedOperationException(
-                            "item alignment mismatch");
-                }
-            }
-
-            offset = i.place(addedTo, offset) + size;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void writeTo0(DexFile file, AnnotatedOutput out) {
-        int size = items.size();
-
-        if (out.annotates()) {
-            out.annotate(0, offsetString() + " " + typeName());
-            out.annotate(4, "  size: " + Hex.u4(size));
-        }
-
-        out.writeInt(size);
-
-        for (OffsettedItem i : items) {
-            i.writeTo(file, out);
-        }
-    }
-
-    /**
-     * Get the size of the header of this list.
-     *
-     * @return {@code >= 0;} the header size
-     */
-    private int headerSize() {
-        /*
-         * Because of how this instance was set up, this is the same
-         * as the alignment.
-         */
-        return getAlignment();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/dex/file/ValueEncoder.java b/dx/src/main/java/com/android/dx/dex/file/ValueEncoder.java
deleted file mode 100644
index 9c433a3..0000000
--- a/dx/src/main/java/com/android/dx/dex/file/ValueEncoder.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2008 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.dex.file;
-
-import com.android.dx.rop.annotation.Annotation;
-import com.android.dx.rop.annotation.NameValuePair;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstAnnotation;
-import com.android.dx.rop.cst.CstArray;
-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.CstEnumRef;
-import com.android.dx.rop.cst.CstFieldRef;
-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.CstLiteralBits;
-import com.android.dx.rop.cst.CstLong;
-import com.android.dx.rop.cst.CstMethodRef;
-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.util.AnnotatedOutput;
-import com.android.dx.util.Hex;
-import java.util.Collection;
-
-/**
- * Handler for writing out {@code encoded_values} and parts
- * thereof.
- */
-public final class ValueEncoder {
-    /** annotation value type constant: {@code byte} */
-    private static final int VALUE_BYTE = 0x00;
-
-    /** annotation value type constant: {@code short} */
-    private static final int VALUE_SHORT = 0x02;
-
-    /** annotation value type constant: {@code char} */
-    private static final int VALUE_CHAR = 0x03;
-
-    /** annotation value type constant: {@code int} */
-    private static final int VALUE_INT = 0x04;
-
-    /** annotation value type constant: {@code long} */
-    private static final int VALUE_LONG = 0x06;
-
-    /** annotation value type constant: {@code float} */
-    private static final int VALUE_FLOAT = 0x10;
-
-    /** annotation value type constant: {@code double} */
-    private static final int VALUE_DOUBLE = 0x11;
-
-    /** annotation value type constant: {@code string} */
-    private static final int VALUE_STRING = 0x17;
-
-    /** annotation value type constant: {@code type} */
-    private static final int VALUE_TYPE = 0x18;
-
-    /** annotation value type constant: {@code field} */
-    private static final int VALUE_FIELD = 0x19;
-
-    /** annotation value type constant: {@code method} */
-    private static final int VALUE_METHOD = 0x1a;
-
-    /** annotation value type constant: {@code enum} */
-    private static final int VALUE_ENUM = 0x1b;
-
-    /** annotation value type constant: {@code array} */
-    private static final int VALUE_ARRAY = 0x1c;
-
-    /** annotation value type constant: {@code annotation} */
-    private static final int VALUE_ANNOTATION = 0x1d;
-
-    /** annotation value type constant: {@code null} */
-    private static final int VALUE_NULL = 0x1e;
-
-    /** annotation value type constant: {@code boolean} */
-    private static final int VALUE_BOOLEAN = 0x1f;
-
-    /** {@code non-null;} file being written */
-    private final DexFile file;
-
-    /** {@code non-null;} output stream to write to */
-    private final AnnotatedOutput out;
-
-    /**
-     * Construct an instance.
-     *
-     * @param file {@code non-null;} file being written
-     * @param out {@code non-null;} output stream to write to
-     */
-    public ValueEncoder(DexFile file, AnnotatedOutput out) {
-        if (file == null) {
-            throw new NullPointerException("file == null");
-        }
-
-        if (out == null) {
-            throw new NullPointerException("out == null");
-        }
-
-        this.file = file;
-        this.out = out;
-    }
-
-    /**
-     * Writes out the encoded form of the given constant.
-     *
-     * @param cst {@code non-null;} the constant to write
-     */
-    public void writeConstant(Constant cst) {
-        int type = constantToValueType(cst);
-        int arg;
-
-        switch (type) {
-            case VALUE_BYTE:
-            case VALUE_SHORT:
-            case VALUE_INT:
-            case VALUE_LONG: {
-                long value = ((CstLiteralBits) cst).getLongBits();
-                writeSignedIntegralValue(type, value);
-                break;
-            }
-            case VALUE_CHAR: {
-                long value = ((CstLiteralBits) cst).getLongBits();
-                writeUnsignedIntegralValue(type, value);
-                break;
-            }
-            case VALUE_FLOAT: {
-                // Shift value left 32 so that right-zero-extension works.
-                long value = ((CstFloat) cst).getLongBits() << 32;
-                writeRightZeroExtendedValue(type, value);
-                break;
-            }
-            case VALUE_DOUBLE: {
-                long value = ((CstDouble) cst).getLongBits();
-                writeRightZeroExtendedValue(type, value);
-                break;
-            }
-            case VALUE_STRING: {
-                int index = file.getStringIds().indexOf((CstString) cst);
-                writeUnsignedIntegralValue(type, (long) index);
-                break;
-            }
-            case VALUE_TYPE: {
-                int index = file.getTypeIds().indexOf((CstType) cst);
-                writeUnsignedIntegralValue(type, (long) index);
-                break;
-            }
-            case VALUE_FIELD: {
-                int index = file.getFieldIds().indexOf((CstFieldRef) cst);
-                writeUnsignedIntegralValue(type, (long) index);
-                break;
-            }
-            case VALUE_METHOD: {
-                int index = file.getMethodIds().indexOf((CstMethodRef) cst);
-                writeUnsignedIntegralValue(type, (long) index);
-                break;
-            }
-            case VALUE_ENUM: {
-                CstFieldRef fieldRef = ((CstEnumRef) cst).getFieldRef();
-                int index = file.getFieldIds().indexOf(fieldRef);
-                writeUnsignedIntegralValue(type, (long) index);
-                break;
-            }
-            case VALUE_ARRAY: {
-                out.writeByte(type);
-                writeArray((CstArray) cst, false);
-                break;
-            }
-            case VALUE_ANNOTATION: {
-                out.writeByte(type);
-                writeAnnotation(((CstAnnotation) cst).getAnnotation(),
-                        false);
-                break;
-            }
-            case VALUE_NULL: {
-                out.writeByte(type);
-                break;
-            }
-            case VALUE_BOOLEAN: {
-                int value = ((CstBoolean) cst).getIntBits();
-                out.writeByte(type | (value << 5));
-                break;
-            }
-            default: {
-                throw new RuntimeException("Shouldn't happen");
-            }
-        }
-    }
-
-    /**
-     * Gets the value type for the given constant.
-     *
-     * @param cst {@code non-null;} the constant
-     * @return the value type; one of the {@code VALUE_*} constants
-     * defined by this class
-     */
-    private static int constantToValueType(Constant cst) {
-        /*
-         * TODO: Constant should probable have an associated enum, so this
-         * can be a switch().
-         */
-        if (cst instanceof CstByte) {
-            return VALUE_BYTE;
-        } else if (cst instanceof CstShort) {
-            return VALUE_SHORT;
-        } else if (cst instanceof CstChar) {
-            return VALUE_CHAR;
-        } else if (cst instanceof CstInteger) {
-            return VALUE_INT;
-        } else if (cst instanceof CstLong) {
-            return VALUE_LONG;
-        } else if (cst instanceof CstFloat) {
-            return VALUE_FLOAT;
-        } else if (cst instanceof CstDouble) {
-            return VALUE_DOUBLE;
-        } else if (cst instanceof CstString) {
-            return VALUE_STRING;
-        } else if (cst instanceof CstType) {
-            return VALUE_TYPE;
-        } else if (cst instanceof CstFieldRef) {
-            return VALUE_FIELD;
-        } else if (cst instanceof CstMethodRef) {
-            return VALUE_METHOD;
-        } else if (cst instanceof CstEnumRef) {
-            return VALUE_ENUM;
-        } else if (cst instanceof CstArray) {
-            return VALUE_ARRAY;
-        } else if (cst instanceof CstAnnotation) {
-            return VALUE_ANNOTATION;
-        } else if (cst instanceof CstKnownNull) {
-            return VALUE_NULL;
-        } else if (cst instanceof CstBoolean) {
-            return VALUE_BOOLEAN;
-        } else {
-            throw new RuntimeException("Shouldn't happen");
-        }
-    }
-
-    /**
-     * Writes out the encoded form of the given array, that is, as
-     * an {@code encoded_array} and not including a
-     * {@code value_type} prefix. If the output stream keeps
-     * (debugging) annotations and {@code topLevel} is
-     * {@code true}, then this method will write (debugging)
-     * annotations.
-     *
-     * @param array {@code non-null;} array instance to write
-     * @param topLevel {@code true} iff the given annotation is the
-     * top-level annotation or {@code false} if it is a sub-annotation
-     * of some other annotation
-     */
-    public void writeArray(CstArray array, boolean topLevel) {
-        boolean annotates = topLevel && out.annotates();
-        CstArray.List list = ((CstArray) array).getList();
-        int size = list.size();
-
-        if (annotates) {
-            out.annotate("  size: " + Hex.u4(size));
-        }
-
-        out.writeUleb128(size);
-
-        for (int i = 0; i < size; i++) {
-            Constant cst = list.get(i);
-            if (annotates) {
-                out.annotate("  [" + Integer.toHexString(i) + "] " +
-                        constantToHuman(cst));
-            }
-            writeConstant(cst);
-        }
-
-        if (annotates) {
-            out.endAnnotation();
-        }
-    }
-
-    /**
-     * Writes out the encoded form of the given annotation, that is,
-     * as an {@code encoded_annotation} and not including a
-     * {@code value_type} prefix. If the output stream keeps
-     * (debugging) annotations and {@code topLevel} is
-     * {@code true}, then this method will write (debugging)
-     * annotations.
-     *
-     * @param annotation {@code non-null;} annotation instance to write
-     * @param topLevel {@code true} iff the given annotation is the
-     * top-level annotation or {@code false} if it is a sub-annotation
-     * of some other annotation
-     */
-    public void writeAnnotation(Annotation annotation, boolean topLevel) {
-        boolean annotates = topLevel && out.annotates();
-        StringIdsSection stringIds = file.getStringIds();
-        TypeIdsSection typeIds = file.getTypeIds();
-
-        CstType type = annotation.getType();
-        int typeIdx = typeIds.indexOf(type);
-
-        if (annotates) {
-            out.annotate("  type_idx: " + Hex.u4(typeIdx) + " // " +
-                    type.toHuman());
-        }
-
-        out.writeUleb128(typeIds.indexOf(annotation.getType()));
-
-        Collection<NameValuePair> pairs = annotation.getNameValuePairs();
-        int size = pairs.size();
-
-        if (annotates) {
-            out.annotate("  size: " + Hex.u4(size));
-        }
-
-        out.writeUleb128(size);
-
-        int at = 0;
-        for (NameValuePair pair : pairs) {
-            CstString name = pair.getName();
-            int nameIdx = stringIds.indexOf(name);
-            Constant value = pair.getValue();
-
-            if (annotates) {
-                out.annotate(0, "  elements[" + at + "]:");
-                at++;
-                out.annotate("    name_idx: " + Hex.u4(nameIdx) + " // " +
-                        name.toHuman());
-            }
-
-            out.writeUleb128(nameIdx);
-
-            if (annotates) {
-                out.annotate("    value: " + constantToHuman(value));
-            }
-
-            writeConstant(value);
-        }
-
-        if (annotates) {
-            out.endAnnotation();
-        }
-    }
-
-    /**
-     * Gets the colloquial type name and human form of the type of the
-     * given constant, when used as an encoded value.
-     *
-     * @param cst {@code non-null;} the constant
-     * @return {@code non-null;} its type name and human form
-     */
-    public static String constantToHuman(Constant cst) {
-        int type = constantToValueType(cst);
-
-        if (type == VALUE_NULL) {
-            return "null";
-        }
-
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(cst.typeName());
-        sb.append(' ');
-        sb.append(cst.toHuman());
-
-        return sb.toString();
-    }
-
-    /**
-     * Helper for {@link #writeConstant}, which writes out the value
-     * for any signed integral type.
-     *
-     * @param type the type constant
-     * @param value {@code long} bits of the value
-     */
-    private void writeSignedIntegralValue(int type, long value) {
-        /*
-         * Figure out how many bits are needed to represent the value,
-         * including a sign bit: The bit count is subtracted from 65
-         * and not 64 to account for the sign bit. The xor operation
-         * has the effect of leaving non-negative values alone and
-         * unary complementing negative values (so that a leading zero
-         * count always returns a useful number for our present
-         * purpose).
-         */
-        int requiredBits =
-            65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-    /**
-     * Helper for {@link #writeConstant}, which writes out the value
-     * for any unsigned integral type.
-     *
-     * @param type the type constant
-     * @param value {@code long} bits of the value
-     */
-    private void writeUnsignedIntegralValue(int type, long value) {
-        // Figure out how many bits are needed to represent the value.
-        int requiredBits = 64 - Long.numberOfLeadingZeros(value);
-        if (requiredBits == 0) {
-            requiredBits = 1;
-        }
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-    /**
-     * Helper for {@link #writeConstant}, which writes out a
-     * right-zero-extended value.
-     *
-     * @param type the type constant
-     * @param value {@code long} bits of the value
-     */
-    private void writeRightZeroExtendedValue(int type, long value) {
-        // Figure out how many bits are needed to represent the value.
-        int requiredBits = 64 - Long.numberOfTrailingZeros(value);
-        if (requiredBits == 0) {
-            requiredBits = 1;
-        }
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        // Scootch the first bits to be written down to the low-order bits.
-        value >>= 64 - (requiredBytes * 8);
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-
-    /**
-     * Helper for {@code addContents()} methods, which adds
-     * contents for a particular {@link Annotation}, calling itself
-     * recursively should it encounter a nested annotation.
-     *
-     * @param file {@code non-null;} the file to add to
-     * @param annotation {@code non-null;} the annotation to add contents for
-     */
-    public static void addContents(DexFile file, Annotation annotation) {
-        TypeIdsSection typeIds = file.getTypeIds();
-        StringIdsSection stringIds = file.getStringIds();
-
-        typeIds.intern(annotation.getType());
-
-        for (NameValuePair pair : annotation.getNameValuePairs()) {
-            stringIds.intern(pair.getName());
-            addContents(file, pair.getValue());
-        }
-    }
-
-    /**
-     * Helper for {@code addContents()} methods, which adds
-     * contents for a particular constant, calling itself recursively
-     * should it encounter a {@link CstArray} and calling {@link
-     * #addContents(DexFile,Annotation)} recursively should it
-     * encounter a {@link CstAnnotation}.
-     *
-     * @param file {@code non-null;} the file to add to
-     * @param cst {@code non-null;} the constant to add contents for
-     */
-    public static void addContents(DexFile file, Constant cst) {
-        if (cst instanceof CstAnnotation) {
-            addContents(file, ((CstAnnotation) cst).getAnnotation());
-        } else if (cst instanceof CstArray) {
-            CstArray.List list = ((CstArray) cst).getList();
-            int size = list.size();
-            for (int i = 0; i < size; i++) {
-                addContents(file, list.get(i));
-            }
-        } else {
-            file.internIfAppropriate(cst);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/Code.java b/dx/src/main/java/com/android/dx/io/Code.java
deleted file mode 100644
index ba95d1b..0000000
--- a/dx/src/main/java/com/android/dx/io/Code.java
+++ /dev/null
@@ -1,114 +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.io;
-
-public final class Code {
-    private final int registersSize;
-    private final int insSize;
-    private final int outsSize;
-    private final int debugInfoOffset;
-    private final short[] instructions;
-    private final Try[] tries;
-    private final CatchHandler[] catchHandlers;
-
-    public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,
-            short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {
-        this.registersSize = registersSize;
-        this.insSize = insSize;
-        this.outsSize = outsSize;
-        this.debugInfoOffset = debugInfoOffset;
-        this.instructions = instructions;
-        this.tries = tries;
-        this.catchHandlers = catchHandlers;
-    }
-
-    public int getRegistersSize() {
-        return registersSize;
-    }
-
-    public int getInsSize() {
-        return insSize;
-    }
-
-    public int getOutsSize() {
-        return outsSize;
-    }
-
-    public int getDebugInfoOffset() {
-        return debugInfoOffset;
-    }
-
-    public short[] getInstructions() {
-        return instructions;
-    }
-
-    public Try[] getTries() {
-        return tries;
-    }
-
-    public CatchHandler[] getCatchHandlers() {
-        return catchHandlers;
-    }
-
-    public static class Try {
-        final int startAddress;
-        final int instructionCount;
-        final int handlerOffset;
-
-        Try(int startAddress, int instructionCount, int handlerOffset) {
-            this.startAddress = startAddress;
-            this.instructionCount = instructionCount;
-            this.handlerOffset = handlerOffset;
-        }
-
-        public int getStartAddress() {
-            return startAddress;
-        }
-
-        public int getInstructionCount() {
-            return instructionCount;
-        }
-
-        public int getHandlerOffset() {
-            return handlerOffset;
-        }
-    }
-
-    public static class CatchHandler {
-        final int[] typeIndexes;
-        final int[] addresses;
-        final int catchAllAddress;
-
-        public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress) {
-            this.typeIndexes = typeIndexes;
-            this.addresses = addresses;
-            this.catchAllAddress = catchAllAddress;
-        }
-
-        public int[] getTypeIndexes() {
-            return typeIndexes;
-        }
-
-        public int[] getAddresses() {
-            return addresses;
-        }
-
-        public int getCatchAllAddress() {
-            return catchAllAddress;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/CodeReader.java b/dx/src/main/java/com/android/dx/io/CodeReader.java
deleted file mode 100644
index cab1063..0000000
--- a/dx/src/main/java/com/android/dx/io/CodeReader.java
+++ /dev/null
@@ -1,121 +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.io;
-
-import com.android.dx.io.instructions.DecodedInstruction;
-import com.android.dx.util.DexException;
-
-/**
- * Walks through a block of code and calls visitor call backs.
- */
-public final class CodeReader {
-    private Visitor fallbackVisitor = null;
-    private Visitor stringVisitor = null;
-    private Visitor typeVisitor = null;
-    private Visitor fieldVisitor = null;
-    private Visitor methodVisitor = null;
-
-    /**
-     * Sets {@code visitor} as the visitor for all instructions.
-     */
-    public void setAllVisitors(Visitor visitor) {
-        fallbackVisitor = visitor;
-        stringVisitor = visitor;
-        typeVisitor = visitor;
-        fieldVisitor = visitor;
-        methodVisitor = visitor;
-    }
-
-    /**
-     * Sets {@code visitor} as the visitor for all instructions not
-     * otherwise handled.
-     */
-    public void setFallbackVisitor(Visitor visitor) {
-        fallbackVisitor = visitor;
-    }
-
-    /**
-     * Sets {@code visitor} as the visitor for all string instructions.
-     */
-    public void setStringVisitor(Visitor visitor) {
-        stringVisitor = visitor;
-    }
-
-    /**
-     * Sets {@code visitor} as the visitor for all type instructions.
-     */
-    public void setTypeVisitor(Visitor visitor) {
-        typeVisitor = visitor;
-    }
-
-    /**
-     * Sets {@code visitor} as the visitor for all field instructions.
-     */
-    public void setFieldVisitor(Visitor visitor) {
-        fieldVisitor = visitor;
-    }
-
-    /**
-     * Sets {@code visitor} as the visitor for all method instructions.
-     */
-    public void setMethodVisitor(Visitor visitor) {
-        methodVisitor = visitor;
-    }
-
-    public void visitAll(DecodedInstruction[] decodedInstructions)
-            throws DexException {
-        int size = decodedInstructions.length;
-
-        for (int i = 0; i < size; i++) {
-            DecodedInstruction one = decodedInstructions[i];
-            if (one == null) {
-                continue;
-            }
-
-            callVisit(decodedInstructions, one);
-        }
-    }
-
-    public void visitAll(short[] encodedInstructions) throws DexException {
-        DecodedInstruction[] decodedInstructions =
-            DecodedInstruction.decodeAll(encodedInstructions);
-        visitAll(decodedInstructions);
-    }
-
-    private void callVisit(DecodedInstruction[] all, DecodedInstruction one) {
-        Visitor visitor = null;
-
-        switch (OpcodeInfo.getIndexType(one.getOpcode())) {
-            case STRING_REF: visitor = stringVisitor; break;
-            case TYPE_REF:   visitor = typeVisitor;   break;
-            case FIELD_REF:  visitor = fieldVisitor;  break;
-            case METHOD_REF: visitor = methodVisitor; break;
-        }
-
-        if (visitor == null) {
-            visitor = fallbackVisitor;
-        }
-
-        if (visitor != null) {
-            visitor.visit(all, one);
-        }
-    }
-
-    public interface Visitor {
-        void visit(DecodedInstruction[] all, DecodedInstruction one);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/IndexType.java b/dx/src/main/java/com/android/dx/io/IndexType.java
deleted file mode 100644
index bbddfa8..0000000
--- a/dx/src/main/java/com/android/dx/io/IndexType.java
+++ /dev/null
@@ -1,52 +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.io;
-
-/**
- * The various types that an index in a Dalvik instruction might refer to.
- */
-public enum IndexType {
-    /** "Unknown." Used for undefined opcodes. */
-    UNKNOWN,
-
-    /** no index used */
-    NONE,
-
-    /** "It depends." Used for {@code throw-verification-error}. */
-    VARIES,
-
-    /** type reference index */
-    TYPE_REF,
-
-    /** string reference index */
-    STRING_REF,
-
-    /** method reference index */
-    METHOD_REF,
-
-    /** field reference index */
-    FIELD_REF,
-
-    /** inline method index (for inline linked method invocations) */
-    INLINE_METHOD,
-
-    /** direct vtable offset (for static linked method invocations) */
-    VTABLE_OFFSET,
-
-    /** direct field offset (for static linked field accesses) */
-    FIELD_OFFSET;
-}
diff --git a/dx/src/main/java/com/android/dx/io/OpcodeInfo.java b/dx/src/main/java/com/android/dx/io/OpcodeInfo.java
deleted file mode 100644
index c8fcf25..0000000
--- a/dx/src/main/java/com/android/dx/io/OpcodeInfo.java
+++ /dev/null
@@ -1,1460 +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.io;
-
-import com.android.dx.io.instructions.InstructionCodec;
-import com.android.dx.util.Hex;
-
-/**
- * Information about each Dalvik opcode.
- */
-public final class OpcodeInfo {
-    /*
-     * TODO: Merge at least most of the info from the Dops class into
-     * this one.
-     */
-
-    /** non-null; array containing all the information */
-    private static final Info[] INFO;
-
-    /**
-     * pseudo-opcode used for nonstandard formatted "instructions"
-     * (which are mostly not actually instructions, though they do
-     * appear in instruction lists). TODO: Retire the usage of this
-     * constant.
-     */
-    public static final Info SPECIAL_FORMAT =
-        new Info(Opcodes.SPECIAL_FORMAT, "<special>",
-                InstructionCodec.FORMAT_00X, IndexType.NONE);
-
-    // TODO: These payload opcodes should be generated by opcode-gen.
-
-    public static final Info PACKED_SWITCH_PAYLOAD =
-        new Info(Opcodes.PACKED_SWITCH_PAYLOAD, "packed-switch-payload",
-                InstructionCodec.FORMAT_PACKED_SWITCH_PAYLOAD,
-                IndexType.NONE);
-
-    public static final Info SPARSE_SWITCH_PAYLOAD =
-        new Info(Opcodes.SPARSE_SWITCH_PAYLOAD, "sparse-switch-payload",
-                InstructionCodec.FORMAT_SPARSE_SWITCH_PAYLOAD,
-                IndexType.NONE);
-
-    public static final Info FILL_ARRAY_DATA_PAYLOAD =
-        new Info(Opcodes.FILL_ARRAY_DATA_PAYLOAD, "fill-array-data-payload",
-                InstructionCodec.FORMAT_FILL_ARRAY_DATA_PAYLOAD,
-                IndexType.NONE);
-
-    // BEGIN(opcode-info-defs); GENERATED AUTOMATICALLY BY opcode-gen
-    public static final Info NOP =
-        new Info(Opcodes.NOP, "nop",
-            InstructionCodec.FORMAT_10X, IndexType.NONE);
-
-    public static final Info MOVE =
-        new Info(Opcodes.MOVE, "move",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MOVE_FROM16 =
-        new Info(Opcodes.MOVE_FROM16, "move/from16",
-            InstructionCodec.FORMAT_22X, IndexType.NONE);
-
-    public static final Info MOVE_16 =
-        new Info(Opcodes.MOVE_16, "move/16",
-            InstructionCodec.FORMAT_32X, IndexType.NONE);
-
-    public static final Info MOVE_WIDE =
-        new Info(Opcodes.MOVE_WIDE, "move-wide",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MOVE_WIDE_FROM16 =
-        new Info(Opcodes.MOVE_WIDE_FROM16, "move-wide/from16",
-            InstructionCodec.FORMAT_22X, IndexType.NONE);
-
-    public static final Info MOVE_WIDE_16 =
-        new Info(Opcodes.MOVE_WIDE_16, "move-wide/16",
-            InstructionCodec.FORMAT_32X, IndexType.NONE);
-
-    public static final Info MOVE_OBJECT =
-        new Info(Opcodes.MOVE_OBJECT, "move-object",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MOVE_OBJECT_FROM16 =
-        new Info(Opcodes.MOVE_OBJECT_FROM16, "move-object/from16",
-            InstructionCodec.FORMAT_22X, IndexType.NONE);
-
-    public static final Info MOVE_OBJECT_16 =
-        new Info(Opcodes.MOVE_OBJECT_16, "move-object/16",
-            InstructionCodec.FORMAT_32X, IndexType.NONE);
-
-    public static final Info MOVE_RESULT =
-        new Info(Opcodes.MOVE_RESULT, "move-result",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info MOVE_RESULT_WIDE =
-        new Info(Opcodes.MOVE_RESULT_WIDE, "move-result-wide",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info MOVE_RESULT_OBJECT =
-        new Info(Opcodes.MOVE_RESULT_OBJECT, "move-result-object",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info MOVE_EXCEPTION =
-        new Info(Opcodes.MOVE_EXCEPTION, "move-exception",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info RETURN_VOID =
-        new Info(Opcodes.RETURN_VOID, "return-void",
-            InstructionCodec.FORMAT_10X, IndexType.NONE);
-
-    public static final Info RETURN =
-        new Info(Opcodes.RETURN, "return",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info RETURN_WIDE =
-        new Info(Opcodes.RETURN_WIDE, "return-wide",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info RETURN_OBJECT =
-        new Info(Opcodes.RETURN_OBJECT, "return-object",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info CONST_4 =
-        new Info(Opcodes.CONST_4, "const/4",
-            InstructionCodec.FORMAT_11N, IndexType.NONE);
-
-    public static final Info CONST_16 =
-        new Info(Opcodes.CONST_16, "const/16",
-            InstructionCodec.FORMAT_21S, IndexType.NONE);
-
-    public static final Info CONST =
-        new Info(Opcodes.CONST, "const",
-            InstructionCodec.FORMAT_31I, IndexType.NONE);
-
-    public static final Info CONST_HIGH16 =
-        new Info(Opcodes.CONST_HIGH16, "const/high16",
-            InstructionCodec.FORMAT_21H, IndexType.NONE);
-
-    public static final Info CONST_WIDE_16 =
-        new Info(Opcodes.CONST_WIDE_16, "const-wide/16",
-            InstructionCodec.FORMAT_21S, IndexType.NONE);
-
-    public static final Info CONST_WIDE_32 =
-        new Info(Opcodes.CONST_WIDE_32, "const-wide/32",
-            InstructionCodec.FORMAT_31I, IndexType.NONE);
-
-    public static final Info CONST_WIDE =
-        new Info(Opcodes.CONST_WIDE, "const-wide",
-            InstructionCodec.FORMAT_51L, IndexType.NONE);
-
-    public static final Info CONST_WIDE_HIGH16 =
-        new Info(Opcodes.CONST_WIDE_HIGH16, "const-wide/high16",
-            InstructionCodec.FORMAT_21H, IndexType.NONE);
-
-    public static final Info CONST_STRING =
-        new Info(Opcodes.CONST_STRING, "const-string",
-            InstructionCodec.FORMAT_21C, IndexType.STRING_REF);
-
-    public static final Info CONST_STRING_JUMBO =
-        new Info(Opcodes.CONST_STRING_JUMBO, "const-string/jumbo",
-            InstructionCodec.FORMAT_31C, IndexType.STRING_REF);
-
-    public static final Info CONST_CLASS =
-        new Info(Opcodes.CONST_CLASS, "const-class",
-            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);
-
-    public static final Info MONITOR_ENTER =
-        new Info(Opcodes.MONITOR_ENTER, "monitor-enter",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info MONITOR_EXIT =
-        new Info(Opcodes.MONITOR_EXIT, "monitor-exit",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info CHECK_CAST =
-        new Info(Opcodes.CHECK_CAST, "check-cast",
-            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);
-
-    public static final Info INSTANCE_OF =
-        new Info(Opcodes.INSTANCE_OF, "instance-of",
-            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);
-
-    public static final Info ARRAY_LENGTH =
-        new Info(Opcodes.ARRAY_LENGTH, "array-length",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NEW_INSTANCE =
-        new Info(Opcodes.NEW_INSTANCE, "new-instance",
-            InstructionCodec.FORMAT_21C, IndexType.TYPE_REF);
-
-    public static final Info NEW_ARRAY =
-        new Info(Opcodes.NEW_ARRAY, "new-array",
-            InstructionCodec.FORMAT_22C, IndexType.TYPE_REF);
-
-    public static final Info FILLED_NEW_ARRAY =
-        new Info(Opcodes.FILLED_NEW_ARRAY, "filled-new-array",
-            InstructionCodec.FORMAT_35C, IndexType.TYPE_REF);
-
-    public static final Info FILLED_NEW_ARRAY_RANGE =
-        new Info(Opcodes.FILLED_NEW_ARRAY_RANGE, "filled-new-array/range",
-            InstructionCodec.FORMAT_3RC, IndexType.TYPE_REF);
-
-    public static final Info FILL_ARRAY_DATA =
-        new Info(Opcodes.FILL_ARRAY_DATA, "fill-array-data",
-            InstructionCodec.FORMAT_31T, IndexType.NONE);
-
-    public static final Info THROW =
-        new Info(Opcodes.THROW, "throw",
-            InstructionCodec.FORMAT_11X, IndexType.NONE);
-
-    public static final Info GOTO =
-        new Info(Opcodes.GOTO, "goto",
-            InstructionCodec.FORMAT_10T, IndexType.NONE);
-
-    public static final Info GOTO_16 =
-        new Info(Opcodes.GOTO_16, "goto/16",
-            InstructionCodec.FORMAT_20T, IndexType.NONE);
-
-    public static final Info GOTO_32 =
-        new Info(Opcodes.GOTO_32, "goto/32",
-            InstructionCodec.FORMAT_30T, IndexType.NONE);
-
-    public static final Info PACKED_SWITCH =
-        new Info(Opcodes.PACKED_SWITCH, "packed-switch",
-            InstructionCodec.FORMAT_31T, IndexType.NONE);
-
-    public static final Info SPARSE_SWITCH =
-        new Info(Opcodes.SPARSE_SWITCH, "sparse-switch",
-            InstructionCodec.FORMAT_31T, IndexType.NONE);
-
-    public static final Info CMPL_FLOAT =
-        new Info(Opcodes.CMPL_FLOAT, "cmpl-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info CMPG_FLOAT =
-        new Info(Opcodes.CMPG_FLOAT, "cmpg-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info CMPL_DOUBLE =
-        new Info(Opcodes.CMPL_DOUBLE, "cmpl-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info CMPG_DOUBLE =
-        new Info(Opcodes.CMPG_DOUBLE, "cmpg-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info CMP_LONG =
-        new Info(Opcodes.CMP_LONG, "cmp-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info IF_EQ =
-        new Info(Opcodes.IF_EQ, "if-eq",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_NE =
-        new Info(Opcodes.IF_NE, "if-ne",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_LT =
-        new Info(Opcodes.IF_LT, "if-lt",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_GE =
-        new Info(Opcodes.IF_GE, "if-ge",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_GT =
-        new Info(Opcodes.IF_GT, "if-gt",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_LE =
-        new Info(Opcodes.IF_LE, "if-le",
-            InstructionCodec.FORMAT_22T, IndexType.NONE);
-
-    public static final Info IF_EQZ =
-        new Info(Opcodes.IF_EQZ, "if-eqz",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info IF_NEZ =
-        new Info(Opcodes.IF_NEZ, "if-nez",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info IF_LTZ =
-        new Info(Opcodes.IF_LTZ, "if-ltz",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info IF_GEZ =
-        new Info(Opcodes.IF_GEZ, "if-gez",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info IF_GTZ =
-        new Info(Opcodes.IF_GTZ, "if-gtz",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info IF_LEZ =
-        new Info(Opcodes.IF_LEZ, "if-lez",
-            InstructionCodec.FORMAT_21T, IndexType.NONE);
-
-    public static final Info AGET =
-        new Info(Opcodes.AGET, "aget",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_WIDE =
-        new Info(Opcodes.AGET_WIDE, "aget-wide",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_OBJECT =
-        new Info(Opcodes.AGET_OBJECT, "aget-object",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_BOOLEAN =
-        new Info(Opcodes.AGET_BOOLEAN, "aget-boolean",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_BYTE =
-        new Info(Opcodes.AGET_BYTE, "aget-byte",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_CHAR =
-        new Info(Opcodes.AGET_CHAR, "aget-char",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AGET_SHORT =
-        new Info(Opcodes.AGET_SHORT, "aget-short",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT =
-        new Info(Opcodes.APUT, "aput",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_WIDE =
-        new Info(Opcodes.APUT_WIDE, "aput-wide",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_OBJECT =
-        new Info(Opcodes.APUT_OBJECT, "aput-object",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_BOOLEAN =
-        new Info(Opcodes.APUT_BOOLEAN, "aput-boolean",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_BYTE =
-        new Info(Opcodes.APUT_BYTE, "aput-byte",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_CHAR =
-        new Info(Opcodes.APUT_CHAR, "aput-char",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info APUT_SHORT =
-        new Info(Opcodes.APUT_SHORT, "aput-short",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info IGET =
-        new Info(Opcodes.IGET, "iget",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_WIDE =
-        new Info(Opcodes.IGET_WIDE, "iget-wide",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_OBJECT =
-        new Info(Opcodes.IGET_OBJECT, "iget-object",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_BOOLEAN =
-        new Info(Opcodes.IGET_BOOLEAN, "iget-boolean",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_BYTE =
-        new Info(Opcodes.IGET_BYTE, "iget-byte",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_CHAR =
-        new Info(Opcodes.IGET_CHAR, "iget-char",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IGET_SHORT =
-        new Info(Opcodes.IGET_SHORT, "iget-short",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT =
-        new Info(Opcodes.IPUT, "iput",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_WIDE =
-        new Info(Opcodes.IPUT_WIDE, "iput-wide",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_OBJECT =
-        new Info(Opcodes.IPUT_OBJECT, "iput-object",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_BOOLEAN =
-        new Info(Opcodes.IPUT_BOOLEAN, "iput-boolean",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_BYTE =
-        new Info(Opcodes.IPUT_BYTE, "iput-byte",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_CHAR =
-        new Info(Opcodes.IPUT_CHAR, "iput-char",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_SHORT =
-        new Info(Opcodes.IPUT_SHORT, "iput-short",
-            InstructionCodec.FORMAT_22C, IndexType.FIELD_REF);
-
-    public static final Info SGET =
-        new Info(Opcodes.SGET, "sget",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_WIDE =
-        new Info(Opcodes.SGET_WIDE, "sget-wide",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_OBJECT =
-        new Info(Opcodes.SGET_OBJECT, "sget-object",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_BOOLEAN =
-        new Info(Opcodes.SGET_BOOLEAN, "sget-boolean",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_BYTE =
-        new Info(Opcodes.SGET_BYTE, "sget-byte",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_CHAR =
-        new Info(Opcodes.SGET_CHAR, "sget-char",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SGET_SHORT =
-        new Info(Opcodes.SGET_SHORT, "sget-short",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT =
-        new Info(Opcodes.SPUT, "sput",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_WIDE =
-        new Info(Opcodes.SPUT_WIDE, "sput-wide",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_OBJECT =
-        new Info(Opcodes.SPUT_OBJECT, "sput-object",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_BOOLEAN =
-        new Info(Opcodes.SPUT_BOOLEAN, "sput-boolean",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_BYTE =
-        new Info(Opcodes.SPUT_BYTE, "sput-byte",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_CHAR =
-        new Info(Opcodes.SPUT_CHAR, "sput-char",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_SHORT =
-        new Info(Opcodes.SPUT_SHORT, "sput-short",
-            InstructionCodec.FORMAT_21C, IndexType.FIELD_REF);
-
-    public static final Info INVOKE_VIRTUAL =
-        new Info(Opcodes.INVOKE_VIRTUAL, "invoke-virtual",
-            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_SUPER =
-        new Info(Opcodes.INVOKE_SUPER, "invoke-super",
-            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_DIRECT =
-        new Info(Opcodes.INVOKE_DIRECT, "invoke-direct",
-            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_STATIC =
-        new Info(Opcodes.INVOKE_STATIC, "invoke-static",
-            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_INTERFACE =
-        new Info(Opcodes.INVOKE_INTERFACE, "invoke-interface",
-            InstructionCodec.FORMAT_35C, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_VIRTUAL_RANGE =
-        new Info(Opcodes.INVOKE_VIRTUAL_RANGE, "invoke-virtual/range",
-            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_SUPER_RANGE =
-        new Info(Opcodes.INVOKE_SUPER_RANGE, "invoke-super/range",
-            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_DIRECT_RANGE =
-        new Info(Opcodes.INVOKE_DIRECT_RANGE, "invoke-direct/range",
-            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_STATIC_RANGE =
-        new Info(Opcodes.INVOKE_STATIC_RANGE, "invoke-static/range",
-            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_INTERFACE_RANGE =
-        new Info(Opcodes.INVOKE_INTERFACE_RANGE, "invoke-interface/range",
-            InstructionCodec.FORMAT_3RC, IndexType.METHOD_REF);
-
-    public static final Info NEG_INT =
-        new Info(Opcodes.NEG_INT, "neg-int",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NOT_INT =
-        new Info(Opcodes.NOT_INT, "not-int",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NEG_LONG =
-        new Info(Opcodes.NEG_LONG, "neg-long",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NOT_LONG =
-        new Info(Opcodes.NOT_LONG, "not-long",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NEG_FLOAT =
-        new Info(Opcodes.NEG_FLOAT, "neg-float",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info NEG_DOUBLE =
-        new Info(Opcodes.NEG_DOUBLE, "neg-double",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_LONG =
-        new Info(Opcodes.INT_TO_LONG, "int-to-long",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_FLOAT =
-        new Info(Opcodes.INT_TO_FLOAT, "int-to-float",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_DOUBLE =
-        new Info(Opcodes.INT_TO_DOUBLE, "int-to-double",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info LONG_TO_INT =
-        new Info(Opcodes.LONG_TO_INT, "long-to-int",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info LONG_TO_FLOAT =
-        new Info(Opcodes.LONG_TO_FLOAT, "long-to-float",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info LONG_TO_DOUBLE =
-        new Info(Opcodes.LONG_TO_DOUBLE, "long-to-double",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info FLOAT_TO_INT =
-        new Info(Opcodes.FLOAT_TO_INT, "float-to-int",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info FLOAT_TO_LONG =
-        new Info(Opcodes.FLOAT_TO_LONG, "float-to-long",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info FLOAT_TO_DOUBLE =
-        new Info(Opcodes.FLOAT_TO_DOUBLE, "float-to-double",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DOUBLE_TO_INT =
-        new Info(Opcodes.DOUBLE_TO_INT, "double-to-int",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DOUBLE_TO_LONG =
-        new Info(Opcodes.DOUBLE_TO_LONG, "double-to-long",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DOUBLE_TO_FLOAT =
-        new Info(Opcodes.DOUBLE_TO_FLOAT, "double-to-float",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_BYTE =
-        new Info(Opcodes.INT_TO_BYTE, "int-to-byte",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_CHAR =
-        new Info(Opcodes.INT_TO_CHAR, "int-to-char",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info INT_TO_SHORT =
-        new Info(Opcodes.INT_TO_SHORT, "int-to-short",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info ADD_INT =
-        new Info(Opcodes.ADD_INT, "add-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SUB_INT =
-        new Info(Opcodes.SUB_INT, "sub-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info MUL_INT =
-        new Info(Opcodes.MUL_INT, "mul-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info DIV_INT =
-        new Info(Opcodes.DIV_INT, "div-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info REM_INT =
-        new Info(Opcodes.REM_INT, "rem-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AND_INT =
-        new Info(Opcodes.AND_INT, "and-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info OR_INT =
-        new Info(Opcodes.OR_INT, "or-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info XOR_INT =
-        new Info(Opcodes.XOR_INT, "xor-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SHL_INT =
-        new Info(Opcodes.SHL_INT, "shl-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SHR_INT =
-        new Info(Opcodes.SHR_INT, "shr-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info USHR_INT =
-        new Info(Opcodes.USHR_INT, "ushr-int",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info ADD_LONG =
-        new Info(Opcodes.ADD_LONG, "add-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SUB_LONG =
-        new Info(Opcodes.SUB_LONG, "sub-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info MUL_LONG =
-        new Info(Opcodes.MUL_LONG, "mul-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info DIV_LONG =
-        new Info(Opcodes.DIV_LONG, "div-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info REM_LONG =
-        new Info(Opcodes.REM_LONG, "rem-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info AND_LONG =
-        new Info(Opcodes.AND_LONG, "and-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info OR_LONG =
-        new Info(Opcodes.OR_LONG, "or-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info XOR_LONG =
-        new Info(Opcodes.XOR_LONG, "xor-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SHL_LONG =
-        new Info(Opcodes.SHL_LONG, "shl-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SHR_LONG =
-        new Info(Opcodes.SHR_LONG, "shr-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info USHR_LONG =
-        new Info(Opcodes.USHR_LONG, "ushr-long",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info ADD_FLOAT =
-        new Info(Opcodes.ADD_FLOAT, "add-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SUB_FLOAT =
-        new Info(Opcodes.SUB_FLOAT, "sub-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info MUL_FLOAT =
-        new Info(Opcodes.MUL_FLOAT, "mul-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info DIV_FLOAT =
-        new Info(Opcodes.DIV_FLOAT, "div-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info REM_FLOAT =
-        new Info(Opcodes.REM_FLOAT, "rem-float",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info ADD_DOUBLE =
-        new Info(Opcodes.ADD_DOUBLE, "add-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info SUB_DOUBLE =
-        new Info(Opcodes.SUB_DOUBLE, "sub-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info MUL_DOUBLE =
-        new Info(Opcodes.MUL_DOUBLE, "mul-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info DIV_DOUBLE =
-        new Info(Opcodes.DIV_DOUBLE, "div-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info REM_DOUBLE =
-        new Info(Opcodes.REM_DOUBLE, "rem-double",
-            InstructionCodec.FORMAT_23X, IndexType.NONE);
-
-    public static final Info ADD_INT_2ADDR =
-        new Info(Opcodes.ADD_INT_2ADDR, "add-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SUB_INT_2ADDR =
-        new Info(Opcodes.SUB_INT_2ADDR, "sub-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MUL_INT_2ADDR =
-        new Info(Opcodes.MUL_INT_2ADDR, "mul-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DIV_INT_2ADDR =
-        new Info(Opcodes.DIV_INT_2ADDR, "div-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info REM_INT_2ADDR =
-        new Info(Opcodes.REM_INT_2ADDR, "rem-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info AND_INT_2ADDR =
-        new Info(Opcodes.AND_INT_2ADDR, "and-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info OR_INT_2ADDR =
-        new Info(Opcodes.OR_INT_2ADDR, "or-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info XOR_INT_2ADDR =
-        new Info(Opcodes.XOR_INT_2ADDR, "xor-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SHL_INT_2ADDR =
-        new Info(Opcodes.SHL_INT_2ADDR, "shl-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SHR_INT_2ADDR =
-        new Info(Opcodes.SHR_INT_2ADDR, "shr-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info USHR_INT_2ADDR =
-        new Info(Opcodes.USHR_INT_2ADDR, "ushr-int/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info ADD_LONG_2ADDR =
-        new Info(Opcodes.ADD_LONG_2ADDR, "add-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SUB_LONG_2ADDR =
-        new Info(Opcodes.SUB_LONG_2ADDR, "sub-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MUL_LONG_2ADDR =
-        new Info(Opcodes.MUL_LONG_2ADDR, "mul-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DIV_LONG_2ADDR =
-        new Info(Opcodes.DIV_LONG_2ADDR, "div-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info REM_LONG_2ADDR =
-        new Info(Opcodes.REM_LONG_2ADDR, "rem-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info AND_LONG_2ADDR =
-        new Info(Opcodes.AND_LONG_2ADDR, "and-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info OR_LONG_2ADDR =
-        new Info(Opcodes.OR_LONG_2ADDR, "or-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info XOR_LONG_2ADDR =
-        new Info(Opcodes.XOR_LONG_2ADDR, "xor-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SHL_LONG_2ADDR =
-        new Info(Opcodes.SHL_LONG_2ADDR, "shl-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SHR_LONG_2ADDR =
-        new Info(Opcodes.SHR_LONG_2ADDR, "shr-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info USHR_LONG_2ADDR =
-        new Info(Opcodes.USHR_LONG_2ADDR, "ushr-long/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info ADD_FLOAT_2ADDR =
-        new Info(Opcodes.ADD_FLOAT_2ADDR, "add-float/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SUB_FLOAT_2ADDR =
-        new Info(Opcodes.SUB_FLOAT_2ADDR, "sub-float/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MUL_FLOAT_2ADDR =
-        new Info(Opcodes.MUL_FLOAT_2ADDR, "mul-float/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DIV_FLOAT_2ADDR =
-        new Info(Opcodes.DIV_FLOAT_2ADDR, "div-float/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info REM_FLOAT_2ADDR =
-        new Info(Opcodes.REM_FLOAT_2ADDR, "rem-float/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info ADD_DOUBLE_2ADDR =
-        new Info(Opcodes.ADD_DOUBLE_2ADDR, "add-double/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info SUB_DOUBLE_2ADDR =
-        new Info(Opcodes.SUB_DOUBLE_2ADDR, "sub-double/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info MUL_DOUBLE_2ADDR =
-        new Info(Opcodes.MUL_DOUBLE_2ADDR, "mul-double/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info DIV_DOUBLE_2ADDR =
-        new Info(Opcodes.DIV_DOUBLE_2ADDR, "div-double/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info REM_DOUBLE_2ADDR =
-        new Info(Opcodes.REM_DOUBLE_2ADDR, "rem-double/2addr",
-            InstructionCodec.FORMAT_12X, IndexType.NONE);
-
-    public static final Info ADD_INT_LIT16 =
-        new Info(Opcodes.ADD_INT_LIT16, "add-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info RSUB_INT =
-        new Info(Opcodes.RSUB_INT, "rsub-int",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info MUL_INT_LIT16 =
-        new Info(Opcodes.MUL_INT_LIT16, "mul-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info DIV_INT_LIT16 =
-        new Info(Opcodes.DIV_INT_LIT16, "div-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info REM_INT_LIT16 =
-        new Info(Opcodes.REM_INT_LIT16, "rem-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info AND_INT_LIT16 =
-        new Info(Opcodes.AND_INT_LIT16, "and-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info OR_INT_LIT16 =
-        new Info(Opcodes.OR_INT_LIT16, "or-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info XOR_INT_LIT16 =
-        new Info(Opcodes.XOR_INT_LIT16, "xor-int/lit16",
-            InstructionCodec.FORMAT_22S, IndexType.NONE);
-
-    public static final Info ADD_INT_LIT8 =
-        new Info(Opcodes.ADD_INT_LIT8, "add-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info RSUB_INT_LIT8 =
-        new Info(Opcodes.RSUB_INT_LIT8, "rsub-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info MUL_INT_LIT8 =
-        new Info(Opcodes.MUL_INT_LIT8, "mul-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info DIV_INT_LIT8 =
-        new Info(Opcodes.DIV_INT_LIT8, "div-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info REM_INT_LIT8 =
-        new Info(Opcodes.REM_INT_LIT8, "rem-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info AND_INT_LIT8 =
-        new Info(Opcodes.AND_INT_LIT8, "and-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info OR_INT_LIT8 =
-        new Info(Opcodes.OR_INT_LIT8, "or-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info XOR_INT_LIT8 =
-        new Info(Opcodes.XOR_INT_LIT8, "xor-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info SHL_INT_LIT8 =
-        new Info(Opcodes.SHL_INT_LIT8, "shl-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info SHR_INT_LIT8 =
-        new Info(Opcodes.SHR_INT_LIT8, "shr-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info USHR_INT_LIT8 =
-        new Info(Opcodes.USHR_INT_LIT8, "ushr-int/lit8",
-            InstructionCodec.FORMAT_22B, IndexType.NONE);
-
-    public static final Info CONST_CLASS_JUMBO =
-        new Info(Opcodes.CONST_CLASS_JUMBO, "const-class/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
-    public static final Info CHECK_CAST_JUMBO =
-        new Info(Opcodes.CHECK_CAST_JUMBO, "check-cast/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
-    public static final Info INSTANCE_OF_JUMBO =
-        new Info(Opcodes.INSTANCE_OF_JUMBO, "instance-of/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.TYPE_REF);
-
-    public static final Info NEW_INSTANCE_JUMBO =
-        new Info(Opcodes.NEW_INSTANCE_JUMBO, "new-instance/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
-    public static final Info NEW_ARRAY_JUMBO =
-        new Info(Opcodes.NEW_ARRAY_JUMBO, "new-array/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.TYPE_REF);
-
-    public static final Info FILLED_NEW_ARRAY_JUMBO =
-        new Info(Opcodes.FILLED_NEW_ARRAY_JUMBO, "filled-new-array/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.TYPE_REF);
-
-    public static final Info IGET_JUMBO =
-        new Info(Opcodes.IGET_JUMBO, "iget/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_WIDE_JUMBO =
-        new Info(Opcodes.IGET_WIDE_JUMBO, "iget-wide/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_OBJECT_JUMBO =
-        new Info(Opcodes.IGET_OBJECT_JUMBO, "iget-object/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_BOOLEAN_JUMBO =
-        new Info(Opcodes.IGET_BOOLEAN_JUMBO, "iget-boolean/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_BYTE_JUMBO =
-        new Info(Opcodes.IGET_BYTE_JUMBO, "iget-byte/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_CHAR_JUMBO =
-        new Info(Opcodes.IGET_CHAR_JUMBO, "iget-char/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IGET_SHORT_JUMBO =
-        new Info(Opcodes.IGET_SHORT_JUMBO, "iget-short/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_JUMBO =
-        new Info(Opcodes.IPUT_JUMBO, "iput/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_WIDE_JUMBO =
-        new Info(Opcodes.IPUT_WIDE_JUMBO, "iput-wide/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_OBJECT_JUMBO =
-        new Info(Opcodes.IPUT_OBJECT_JUMBO, "iput-object/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_BOOLEAN_JUMBO =
-        new Info(Opcodes.IPUT_BOOLEAN_JUMBO, "iput-boolean/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_BYTE_JUMBO =
-        new Info(Opcodes.IPUT_BYTE_JUMBO, "iput-byte/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_CHAR_JUMBO =
-        new Info(Opcodes.IPUT_CHAR_JUMBO, "iput-char/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info IPUT_SHORT_JUMBO =
-        new Info(Opcodes.IPUT_SHORT_JUMBO, "iput-short/jumbo",
-            InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
-    public static final Info SGET_JUMBO =
-        new Info(Opcodes.SGET_JUMBO, "sget/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_WIDE_JUMBO =
-        new Info(Opcodes.SGET_WIDE_JUMBO, "sget-wide/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_OBJECT_JUMBO =
-        new Info(Opcodes.SGET_OBJECT_JUMBO, "sget-object/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_BOOLEAN_JUMBO =
-        new Info(Opcodes.SGET_BOOLEAN_JUMBO, "sget-boolean/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_BYTE_JUMBO =
-        new Info(Opcodes.SGET_BYTE_JUMBO, "sget-byte/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_CHAR_JUMBO =
-        new Info(Opcodes.SGET_CHAR_JUMBO, "sget-char/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SGET_SHORT_JUMBO =
-        new Info(Opcodes.SGET_SHORT_JUMBO, "sget-short/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_JUMBO =
-        new Info(Opcodes.SPUT_JUMBO, "sput/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_WIDE_JUMBO =
-        new Info(Opcodes.SPUT_WIDE_JUMBO, "sput-wide/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_OBJECT_JUMBO =
-        new Info(Opcodes.SPUT_OBJECT_JUMBO, "sput-object/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_BOOLEAN_JUMBO =
-        new Info(Opcodes.SPUT_BOOLEAN_JUMBO, "sput-boolean/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_BYTE_JUMBO =
-        new Info(Opcodes.SPUT_BYTE_JUMBO, "sput-byte/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_CHAR_JUMBO =
-        new Info(Opcodes.SPUT_CHAR_JUMBO, "sput-char/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info SPUT_SHORT_JUMBO =
-        new Info(Opcodes.SPUT_SHORT_JUMBO, "sput-short/jumbo",
-            InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
-    public static final Info INVOKE_VIRTUAL_JUMBO =
-        new Info(Opcodes.INVOKE_VIRTUAL_JUMBO, "invoke-virtual/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_SUPER_JUMBO =
-        new Info(Opcodes.INVOKE_SUPER_JUMBO, "invoke-super/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_DIRECT_JUMBO =
-        new Info(Opcodes.INVOKE_DIRECT_JUMBO, "invoke-direct/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_STATIC_JUMBO =
-        new Info(Opcodes.INVOKE_STATIC_JUMBO, "invoke-static/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
-    public static final Info INVOKE_INTERFACE_JUMBO =
-        new Info(Opcodes.INVOKE_INTERFACE_JUMBO, "invoke-interface/jumbo",
-            InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
-    // END(opcode-info-defs)
-
-    // Static initialization.
-    static {
-        INFO = new Info[Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1];
-
-        // TODO: Stop using this constant.
-        set(SPECIAL_FORMAT);
-
-        // TODO: These payload opcodes should be generated by opcode-gen.
-        set(PACKED_SWITCH_PAYLOAD);
-        set(SPARSE_SWITCH_PAYLOAD);
-        set(FILL_ARRAY_DATA_PAYLOAD);
-
-        // BEGIN(opcode-info-init); GENERATED AUTOMATICALLY BY opcode-gen
-        set(NOP);
-        set(MOVE);
-        set(MOVE_FROM16);
-        set(MOVE_16);
-        set(MOVE_WIDE);
-        set(MOVE_WIDE_FROM16);
-        set(MOVE_WIDE_16);
-        set(MOVE_OBJECT);
-        set(MOVE_OBJECT_FROM16);
-        set(MOVE_OBJECT_16);
-        set(MOVE_RESULT);
-        set(MOVE_RESULT_WIDE);
-        set(MOVE_RESULT_OBJECT);
-        set(MOVE_EXCEPTION);
-        set(RETURN_VOID);
-        set(RETURN);
-        set(RETURN_WIDE);
-        set(RETURN_OBJECT);
-        set(CONST_4);
-        set(CONST_16);
-        set(CONST);
-        set(CONST_HIGH16);
-        set(CONST_WIDE_16);
-        set(CONST_WIDE_32);
-        set(CONST_WIDE);
-        set(CONST_WIDE_HIGH16);
-        set(CONST_STRING);
-        set(CONST_STRING_JUMBO);
-        set(CONST_CLASS);
-        set(MONITOR_ENTER);
-        set(MONITOR_EXIT);
-        set(CHECK_CAST);
-        set(INSTANCE_OF);
-        set(ARRAY_LENGTH);
-        set(NEW_INSTANCE);
-        set(NEW_ARRAY);
-        set(FILLED_NEW_ARRAY);
-        set(FILLED_NEW_ARRAY_RANGE);
-        set(FILL_ARRAY_DATA);
-        set(THROW);
-        set(GOTO);
-        set(GOTO_16);
-        set(GOTO_32);
-        set(PACKED_SWITCH);
-        set(SPARSE_SWITCH);
-        set(CMPL_FLOAT);
-        set(CMPG_FLOAT);
-        set(CMPL_DOUBLE);
-        set(CMPG_DOUBLE);
-        set(CMP_LONG);
-        set(IF_EQ);
-        set(IF_NE);
-        set(IF_LT);
-        set(IF_GE);
-        set(IF_GT);
-        set(IF_LE);
-        set(IF_EQZ);
-        set(IF_NEZ);
-        set(IF_LTZ);
-        set(IF_GEZ);
-        set(IF_GTZ);
-        set(IF_LEZ);
-        set(AGET);
-        set(AGET_WIDE);
-        set(AGET_OBJECT);
-        set(AGET_BOOLEAN);
-        set(AGET_BYTE);
-        set(AGET_CHAR);
-        set(AGET_SHORT);
-        set(APUT);
-        set(APUT_WIDE);
-        set(APUT_OBJECT);
-        set(APUT_BOOLEAN);
-        set(APUT_BYTE);
-        set(APUT_CHAR);
-        set(APUT_SHORT);
-        set(IGET);
-        set(IGET_WIDE);
-        set(IGET_OBJECT);
-        set(IGET_BOOLEAN);
-        set(IGET_BYTE);
-        set(IGET_CHAR);
-        set(IGET_SHORT);
-        set(IPUT);
-        set(IPUT_WIDE);
-        set(IPUT_OBJECT);
-        set(IPUT_BOOLEAN);
-        set(IPUT_BYTE);
-        set(IPUT_CHAR);
-        set(IPUT_SHORT);
-        set(SGET);
-        set(SGET_WIDE);
-        set(SGET_OBJECT);
-        set(SGET_BOOLEAN);
-        set(SGET_BYTE);
-        set(SGET_CHAR);
-        set(SGET_SHORT);
-        set(SPUT);
-        set(SPUT_WIDE);
-        set(SPUT_OBJECT);
-        set(SPUT_BOOLEAN);
-        set(SPUT_BYTE);
-        set(SPUT_CHAR);
-        set(SPUT_SHORT);
-        set(INVOKE_VIRTUAL);
-        set(INVOKE_SUPER);
-        set(INVOKE_DIRECT);
-        set(INVOKE_STATIC);
-        set(INVOKE_INTERFACE);
-        set(INVOKE_VIRTUAL_RANGE);
-        set(INVOKE_SUPER_RANGE);
-        set(INVOKE_DIRECT_RANGE);
-        set(INVOKE_STATIC_RANGE);
-        set(INVOKE_INTERFACE_RANGE);
-        set(NEG_INT);
-        set(NOT_INT);
-        set(NEG_LONG);
-        set(NOT_LONG);
-        set(NEG_FLOAT);
-        set(NEG_DOUBLE);
-        set(INT_TO_LONG);
-        set(INT_TO_FLOAT);
-        set(INT_TO_DOUBLE);
-        set(LONG_TO_INT);
-        set(LONG_TO_FLOAT);
-        set(LONG_TO_DOUBLE);
-        set(FLOAT_TO_INT);
-        set(FLOAT_TO_LONG);
-        set(FLOAT_TO_DOUBLE);
-        set(DOUBLE_TO_INT);
-        set(DOUBLE_TO_LONG);
-        set(DOUBLE_TO_FLOAT);
-        set(INT_TO_BYTE);
-        set(INT_TO_CHAR);
-        set(INT_TO_SHORT);
-        set(ADD_INT);
-        set(SUB_INT);
-        set(MUL_INT);
-        set(DIV_INT);
-        set(REM_INT);
-        set(AND_INT);
-        set(OR_INT);
-        set(XOR_INT);
-        set(SHL_INT);
-        set(SHR_INT);
-        set(USHR_INT);
-        set(ADD_LONG);
-        set(SUB_LONG);
-        set(MUL_LONG);
-        set(DIV_LONG);
-        set(REM_LONG);
-        set(AND_LONG);
-        set(OR_LONG);
-        set(XOR_LONG);
-        set(SHL_LONG);
-        set(SHR_LONG);
-        set(USHR_LONG);
-        set(ADD_FLOAT);
-        set(SUB_FLOAT);
-        set(MUL_FLOAT);
-        set(DIV_FLOAT);
-        set(REM_FLOAT);
-        set(ADD_DOUBLE);
-        set(SUB_DOUBLE);
-        set(MUL_DOUBLE);
-        set(DIV_DOUBLE);
-        set(REM_DOUBLE);
-        set(ADD_INT_2ADDR);
-        set(SUB_INT_2ADDR);
-        set(MUL_INT_2ADDR);
-        set(DIV_INT_2ADDR);
-        set(REM_INT_2ADDR);
-        set(AND_INT_2ADDR);
-        set(OR_INT_2ADDR);
-        set(XOR_INT_2ADDR);
-        set(SHL_INT_2ADDR);
-        set(SHR_INT_2ADDR);
-        set(USHR_INT_2ADDR);
-        set(ADD_LONG_2ADDR);
-        set(SUB_LONG_2ADDR);
-        set(MUL_LONG_2ADDR);
-        set(DIV_LONG_2ADDR);
-        set(REM_LONG_2ADDR);
-        set(AND_LONG_2ADDR);
-        set(OR_LONG_2ADDR);
-        set(XOR_LONG_2ADDR);
-        set(SHL_LONG_2ADDR);
-        set(SHR_LONG_2ADDR);
-        set(USHR_LONG_2ADDR);
-        set(ADD_FLOAT_2ADDR);
-        set(SUB_FLOAT_2ADDR);
-        set(MUL_FLOAT_2ADDR);
-        set(DIV_FLOAT_2ADDR);
-        set(REM_FLOAT_2ADDR);
-        set(ADD_DOUBLE_2ADDR);
-        set(SUB_DOUBLE_2ADDR);
-        set(MUL_DOUBLE_2ADDR);
-        set(DIV_DOUBLE_2ADDR);
-        set(REM_DOUBLE_2ADDR);
-        set(ADD_INT_LIT16);
-        set(RSUB_INT);
-        set(MUL_INT_LIT16);
-        set(DIV_INT_LIT16);
-        set(REM_INT_LIT16);
-        set(AND_INT_LIT16);
-        set(OR_INT_LIT16);
-        set(XOR_INT_LIT16);
-        set(ADD_INT_LIT8);
-        set(RSUB_INT_LIT8);
-        set(MUL_INT_LIT8);
-        set(DIV_INT_LIT8);
-        set(REM_INT_LIT8);
-        set(AND_INT_LIT8);
-        set(OR_INT_LIT8);
-        set(XOR_INT_LIT8);
-        set(SHL_INT_LIT8);
-        set(SHR_INT_LIT8);
-        set(USHR_INT_LIT8);
-        set(CONST_CLASS_JUMBO);
-        set(CHECK_CAST_JUMBO);
-        set(INSTANCE_OF_JUMBO);
-        set(NEW_INSTANCE_JUMBO);
-        set(NEW_ARRAY_JUMBO);
-        set(FILLED_NEW_ARRAY_JUMBO);
-        set(IGET_JUMBO);
-        set(IGET_WIDE_JUMBO);
-        set(IGET_OBJECT_JUMBO);
-        set(IGET_BOOLEAN_JUMBO);
-        set(IGET_BYTE_JUMBO);
-        set(IGET_CHAR_JUMBO);
-        set(IGET_SHORT_JUMBO);
-        set(IPUT_JUMBO);
-        set(IPUT_WIDE_JUMBO);
-        set(IPUT_OBJECT_JUMBO);
-        set(IPUT_BOOLEAN_JUMBO);
-        set(IPUT_BYTE_JUMBO);
-        set(IPUT_CHAR_JUMBO);
-        set(IPUT_SHORT_JUMBO);
-        set(SGET_JUMBO);
-        set(SGET_WIDE_JUMBO);
-        set(SGET_OBJECT_JUMBO);
-        set(SGET_BOOLEAN_JUMBO);
-        set(SGET_BYTE_JUMBO);
-        set(SGET_CHAR_JUMBO);
-        set(SGET_SHORT_JUMBO);
-        set(SPUT_JUMBO);
-        set(SPUT_WIDE_JUMBO);
-        set(SPUT_OBJECT_JUMBO);
-        set(SPUT_BOOLEAN_JUMBO);
-        set(SPUT_BYTE_JUMBO);
-        set(SPUT_CHAR_JUMBO);
-        set(SPUT_SHORT_JUMBO);
-        set(INVOKE_VIRTUAL_JUMBO);
-        set(INVOKE_SUPER_JUMBO);
-        set(INVOKE_DIRECT_JUMBO);
-        set(INVOKE_STATIC_JUMBO);
-        set(INVOKE_INTERFACE_JUMBO);
-        // END(opcode-info-init)
-    }
-
-    /**
-     * This class is uninstantiable.
-     */
-    private OpcodeInfo() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Gets the {@link @Info} for the given opcode value.
-     *
-     * @param opcode {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the
-     * opcode value
-     * @return non-null; the associated opcode information instance
-     */
-    public static Info get(int opcode) {
-        int idx = opcode - Opcodes.MIN_VALUE;
-
-        try {
-            Info result = INFO[idx];
-            if (result != null) {
-                return result;
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Fall through.
-        }
-
-        throw new IllegalArgumentException("bogus opcode: "
-                + Hex.u2or4(opcode));
-    }
-
-    /**
-     * Gets the name of the given opcode.
-     */
-    public static String getName(int opcode) {
-        return get(opcode).getName();
-    }
-
-    /**
-     * Gets the format (an {@link InstructionCodec}) for the given opcode
-     * value.
-     */
-    public static InstructionCodec getFormat(int opcode) {
-        return get(opcode).getFormat();
-    }
-
-    /**
-     * Gets the {@link IndexType} for the given opcode value.
-     */
-    public static IndexType getIndexType(int opcode) {
-        return get(opcode).getIndexType();
-    }
-
-    /**
-     * Puts the given opcode into the table of all ops.
-     *
-     * @param opcode non-null; the opcode
-     */
-    private static void set(Info opcode) {
-        int idx = opcode.getOpcode() - Opcodes.MIN_VALUE;
-        INFO[idx] = opcode;
-    }
-
-    /**
-     * Information about an opcode.
-     */
-    public static class Info {
-        private final int opcode;
-        private final String name;
-        private final InstructionCodec format;
-        private final IndexType indexType;
-
-        public Info(int opcode, String name, InstructionCodec format,
-                IndexType indexType) {
-            this.opcode = opcode;
-            this.name = name;
-            this.format = format;
-            this.indexType = indexType;
-        }
-
-        public int getOpcode() {
-            return opcode;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public InstructionCodec getFormat() {
-            return format;
-        }
-
-        public IndexType getIndexType() {
-            return indexType;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/Opcodes.java b/dx/src/main/java/com/android/dx/io/Opcodes.java
deleted file mode 100644
index 4a255f7..0000000
--- a/dx/src/main/java/com/android/dx/io/Opcodes.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007 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.io;
-
-/**
- * All the Dalvik opcode value constants. See the related spec
- * document for the meaning and instruction format of each opcode.
- */
-public final class Opcodes {
-    /**
-     * pseudo-opcode used for nonstandard format payload "instructions". TODO:
-     * Retire this concept, and start treating the payload instructions
-     * more like the rest.
-     */
-    public static final int SPECIAL_FORMAT = -1;
-
-    /**
-     * pseudo-opcode used to indicate there is no next opcode; used
-     * in opcode chaining lists
-     */
-    public static final int NO_NEXT = -1;
-
-    /** minimum valid opcode value */
-    public static final int MIN_VALUE = -1;
-
-    /** maximum valid opcode value */
-    public static final int MAX_VALUE = 0xffff;
-
-    // BEGIN(opcodes); GENERATED AUTOMATICALLY BY opcode-gen
-    public static final int NOP = 0x00;
-    public static final int MOVE = 0x01;
-    public static final int MOVE_FROM16 = 0x02;
-    public static final int MOVE_16 = 0x03;
-    public static final int MOVE_WIDE = 0x04;
-    public static final int MOVE_WIDE_FROM16 = 0x05;
-    public static final int MOVE_WIDE_16 = 0x06;
-    public static final int MOVE_OBJECT = 0x07;
-    public static final int MOVE_OBJECT_FROM16 = 0x08;
-    public static final int MOVE_OBJECT_16 = 0x09;
-    public static final int MOVE_RESULT = 0x0a;
-    public static final int MOVE_RESULT_WIDE = 0x0b;
-    public static final int MOVE_RESULT_OBJECT = 0x0c;
-    public static final int MOVE_EXCEPTION = 0x0d;
-    public static final int RETURN_VOID = 0x0e;
-    public static final int RETURN = 0x0f;
-    public static final int RETURN_WIDE = 0x10;
-    public static final int RETURN_OBJECT = 0x11;
-    public static final int CONST_4 = 0x12;
-    public static final int CONST_16 = 0x13;
-    public static final int CONST = 0x14;
-    public static final int CONST_HIGH16 = 0x15;
-    public static final int CONST_WIDE_16 = 0x16;
-    public static final int CONST_WIDE_32 = 0x17;
-    public static final int CONST_WIDE = 0x18;
-    public static final int CONST_WIDE_HIGH16 = 0x19;
-    public static final int CONST_STRING = 0x1a;
-    public static final int CONST_STRING_JUMBO = 0x1b;
-    public static final int CONST_CLASS = 0x1c;
-    public static final int MONITOR_ENTER = 0x1d;
-    public static final int MONITOR_EXIT = 0x1e;
-    public static final int CHECK_CAST = 0x1f;
-    public static final int INSTANCE_OF = 0x20;
-    public static final int ARRAY_LENGTH = 0x21;
-    public static final int NEW_INSTANCE = 0x22;
-    public static final int NEW_ARRAY = 0x23;
-    public static final int FILLED_NEW_ARRAY = 0x24;
-    public static final int FILLED_NEW_ARRAY_RANGE = 0x25;
-    public static final int FILL_ARRAY_DATA = 0x26;
-    public static final int THROW = 0x27;
-    public static final int GOTO = 0x28;
-    public static final int GOTO_16 = 0x29;
-    public static final int GOTO_32 = 0x2a;
-    public static final int PACKED_SWITCH = 0x2b;
-    public static final int SPARSE_SWITCH = 0x2c;
-    public static final int CMPL_FLOAT = 0x2d;
-    public static final int CMPG_FLOAT = 0x2e;
-    public static final int CMPL_DOUBLE = 0x2f;
-    public static final int CMPG_DOUBLE = 0x30;
-    public static final int CMP_LONG = 0x31;
-    public static final int IF_EQ = 0x32;
-    public static final int IF_NE = 0x33;
-    public static final int IF_LT = 0x34;
-    public static final int IF_GE = 0x35;
-    public static final int IF_GT = 0x36;
-    public static final int IF_LE = 0x37;
-    public static final int IF_EQZ = 0x38;
-    public static final int IF_NEZ = 0x39;
-    public static final int IF_LTZ = 0x3a;
-    public static final int IF_GEZ = 0x3b;
-    public static final int IF_GTZ = 0x3c;
-    public static final int IF_LEZ = 0x3d;
-    public static final int AGET = 0x44;
-    public static final int AGET_WIDE = 0x45;
-    public static final int AGET_OBJECT = 0x46;
-    public static final int AGET_BOOLEAN = 0x47;
-    public static final int AGET_BYTE = 0x48;
-    public static final int AGET_CHAR = 0x49;
-    public static final int AGET_SHORT = 0x4a;
-    public static final int APUT = 0x4b;
-    public static final int APUT_WIDE = 0x4c;
-    public static final int APUT_OBJECT = 0x4d;
-    public static final int APUT_BOOLEAN = 0x4e;
-    public static final int APUT_BYTE = 0x4f;
-    public static final int APUT_CHAR = 0x50;
-    public static final int APUT_SHORT = 0x51;
-    public static final int IGET = 0x52;
-    public static final int IGET_WIDE = 0x53;
-    public static final int IGET_OBJECT = 0x54;
-    public static final int IGET_BOOLEAN = 0x55;
-    public static final int IGET_BYTE = 0x56;
-    public static final int IGET_CHAR = 0x57;
-    public static final int IGET_SHORT = 0x58;
-    public static final int IPUT = 0x59;
-    public static final int IPUT_WIDE = 0x5a;
-    public static final int IPUT_OBJECT = 0x5b;
-    public static final int IPUT_BOOLEAN = 0x5c;
-    public static final int IPUT_BYTE = 0x5d;
-    public static final int IPUT_CHAR = 0x5e;
-    public static final int IPUT_SHORT = 0x5f;
-    public static final int SGET = 0x60;
-    public static final int SGET_WIDE = 0x61;
-    public static final int SGET_OBJECT = 0x62;
-    public static final int SGET_BOOLEAN = 0x63;
-    public static final int SGET_BYTE = 0x64;
-    public static final int SGET_CHAR = 0x65;
-    public static final int SGET_SHORT = 0x66;
-    public static final int SPUT = 0x67;
-    public static final int SPUT_WIDE = 0x68;
-    public static final int SPUT_OBJECT = 0x69;
-    public static final int SPUT_BOOLEAN = 0x6a;
-    public static final int SPUT_BYTE = 0x6b;
-    public static final int SPUT_CHAR = 0x6c;
-    public static final int SPUT_SHORT = 0x6d;
-    public static final int INVOKE_VIRTUAL = 0x6e;
-    public static final int INVOKE_SUPER = 0x6f;
-    public static final int INVOKE_DIRECT = 0x70;
-    public static final int INVOKE_STATIC = 0x71;
-    public static final int INVOKE_INTERFACE = 0x72;
-    public static final int INVOKE_VIRTUAL_RANGE = 0x74;
-    public static final int INVOKE_SUPER_RANGE = 0x75;
-    public static final int INVOKE_DIRECT_RANGE = 0x76;
-    public static final int INVOKE_STATIC_RANGE = 0x77;
-    public static final int INVOKE_INTERFACE_RANGE = 0x78;
-    public static final int NEG_INT = 0x7b;
-    public static final int NOT_INT = 0x7c;
-    public static final int NEG_LONG = 0x7d;
-    public static final int NOT_LONG = 0x7e;
-    public static final int NEG_FLOAT = 0x7f;
-    public static final int NEG_DOUBLE = 0x80;
-    public static final int INT_TO_LONG = 0x81;
-    public static final int INT_TO_FLOAT = 0x82;
-    public static final int INT_TO_DOUBLE = 0x83;
-    public static final int LONG_TO_INT = 0x84;
-    public static final int LONG_TO_FLOAT = 0x85;
-    public static final int LONG_TO_DOUBLE = 0x86;
-    public static final int FLOAT_TO_INT = 0x87;
-    public static final int FLOAT_TO_LONG = 0x88;
-    public static final int FLOAT_TO_DOUBLE = 0x89;
-    public static final int DOUBLE_TO_INT = 0x8a;
-    public static final int DOUBLE_TO_LONG = 0x8b;
-    public static final int DOUBLE_TO_FLOAT = 0x8c;
-    public static final int INT_TO_BYTE = 0x8d;
-    public static final int INT_TO_CHAR = 0x8e;
-    public static final int INT_TO_SHORT = 0x8f;
-    public static final int ADD_INT = 0x90;
-    public static final int SUB_INT = 0x91;
-    public static final int MUL_INT = 0x92;
-    public static final int DIV_INT = 0x93;
-    public static final int REM_INT = 0x94;
-    public static final int AND_INT = 0x95;
-    public static final int OR_INT = 0x96;
-    public static final int XOR_INT = 0x97;
-    public static final int SHL_INT = 0x98;
-    public static final int SHR_INT = 0x99;
-    public static final int USHR_INT = 0x9a;
-    public static final int ADD_LONG = 0x9b;
-    public static final int SUB_LONG = 0x9c;
-    public static final int MUL_LONG = 0x9d;
-    public static final int DIV_LONG = 0x9e;
-    public static final int REM_LONG = 0x9f;
-    public static final int AND_LONG = 0xa0;
-    public static final int OR_LONG = 0xa1;
-    public static final int XOR_LONG = 0xa2;
-    public static final int SHL_LONG = 0xa3;
-    public static final int SHR_LONG = 0xa4;
-    public static final int USHR_LONG = 0xa5;
-    public static final int ADD_FLOAT = 0xa6;
-    public static final int SUB_FLOAT = 0xa7;
-    public static final int MUL_FLOAT = 0xa8;
-    public static final int DIV_FLOAT = 0xa9;
-    public static final int REM_FLOAT = 0xaa;
-    public static final int ADD_DOUBLE = 0xab;
-    public static final int SUB_DOUBLE = 0xac;
-    public static final int MUL_DOUBLE = 0xad;
-    public static final int DIV_DOUBLE = 0xae;
-    public static final int REM_DOUBLE = 0xaf;
-    public static final int ADD_INT_2ADDR = 0xb0;
-    public static final int SUB_INT_2ADDR = 0xb1;
-    public static final int MUL_INT_2ADDR = 0xb2;
-    public static final int DIV_INT_2ADDR = 0xb3;
-    public static final int REM_INT_2ADDR = 0xb4;
-    public static final int AND_INT_2ADDR = 0xb5;
-    public static final int OR_INT_2ADDR = 0xb6;
-    public static final int XOR_INT_2ADDR = 0xb7;
-    public static final int SHL_INT_2ADDR = 0xb8;
-    public static final int SHR_INT_2ADDR = 0xb9;
-    public static final int USHR_INT_2ADDR = 0xba;
-    public static final int ADD_LONG_2ADDR = 0xbb;
-    public static final int SUB_LONG_2ADDR = 0xbc;
-    public static final int MUL_LONG_2ADDR = 0xbd;
-    public static final int DIV_LONG_2ADDR = 0xbe;
-    public static final int REM_LONG_2ADDR = 0xbf;
-    public static final int AND_LONG_2ADDR = 0xc0;
-    public static final int OR_LONG_2ADDR = 0xc1;
-    public static final int XOR_LONG_2ADDR = 0xc2;
-    public static final int SHL_LONG_2ADDR = 0xc3;
-    public static final int SHR_LONG_2ADDR = 0xc4;
-    public static final int USHR_LONG_2ADDR = 0xc5;
-    public static final int ADD_FLOAT_2ADDR = 0xc6;
-    public static final int SUB_FLOAT_2ADDR = 0xc7;
-    public static final int MUL_FLOAT_2ADDR = 0xc8;
-    public static final int DIV_FLOAT_2ADDR = 0xc9;
-    public static final int REM_FLOAT_2ADDR = 0xca;
-    public static final int ADD_DOUBLE_2ADDR = 0xcb;
-    public static final int SUB_DOUBLE_2ADDR = 0xcc;
-    public static final int MUL_DOUBLE_2ADDR = 0xcd;
-    public static final int DIV_DOUBLE_2ADDR = 0xce;
-    public static final int REM_DOUBLE_2ADDR = 0xcf;
-    public static final int ADD_INT_LIT16 = 0xd0;
-    public static final int RSUB_INT = 0xd1;
-    public static final int MUL_INT_LIT16 = 0xd2;
-    public static final int DIV_INT_LIT16 = 0xd3;
-    public static final int REM_INT_LIT16 = 0xd4;
-    public static final int AND_INT_LIT16 = 0xd5;
-    public static final int OR_INT_LIT16 = 0xd6;
-    public static final int XOR_INT_LIT16 = 0xd7;
-    public static final int ADD_INT_LIT8 = 0xd8;
-    public static final int RSUB_INT_LIT8 = 0xd9;
-    public static final int MUL_INT_LIT8 = 0xda;
-    public static final int DIV_INT_LIT8 = 0xdb;
-    public static final int REM_INT_LIT8 = 0xdc;
-    public static final int AND_INT_LIT8 = 0xdd;
-    public static final int OR_INT_LIT8 = 0xde;
-    public static final int XOR_INT_LIT8 = 0xdf;
-    public static final int SHL_INT_LIT8 = 0xe0;
-    public static final int SHR_INT_LIT8 = 0xe1;
-    public static final int USHR_INT_LIT8 = 0xe2;
-    public static final int CONST_CLASS_JUMBO = 0x00ff;
-    public static final int CHECK_CAST_JUMBO = 0x01ff;
-    public static final int INSTANCE_OF_JUMBO = 0x02ff;
-    public static final int NEW_INSTANCE_JUMBO = 0x03ff;
-    public static final int NEW_ARRAY_JUMBO = 0x04ff;
-    public static final int FILLED_NEW_ARRAY_JUMBO = 0x05ff;
-    public static final int IGET_JUMBO = 0x06ff;
-    public static final int IGET_WIDE_JUMBO = 0x07ff;
-    public static final int IGET_OBJECT_JUMBO = 0x08ff;
-    public static final int IGET_BOOLEAN_JUMBO = 0x09ff;
-    public static final int IGET_BYTE_JUMBO = 0x0aff;
-    public static final int IGET_CHAR_JUMBO = 0x0bff;
-    public static final int IGET_SHORT_JUMBO = 0x0cff;
-    public static final int IPUT_JUMBO = 0x0dff;
-    public static final int IPUT_WIDE_JUMBO = 0x0eff;
-    public static final int IPUT_OBJECT_JUMBO = 0x0fff;
-    public static final int IPUT_BOOLEAN_JUMBO = 0x10ff;
-    public static final int IPUT_BYTE_JUMBO = 0x11ff;
-    public static final int IPUT_CHAR_JUMBO = 0x12ff;
-    public static final int IPUT_SHORT_JUMBO = 0x13ff;
-    public static final int SGET_JUMBO = 0x14ff;
-    public static final int SGET_WIDE_JUMBO = 0x15ff;
-    public static final int SGET_OBJECT_JUMBO = 0x16ff;
-    public static final int SGET_BOOLEAN_JUMBO = 0x17ff;
-    public static final int SGET_BYTE_JUMBO = 0x18ff;
-    public static final int SGET_CHAR_JUMBO = 0x19ff;
-    public static final int SGET_SHORT_JUMBO = 0x1aff;
-    public static final int SPUT_JUMBO = 0x1bff;
-    public static final int SPUT_WIDE_JUMBO = 0x1cff;
-    public static final int SPUT_OBJECT_JUMBO = 0x1dff;
-    public static final int SPUT_BOOLEAN_JUMBO = 0x1eff;
-    public static final int SPUT_BYTE_JUMBO = 0x1fff;
-    public static final int SPUT_CHAR_JUMBO = 0x20ff;
-    public static final int SPUT_SHORT_JUMBO = 0x21ff;
-    public static final int INVOKE_VIRTUAL_JUMBO = 0x22ff;
-    public static final int INVOKE_SUPER_JUMBO = 0x23ff;
-    public static final int INVOKE_DIRECT_JUMBO = 0x24ff;
-    public static final int INVOKE_STATIC_JUMBO = 0x25ff;
-    public static final int INVOKE_INTERFACE_JUMBO = 0x26ff;
-    // END(opcodes)
-
-    // TODO: Generate these payload opcodes with opcode-gen.
-
-    /**
-     * special pseudo-opcode value for packed-switch data payload
-     * instructions
-     */
-    public static final int PACKED_SWITCH_PAYLOAD = 0x100;
-
-    /** special pseudo-opcode value for packed-switch data payload
-     * instructions
-     */
-    public static final int SPARSE_SWITCH_PAYLOAD = 0x200;
-
-    /** special pseudo-opcode value for fill-array-data data payload
-     * instructions
-     */
-    public static final int FILL_ARRAY_DATA_PAYLOAD = 0x300;
-
-    /**
-     * This class is uninstantiable.
-     */
-    private Opcodes() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Determines if the given opcode has the right "shape" to be
-     * valid. This includes the range {@code 0x01..0xfe}, the range
-     * {@code 0x00ff..0xffff} where the low-order byte is either
-     * {@code 0} or {@code 0xff}, and the special opcode values {@code
-     * SPECIAL_FORMAT} and {@code NO_NEXT}. Note that not all of the
-     * opcode values that pass this test are in fact used. This method
-     * is meant to perform a quick check to reject blatantly wrong
-     * values (e.g. when validating arguments).
-     *
-     * @param opcode the opcode value
-     * @return {@code true} iff the value has the right "shape" to be
-     * possibly valid
-     */
-    public static boolean isValidShape(int opcode) {
-        /*
-         * Note: This method bakes in knowledge that all opcodes are
-         * one of the forms:
-         *
-         *   * single byte in range 0x01..0xfe -- normal opcodes
-         *   * (byteValue << 8) -- nop and data payload opcodes
-         *   * ((byteValue << 8) | 0xff) -- 16-bit extended opcodes
-         *   * SPECIAL_FORMAT or NO_NEXT -- pseudo-opcodes
-         */
-
-        // Note: SPECIAL_FORMAT == NO_NEXT.
-        if (opcode < SPECIAL_FORMAT) {
-            return false;
-        } else if (opcode == SPECIAL_FORMAT) {
-            return true;
-        }
-
-        int lowByte = opcode & 0xff;
-        if ((lowByte == 0) || (lowByte == 0xff)) {
-            return true;
-        }
-
-        return (opcode & 0xff00) == 0;
-    }
-
-    /**
-     * Gets whether ({@code true}) or not ({@code false}) the given
-     * opcode value is an "extended" opcode (not counting the nop-like
-     * payload opcodes). Extended opcodes require a full 16-bit code
-     * unit to represent, without leaving space for an argument byte.
-     * 
-     * @param opcode the opcode value
-     * @return {@code true} iff the opcode is an "extended" opcode
-     */
-    public static boolean isExtended(int opcode) {
-        /*
-         * Note: Extended opcodes all have the form ((byteValue << 8)
-         * | 0xff).
-         */
-        return (opcode >= 0x00ff);
-    }
-
-    /**
-     * Gets the opcode out of an opcode unit, the latter of which may also
-     * include one or more argument values.
-     *
-     * @param opcodeUnit the opcode-containing code unit
-     * @return the extracted opcode
-     */
-    public static int extractOpcodeFromUnit(int opcodeUnit) {
-        /*
-         * Note: This method bakes in knowledge that all opcodes are
-         * either single-byte or of the forms (byteValue << 8) or
-         * ((byteValue << 8) | 0xff).
-         */
-
-        int lowByte = opcodeUnit & 0xff;
-        return ((lowByte == 0) || (lowByte == 0xff)) ? opcodeUnit : lowByte;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/AddressMap.java b/dx/src/main/java/com/android/dx/io/instructions/AddressMap.java
deleted file mode 100644
index a8dbe0b..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/AddressMap.java
+++ /dev/null
@@ -1,52 +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.io.instructions;
-
-import java.io.EOFException;
-import java.util.HashMap;
-
-/**
- * Map from addresses to addresses, where addresses are all
- * {@code int}s.
- */
-public final class AddressMap {
-    /** underlying map. TODO: This might be too inefficient. */
-    private final HashMap<Integer,Integer> map;
-
-    /**
-     * Constructs an instance.
-     */
-    public AddressMap() {
-        map = new HashMap<Integer,Integer>();
-    }
-
-    /**
-     * Gets the value address corresponding to the given key address. Returns
-     * {@code -1} if there is no mapping.
-     */
-    public int get(int keyAddress) {
-        Integer value = map.get(keyAddress);
-        return (value == null) ? -1 : value;
-    }
-
-    /**
-     * Sets the value address associated with the given key address.
-     */
-    public void put(int keyAddress, int valueAddress) {
-        map.put(keyAddress, valueAddress);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/BaseCodeCursor.java b/dx/src/main/java/com/android/dx/io/instructions/BaseCodeCursor.java
deleted file mode 100644
index 6915fa8..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/BaseCodeCursor.java
+++ /dev/null
@@ -1,61 +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.io.instructions;
-
-import java.io.EOFException;
-
-/**
- * Base implementation of {@link CodeCursor}.
- */
-public abstract class BaseCodeCursor implements CodeCursor {
-    /** base address map */
-    private final AddressMap baseAddressMap;
-
-    /** next index within {@link #array} to read from or write to */
-    private int cursor;
-
-    /**
-     * Constructs an instance.
-     */
-    public BaseCodeCursor() {
-        this.baseAddressMap = new AddressMap();
-        this.cursor = 0;
-    }
-
-    /** @inheritDoc */
-    public final int cursor() {
-        return cursor;
-    }
-
-    /** @inheritDoc */
-    public final int baseAddressForCursor() {
-        int mapped = baseAddressMap.get(cursor);
-        return (mapped >= 0) ? mapped : cursor;
-    }
-
-    /** @inheritDoc */
-    public final void setBaseAddress(int targetAddress, int baseAddress) {
-        baseAddressMap.put(targetAddress, baseAddress);
-    }
-
-    /**
-     * Advance the cursor by the indicated amount.
-     */
-    protected final void advance(int amount) {
-        cursor += amount;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/CodeCursor.java b/dx/src/main/java/com/android/dx/io/instructions/CodeCursor.java
deleted file mode 100644
index 68eb9c9..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/CodeCursor.java
+++ /dev/null
@@ -1,47 +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.io.instructions;
-
-/**
- * Cursor over code units, for reading or writing out Dalvik bytecode.
- */
-public interface CodeCursor {
-    /**
-     * Gets the cursor. The cursor is the offset in code units from
-     * the start of the input of the next code unit to be read or
-     * written, where the input generally consists of the code for a
-     * single method.
-     */
-    public int cursor();
-
-    /**
-     * Gets the base address associated with the current cursor. This
-     * differs from the cursor value when explicitly set (by {@link
-     * #setBaseAddress). This is used, in particular, to convey base
-     * addresses to switch data payload instructions, whose relative
-     * addresses are relative to the address of a dependant switch
-     * instruction.
-     */
-    public int baseAddressForCursor();
-
-    /**
-     * Sets the base address for the given target address to be as indicated.
-     *
-     * @see #baseAddressForCursor
-     */
-    public void setBaseAddress(int targetAddress, int baseAddress);
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/CodeInput.java b/dx/src/main/java/com/android/dx/io/instructions/CodeInput.java
deleted file mode 100644
index 41a5ef7..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/CodeInput.java
+++ /dev/null
@@ -1,45 +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.io.instructions;
-
-import java.io.EOFException;
-
-/**
- * Input stream of code units, for reading in Dalvik bytecode.
- */
-public interface CodeInput extends CodeCursor {
-    /**
-     * Returns whether there are any more code units to read. This
-     * is analogous to {@code hasNext()} on an interator.
-     */
-    public boolean hasMore();
-
-    /**
-     * Reads a code unit.
-     */
-    public int read() throws EOFException;
-
-    /**
-     * Reads two code units, treating them as a little-endian {@code int}.
-     */
-    public int readInt() throws EOFException;
-
-    /**
-     * Reads four code units, treating them as a little-endian {@code long}.
-     */
-    public long readLong() throws EOFException;
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/CodeOutput.java b/dx/src/main/java/com/android/dx/io/instructions/CodeOutput.java
deleted file mode 100644
index 7d0077e..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/CodeOutput.java
+++ /dev/null
@@ -1,77 +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.io.instructions;
-
-/**
- * Output stream of code units, for writing out Dalvik bytecode.
- */
-public interface CodeOutput extends CodeCursor {
-    /**
-     * Writes a code unit.
-     */
-    public void write(short codeUnit);
-
-    /**
-     * Writes two code units.
-     */
-    public void write(short u0, short u1);
-
-    /**
-     * Writes three code units.
-     */
-    public void write(short u0, short u1, short u2);
-
-    /**
-     * Writes four code units.
-     */
-    public void write(short u0, short u1, short u2, short u3);
-
-    /**
-     * Writes five code units.
-     */
-    public void write(short u0, short u1, short u2, short u3, short u4);
-
-    /**
-     * Writes an {@code int}, little-endian.
-     */
-    public void writeInt(int value);
-
-    /**
-     * Writes a {@code long}, little-endian.
-     */
-    public void writeLong(long value);
-
-    /**
-     * Writes the contents of the given array.
-     */
-    public void write(byte[] data);
-
-    /**
-     * Writes the contents of the given array.
-     */
-    public void write(short[] data);
-
-    /**
-     * Writes the contents of the given array.
-     */
-    public void write(int[] data);
-
-    /**
-     * Writes the contents of the given array.
-     */
-    public void write(long[] data);
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/DecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/DecodedInstruction.java
deleted file mode 100644
index 9d9e88e..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/DecodedInstruction.java
+++ /dev/null
@@ -1,478 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-import com.android.dx.io.OpcodeInfo;
-import com.android.dx.io.Opcodes;
-import com.android.dx.util.DexException;
-import com.android.dx.util.Hex;
-import java.io.EOFException;
-
-/**
- * A decoded Dalvik instruction. This consists of a format codec, a
- * numeric opcode, an optional index type, and any additional
- * arguments of the instruction. The additional arguments (if any) are
- * represented as uninterpreted data.
- *
- * <p><b>Note:</b> The names of the arguments are <i>not</i> meant to
- * match the names given in the Dalvik instruction format
- * specification, specification which just names fields (somewhat)
- * arbitrarily alphabetically from A. In this class, non-register
- * fields are given descriptive names and register fields are
- * consistently named alphabetically.</p>
- */
-public abstract class DecodedInstruction {
-    /** non-null; instruction format / codec */
-    private final InstructionCodec format;
-
-    /** opcode number */
-    private final int opcode;
-
-    /** constant index argument */
-    private final int index;
-
-    /** null-ok; index type */
-    private final IndexType indexType;
-
-    /**
-     * target address argument. This is an absolute address, not just
-     * a signed offset. <b>Note:</b> The address is unsigned, even
-     * though it is stored in an {@code int}.
-     */
-    private final int target;
-
-    /**
-     * literal value argument; also used for special verification error
-     * constants (formats 20bc and 40sc) as well as should-be-zero values
-     * (formats 10x, 20t, 30t, and 32x)
-     */
-    private final long literal;
-
-    /**
-     * Decodes an instruction from the given input source.
-     */
-    public static DecodedInstruction decode(CodeInput in) throws EOFException {
-        int opcodeUnit = in.read();
-        int opcode = Opcodes.extractOpcodeFromUnit(opcodeUnit);
-        InstructionCodec format = OpcodeInfo.getFormat(opcode);
-
-        return format.decode(opcodeUnit, in);
-    }
-
-    /**
-     * Decodes an array of instructions. The result has non-null
-     * elements at each offset that represents the start of an
-     * instruction.
-     */
-    public static DecodedInstruction[] decodeAll(short[] encodedInstructions) {
-        int size = encodedInstructions.length;
-        DecodedInstruction[] decoded = new DecodedInstruction[size];
-        ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions);
-
-        try {
-            while (in.hasMore()) {
-                decoded[in.cursor()] = DecodedInstruction.decode(in);
-            }
-        } catch (EOFException ex) {
-            throw new DexException(ex);
-        }
-
-        return decoded;
-    }
-
-    /**
-     * Constructs an instance.
-     */
-    public DecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal) {
-        if (format == null) {
-            throw new NullPointerException("format == null");
-        }
-
-        if (!Opcodes.isValidShape(opcode)) {
-            throw new IllegalArgumentException("invalid opcode");
-        }
-
-        this.format = format;
-        this.opcode = opcode;
-        this.index = index;
-        this.indexType = indexType;
-        this.target = target;
-        this.literal = literal;
-    }
-
-    public final InstructionCodec getFormat() {
-        return format;
-    }
-
-    public final int getOpcode() {
-        return opcode;
-    }
-
-    /**
-     * Gets the opcode, as a code unit.
-     */
-    public final short getOpcodeUnit() {
-        return (short) opcode;
-    }
-
-    public final int getIndex() {
-        return index;
-    }
-
-    /**
-     * Gets the index, as a code unit.
-     */
-    public final short getIndexUnit() {
-        return (short) index;
-    }
-
-    public final IndexType getIndexType() {
-        return indexType;
-    }
-
-    /**
-     * Gets the raw target.
-     */
-    public final int getTarget() {
-        return target;
-    }
-
-    /**
-     * Gets the target as a relative offset from the given address.
-     */
-    public final int getTarget(int baseAddress) {
-        return target - baseAddress;
-    }
-
-    /**
-     * Gets the target as a relative offset from the given base
-     * address, as a code unit. This will throw if the value is out of
-     * the range of a signed code unit.
-     */
-    public final short getTargetUnit(int baseAddress) {
-        int relativeTarget = getTarget(baseAddress);
-
-        if (relativeTarget != (short) relativeTarget) {
-            throw new DexException("Target out of range: "
-                    + Hex.s4(relativeTarget));
-        }
-
-        return (short) relativeTarget;
-    }
-
-    /**
-     * Gets the target as a relative offset from the given base
-     * address, masked to be a byte in size. This will throw if the
-     * value is out of the range of a signed byte.
-     */
-    public final int getTargetByte(int baseAddress) {
-        int relativeTarget = getTarget(baseAddress);
-
-        if (relativeTarget != (byte) relativeTarget) {
-            throw new DexException("Target out of range: "
-                    + Hex.s4(relativeTarget));
-        }
-
-        return relativeTarget & 0xff;
-    }
-
-    public final long getLiteral() {
-        return literal;
-    }
-
-    /**
-     * Gets the literal value, masked to be an int in size. This will
-     * throw if the value is out of the range of a signed int.
-     */
-    public final int getLiteralInt() {
-        if (literal != (int) literal) {
-            throw new DexException("Literal out of range: " + Hex.u8(literal));
-        }
-
-        return (int) literal;
-    }
-
-    /**
-     * Gets the literal value, as a code unit. This will throw if the
-     * value is out of the range of a signed code unit.
-     */
-    public final short getLiteralUnit() {
-        if (literal != (short) literal) {
-            throw new DexException("Literal out of range: " + Hex.u8(literal));
-        }
-
-        return (short) literal;
-    }
-
-    /**
-     * Gets the literal value, masked to be a byte in size. This will
-     * throw if the value is out of the range of a signed byte.
-     */
-    public final int getLiteralByte() {
-        if (literal != (byte) literal) {
-            throw new DexException("Literal out of range: " + Hex.u8(literal));
-        }
-
-        return (int) literal & 0xff;
-    }
-
-    /**
-     * Gets the literal value, masked to be a nibble in size. This
-     * will throw if the value is out of the range of a signed nibble.
-     */
-    public final int getLiteralNibble() {
-        if ((literal < -8) || (literal > 7)) {
-            throw new DexException("Literal out of range: " + Hex.u8(literal));
-        }
-
-        return (int) literal & 0xf;
-    }
-
-    public abstract int getRegisterCount();
-
-    public int getA() {
-        return 0;
-    }
-
-    public int getB() {
-        return 0;
-    }
-
-    public int getC() {
-        return 0;
-    }
-
-    public int getD() {
-        return 0;
-    }
-
-    public int getE() {
-        return 0;
-    }
-
-    /**
-     * Gets the register count, as a code unit. This will throw if the
-     * value is out of the range of an unsigned code unit.
-     */
-    public final short getRegisterCountUnit() {
-        int registerCount = getRegisterCount();
-
-        if ((registerCount & ~0xffff) != 0) {
-            throw new DexException("Register count out of range: "
-                    + Hex.u8(registerCount));
-        }
-
-        return (short) registerCount;
-    }
-
-    /**
-     * Gets the A register number, as a code unit. This will throw if the
-     * value is out of the range of an unsigned code unit.
-     */
-    public final short getAUnit() {
-        int a = getA();
-
-        if ((a & ~0xffff) != 0) {
-            throw new DexException("Register A out of range: " + Hex.u8(a));
-        }
-
-        return (short) a;
-    }
-
-    /**
-     * Gets the A register number, as a byte. This will throw if the
-     * value is out of the range of an unsigned byte.
-     */
-    public final short getAByte() {
-        int a = getA();
-
-        if ((a & ~0xff) != 0) {
-            throw new DexException("Register A out of range: " + Hex.u8(a));
-        }
-
-        return (short) a;
-    }
-
-    /**
-     * Gets the A register number, as a nibble. This will throw if the
-     * value is out of the range of an unsigned nibble.
-     */
-    public final short getANibble() {
-        int a = getA();
-
-        if ((a & ~0xf) != 0) {
-            throw new DexException("Register A out of range: " + Hex.u8(a));
-        }
-
-        return (short) a;
-    }
-
-    /**
-     * Gets the B register number, as a code unit. This will throw if the
-     * value is out of the range of an unsigned code unit.
-     */
-    public final short getBUnit() {
-        int b = getB();
-
-        if ((b & ~0xffff) != 0) {
-            throw new DexException("Register B out of range: " + Hex.u8(b));
-        }
-
-        return (short) b;
-    }
-
-    /**
-     * Gets the B register number, as a byte. This will throw if the
-     * value is out of the range of an unsigned byte.
-     */
-    public final short getBByte() {
-        int b = getB();
-
-        if ((b & ~0xff) != 0) {
-            throw new DexException("Register B out of range: " + Hex.u8(b));
-        }
-
-        return (short) b;
-    }
-
-    /**
-     * Gets the B register number, as a nibble. This will throw if the
-     * value is out of the range of an unsigned nibble.
-     */
-    public final short getBNibble() {
-        int b = getB();
-
-        if ((b & ~0xf) != 0) {
-            throw new DexException("Register B out of range: " + Hex.u8(b));
-        }
-
-        return (short) b;
-    }
-
-    /**
-     * Gets the C register number, as a code unit. This will throw if the
-     * value is out of the range of an unsigned code unit.
-     */
-    public final short getCUnit() {
-        int c = getC();
-
-        if ((c & ~0xffff) != 0) {
-            throw new DexException("Register C out of range: " + Hex.u8(c));
-        }
-
-        return (short) c;
-    }
-
-    /**
-     * Gets the C register number, as a byte. This will throw if the
-     * value is out of the range of an unsigned byte.
-     */
-    public final short getCByte() {
-        int c = getC();
-
-        if ((c & ~0xff) != 0) {
-            throw new DexException("Register C out of range: " + Hex.u8(c));
-        }
-
-        return (short) c;
-    }
-
-    /**
-     * Gets the C register number, as a nibble. This will throw if the
-     * value is out of the range of an unsigned nibble.
-     */
-    public final short getCNibble() {
-        int c = getC();
-
-        if ((c & ~0xf) != 0) {
-            throw new DexException("Register C out of range: " + Hex.u8(c));
-        }
-
-        return (short) c;
-    }
-
-    /**
-     * Gets the D register number, as a code unit. This will throw if the
-     * value is out of the range of an unsigned code unit.
-     */
-    public final short getDUnit() {
-        int d = getD();
-
-        if ((d & ~0xffff) != 0) {
-            throw new DexException("Register D out of range: " + Hex.u8(d));
-        }
-
-        return (short) d;
-    }
-
-    /**
-     * Gets the D register number, as a byte. This will throw if the
-     * value is out of the range of an unsigned byte.
-     */
-    public final short getDByte() {
-        int d = getD();
-
-        if ((d & ~0xff) != 0) {
-            throw new DexException("Register D out of range: " + Hex.u8(d));
-        }
-
-        return (short) d;
-    }
-
-    /**
-     * Gets the D register number, as a nibble. This will throw if the
-     * value is out of the range of an unsigned nibble.
-     */
-    public final short getDNibble() {
-        int d = getD();
-
-        if ((d & ~0xf) != 0) {
-            throw new DexException("Register D out of range: " + Hex.u8(d));
-        }
-
-        return (short) d;
-    }
-
-    /**
-     * Gets the E register number, as a nibble. This will throw if the
-     * value is out of the range of an unsigned nibble.
-     */
-    public final short getENibble() {
-        int e = getE();
-
-        if ((e & ~0xf) != 0) {
-            throw new DexException("Register E out of range: " + Hex.u8(e));
-        }
-
-        return (short) e;
-    }
-
-    /**
-     * Encodes this instance to the given output.
-     */
-    public final void encode(CodeOutput out) {
-        format.encode(this, out);
-    }
-
-    /**
-     * Returns an instance just like this one, except with the index replaced
-     * with the given one.
-     */
-    public abstract DecodedInstruction withIndex(int newIndex);
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/FillArrayDataPayloadDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/FillArrayDataPayloadDecodedInstruction.java
deleted file mode 100644
index 64fc55b..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/FillArrayDataPayloadDecodedInstruction.java
+++ /dev/null
@@ -1,100 +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.io.instructions;
-
-/**
- * A decoded Dalvik instruction which contains the payload for
- * a {@code packed-switch} instruction.
- */
-public final class FillArrayDataPayloadDecodedInstruction
-        extends DecodedInstruction {
-    /** data array */
-    private final Object data;
-
-    /** number of elements */
-    private final int size;
-
-    /** element width */
-    private final int elementWidth;
-
-    /**
-     * Constructs an instance. This private instance doesn't check the
-     * type of the data array.
-     */
-    private FillArrayDataPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, Object data, int size, int elementWidth) {
-        super(format, opcode, 0, null, 0, 0L);
-
-        this.data = data;
-        this.size = size;
-        this.elementWidth = elementWidth;
-    }
-
-    /**
-     * Constructs an instance.
-     */
-    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, byte[] data) {
-        this(format, opcode, data, data.length, 1);
-    }
-
-    /**
-     * Constructs an instance.
-     */
-    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, short[] data) {
-        this(format, opcode, data, data.length, 2);
-    }
-
-    /**
-     * Constructs an instance.
-     */
-    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, int[] data) {
-        this(format, opcode, data, data.length, 4);
-    }
-
-    /**
-     * Constructs an instance.
-     */
-    public FillArrayDataPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, long[] data) {
-        this(format, opcode, data, data.length, 8);
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 0;
-    }
-
-    public short getElementWidthUnit() {
-        return (short) elementWidth;
-    }
-
-    public int getSize() {
-        return size;
-    }
-
-    public Object getData() {
-        return data;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        throw new UnsupportedOperationException("no index in instruction");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/FiveRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/FiveRegisterDecodedInstruction.java
deleted file mode 100644
index 6e14d34..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/FiveRegisterDecodedInstruction.java
+++ /dev/null
@@ -1,91 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has five register arguments.
- */
-public final class FiveRegisterDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /** register argument "B" */
-    private final int b;
-
-    /** register argument "C" */
-    private final int c;
-
-    /** register argument "D" */
-    private final int d;
-
-    /** register argument "E" */
-    private final int e;
-
-    /**
-     * Constructs an instance.
-     */
-    public FiveRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a, int b, int c, int d, int e) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-        this.b = b;
-        this.c = c;
-        this.d = d;
-        this.e = e;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 5;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public int getB() {
-        return b;
-    }
-
-    /** @inheritDoc */
-    public int getC() {
-        return c;
-    }
-
-    /** @inheritDoc */
-    public int getD() {
-        return d;
-    }
-
-    /** @inheritDoc */
-    public int getE() {
-        return e;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new FiveRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a, b, c, d, e);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/FourRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/FourRegisterDecodedInstruction.java
deleted file mode 100644
index 29836d0..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/FourRegisterDecodedInstruction.java
+++ /dev/null
@@ -1,82 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has five register arguments.
- */
-public final class FourRegisterDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /** register argument "B" */
-    private final int b;
-
-    /** register argument "C" */
-    private final int c;
-
-    /** register argument "D" */
-    private final int d;
-
-    /**
-     * Constructs an instance.
-     */
-    public FourRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a, int b, int c, int d) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-        this.b = b;
-        this.c = c;
-        this.d = d;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 4;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public int getB() {
-        return b;
-    }
-
-    /** @inheritDoc */
-    public int getC() {
-        return c;
-    }
-
-    /** @inheritDoc */
-    public int getD() {
-        return d;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new FourRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a, b, c, d);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/InstructionCodec.java b/dx/src/main/java/com/android/dx/io/instructions/InstructionCodec.java
deleted file mode 100644
index b864b83..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/InstructionCodec.java
+++ /dev/null
@@ -1,1099 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-import com.android.dx.io.OpcodeInfo;
-import com.android.dx.io.Opcodes;
-import com.android.dx.util.DexException;
-import com.android.dx.util.Hex;
-
-import java.io.EOFException;
-
-/**
- * Representation of an instruction format, which knows how to decode into
- * and encode from instances of {@link DecodedInstruction}.
- */
-public enum InstructionCodec {
-    FORMAT_00X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcodeUnit, 0, null,
-                    0, 0L);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(insn.getOpcodeUnit());
-        }
-    },
-
-    FORMAT_10X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int literal = byte1(opcodeUnit); // should be zero
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(insn.getOpcodeUnit());
-        }
-    },
-
-    FORMAT_12X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int b = nibble3(opcodeUnit);
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcodeUnit(),
-                             makeByte(insn.getA(), insn.getB())));
-        }
-    },
-
-    FORMAT_11N() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int literal = (nibble3(opcodeUnit) << 28) >> 28; // sign-extend
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcodeUnit(),
-                             makeByte(insn.getA(), insn.getLiteralNibble())));
-        }
-    },
-
-    FORMAT_11X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(codeUnit(insn.getOpcode(), insn.getA()));
-        }
-    },
-
-    FORMAT_10T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int target = (byte) byte1(opcodeUnit); // sign-extend
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    baseAddress + target, 0L);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int relativeTarget = insn.getTargetByte(out.cursor());
-            out.write(codeUnit(insn.getOpcode(), relativeTarget));
-        }
-    },
-
-    FORMAT_20T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int literal = byte1(opcodeUnit); // should be zero
-            int target = (short) in.read(); // sign-extend
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    baseAddress + target, literal);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            short relativeTarget = insn.getTargetUnit(out.cursor());
-            out.write(insn.getOpcodeUnit(), relativeTarget);
-        }
-    },
-
-    FORMAT_20BC() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            // Note: We use the literal field to hold the decoded AA value.
-            int opcode = byte0(opcodeUnit);
-            int literal = byte1(opcodeUnit);
-            int index = in.read();
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcode, index, IndexType.VARIES,
-                    0, literal);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getLiteralByte()),
-                    insn.getIndexUnit());
-        }
-    },
-
-    FORMAT_22X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int b = in.read();
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    insn.getBUnit());
-        }
-    },
-
-    FORMAT_21T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int target = (short) in.read(); // sign-extend
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    baseAddress + target, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            short relativeTarget = insn.getTargetUnit(out.cursor());
-            out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget);
-        }
-    },
-
-    FORMAT_21S() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int literal = (short) in.read(); // sign-extend
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    insn.getLiteralUnit());
-        }
-    },
-
-    FORMAT_21H() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            long literal = (short) in.read(); // sign-extend
-
-            /*
-             * Format 21h decodes differently depending on the opcode,
-             * because the "signed hat" might represent either a 32-
-             * or 64- bit value.
-             */
-            literal <<= (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;
-
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            // See above.
-            int opcode = insn.getOpcode();
-            int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;
-            short literal = (short) (insn.getLiteral() >> shift);
-
-            out.write(codeUnit(opcode, insn.getA()), literal);
-        }
-    },
-
-    FORMAT_21C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int index = in.read();
-            IndexType indexType = OpcodeInfo.getIndexType(opcode);
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, index, indexType,
-                    0, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    insn.getIndexUnit());
-        }
-    },
-
-    FORMAT_23X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int bc = in.read();
-            int b = byte0(bc);
-            int c = byte1(bc);
-            return new ThreeRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, 0L,
-                    a, b, c);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    codeUnit(insn.getB(), insn.getC()));
-        }
-    },
-
-    FORMAT_22B() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int bc = in.read();
-            int b = byte0(bc);
-            int literal = (byte) byte1(bc); // sign-extend
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    codeUnit(insn.getB(),
-                             insn.getLiteralByte()));
-        }
-    },
-
-    FORMAT_22T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int b = nibble3(opcodeUnit);
-            int target = (short) in.read(); // sign-extend
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    baseAddress + target, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            short relativeTarget = insn.getTargetUnit(out.cursor());
-            out.write(
-                    codeUnit(insn.getOpcode(),
-                             makeByte(insn.getA(), insn.getB())),
-                    relativeTarget);
-        }
-    },
-
-    FORMAT_22S() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int b = nibble3(opcodeUnit);
-            int literal = (short) in.read(); // sign-extend
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(),
-                             makeByte(insn.getA(), insn.getB())),
-                    insn.getLiteralUnit());
-        }
-    },
-
-    FORMAT_22C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int b = nibble3(opcodeUnit);
-            int index = in.read();
-            IndexType indexType = OpcodeInfo.getIndexType(opcode);
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, index, indexType,
-                    0, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(),
-                             makeByte(insn.getA(), insn.getB())),
-                    insn.getIndexUnit());
-        }
-    },
-
-    FORMAT_22CS() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = nibble2(opcodeUnit);
-            int b = nibble3(opcodeUnit);
-            int index = in.read();
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, index, IndexType.FIELD_OFFSET,
-                    0, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    codeUnit(insn.getOpcode(),
-                             makeByte(insn.getA(), insn.getB())),
-                    insn.getIndexUnit());
-        }
-    },
-
-    FORMAT_30T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int literal = byte1(opcodeUnit); // should be zero
-            int target = in.readInt();
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    baseAddress + target, literal);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int relativeTarget = insn.getTarget(out.cursor());
-            out.write(insn.getOpcodeUnit(),
-                    unit0(relativeTarget), unit1(relativeTarget));
-        }
-    },
-
-    FORMAT_32X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int literal = byte1(opcodeUnit); // should be zero
-            int a = in.read();
-            int b = in.read();
-            return new TwoRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(insn.getOpcodeUnit(), insn.getAUnit(), insn.getBUnit());
-        }
-    },
-
-    FORMAT_31I() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int literal = in.readInt();
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int literal = insn.getLiteralInt();
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    unit0(literal),
-                    unit1(literal));
-        }
-    },
-
-    FORMAT_31T() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.cursor() - 1;
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int target = baseAddress + in.readInt();
-
-            /*
-             * Switch instructions need to "forward" their addresses to their
-             * payload target instructions.
-             */
-            switch (opcode) {
-                case Opcodes.PACKED_SWITCH:
-                case Opcodes.SPARSE_SWITCH: {
-                    in.setBaseAddress(target, baseAddress);
-                    break;
-                }
-            }
-
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    target, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int relativeTarget = insn.getTarget(out.cursor());
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    unit0(relativeTarget), unit1(relativeTarget));
-        }
-    },
-
-    FORMAT_31C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            int index = in.readInt();
-            IndexType indexType = OpcodeInfo.getIndexType(opcode);
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, index, indexType,
-                    0, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int index = insn.getIndex();
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    unit0(index),
-                    unit1(index));
-        }
-    },
-
-    FORMAT_35C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterList(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterList(insn, out);
-        }
-    },
-
-    FORMAT_35MS() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterList(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterList(insn, out);
-        }
-    },
-
-    FORMAT_35MI() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterList(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterList(insn, out);
-        }
-    },
-
-    FORMAT_3RC() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterRange(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterRange(insn, out);
-        }
-    },
-
-    FORMAT_3RMS() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterRange(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterRange(insn, out);
-        }
-    },
-
-    FORMAT_3RMI() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            return decodeRegisterRange(this, opcodeUnit, in);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            encodeRegisterRange(insn, out);
-        }
-    },
-
-    FORMAT_51L() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int opcode = byte0(opcodeUnit);
-            int a = byte1(opcodeUnit);
-            long literal = in.readLong();
-            return new OneRegisterDecodedInstruction(
-                    this, opcode, 0, null,
-                    0, literal,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            long literal = insn.getLiteral();
-            out.write(
-                    codeUnit(insn.getOpcode(), insn.getA()),
-                    unit0(literal),
-                    unit1(literal),
-                    unit2(literal),
-                    unit3(literal));
-        }
-    },
-
-    FORMAT_33X() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int ab = in.read();
-            int a = byte0(ab);
-            int b = byte1(ab);
-            int c = in.read();
-            return new ThreeRegisterDecodedInstruction(
-                    this, opcodeUnit, 0, null,
-                    0, 0L,
-                    a, b, c);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    insn.getOpcodeUnit(),
-                    codeUnit(insn.getA(), insn.getB()),
-                    insn.getCUnit());
-        }
-    },
-
-    FORMAT_32S() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int ab = in.read();
-            int a = byte0(ab);
-            int b = byte1(ab);
-            int literal = (short) in.read(); // sign-extend
-            return new TwoRegisterDecodedInstruction(
-                    this, opcodeUnit, 0, null,
-                    0, literal,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            out.write(
-                    insn.getOpcodeUnit(),
-                    codeUnit(insn.getA(), insn.getB()),
-                    insn.getLiteralUnit());
-        }
-    },
-
-    FORMAT_40SC() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            // Note: We use the literal field to hold the decoded AA value.
-            int index = in.readInt();
-            int literal = in.read();
-            return new ZeroRegisterDecodedInstruction(
-                    this, opcodeUnit, index, IndexType.VARIES,
-                    0, literal);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int index = insn.getIndex();
-            out.write(
-                    insn.getOpcodeUnit(),
-                    unit0(index),
-                    unit1(index),
-                    insn.getLiteralUnit());
-        }
-    },
-
-    FORMAT_41C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int index = in.readInt();
-            int a = in.read();
-            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
-            return new OneRegisterDecodedInstruction(
-                    this, opcodeUnit, index, indexType,
-                    0, 0L,
-                    a);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int index = insn.getIndex();
-            out.write(
-                    insn.getOpcodeUnit(),
-                    unit0(index),
-                    unit1(index),
-                    insn.getAUnit());
-        }
-    },
-
-    FORMAT_52C() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int index = in.readInt();
-            int a = in.read();
-            int b = in.read();
-            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
-            return new TwoRegisterDecodedInstruction(
-                    this, opcodeUnit, index, indexType,
-                    0, 0L,
-                    a, b);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int index = insn.getIndex();
-            out.write(
-                    insn.getOpcodeUnit(),
-                    unit0(index),
-                    unit1(index),
-                    insn.getAUnit(),
-                    insn.getBUnit());
-        }
-    },
-
-    FORMAT_5RC() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int index = in.readInt();
-            int registerCount = in.read();
-            int a = in.read();
-            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
-            return new RegisterRangeDecodedInstruction(
-                    this, opcodeUnit, index, indexType,
-                    0, 0L,
-                    a, registerCount);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            int index = insn.getIndex();
-            out.write(
-                    insn.getOpcodeUnit(),
-                    unit0(index),
-                    unit1(index),
-                    insn.getRegisterCountUnit(),
-                    insn.getAUnit());
-        }
-    },
-
-    FORMAT_PACKED_SWITCH_PAYLOAD() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode
-            int size = in.read();
-            int firstKey = in.readInt();
-            int[] targets = new int[size];
-
-            for (int i = 0; i < size; i++) {
-                targets[i] = baseAddress + in.readInt();
-            }
-
-            return new PackedSwitchPayloadDecodedInstruction(
-                    this, opcodeUnit, firstKey, targets);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            PackedSwitchPayloadDecodedInstruction payload =
-                (PackedSwitchPayloadDecodedInstruction) insn;
-            int[] targets = payload.getTargets();
-            int baseAddress = out.baseAddressForCursor();
-
-            out.write(payload.getOpcodeUnit());
-            out.write(asUnsignedUnit(targets.length));
-            out.writeInt(payload.getFirstKey());
-
-            for (int target : targets) {
-                out.writeInt(target - baseAddress);
-            }
-        }
-    },
-
-    FORMAT_SPARSE_SWITCH_PAYLOAD() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int baseAddress = in.baseAddressForCursor() - 1; // already read opcode
-            int size = in.read();
-            int[] keys = new int[size];
-            int[] targets = new int[size];
-
-            for (int i = 0; i < size; i++) {
-                keys[i] = in.readInt();
-            }
-
-            for (int i = 0; i < size; i++) {
-                targets[i] = baseAddress + in.readInt();
-            }
-
-            return new SparseSwitchPayloadDecodedInstruction(
-                    this, opcodeUnit, keys, targets);
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            SparseSwitchPayloadDecodedInstruction payload =
-                (SparseSwitchPayloadDecodedInstruction) insn;
-            int[] keys = payload.getKeys();
-            int[] targets = payload.getTargets();
-            int baseAddress = out.baseAddressForCursor();
-
-            out.write(payload.getOpcodeUnit());
-            out.write(asUnsignedUnit(targets.length));
-
-            for (int key : keys) {
-                out.writeInt(key);
-            }
-
-            for (int target : targets) {
-                out.writeInt(target - baseAddress);
-            }
-        }
-    },
-
-    FORMAT_FILL_ARRAY_DATA_PAYLOAD() {
-        @Override public DecodedInstruction decode(int opcodeUnit,
-                CodeInput in) throws EOFException {
-            int elementWidth = in.read();
-            int size = in.readInt();
-
-            switch (elementWidth) {
-                case 1: {
-                    byte[] array = new byte[size];
-                    boolean even = true;
-                    for (int i = 0, value = 0; i < size; i++, even = !even) {
-                        if (even) {
-                            value = in.read();
-                        }
-                        array[i] = (byte) (value & 0xff);
-                        value >>= 8;
-                    }
-                    return new FillArrayDataPayloadDecodedInstruction(
-                            this, opcodeUnit, array);
-                }
-                case 2: {
-                    short[] array = new short[size];
-                    for (int i = 0; i < size; i++) {
-                        array[i] = (short) in.read();
-                    }
-                    return new FillArrayDataPayloadDecodedInstruction(
-                            this, opcodeUnit, array);
-                }
-                case 4: {
-                    int[] array = new int[size];
-                    for (int i = 0; i < size; i++) {
-                        array[i] = in.readInt();
-                    }
-                    return new FillArrayDataPayloadDecodedInstruction(
-                            this, opcodeUnit, array);
-                }
-                case 8: {
-                    long[] array = new long[size];
-                    for (int i = 0; i < size; i++) {
-                        array[i] = in.readLong();
-                    }
-                    return new FillArrayDataPayloadDecodedInstruction(
-                            this, opcodeUnit, array);
-                }
-            }
-
-            throw new DexException("bogus element_width: "
-                    + Hex.u2(elementWidth));
-        }
-
-        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
-            FillArrayDataPayloadDecodedInstruction payload =
-                (FillArrayDataPayloadDecodedInstruction) insn;
-            short elementWidth = payload.getElementWidthUnit();
-            Object data = payload.getData();
-
-            out.write(payload.getOpcodeUnit());
-            out.write(elementWidth);
-            out.writeInt(payload.getSize());
-
-            switch (elementWidth) {
-                case 1: out.write((byte[]) data);  break;
-                case 2: out.write((short[]) data); break;
-                case 4: out.write((int[]) data);   break;
-                case 8: out.write((long[]) data);  break;
-                default: {
-                    throw new DexException("bogus element_width: "
-                            + Hex.u2(elementWidth));
-                }
-            }
-        }
-    };
-
-    /**
-     * Decodes an instruction specified by the given opcode unit, reading
-     * any required additional code units from the given input source.
-     */
-    public abstract DecodedInstruction decode(int opcodeUnit, CodeInput in)
-        throws EOFException;
-
-    /**
-     * Encodes the given instruction.
-     */
-    public abstract void encode(DecodedInstruction insn, CodeOutput out);
-
-    /**
-     * Helper method that decodes any of the register-list formats.
-     */
-    private static DecodedInstruction decodeRegisterList(
-            InstructionCodec format, int opcodeUnit, CodeInput in)
-            throws EOFException {
-        int opcode = byte0(opcodeUnit);
-        int e = nibble2(opcodeUnit);
-        int registerCount = nibble3(opcodeUnit);
-        int index = in.read();
-        int abcd = in.read();
-        int a = nibble0(abcd);
-        int b = nibble1(abcd);
-        int c = nibble2(abcd);
-        int d = nibble3(abcd);
-        IndexType indexType = OpcodeInfo.getIndexType(opcode);
-
-        // TODO: Having to switch like this is less than ideal.
-        switch (registerCount) {
-            case 0:
-                return new ZeroRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L);
-            case 1:
-                return new OneRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L,
-                        a);
-            case 2:
-                return new TwoRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L,
-                        a, b);
-            case 3:
-                return new ThreeRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L,
-                        a, b, c);
-            case 4:
-                return new FourRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L,
-                        a, b, c, d);
-            case 5:
-                return new FiveRegisterDecodedInstruction(
-                        format, opcode, index, indexType,
-                        0, 0L,
-                        a, b, c, d, e);
-        }
-
-        throw new DexException("bogus registerCount: "
-                + Hex.uNibble(registerCount));
-    }
-
-    /**
-     * Helper method that encodes any of the register-list formats.
-     */
-    private static void encodeRegisterList(DecodedInstruction insn,
-            CodeOutput out) {
-        out.write(codeUnit(insn.getOpcode(),
-                        makeByte(insn.getE(), insn.getRegisterCount())),
-                insn.getIndexUnit(),
-                codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD()));
-    }
-
-    /**
-     * Helper method that decodes any of the three-unit register-range formats.
-     */
-    private static DecodedInstruction decodeRegisterRange(
-            InstructionCodec format, int opcodeUnit, CodeInput in)
-            throws EOFException {
-        int opcode = byte0(opcodeUnit);
-        int registerCount = byte1(opcodeUnit);
-        int index = in.read();
-        int a = in.read();
-        IndexType indexType = OpcodeInfo.getIndexType(opcode);
-        return new RegisterRangeDecodedInstruction(
-                format, opcode, index, indexType,
-                0, 0L,
-                a, registerCount);
-    }
-
-    /**
-     * Helper method that encodes any of the three-unit register-range formats.
-     */
-    private static void encodeRegisterRange(DecodedInstruction insn,
-            CodeOutput out) {
-        out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()),
-                insn.getIndexUnit(),
-                insn.getAUnit());
-    }
-
-    private static short codeUnit(int lowByte, int highByte) {
-        if ((lowByte & ~0xff) != 0) {
-            throw new IllegalArgumentException("bogus lowByte");
-        }
-
-        if ((highByte & ~0xff) != 0) {
-            throw new IllegalArgumentException("bogus highByte");
-        }
-
-        return (short) (lowByte | (highByte << 8));
-    }
-
-    private static short codeUnit(int nibble0, int nibble1, int nibble2,
-            int nibble3) {
-        if ((nibble0 & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus nibble0");
-        }
-
-        if ((nibble1 & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus nibble1");
-        }
-
-        if ((nibble2 & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus nibble2");
-        }
-
-        if ((nibble3 & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus nibble3");
-        }
-
-        return (short) (nibble0 | (nibble1 << 4)
-                | (nibble2 << 8) | (nibble3 << 12));
-    }
-
-    private static int makeByte(int lowNibble, int highNibble) {
-        if ((lowNibble & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus lowNibble");
-        }
-
-        if ((highNibble & ~0xf) != 0) {
-            throw new IllegalArgumentException("bogus highNibble");
-        }
-
-        return lowNibble | (highNibble << 4);
-    }
-
-    private static short asUnsignedUnit(int value) {
-        if ((value & ~0xffff) != 0) {
-            throw new IllegalArgumentException("bogus unsigned code unit");
-        }
-
-        return (short) value;
-    }
-
-    private static short unit0(int value) {
-        return (short) value;
-    }
-
-    private static short unit1(int value) {
-        return (short) (value >> 16);
-    }
-
-    private static short unit0(long value) {
-        return (short) value;
-    }
-
-    private static short unit1(long value) {
-        return (short) (value >> 16);
-    }
-
-    private static short unit2(long value) {
-        return (short) (value >> 32);
-    }
-
-    private static short unit3(long value) {
-        return (short) (value >> 48);
-    }
-
-    private static int byte0(int value) {
-        return value & 0xff;
-    }
-
-    private static int byte1(int value) {
-        return (value >> 8) & 0xff;
-    }
-
-    private static int byte2(int value) {
-        return (value >> 16) & 0xff;
-    }
-
-    private static int byte3(int value) {
-        return value >>> 24;
-    }
-
-    private static int nibble0(int value) {
-        return value & 0xf;
-    }
-
-    private static int nibble1(int value) {
-        return (value >> 4) & 0xf;
-    }
-
-    private static int nibble2(int value) {
-        return (value >> 8) & 0xf;
-    }
-
-    private static int nibble3(int value) {
-        return (value >> 12) & 0xf;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/OneRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/OneRegisterDecodedInstruction.java
deleted file mode 100644
index fd38e3b..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/OneRegisterDecodedInstruction.java
+++ /dev/null
@@ -1,55 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has one register argument.
- */
-public final class OneRegisterDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /**
-     * Constructs an instance.
-     */
-    public OneRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 1;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new OneRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/PackedSwitchPayloadDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/PackedSwitchPayloadDecodedInstruction.java
deleted file mode 100644
index c31d319..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/PackedSwitchPayloadDecodedInstruction.java
+++ /dev/null
@@ -1,62 +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.io.instructions;
-
-/**
- * A decoded Dalvik instruction which contains the payload for
- * a {@code packed-switch} instruction.
- */
-public final class PackedSwitchPayloadDecodedInstruction
-        extends DecodedInstruction {
-    /** first key value */
-    private final int firstKey;
-
-    /**
-     * array of target addresses. These are absolute, not relative,
-     * addresses.
-     */
-    private final int[] targets;
-
-    /**
-     * Constructs an instance.
-     */
-    public PackedSwitchPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, int firstKey, int[] targets) {
-        super(format, opcode, 0, null, 0, 0L);
-
-        this.firstKey = firstKey;
-        this.targets = targets;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 0;
-    }
-
-    public int getFirstKey() {
-        return firstKey;
-    }
-
-    public int[] getTargets() {
-        return targets;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        throw new UnsupportedOperationException("no index in instruction");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/RegisterRangeDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/RegisterRangeDecodedInstruction.java
deleted file mode 100644
index f294f63..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/RegisterRangeDecodedInstruction.java
+++ /dev/null
@@ -1,60 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has register range arguments (an
- * "A" start register and a register count).
- */
-public final class RegisterRangeDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /** register count */
-    private final int registerCount;
-
-    /**
-     * Constructs an instance.
-     */
-    public RegisterRangeDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a, int registerCount) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-        this.registerCount = registerCount;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return registerCount;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new RegisterRangeDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a, registerCount);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeInput.java b/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeInput.java
deleted file mode 100644
index 49ce473..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeInput.java
+++ /dev/null
@@ -1,73 +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.io.instructions;
-
-import java.io.EOFException;
-
-/**
- * Implementation of {@code CodeInput} that reads from a {@code short[]}.
- */
-public final class ShortArrayCodeInput extends BaseCodeCursor
-        implements CodeInput {
-    /** source array to read from */
-    private final short[] array;
-
-    /**
-     * Constructs an instance.
-     */
-    public ShortArrayCodeInput(short[] array) {
-        if (array == null) {
-            throw new NullPointerException("array == null");
-        }
-
-        this.array = array;
-    }
-
-    /** @inheritDoc */
-    public boolean hasMore() {
-        return cursor() < array.length;
-    }
-
-    /** @inheritDoc */
-    public int read() throws EOFException {
-        try {
-            int value = array[cursor()];
-            advance(1);
-            return value & 0xffff;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            throw new EOFException();
-        }
-    }
-
-    /** @inheritDoc */
-    public int readInt() throws EOFException {
-        int short0 = read();
-        int short1 = read();
-
-        return short0 | (short1 << 16);
-    }
-
-    /** @inheritDoc */
-    public long readLong() throws EOFException {
-        long short0 = read();
-        long short1 = read();
-        long short2 = read();
-        long short3 = read();
-
-        return short0 | (short1 << 16) | (short2 << 32) | (short3 << 48);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeOutput.java b/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeOutput.java
deleted file mode 100644
index efa7ddd..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/ShortArrayCodeOutput.java
+++ /dev/null
@@ -1,146 +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.io.instructions;
-
-/**
- * Implementation of {@code CodeOutput} that writes to a {@code short[]}.
- */
-public final class ShortArrayCodeOutput extends BaseCodeCursor
-        implements CodeOutput {
-    /** array to write to */
-    private final short[] array;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param maxSize the maximum number of code units that will be written
-     */
-    public ShortArrayCodeOutput(int maxSize) {
-        if (maxSize < 0) {
-            throw new IllegalArgumentException("maxSize < 0");
-        }
-
-        this.array = new short[maxSize];
-    }
-
-    /**
-     * Gets the array. The returned array contains exactly the data
-     * written (e.g. no leftover space at the end).
-     */
-    public short[] getArray() {
-        int cursor = cursor();
-
-        if (cursor == array.length) {
-            return array;
-        }
-
-        short[] result = new short[cursor];
-        System.arraycopy(array, 0, result, 0, cursor);
-        return result;
-    }
-
-    /** @inheritDoc */
-    public void write(short codeUnit) {
-        array[cursor()] = codeUnit;
-        advance(1);
-    }
-
-    /** @inheritDoc */
-    public void write(short u0, short u1) {
-        write(u0);
-        write(u1);
-    }
-
-    /** @inheritDoc */
-    public void write(short u0, short u1, short u2) {
-        write(u0);
-        write(u1);
-        write(u2);
-    }
-
-    /** @inheritDoc */
-    public void write(short u0, short u1, short u2, short u3) {
-        write(u0);
-        write(u1);
-        write(u2);
-        write(u3);
-    }
-
-    /** @inheritDoc */
-    public void write(short u0, short u1, short u2, short u3, short u4) {
-        write(u0);
-        write(u1);
-        write(u2);
-        write(u3);
-        write(u4);
-    }
-
-    /** @inheritDoc */
-    public void writeInt(int value) {
-        write((short) value);
-        write((short) (value >> 16));
-    }
-
-    /** @inheritDoc */
-    public void writeLong(long value) {
-        write((short) value);
-        write((short) (value >> 16));
-        write((short) (value >> 32));
-        write((short) (value >> 48));
-    }
-
-    /** @inheritDoc */
-    public void write(byte[] data) {
-        int value = 0;
-        boolean even = true;
-        for (byte b : data) {
-            if (even) {
-                value = b & 0xff;
-                even = false;
-            } else {
-                value |= b << 8;
-                write((short) value);
-                even = true;
-            }
-        }
-
-        if (!even) {
-            write((short) value);
-        }
-    }
-
-    /** @inheritDoc */
-    public void write(short[] data) {
-        for (short unit : data) {
-            write(unit);
-        }
-    }
-
-    /** @inheritDoc */
-    public void write(int[] data) {
-        for (int i : data) {
-            writeInt(i);
-        }
-    }
-
-    /** @inheritDoc */
-    public void write(long[] data) {
-        for (long l : data) {
-            writeLong(l);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/SparseSwitchPayloadDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/SparseSwitchPayloadDecodedInstruction.java
deleted file mode 100644
index bfc47c9..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/SparseSwitchPayloadDecodedInstruction.java
+++ /dev/null
@@ -1,66 +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.io.instructions;
-
-/**
- * A decoded Dalvik instruction which contains the payload for
- * a {@code packed-switch} instruction.
- */
-public final class SparseSwitchPayloadDecodedInstruction
-        extends DecodedInstruction {
-    /** array of key values */
-    private final int[] keys;
-
-    /**
-     * array of target addresses. These are absolute, not relative,
-     * addresses.
-     */
-    private final int[] targets;
-
-    /**
-     * Constructs an instance.
-     */
-    public SparseSwitchPayloadDecodedInstruction(InstructionCodec format,
-            int opcode, int[] keys, int[] targets) {
-        super(format, opcode, 0, null, 0, 0L);
-
-        if (keys.length != targets.length) {
-            throw new IllegalArgumentException("keys/targets length mismatch");
-        }
-
-        this.keys = keys;
-        this.targets = targets;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 0;
-    }
-
-    public int[] getKeys() {
-        return keys;
-    }
-
-    public int[] getTargets() {
-        return targets;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        throw new UnsupportedOperationException("no index in instruction");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/ThreeRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/ThreeRegisterDecodedInstruction.java
deleted file mode 100644
index a463677..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/ThreeRegisterDecodedInstruction.java
+++ /dev/null
@@ -1,73 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has three register arguments.
- */
-public final class ThreeRegisterDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /** register argument "B" */
-    private final int b;
-
-    /** register argument "C" */
-    private final int c;
-
-    /**
-     * Constructs an instance.
-     */
-    public ThreeRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a, int b, int c) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-        this.b = b;
-        this.c = c;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 3;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public int getB() {
-        return b;
-    }
-
-    /** @inheritDoc */
-    public int getC() {
-        return c;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new ThreeRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a, b, c);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/TwoRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/TwoRegisterDecodedInstruction.java
deleted file mode 100644
index acb77ba..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/TwoRegisterDecodedInstruction.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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has two register arguments.
- */
-public final class TwoRegisterDecodedInstruction extends DecodedInstruction {
-    /** register argument "A" */
-    private final int a;
-
-    /** register argument "B" */
-    private final int b;
-
-    /**
-     * Constructs an instance.
-     */
-    public TwoRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal,
-            int a, int b) {
-        super(format, opcode, index, indexType, target, literal);
-
-        this.a = a;
-        this.b = b;
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 2;
-    }
-
-    /** @inheritDoc */
-    public int getA() {
-        return a;
-    }
-
-    /** @inheritDoc */
-    public int getB() {
-        return b;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new TwoRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral(), a, b);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/io/instructions/ZeroRegisterDecodedInstruction.java b/dx/src/main/java/com/android/dx/io/instructions/ZeroRegisterDecodedInstruction.java
deleted file mode 100644
index 172caa4..0000000
--- a/dx/src/main/java/com/android/dx/io/instructions/ZeroRegisterDecodedInstruction.java
+++ /dev/null
@@ -1,44 +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.io.instructions;
-
-import com.android.dx.io.IndexType;
-
-/**
- * A decoded Dalvik instruction which has no register arguments.
- */
-public final class ZeroRegisterDecodedInstruction extends DecodedInstruction {
-    /**
-     * Constructs an instance.
-     */
-    public ZeroRegisterDecodedInstruction(InstructionCodec format, int opcode,
-            int index, IndexType indexType, int target, long literal) {
-        super(format, opcode, index, indexType, target, literal);
-    }
-
-    /** @inheritDoc */
-    public int getRegisterCount() {
-        return 0;
-    }
-
-    /** @inheritDoc */
-    public DecodedInstruction withIndex(int newIndex) {
-        return new ZeroRegisterDecodedInstruction(
-                getFormat(), getOpcode(), newIndex, getIndexType(),
-                getTarget(), getLiteral());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/annotation/Annotation.java b/dx/src/main/java/com/android/dx/rop/annotation/Annotation.java
deleted file mode 100644
index 8f9e976..0000000
--- a/dx/src/main/java/com/android/dx/rop/annotation/Annotation.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.annotation;
-
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.MutabilityControl;
-import com.android.dx.util.ToHuman;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.TreeMap;
-
-/**
- * An annotation on an element of a class. Annotations have an
- * associated type and additionally consist of a set of (name, value)
- * pairs, where the names are unique.
- */
-public final class Annotation extends MutabilityControl
-        implements Comparable<Annotation>, ToHuman {
-    /** {@code non-null;} type of the annotation */
-    private final CstType type;
-
-    /** {@code non-null;} the visibility of the annotation */
-    private final AnnotationVisibility visibility;
-
-    /** {@code non-null;} map from names to {@link NameValuePair} instances */
-    private final TreeMap<CstString, NameValuePair> elements;
-
-    /**
-     * Construct an instance. It initially contains no elements.
-     *
-     * @param type {@code non-null;} type of the annotation
-     * @param visibility {@code non-null;} the visibility of the annotation
-     */
-    public Annotation(CstType type, AnnotationVisibility visibility) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        if (visibility == null) {
-            throw new NullPointerException("visibility == null");
-        }
-
-        this.type = type;
-        this.visibility = visibility;
-        this.elements = new TreeMap<CstString, NameValuePair>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (! (other instanceof Annotation)) {
-            return false;
-        }
-
-        Annotation otherAnnotation = (Annotation) other;
-
-        if (! (type.equals(otherAnnotation.type)
-                        && (visibility == otherAnnotation.visibility))) {
-            return false;
-        }
-
-        return elements.equals(otherAnnotation.elements);
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        int hash = type.hashCode();
-        hash = (hash * 31) + elements.hashCode();
-        hash = (hash * 31) + visibility.hashCode();
-        return hash;
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(Annotation other) {
-        int result = type.compareTo(other.type);
-
-        if (result != 0) {
-            return result;
-        }
-
-        result = visibility.compareTo(other.visibility);
-
-        if (result != 0) {
-            return result;
-        }
-
-        Iterator<NameValuePair> thisIter = elements.values().iterator();
-        Iterator<NameValuePair> otherIter = other.elements.values().iterator();
-
-        while (thisIter.hasNext() && otherIter.hasNext()) {
-            NameValuePair thisOne = thisIter.next();
-            NameValuePair otherOne = otherIter.next();
-
-            result = thisOne.compareTo(otherOne);
-            if (result != 0) {
-                return result;
-            }
-        }
-
-        if (thisIter.hasNext()) {
-            return 1;
-        } else if (otherIter.hasNext()) {
-            return -1;
-        }
-
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return toHuman();
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(visibility.toHuman());
-        sb.append("-annotation ");
-        sb.append(type.toHuman());
-        sb.append(" {");
-
-        boolean first = true;
-        for (NameValuePair pair : elements.values()) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            sb.append(pair.getName().toHuman());
-            sb.append(": ");
-            sb.append(pair.getValue().toHuman());
-        }
-
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     * Gets the type of this instance.
-     *
-     * @return {@code non-null;} the type
-     */
-    public CstType getType() {
-        return type;
-    }
-
-    /**
-     * Gets the visibility of this instance.
-     *
-     * @return {@code non-null;} the visibility
-     */
-    public AnnotationVisibility getVisibility() {
-        return visibility;
-    }
-
-    /**
-     * Put an element into the set of (name, value) pairs for this instance.
-     * If there is a preexisting element with the same name, it will be
-     * replaced by this method.
-     *
-     * @param pair {@code non-null;} the (name, value) pair to place into this instance
-     */
-    public void put(NameValuePair pair) {
-        throwIfImmutable();
-
-        if (pair == null) {
-            throw new NullPointerException("pair == null");
-        }
-
-        elements.put(pair.getName(), pair);
-    }
-
-    /**
-     * Add an element to the set of (name, value) pairs for this instance.
-     * It is an error to call this method if there is a preexisting element
-     * with the same name.
-     *
-     * @param pair {@code non-null;} the (name, value) pair to add to this instance
-     */
-    public void add(NameValuePair pair) {
-        throwIfImmutable();
-
-        if (pair == null) {
-            throw new NullPointerException("pair == null");
-        }
-
-        CstString name = pair.getName();
-
-        if (elements.get(name) != null) {
-            throw new IllegalArgumentException("name already added: " + name);
-        }
-
-        elements.put(name, pair);
-    }
-
-    /**
-     * Gets the set of name-value pairs contained in this instance. The
-     * result is always unmodifiable.
-     *
-     * @return {@code non-null;} the set of name-value pairs
-     */
-    public Collection<NameValuePair> getNameValuePairs() {
-        return Collections.unmodifiableCollection(elements.values());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/annotation/AnnotationVisibility.java b/dx/src/main/java/com/android/dx/rop/annotation/AnnotationVisibility.java
deleted file mode 100644
index c717b8c..0000000
--- a/dx/src/main/java/com/android/dx/rop/annotation/AnnotationVisibility.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 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.rop.annotation;
-
-import com.android.dx.util.ToHuman;
-
-/**
- * Visibility scope of an annotation.
- */
-public enum AnnotationVisibility implements ToHuman {
-    RUNTIME("runtime"),
-    BUILD("build"),
-    SYSTEM("system"),
-    EMBEDDED("embedded");
-
-    /** {@code non-null;} the human-oriented string representation */
-    private final String human;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param human {@code non-null;} the human-oriented string representation
-     */
-    private AnnotationVisibility(String human) {
-        this.human = human;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return human;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/annotation/Annotations.java b/dx/src/main/java/com/android/dx/rop/annotation/Annotations.java
deleted file mode 100644
index 807d5d4..0000000
--- a/dx/src/main/java/com/android/dx/rop/annotation/Annotations.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.annotation;
-
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.MutabilityControl;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.TreeMap;
-
-/**
- * List of {@link Annotation} instances.
- */
-public final class Annotations extends MutabilityControl
-        implements Comparable<Annotations> {
-    /** {@code non-null;} immutable empty instance */
-    public static final Annotations EMPTY = new Annotations();
-
-    static {
-        EMPTY.setImmutable();
-    }
-
-    /** {@code non-null;} map from types to annotations */
-    private final TreeMap<CstType, Annotation> annotations;
-
-    /**
-     * Constructs an immutable instance which is the combination of the
-     * two given instances. The two instances must contain disjoint sets
-     * of types.
-     *
-     * @param a1 {@code non-null;} an instance
-     * @param a2 {@code non-null;} the other instance
-     * @return {@code non-null;} the combination
-     * @throws IllegalArgumentException thrown if there is a duplicate type
-     */
-    public static Annotations combine(Annotations a1, Annotations a2) {
-        Annotations result = new Annotations();
-
-        result.addAll(a1);
-        result.addAll(a2);
-        result.setImmutable();
-
-        return result;
-    }
-
-    /**
-     * Constructs an immutable instance which is the combination of the
-     * given instance with the given additional annotation. The latter's
-     * type must not already appear in the former.
-     *
-     * @param annotations {@code non-null;} the instance to augment
-     * @param annotation {@code non-null;} the additional annotation
-     * @return {@code non-null;} the combination
-     * @throws IllegalArgumentException thrown if there is a duplicate type
-     */
-    public static Annotations combine(Annotations annotations,
-            Annotation annotation) {
-        Annotations result = new Annotations();
-
-        result.addAll(annotations);
-        result.add(annotation);
-        result.setImmutable();
-
-        return result;
-    }
-
-    /**
-     * Constructs an empty instance.
-     */
-    public Annotations() {
-        annotations = new TreeMap<CstType, Annotation>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return annotations.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (! (other instanceof Annotations)) {
-            return false;
-        }
-
-        Annotations otherAnnotations = (Annotations) other;
-
-        return annotations.equals(otherAnnotations.annotations);
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(Annotations other) {
-        Iterator<Annotation> thisIter = annotations.values().iterator();
-        Iterator<Annotation> otherIter = other.annotations.values().iterator();
-
-        while (thisIter.hasNext() && otherIter.hasNext()) {
-            Annotation thisOne = thisIter.next();
-            Annotation otherOne = otherIter.next();
-
-            int result = thisOne.compareTo(otherOne);
-            if (result != 0) {
-                return result;
-            }
-        }
-
-        if (thisIter.hasNext()) {
-            return 1;
-        } else if (otherIter.hasNext()) {
-            return -1;
-        }
-
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        boolean first = true;
-
-        sb.append("annotations{");
-
-        for (Annotation a : annotations.values()) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            sb.append(a.toHuman());
-        }
-
-        sb.append("}");
-        return sb.toString();
-    }
-
-    /**
-     * Gets the number of elements in this instance.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int size() {
-        return annotations.size();
-    }
-
-    /**
-     * Adds an element to this instance. There must not already be an
-     * element of the same type.
-     *
-     * @param annotation {@code non-null;} the element to add
-     * @throws IllegalArgumentException thrown if there is a duplicate type
-     */
-    public void add(Annotation annotation) {
-        throwIfImmutable();
-
-        if (annotation == null) {
-            throw new NullPointerException("annotation == null");
-        }
-
-        CstType type = annotation.getType();
-
-        if (annotations.containsKey(type)) {
-            throw new IllegalArgumentException("duplicate type: " +
-                    type.toHuman());
-        }
-
-        annotations.put(type, annotation);
-    }
-
-    /**
-     * Adds all of the elements of the given instance to this one. The
-     * instances must not have any duplicate types.
-     *
-     * @param toAdd {@code non-null;} the annotations to add
-     * @throws IllegalArgumentException thrown if there is a duplicate type
-     */
-    public void addAll(Annotations toAdd) {
-        throwIfImmutable();
-
-        if (toAdd == null) {
-            throw new NullPointerException("toAdd == null");
-        }
-
-        for (Annotation a : toAdd.annotations.values()) {
-            add(a);
-        }
-    }
-
-    /**
-     * Gets the set of annotations contained in this instance. The
-     * result is always unmodifiable.
-     *
-     * @return {@code non-null;} the set of annotations
-     */
-    public Collection<Annotation> getAnnotations() {
-        return Collections.unmodifiableCollection(annotations.values());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/annotation/AnnotationsList.java b/dx/src/main/java/com/android/dx/rop/annotation/AnnotationsList.java
deleted file mode 100644
index b97b385..0000000
--- a/dx/src/main/java/com/android/dx/rop/annotation/AnnotationsList.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.annotation;
-
-import com.android.dx.util.FixedSizeList;
-
-/**
- * List of {@link Annotations} instances.
- */
-public final class AnnotationsList
-        extends FixedSizeList {
-    /** {@code non-null;} immutable empty instance */
-    public static final AnnotationsList EMPTY = new AnnotationsList(0);
-
-    /**
-     * Constructs an immutable instance which is the combination of
-     * the two given instances. The two instances must each have the
-     * same number of elements, and each pair of elements must contain
-     * disjoint sets of types.
-     *
-     * @param list1 {@code non-null;} an instance
-     * @param list2 {@code non-null;} the other instance
-     * @return {@code non-null;} the combination
-     */
-    public static AnnotationsList combine(AnnotationsList list1,
-            AnnotationsList list2) {
-        int size = list1.size();
-
-        if (size != list2.size()) {
-            throw new IllegalArgumentException("list1.size() != list2.size()");
-        }
-
-        AnnotationsList result = new AnnotationsList(size);
-
-        for (int i = 0; i < size; i++) {
-            Annotations a1 = list1.get(i);
-            Annotations a2 = list2.get(i);
-            result.set(i, Annotations.combine(a1, a2));
-        }
-
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public AnnotationsList(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Annotations get(int n) {
-        return (Annotations) get0(n);
-    }
-
-    /**
-     * Sets the element at the given index. The given element must be
-     * immutable.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param a {@code null-ok;} the element to set at {@code n}
-     */
-    public void set(int n, Annotations a) {
-        a.throwIfMutable();
-        set0(n, a);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/annotation/NameValuePair.java b/dx/src/main/java/com/android/dx/rop/annotation/NameValuePair.java
deleted file mode 100644
index 56c4936..0000000
--- a/dx/src/main/java/com/android/dx/rop/annotation/NameValuePair.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.annotation;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstString;
-
-/**
- * A (name, value) pair. These are used as the contents of an annotation.
- */
-public final class NameValuePair implements Comparable<NameValuePair> {
-    /** {@code non-null;} the name */
-    private final CstString name;
-
-    /** {@code non-null;} the value */
-    private final Constant value;
-
-    /**
-     * Construct an instance.
-     *
-     * @param name {@code non-null;} the name
-     * @param value {@code non-null;} the value
-     */
-    public NameValuePair(CstString name, Constant value) {
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-
-        if (value == null) {
-            throw new NullPointerException("value == null");
-        }
-
-        this.name = name;
-        this.value = value;
-    }
-
-    /** {@inheritDoc} */
-    public String toString() {
-        return name.toHuman() + ":" + value;
-    }
-
-    /** {@inheritDoc} */
-    public int hashCode() {
-        return name.hashCode() * 31 + value.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public boolean equals(Object other) {
-        if (! (other instanceof NameValuePair)) {
-            return false;
-        }
-
-        NameValuePair otherPair = (NameValuePair) other;
-
-        return name.equals(otherPair.name)
-            && value.equals(otherPair.value);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Instances of this class compare in name-major and value-minor
-     * order.</p>
-     */
-    public int compareTo(NameValuePair other) {
-        int result = name.compareTo(other.name);
-
-        if (result != 0) {
-            return result;
-        }
-
-        return value.compareTo(other.value);
-    }
-
-    /**
-     * Gets the name.
-     *
-     * @return {@code non-null;} the name
-     */
-    public CstString getName() {
-        return name;
-    }
-
-    /**
-     * Gets the value.
-     *
-     * @return {@code non-null;} the value
-     */
-    public Constant getValue() {
-        return value;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/AccessFlags.java b/dx/src/main/java/com/android/dx/rop/code/AccessFlags.java
deleted file mode 100644
index 2d84fe8..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/AccessFlags.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.Hex;
-
-/**
- * Constants used as "access flags" in various places in classes, and
- * related utilities. Although, at the rop layer, flags are generally
- * ignored, this is the layer of communication, and as such, this
- * package is where these definitions belong. The flag definitions are
- * identical to Java access flags, but {@code ACC_SUPER} isn't
- * used at all in translated code, and {@code ACC_SYNCHRONIZED}
- * is only used in a very limited way.
- */
-public final class AccessFlags {
-    /** public member / class */
-    public static final int ACC_PUBLIC = 0x0001;
-
-    /** private member */
-    public static final int ACC_PRIVATE = 0x0002;
-
-    /** protected member */
-    public static final int ACC_PROTECTED = 0x0004;
-
-    /** static member */
-    public static final int ACC_STATIC = 0x0008;
-
-    /** final member / class */
-    public static final int ACC_FINAL = 0x0010;
-
-    /**
-     * synchronized method; only valid in dex files for {@code native}
-     * methods
-     */
-    public static final int ACC_SYNCHRONIZED = 0x0020;
-
-    /**
-     * class with new-style {@code invokespecial} for superclass
-     * method access
-     */
-    public static final int ACC_SUPER = 0x0020;
-
-    /** volatile field */
-    public static final int ACC_VOLATILE = 0x0040;
-
-    /** bridge method (generated) */
-    public static final int ACC_BRIDGE = 0x0040;
-
-    /** transient field */
-    public static final int ACC_TRANSIENT = 0x0080;
-
-    /** varargs method */
-    public static final int ACC_VARARGS = 0x0080;
-
-    /** native method */
-    public static final int ACC_NATIVE = 0x0100;
-
-    /** "class" is in fact an public static final interface */
-    public static final int ACC_INTERFACE = 0x0200;
-
-    /** abstract method / class */
-    public static final int ACC_ABSTRACT = 0x0400;
-
-    /**
-     * method with strict floating point ({@code strictfp})
-     * behavior
-     */
-    public static final int ACC_STRICT = 0x0800;
-
-    /** synthetic member */
-    public static final int ACC_SYNTHETIC = 0x1000;
-
-    /** class is an annotation type */
-    public static final int ACC_ANNOTATION = 0x2000;
-
-    /**
-     * class is an enumerated type; field is an element of an enumerated
-     * type
-     */
-    public static final int ACC_ENUM = 0x4000;
-
-    /** method is a constructor */
-    public static final int ACC_CONSTRUCTOR = 0x10000;
-
-    /**
-     * method was declared {@code synchronized}; has no effect on
-     * execution (other than inspecting this flag, per se)
-     */
-    public static final int ACC_DECLARED_SYNCHRONIZED = 0x20000;
-
-    /** flags defined on classes */
-    public static final int CLASS_FLAGS =
-        ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT |
-        ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM;
-
-    /** flags defined on inner classes */
-    public static final int INNER_CLASS_FLAGS =
-        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |
-        ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION |
-        ACC_ENUM;
-
-    /** flags defined on fields */
-    public static final int FIELD_FLAGS =
-        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |
-        ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM;
-
-    /** flags defined on methods */
-    public static final int METHOD_FLAGS =
-        ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL |
-        ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE |
-        ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR |
-        ACC_DECLARED_SYNCHRONIZED;
-
-    /** indicates conversion of class flags */
-    private static final int CONV_CLASS = 1;
-
-    /** indicates conversion of field flags */
-    private static final int CONV_FIELD = 2;
-
-    /** indicates conversion of method flags */
-    private static final int CONV_METHOD = 3;
-
-    /**
-     * This class is uninstantiable.
-     */
-    private AccessFlags() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Returns a human-oriented string representing the given access flags,
-     * as defined on classes (not fields or methods).
-     *
-     * @param flags the flags
-     * @return {@code non-null;} human-oriented string
-     */
-    public static String classString(int flags) {
-        return humanHelper(flags, CLASS_FLAGS, CONV_CLASS);
-    }
-
-    /**
-     * Returns a human-oriented string representing the given access flags,
-     * as defined on inner classes.
-     *
-     * @param flags the flags
-     * @return {@code non-null;} human-oriented string
-     */
-    public static String innerClassString(int flags) {
-        return humanHelper(flags, INNER_CLASS_FLAGS, CONV_CLASS);
-    }
-
-    /**
-     * Returns a human-oriented string representing the given access flags,
-     * as defined on fields (not classes or methods).
-     *
-     * @param flags the flags
-     * @return {@code non-null;} human-oriented string
-     */
-    public static String fieldString(int flags) {
-        return humanHelper(flags, FIELD_FLAGS, CONV_FIELD);
-    }
-
-    /**
-     * Returns a human-oriented string representing the given access flags,
-     * as defined on methods (not classes or fields).
-     *
-     * @param flags the flags
-     * @return {@code non-null;} human-oriented string
-     */
-    public static String methodString(int flags) {
-        return humanHelper(flags, METHOD_FLAGS, CONV_METHOD);
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_PUBLIC} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_PUBLIC} flag
-     */
-    public static boolean isPublic(int flags) {
-        return (flags & ACC_PUBLIC) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_PROTECTED} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_PROTECTED} flag
-     */
-    public static boolean isProtected(int flags) {
-        return (flags & ACC_PROTECTED) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_PRIVATE} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_PRIVATE} flag
-     */
-    public static boolean isPrivate(int flags) {
-        return (flags & ACC_PRIVATE) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_STATIC} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_STATIC} flag
-     */
-    public static boolean isStatic(int flags) {
-        return (flags & ACC_STATIC) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_SYNCHRONIZED} is on in
-     * the given flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_SYNCHRONIZED} flag
-     */
-    public static boolean isSynchronized(int flags) {
-        return (flags & ACC_SYNCHRONIZED) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_ABSTRACT} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_ABSTRACT} flag
-     */
-    public static boolean isAbstract(int flags) {
-        return (flags & ACC_ABSTRACT) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_NATIVE} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_NATIVE} flag
-     */
-    public static boolean isNative(int flags) {
-        return (flags & ACC_NATIVE) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_ANNOTATION} is on in the given
-     * flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_ANNOTATION} flag
-     */
-    public static boolean isAnnotation(int flags) {
-        return (flags & ACC_ANNOTATION) != 0;
-    }
-
-    /**
-     * Returns whether the flag {@code ACC_DECLARED_SYNCHRONIZED} is
-     * on in the given flags.
-     *
-     * @param flags the flags to check
-     * @return the value of the {@code ACC_DECLARED_SYNCHRONIZED} flag
-     */
-    public static boolean isDeclaredSynchronized(int flags) {
-        return (flags & ACC_DECLARED_SYNCHRONIZED) != 0;
-    }
-
-    /**
-     * Helper to return a human-oriented string representing the given
-     * access flags.
-     *
-     * @param flags the defined flags
-     * @param mask mask for the "defined" bits
-     * @param what what the flags represent (one of {@code CONV_*})
-     * @return {@code non-null;} human-oriented string
-     */
-    private static String humanHelper(int flags, int mask, int what) {
-        StringBuffer sb = new StringBuffer(80);
-        int extra = flags & ~mask;
-
-        flags &= mask;
-
-        if ((flags & ACC_PUBLIC) != 0) {
-            sb.append("|public");
-        }
-        if ((flags & ACC_PRIVATE) != 0) {
-            sb.append("|private");
-        }
-        if ((flags & ACC_PROTECTED) != 0) {
-            sb.append("|protected");
-        }
-        if ((flags & ACC_STATIC) != 0) {
-            sb.append("|static");
-        }
-        if ((flags & ACC_FINAL) != 0) {
-            sb.append("|final");
-        }
-        if ((flags & ACC_SYNCHRONIZED) != 0) {
-            if (what == CONV_CLASS) {
-                sb.append("|super");
-            } else {
-                sb.append("|synchronized");
-            }
-        }
-        if ((flags & ACC_VOLATILE) != 0) {
-            if (what == CONV_METHOD) {
-                sb.append("|bridge");
-            } else {
-                sb.append("|volatile");
-            }
-        }
-        if ((flags & ACC_TRANSIENT) != 0) {
-            if (what == CONV_METHOD) {
-                sb.append("|varargs");
-            } else {
-                sb.append("|transient");
-            }
-        }
-        if ((flags & ACC_NATIVE) != 0) {
-            sb.append("|native");
-        }
-        if ((flags & ACC_INTERFACE) != 0) {
-            sb.append("|interface");
-        }
-        if ((flags & ACC_ABSTRACT) != 0) {
-            sb.append("|abstract");
-        }
-        if ((flags & ACC_STRICT) != 0) {
-            sb.append("|strictfp");
-        }
-        if ((flags & ACC_SYNTHETIC) != 0) {
-            sb.append("|synthetic");
-        }
-        if ((flags & ACC_ANNOTATION) != 0) {
-            sb.append("|annotation");
-        }
-        if ((flags & ACC_ENUM) != 0) {
-            sb.append("|enum");
-        }
-        if ((flags & ACC_CONSTRUCTOR) != 0) {
-            sb.append("|constructor");
-        }
-        if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {
-            sb.append("|declared_synchronized");
-        }
-
-        if ((extra != 0) || (sb.length() == 0)) {
-            sb.append('|');
-            sb.append(Hex.u2(extra));
-        }
-
-        return sb.substring(1);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/BasicBlock.java b/dx/src/main/java/com/android/dx/rop/code/BasicBlock.java
deleted file mode 100644
index 9d99833..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/BasicBlock.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-import com.android.dx.util.LabeledItem;
-
-/**
- * Basic block of register-based instructions.
- */
-public final class BasicBlock implements LabeledItem {
-    /** {@code >= 0;} target label for this block */
-    private final int label;
-
-    /** {@code non-null;} list of instructions in this block */
-    private final InsnList insns;
-
-    /**
-     * {@code non-null;} full list of successors that this block may
-     * branch to
-     */
-    private final IntList successors;
-
-    /**
-     * {@code >= -1;} the primary / standard-flow / "default" successor, or
-     * {@code -1} if this block has no successors (that is, it
-     * exits the function/method)
-     */
-    private final int primarySuccessor;
-
-    /**
-     * Constructs an instance. The predecessor set is set to {@code null}.
-     *
-     * @param label {@code >= 0;} target label for this block
-     * @param insns {@code non-null;} list of instructions in this block
-     * @param successors {@code non-null;} full list of successors that this
-     * block may branch to
-     * @param primarySuccessor {@code >= -1;} the primary / standard-flow /
-     * "default" successor, or {@code -1} if this block has no
-     * successors (that is, it exits the function/method or is an
-     * unconditional throw)
-     */
-    public BasicBlock(int label, InsnList insns, IntList successors,
-                      int primarySuccessor) {
-        if (label < 0) {
-            throw new IllegalArgumentException("label < 0");
-        }
-
-        try {
-            insns.throwIfMutable();
-        } catch (NullPointerException ex) {
-            // Elucidate exception.
-            throw new NullPointerException("insns == null");
-        }
-
-        int sz = insns.size();
-
-        if (sz == 0) {
-            throw new IllegalArgumentException("insns.size() == 0");
-        }
-
-        for (int i = sz - 2; i >= 0; i--) {
-            Rop one = insns.get(i).getOpcode();
-            if (one.getBranchingness() != Rop.BRANCH_NONE) {
-                throw new IllegalArgumentException("insns[" + i + "] is a " +
-                                                   "branch or can throw");
-            }
-        }
-
-        Insn lastInsn = insns.get(sz - 1);
-        if (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {
-            throw new IllegalArgumentException("insns does not end with " +
-                                               "a branch or throwing " +
-                                               "instruction");
-        }
-
-        try {
-            successors.throwIfMutable();
-        } catch (NullPointerException ex) {
-            // Elucidate exception.
-            throw new NullPointerException("successors == null");
-        }
-
-        if (primarySuccessor < -1) {
-            throw new IllegalArgumentException("primarySuccessor < -1");
-        }
-
-        if (primarySuccessor >= 0 && !successors.contains(primarySuccessor)) {
-            throw new IllegalArgumentException(
-                    "primarySuccessor " + primarySuccessor + " not in successors " + successors);
-        }
-
-        this.label = label;
-        this.insns = insns;
-        this.successors = successors;
-        this.primarySuccessor = primarySuccessor;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Instances of this class compare by identity. That is,
-     * {@code x.equals(y)} is only true if {@code x == y}.
-     */
-    @Override
-    public boolean equals(Object other) {
-        return (this == other);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Return the identity hashcode of this instance. This is proper,
-     * since instances of this class compare by identity (see {@link #equals}).
-     */
-    @Override
-    public int hashCode() {
-        return System.identityHashCode(this);
-    }
-
-    /**
-     * Gets the target label of this block.
-     *
-     * @return {@code >= 0;} the label
-     */
-    public int getLabel() {
-        return label;
-    }
-
-    /**
-     * Gets the list of instructions inside this block.
-     *
-     * @return {@code non-null;} the instruction list
-     */
-    public InsnList getInsns() {
-        return insns;
-    }
-
-    /**
-     * Gets the list of successors that this block may branch to.
-     *
-     * @return {@code non-null;} the successors list
-     */
-    public IntList getSuccessors() {
-        return successors;
-    }
-
-    /**
-     * Gets the primary successor of this block.
-     *
-     * @return {@code >= -1;} the primary successor, or {@code -1} if this
-     * block has no successors at all
-     */
-    public int getPrimarySuccessor() {
-        return primarySuccessor;
-    }
-
-    /**
-     * Gets the secondary successor of this block. It is only valid to call
-     * this method on blocks that have exactly two successors.
-     *
-     * @return {@code >= 0;} the secondary successor
-     */
-    public int getSecondarySuccessor() {
-        if (successors.size() != 2) {
-            throw new UnsupportedOperationException(
-                    "block doesn't have exactly two successors");
-        }
-
-        int succ = successors.get(0);
-        if (succ == primarySuccessor) {
-            succ = successors.get(1);
-        }
-
-        return succ;
-    }
-
-    /**
-     * Gets the first instruction of this block. This is just a
-     * convenient shorthand for {@code getInsns().get(0)}.
-     *
-     * @return {@code non-null;} the first instruction
-     */
-    public Insn getFirstInsn() {
-        return insns.get(0);
-    }
-
-    /**
-     * Gets the last instruction of this block. This is just a
-     * convenient shorthand for {@code getInsns().getLast()}.
-     *
-     * @return {@code non-null;} the last instruction
-     */
-    public Insn getLastInsn() {
-        return insns.getLast();
-    }
-
-    /**
-     * Returns whether this block might throw an exception. This is
-     * just a convenient shorthand for {@code getLastInsn().canThrow()}.
-     *
-     * @return {@code true} iff this block might throw an
-     * exception
-     */
-    public boolean canThrow() {
-        return insns.getLast().canThrow();
-    }
-
-    /**
-     * Returns whether this block has any associated exception handlers.
-     * This is just a shorthand for inspecting the last instruction in
-     * the block to see if it could throw, and if so, whether it in fact
-     * has any associated handlers.
-     *
-     * @return {@code true} iff this block has any associated
-     * exception handlers
-     */
-    public boolean hasExceptionHandlers() {
-        Insn lastInsn = insns.getLast();
-        return lastInsn.getCatches().size() != 0;
-    }
-
-    /**
-     * Returns the exception handler types associated with this block,
-     * if any. This is just a shorthand for inspecting the last
-     * instruction in the block to see if it could throw, and if so,
-     * grabbing the catch list out of it. If not, this returns an
-     * empty list (not {@code null}).
-     *
-     * @return {@code non-null;} the exception handler types associated with
-     * this block
-     */
-    public TypeList getExceptionHandlerTypes() {
-        Insn lastInsn = insns.getLast();
-        return lastInsn.getCatches();
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the registers in each instruction are offset by the given
-     * amount.
-     *
-     * @param delta the amount to offset register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public BasicBlock withRegisterOffset(int delta) {
-        return new BasicBlock(label, insns.withRegisterOffset(delta),
-                              successors, primarySuccessor);
-    }
-
-    public String toString() {
-        return '{' + Hex.u2(label) + '}';
-    }
-
-    /**
-     * BasicBlock visitor interface
-     */
-    public interface Visitor {
-        /**
-         * Visits a basic block
-         * @param b block visited
-         */
-        public void visitBlock (BasicBlock b);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/BasicBlockList.java b/dx/src/main/java/com/android/dx/rop/code/BasicBlockList.java
deleted file mode 100644
index ef79075..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/BasicBlockList.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-import com.android.dx.util.LabeledList;
-
-/**
- * List of {@link BasicBlock} instances.
- */
-public final class BasicBlockList extends LabeledList {
-    /**
-     * {@code >= -1;} the count of registers required by this method or
-     * {@code -1} if not yet calculated
-     */
-    private int regCount;
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null},
-     * and the first-block label is initially {@code -1}.
-     *
-     * @param size the size of the list
-     */
-    public BasicBlockList(int size) {
-        super(size);
-
-        regCount = -1;
-    }
-
-    /**
-     * Constructs a mutable copy for {@code getMutableCopy()}.
-     *
-     * @param old block to copy
-     */
-    private BasicBlockList(BasicBlockList old) {
-        super(old);
-        regCount = old.regCount;
-    }
-
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public BasicBlock get(int n) {
-        return (BasicBlock) get0(n);
-    }
-
-    /**
-     * Sets the basic block at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param bb {@code null-ok;} the element to set at {@code n}
-     */
-    public void set(int n, BasicBlock bb) {
-        super.set(n, bb);
-
-        // Reset regCount, since it will need to be recalculated.
-        regCount = -1;
-    }
-
-    /**
-     * Returns how many registers this method requires. This is simply
-     * the maximum of register-number-plus-category referred to by this
-     * instance's instructions (indirectly through {@link BasicBlock}
-     * instances).
-     *
-     * @return {@code >= 0;} the register count
-     */
-    public int getRegCount() {
-        if (regCount == -1) {
-            RegCountVisitor visitor = new RegCountVisitor();
-            forEachInsn(visitor);
-            regCount = visitor.getRegCount();
-        }
-
-        return regCount;
-    }
-
-    /**
-     * Gets the total instruction count for this instance. This is the
-     * sum of the instruction counts of each block.
-     *
-     * @return {@code >= 0;} the total instruction count
-     */
-    public int getInstructionCount() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = (BasicBlock) getOrNull0(i);
-            if (one != null) {
-                result += one.getInsns().size();
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the total instruction count for this instance, ignoring
-     * mark-local instructions which are not actually emitted.
-     *
-     * @return {@code >= 0;} the total instruction count
-     */
-    public int getEffectiveInstructionCount() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = (BasicBlock) getOrNull0(i);
-            if (one != null) {
-                InsnList insns = one.getInsns();
-                int insnsSz = insns.size();
-
-                for (int j = 0; j < insnsSz; j++) {
-                    Insn insn = insns.get(j);
-
-                    if (insn.getOpcode().getOpcode() != RegOps.MARK_LOCAL) {
-                        result++;
-                    }
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the first block in the list with the given label, if any.
-     *
-     * @param label {@code >= 0;} the label to look for
-     * @return {@code non-null;} the so-labelled block
-     * @throws IllegalArgumentException thrown if the label isn't found
-     */
-    public BasicBlock labelToBlock(int label) {
-        int idx = indexOfLabel(label);
-
-        if (idx < 0) {
-            throw new IllegalArgumentException("no such label: "
-                    + Hex.u2(label));
-        }
-
-        return get(idx);
-    }
-
-    /**
-     * Visits each instruction of each block in the list, in order.
-     *
-     * @param visitor {@code non-null;} visitor to use
-     */
-    public void forEachInsn(Insn.Visitor visitor) {
-        int sz = size();
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = get(i);
-            InsnList insns = one.getInsns();
-            insns.forEach(visitor);
-        }
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the registers in each instruction are offset by the given
-     * amount. Mutability of the result is inherited from the
-     * original.
-     *
-     * @param delta the amount to offset register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public BasicBlockList withRegisterOffset(int delta) {
-        int sz = size();
-        BasicBlockList result = new BasicBlockList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = (BasicBlock) get0(i);
-            if (one != null) {
-                result.set(i, one.withRegisterOffset(delta));
-            }
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a mutable copy of this list.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public BasicBlockList getMutableCopy() {
-        return new BasicBlockList(this);
-    }
-
-    /**
-     * Gets the preferred successor for the given block. If the block
-     * only has one successor, then that is the preferred successor.
-     * Otherwise, if the block has a primay successor, then that is
-     * the preferred successor. If the block has no successors, then
-     * this returns {@code null}.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code null-ok;} the preferred successor, if any
-     */
-    public BasicBlock preferredSuccessorOf(BasicBlock block) {
-        int primarySuccessor = block.getPrimarySuccessor();
-        IntList successors = block.getSuccessors();
-        int succSize = successors.size();
-
-        switch (succSize) {
-            case 0: {
-                return null;
-            }
-            case 1: {
-                return labelToBlock(successors.get(0));
-            }
-        }
-
-        if (primarySuccessor != -1) {
-            return labelToBlock(primarySuccessor);
-        } else {
-            return labelToBlock(successors.get(0));
-        }
-    }
-
-    /**
-     * Compares the catches of two blocks for equality. This includes
-     * both the catch types and target labels.
-     *
-     * @param block1 {@code non-null;} one block to compare
-     * @param block2 {@code non-null;} the other block to compare
-     * @return {@code true} if the two blocks' non-primary successors
-     * are identical
-     */
-    public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
-        TypeList catches1 = block1.getExceptionHandlerTypes();
-        TypeList catches2 = block2.getExceptionHandlerTypes();
-
-        if (!StdTypeList.equalContents(catches1, catches2)) {
-            return false;
-        }
-
-        IntList succ1 = block1.getSuccessors();
-        IntList succ2 = block2.getSuccessors();
-        int size = succ1.size(); // Both are guaranteed to be the same size.
-
-        int primary1 = block1.getPrimarySuccessor();
-        int primary2 = block2.getPrimarySuccessor();
-
-        if (((primary1 == -1) || (primary2 == -1))
-                && (primary1 != primary2)) {
-            /*
-             * For the current purpose, both blocks in question must
-             * either both have a primary or both not have a primary to
-             * be considered equal, and it turns out here that that's not
-             * the case.
-             */
-            return false;
-        }
-
-        for (int i = 0; i < size; i++) {
-            int label1 = succ1.get(i);
-            int label2 = succ2.get(i);
-
-            if (label1 == primary1) {
-                /*
-                 * It should be the case that block2's primary is at the
-                 * same index. If not, we consider the blocks unequal for
-                 * the current purpose.
-                 */
-                if (label2 != primary2) {
-                    return false;
-                }
-                continue;
-            }
-
-            if (label1 != label2) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Instruction visitor class for counting registers used.
-     */
-    private static class RegCountVisitor
-            implements Insn.Visitor {
-        /** {@code >= 0;} register count in-progress */
-        private int regCount;
-
-        /**
-         * Constructs an instance.
-         */
-        public RegCountVisitor() {
-            regCount = 0;
-        }
-
-        /**
-         * Gets the register count.
-         *
-         * @return {@code >= 0;} the count
-         */
-        public int getRegCount() {
-            return regCount;
-        }
-
-        /** {@inheritDoc} */
-        public void visitPlainInsn(PlainInsn insn) {
-            visit(insn);
-        }
-
-        /** {@inheritDoc} */
-        public void visitPlainCstInsn(PlainCstInsn insn) {
-            visit(insn);
-        }
-
-        /** {@inheritDoc} */
-        public void visitSwitchInsn(SwitchInsn insn) {
-            visit(insn);
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
-            visit(insn);
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingInsn(ThrowingInsn insn) {
-            visit(insn);
-        }
-
-        /** {@inheritDoc} */
-        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
-            visit(insn);
-        }
-
-        /**
-         * Helper for all the {@code visit*} methods.
-         *
-         * @param insn {@code non-null;} instruction being visited
-         */
-        private void visit(Insn insn) {
-            RegisterSpec result = insn.getResult();
-
-            if (result != null) {
-                processReg(result);
-            }
-
-            RegisterSpecList sources = insn.getSources();
-            int sz = sources.size();
-
-            for (int i = 0; i < sz; i++) {
-                processReg(sources.get(i));
-            }
-        }
-
-        /**
-         * Processes the given register spec.
-         *
-         * @param spec {@code non-null;} the register spec
-         */
-        private void processReg(RegisterSpec spec) {
-            int reg = spec.getNextReg();
-
-            if (reg > regCount) {
-                regCount = reg;
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/ConservativeTranslationAdvice.java b/dx/src/main/java/com/android/dx/rop/code/ConservativeTranslationAdvice.java
deleted file mode 100644
index 6c48acf..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/ConservativeTranslationAdvice.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-/**
- * Implementation of {@link TranslationAdvice} which conservatively answers
- * {@code false} to all methods.
- */
-public final class ConservativeTranslationAdvice
-        implements TranslationAdvice {
-    /** {@code non-null;} standard instance of this class */
-    public static final ConservativeTranslationAdvice THE_ONE =
-        new ConservativeTranslationAdvice();
-
-    /**
-     * This class is not publicly instantiable. Use {@link #THE_ONE}.
-     */
-    private ConservativeTranslationAdvice() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    public boolean hasConstantOperation(Rop opcode,
-            RegisterSpec sourceA, RegisterSpec sourceB) {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public boolean requiresSourcesInOrder(Rop opcode,
-            RegisterSpecList sources) {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public int getMaxOptimalRegisterCount() {
-        return Integer.MAX_VALUE;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/CstInsn.java b/dx/src/main/java/com/android/dx/rop/code/CstInsn.java
deleted file mode 100644
index d7de2f4..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/CstInsn.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-
-/**
- * Instruction which contains an explicit reference to a constant.
- */
-public abstract class CstInsn
-        extends Insn {
-    /** {@code non-null;} the constant */
-    private final Constant cst;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param sources {@code non-null;} specs for all the sources
-     * @param cst {@code non-null;} constant
-     */
-    public CstInsn(Rop opcode, SourcePosition position, RegisterSpec result,
-                   RegisterSpecList sources, Constant cst) {
-        super(opcode, position, result, sources);
-
-        if (cst == null) {
-            throw new NullPointerException("cst == null");
-        }
-
-        this.cst = cst;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getInlineString() {
-        return cst.toHuman();
-    }
-
-    /**
-     * Gets the constant.
-     *
-     * @return {@code non-null;} the constant
-     */
-    public Constant getConstant() {
-        return cst;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean contentEquals(Insn b) {
-        /*
-         * The cast (CstInsn)b below should always succeed since
-         * Insn.contentEquals compares classes of this and b.
-         */
-        return super.contentEquals(b)
-                && cst.equals(((CstInsn)b).getConstant());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/DexTranslationAdvice.java b/dx/src/main/java/com/android/dx/rop/code/DexTranslationAdvice.java
deleted file mode 100644
index 35ce2f2..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/DexTranslationAdvice.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.type.Type;
-
-/**
- * Implementation of {@link TranslationAdvice} which represents what
- * the dex format will be able to represent.
- */
-public final class DexTranslationAdvice
-        implements TranslationAdvice {
-    /** {@code non-null;} standard instance of this class */
-    public static final DexTranslationAdvice THE_ONE =
-        new DexTranslationAdvice();
-
-    /** debug advice for disabling invoke-range optimization */
-    public static final DexTranslationAdvice NO_SOURCES_IN_ORDER =
-        new DexTranslationAdvice(true);
-
-    /**
-     * The minimum source width, in register units, for an invoke
-     * instruction that requires its sources to be in order and contiguous.
-     */
-    private static final int MIN_INVOKE_IN_ORDER = 6;
-
-    /** when true: always returns false for requiresSourcesInOrder */
-    private final boolean disableSourcesInOrder;
-
-    /**
-     * This class is not publicly instantiable. Use {@link #THE_ONE}.
-     */
-    private DexTranslationAdvice() {
-        disableSourcesInOrder = false;
-    }
-
-    private DexTranslationAdvice(boolean disableInvokeRange) {
-        this.disableSourcesInOrder = disableInvokeRange;
-    }
-
-    /** {@inheritDoc} */
-    public boolean hasConstantOperation(Rop opcode,
-            RegisterSpec sourceA, RegisterSpec sourceB) {
-        if (sourceA.getType() != Type.INT) {
-            return false;
-        }
-
-        // Return false if second source isn't a constant
-        if (! (sourceB.getTypeBearer() instanceof CstInteger)) {
-            // Except for rsub-int (reverse sub) where first source is constant
-            if (sourceA.getTypeBearer() instanceof CstInteger &&
-                    opcode.getOpcode() == RegOps.SUB) {
-                CstInteger cst = (CstInteger) sourceA.getTypeBearer();
-                return cst.fitsIn16Bits();
-            } else {
-                return false;
-            }
-        }
-
-        CstInteger cst = (CstInteger) sourceB.getTypeBearer();
-
-        switch (opcode.getOpcode()) {
-            // These have 8 and 16 bit cst representations
-            case RegOps.REM:
-            case RegOps.ADD:
-            case RegOps.MUL:
-            case RegOps.DIV:
-            case RegOps.AND:
-            case RegOps.OR:
-            case RegOps.XOR:
-                return cst.fitsIn16Bits();
-            // These only have 8 bit cst reps
-            case RegOps.SHL:
-            case RegOps.SHR:
-            case RegOps.USHR:
-                return cst.fitsIn8Bits();
-            // No sub-const insn, so check if equivalent add-const fits
-            case RegOps.SUB:
-                CstInteger cst2 = CstInteger.make(-cst.getValue());
-                return cst2.fitsIn16Bits();
-            default:
-                return false;
-        }
-    }
-
-    /** {@inheritDoc} */
-    public boolean requiresSourcesInOrder(Rop opcode,
-            RegisterSpecList sources) {
-
-        return !disableSourcesInOrder && opcode.isCallLike()
-                && totalRopWidth(sources) >= MIN_INVOKE_IN_ORDER;
-    }
-
-    /**
-     * Calculates the total rop width of the list of SSA registers
-     *
-     * @param sources {@code non-null;} list of SSA registers
-     * @return {@code >= 0;} rop-form width in register units
-     */
-    private int totalRopWidth(RegisterSpecList sources) {
-        int sz = sources.size();
-        int total = 0;
-
-        for (int i = 0; i < sz; i++) {
-            total += sources.get(i).getCategory();
-        }
-
-        return total;
-    }
-
-    /** {@inheritDoc} */
-    public int getMaxOptimalRegisterCount() {
-        return 16;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/Exceptions.java b/dx/src/main/java/com/android/dx/rop/code/Exceptions.java
deleted file mode 100644
index 1e27a8c..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/Exceptions.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-
-/**
- * Common exception types.
- */
-public final class Exceptions {
-    /** {@code non-null;} the type {@code java.lang.ArithmeticException} */
-    public static final Type TYPE_ArithmeticException =
-        Type.intern("Ljava/lang/ArithmeticException;");
-
-    /**
-     * {@code non-null;} the type
-     * {@code java.lang.ArrayIndexOutOfBoundsException}
-     */
-    public static final Type TYPE_ArrayIndexOutOfBoundsException =
-        Type.intern("Ljava/lang/ArrayIndexOutOfBoundsException;");
-
-    /** {@code non-null;} the type {@code java.lang.ArrayStoreException} */
-    public static final Type TYPE_ArrayStoreException =
-        Type.intern("Ljava/lang/ArrayStoreException;");
-
-    /** {@code non-null;} the type {@code java.lang.ClassCastException} */
-    public static final Type TYPE_ClassCastException =
-        Type.intern("Ljava/lang/ClassCastException;");
-
-    /** {@code non-null;} the type {@code java.lang.Error} */
-    public static final Type TYPE_Error = Type.intern("Ljava/lang/Error;");
-
-    /**
-     * {@code non-null;} the type
-     * {@code java.lang.IllegalMonitorStateException}
-     */
-    public static final Type TYPE_IllegalMonitorStateException =
-        Type.intern("Ljava/lang/IllegalMonitorStateException;");
-
-    /** {@code non-null;} the type {@code java.lang.NegativeArraySizeException} */
-    public static final Type TYPE_NegativeArraySizeException =
-        Type.intern("Ljava/lang/NegativeArraySizeException;");
-
-    /** {@code non-null;} the type {@code java.lang.NullPointerException} */
-    public static final Type TYPE_NullPointerException =
-        Type.intern("Ljava/lang/NullPointerException;");
-
-    /** {@code non-null;} the list {@code [java.lang.Error]} */
-    public static final StdTypeList LIST_Error = StdTypeList.make(TYPE_Error);
-
-    /**
-     * {@code non-null;} the list {@code[java.lang.Error,
-     * java.lang.ArithmeticException]}
-     */
-    public static final StdTypeList LIST_Error_ArithmeticException =
-        StdTypeList.make(TYPE_Error, TYPE_ArithmeticException);
-
-    /**
-     * {@code non-null;} the list {@code[java.lang.Error,
-     * java.lang.ClassCastException]}
-     */
-    public static final StdTypeList LIST_Error_ClassCastException =
-        StdTypeList.make(TYPE_Error, TYPE_ClassCastException);
-
-    /**
-     * {@code non-null;} the list {@code [java.lang.Error,
-     * java.lang.NegativeArraySizeException]}
-     */
-    public static final StdTypeList LIST_Error_NegativeArraySizeException =
-        StdTypeList.make(TYPE_Error, TYPE_NegativeArraySizeException);
-
-    /**
-     * {@code non-null;} the list {@code [java.lang.Error,
-     * java.lang.NullPointerException]}
-     */
-    public static final StdTypeList LIST_Error_NullPointerException =
-        StdTypeList.make(TYPE_Error, TYPE_NullPointerException);
-
-    /**
-     * {@code non-null;} the list {@code [java.lang.Error,
-     * java.lang.NullPointerException,
-     * java.lang.ArrayIndexOutOfBoundsException]}
-     */
-    public static final StdTypeList LIST_Error_Null_ArrayIndexOutOfBounds =
-        StdTypeList.make(TYPE_Error,
-                      TYPE_NullPointerException,
-                      TYPE_ArrayIndexOutOfBoundsException);
-
-    /**
-     * {@code non-null;} the list {@code [java.lang.Error,
-     * java.lang.NullPointerException,
-     * java.lang.ArrayIndexOutOfBoundsException,
-     * java.lang.ArrayStoreException]}
-     */
-    public static final StdTypeList LIST_Error_Null_ArrayIndex_ArrayStore =
-        StdTypeList.make(TYPE_Error,
-                      TYPE_NullPointerException,
-                      TYPE_ArrayIndexOutOfBoundsException,
-                      TYPE_ArrayStoreException);
-
-    /**
-     * {@code non-null;} the list {@code [java.lang.Error,
-     * java.lang.NullPointerException,
-     * java.lang.IllegalMonitorStateException]}
-     */
-    public static final StdTypeList
-        LIST_Error_Null_IllegalMonitorStateException =
-        StdTypeList.make(TYPE_Error,
-                      TYPE_NullPointerException,
-                      TYPE_IllegalMonitorStateException);
-
-    /**
-     * This class is uninstantiable.
-     */
-    private Exceptions() {
-        // This space intentionally left blank.
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/FillArrayDataInsn.java b/dx/src/main/java/com/android/dx/rop/code/FillArrayDataInsn.java
deleted file mode 100644
index ed9345d..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/FillArrayDataInsn.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.rop.type.StdTypeList;
-
-import java.util.ArrayList;
-
-/**
- * Instruction which fills a newly created array with a predefined list of
- * constant values.
- */
-public final class FillArrayDataInsn
-        extends Insn {
-
-    /** non-null: initial values to fill the newly created array */
-    private final ArrayList<Constant> initValues;
-
-    /**
-     * non-null: type of the array. Will be used to determine the width of
-     * elements in the array-data table.
-     */
-    private final Constant arrayType;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param sources {@code non-null;} specs for all the sources
-     * @param initValues {@code non-null;} list of initial values to fill the array
-     * @param cst {@code non-null;} type of the new array
-     */
-    public FillArrayDataInsn(Rop opcode, SourcePosition position,
-                             RegisterSpecList sources,
-                             ArrayList<Constant> initValues,
-                             Constant cst) {
-        super(opcode, position, null, sources);
-
-        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-
-        this.initValues = initValues;
-        this.arrayType = cst;
-    }
-
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return StdTypeList.EMPTY;
-    }
-
-    /**
-     * Return the list of init values
-     * @return {@code non-null;} list of init values
-     */
-    public ArrayList<Constant> getInitValues() {
-        return initValues;
-    }
-
-    /**
-     * Return the type of the newly created array
-     * @return {@code non-null;} array type
-     */
-    public Constant getConstant() {
-        return arrayType;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitFillArrayDataInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        throw new  UnsupportedOperationException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new FillArrayDataInsn(getOpcode(), getPosition(),
-                                     getSources().withOffset(delta),
-                                     initValues, arrayType);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new FillArrayDataInsn(getOpcode(), getPosition(),
-                                     sources, initValues, arrayType);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/Insn.java b/dx/src/main/java/com/android/dx/rop/code/Insn.java
deleted file mode 100644
index 5031f89..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/Insn.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.ToHuman;
-
-/**
- * A register-based instruction. An instruction is the combination of
- * an opcode (which specifies operation and source/result types), a
- * list of actual sources and result registers/values, and additional
- * information.
- */
-public abstract class Insn implements ToHuman {
-    /** {@code non-null;} opcode */
-    private final Rop opcode;
-
-    /** {@code non-null;} source position */
-    private final SourcePosition position;
-
-    /** {@code null-ok;} spec for the result of this instruction, if any */
-    private final RegisterSpec result;
-
-    /** {@code non-null;} specs for all the sources of this instruction */
-    private final RegisterSpecList sources;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param sources {@code non-null;} specs for all the sources
-     */
-    public Insn(Rop opcode, SourcePosition position, RegisterSpec result,
-                RegisterSpecList sources) {
-        if (opcode == null) {
-            throw new NullPointerException("opcode == null");
-        }
-
-        if (position == null) {
-            throw new NullPointerException("position == null");
-        }
-
-        if (sources == null) {
-            throw new NullPointerException("sources == null");
-        }
-
-        this.opcode = opcode;
-        this.position = position;
-        this.result = result;
-        this.sources = sources;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Instances of this class compare by identity. That is,
-     * {@code x.equals(y)} is only true if {@code x == y}.
-     */
-    @Override
-    public final boolean equals(Object other) {
-        return (this == other);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * This implementation returns the identity hashcode of this
-     * instance. This is proper, since instances of this class compare
-     * by identity (see {@link #equals}).
-     */
-    @Override
-    public final int hashCode() {
-        return System.identityHashCode(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return toStringWithInline(getInlineString());
-    }
-
-    /**
-     * Gets a human-oriented (and slightly lossy) string for this instance.
-     *
-     * @return {@code non-null;} the human string form
-     */
-    public String toHuman() {
-        return toHumanWithInline(getInlineString());
-    }
-
-    /**
-     * Gets an "inline" string portion for toHuman(), if available. This
-     * is the portion that appears after the Rop opcode
-     *
-     * @return {@code null-ok;} if non-null, the inline text for toHuman()
-     */
-    public String getInlineString() {
-        return null;
-    }
-
-    /**
-     * Gets the opcode.
-     *
-     * @return {@code non-null;} the opcode
-     */
-    public final Rop getOpcode() {
-        return opcode;
-    }
-
-    /**
-     * Gets the source position.
-     *
-     * @return {@code non-null;} the source position
-     */
-    public final SourcePosition getPosition() {
-        return position;
-    }
-
-    /**
-     * Gets the result spec, if any. A return value of {@code null}
-     * means this instruction returns nothing.
-     *
-     * @return {@code null-ok;} the result spec, if any
-     */
-    public final RegisterSpec getResult() {
-        return result;
-    }
-
-    /**
-     * Gets the spec of a local variable assignment that occurs at this
-     * instruction, or null if no local variable assignment occurs. This
-     * may be the result register, or for {@code mark-local} insns
-     * it may be the source.
-     *
-     * @return {@code null-ok;} a named register spec or null
-     */
-    public final RegisterSpec getLocalAssignment() {
-        RegisterSpec assignment;
-        if (opcode.getOpcode() == RegOps.MARK_LOCAL) {
-            assignment = sources.get(0);
-        } else {
-            assignment = result;
-        }
-
-        if (assignment == null) {
-            return null;
-        }
-
-        LocalItem localItem = assignment.getLocalItem();
-
-        if (localItem == null) {
-            return null;
-        }
-
-        return assignment;
-    }
-
-    /**
-     * Gets the source specs.
-     *
-     * @return {@code non-null;} the source specs
-     */
-    public final RegisterSpecList getSources() {
-        return sources;
-    }
-
-    /**
-     * Gets whether this instruction can possibly throw an exception. This
-     * is just a convenient wrapper for {@code getOpcode().canThrow()}.
-     *
-     * @return {@code true} iff this instruction can possibly throw
-     */
-    public final boolean canThrow() {
-        return opcode.canThrow();
-    }
-
-    /**
-     * Gets the list of possibly-caught exceptions. This returns {@link
-     * StdTypeList#EMPTY} if this instruction has no handlers,
-     * which can be <i>either</i> if this instruction can't possibly
-     * throw or if it merely doesn't handle any of its possible
-     * exceptions. To determine whether this instruction can throw,
-     * use {@link #canThrow}.
-     *
-     * @return {@code non-null;} the catches list
-     */
-    public abstract TypeList getCatches();
-
-    /**
-     * Calls the appropriate method on the given visitor, depending on the
-     * class of this instance. Subclasses must override this.
-     *
-     * @param visitor {@code non-null;} the visitor to call on
-     */
-    public abstract void accept(Visitor visitor);
-
-    /**
-     * Returns an instance that is just like this one, except that it
-     * has a catch list with the given item appended to the end. This
-     * method throws an exception if this instance can't possibly
-     * throw. To determine whether this instruction can throw, use
-     * {@link #canThrow}.
-     *
-     * @param type {@code non-null;} type to append to the catch list
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract Insn withAddedCatch(Type type);
-
-    /**
-     * Returns an instance that is just like this one, except that all
-     * register references have been offset by the given delta.
-     *
-     * @param delta the amount to offset register references by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract Insn withRegisterOffset(int delta);
-
-    /**
-     * Returns an instance that is just like this one, except that, if
-     * possible, the insn is converted into a version in which a source
-     * (if it is a constant) is represented directly rather than as a
-     * register reference. {@code this} is returned in cases where the
-     * translation is not possible.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public Insn withSourceLiteral() {
-        return this;
-    }
-
-    /**
-     * Returns an exact copy of this Insn
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public Insn copy() {
-        return withRegisterOffset(0);
-    }
-
-
-    /**
-     * Compares, handling nulls safely
-     *
-     * @param a first object
-     * @param b second object
-     * @return true if they're equal or both null.
-     */
-    private static boolean equalsHandleNulls (Object a, Object b) {
-        return (a == b) || ((a != null) && a.equals(b));
-    }
-
-    /**
-     * Compares Insn contents, since {@code Insn.equals()} is defined
-     * to be an identity compare. Insn's are {@code contentEquals()}
-     * if they have the same opcode, registers, source position, and other
-     * metadata.
-     *
-     * @return true in the case described above
-     */
-    public boolean contentEquals(Insn b) {
-        return opcode == b.getOpcode()
-                && position.equals(b.getPosition())
-                && (getClass() == b.getClass())
-                && equalsHandleNulls(result, b.getResult())
-                && equalsHandleNulls(sources, b.getSources())
-                && StdTypeList.equalContents(getCatches(), b.getCatches());
-    }
-
-    /**
-     * Returns an instance that is just like this one, except
-     * with new result and source registers.
-     *
-     * @param result {@code null-ok;} new result register
-     * @param sources {@code non-null;} new sources registers
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public abstract Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources);
-
-    /**
-     * Returns the string form of this instance, with the given bit added in
-     * the standard location for an inline argument.
-     *
-     * @param extra {@code null-ok;} the inline argument string
-     * @return {@code non-null;} the string form
-     */
-    protected final String toStringWithInline(String extra) {
-        StringBuffer sb = new StringBuffer(80);
-
-        sb.append("Insn{");
-        sb.append(position);
-        sb.append(' ');
-        sb.append(opcode);
-
-        if (extra != null) {
-            sb.append(' ');
-            sb.append(extra);
-        }
-
-        sb.append(" :: ");
-
-        if (result != null) {
-            sb.append(result);
-            sb.append(" <- ");
-        }
-
-        sb.append(sources);
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /**
-     * Returns the human string form of this instance, with the given
-     * bit added in the standard location for an inline argument.
-     *
-     * @param extra {@code null-ok;} the inline argument string
-     * @return {@code non-null;} the human string form
-     */
-    protected final String toHumanWithInline(String extra) {
-        StringBuffer sb = new StringBuffer(80);
-
-        sb.append(position);
-        sb.append(": ");
-        sb.append(opcode.getNickname());
-
-        if (extra != null) {
-            sb.append("(");
-            sb.append(extra);
-            sb.append(")");
-        }
-
-        if (result == null) {
-            sb.append(" .");
-        } else {
-            sb.append(" ");
-            sb.append(result.toHuman());
-        }
-
-        sb.append(" <-");
-
-        int sz = sources.size();
-        if (sz == 0) {
-            sb.append(" .");
-        } else {
-            for (int i = 0; i < sz; i++) {
-                sb.append(" ");
-                sb.append(sources.get(i).toHuman());
-            }
-        }
-
-        return sb.toString();
-    }
-
-
-    /**
-     * Visitor interface for this (outer) class.
-     */
-    public static interface Visitor {
-        /**
-         * Visits a {@link PlainInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitPlainInsn(PlainInsn insn);
-
-        /**
-         * Visits a {@link PlainCstInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitPlainCstInsn(PlainCstInsn insn);
-
-        /**
-         * Visits a {@link SwitchInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitSwitchInsn(SwitchInsn insn);
-
-        /**
-         * Visits a {@link ThrowingCstInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitThrowingCstInsn(ThrowingCstInsn insn);
-
-        /**
-         * Visits a {@link ThrowingInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitThrowingInsn(ThrowingInsn insn);
-
-        /**
-         * Visits a {@link FillArrayDataInsn}.
-         *
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitFillArrayDataInsn(FillArrayDataInsn insn);
-    }
-
-    /**
-     * Base implementation of {@link Visitor}, which has empty method
-     * bodies for all methods.
-     */
-    public static class BaseVisitor implements Visitor {
-        /** {@inheritDoc} */
-        public void visitPlainInsn(PlainInsn insn) {
-            // This space intentionally left blank.
-        }
-
-        /** {@inheritDoc} */
-        public void visitPlainCstInsn(PlainCstInsn insn) {
-            // This space intentionally left blank.
-        }
-
-        /** {@inheritDoc} */
-        public void visitSwitchInsn(SwitchInsn insn) {
-            // This space intentionally left blank.
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
-            // This space intentionally left blank.
-        }
-
-        /** {@inheritDoc} */
-        public void visitThrowingInsn(ThrowingInsn insn) {
-            // This space intentionally left blank.
-        }
-
-        /** {@inheritDoc} */
-        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
-            // This space intentionally left blank.
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/InsnList.java b/dx/src/main/java/com/android/dx/rop/code/InsnList.java
deleted file mode 100644
index 88abd72..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/InsnList.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.FixedSizeList;
-
-/**
- * List of {@link Insn} instances.
- */
-public final class InsnList
-        extends FixedSizeList {
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public InsnList(int size) {
-        super(size);
-    }
-
-    /**
-     * Gets the element at the given index. It is an error to call
-     * this with the index for an element which was never set; if you
-     * do that, this will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @return {@code non-null;} element at that index
-     */
-    public Insn get(int n) {
-        return (Insn) get0(n);
-    }
-
-    /**
-     * Sets the instruction at the given index.
-     *
-     * @param n {@code >= 0, < size();} which index
-     * @param insn {@code non-null;} the instruction to set at {@code n}
-     */
-    public void set(int n, Insn insn) {
-        set0(n, insn);
-    }
-
-    /**
-     * Gets the last instruction. This is just a convenient shorthand for
-     * {@code get(size() - 1)}.
-     *
-     * @return {@code non-null;} the last instruction
-     */
-    public Insn getLast() {
-        return get(size() - 1);
-    }
-
-    /**
-     * Visits each instruction in the list, in order.
-     *
-     * @param visitor {@code non-null;} visitor to use
-     */
-    public void forEach(Insn.Visitor visitor) {
-        int sz = size();
-
-        for (int i = 0; i < sz; i++) {
-            get(i).accept(visitor);
-        }
-    }
-
-    /**
-     * Compares the contents of this {@code InsnList} with another.
-     * The blocks must have the same number of insns, and each Insn must
-     * also return true to {@code Insn.contentEquals()}.
-     *
-     * @param b to compare
-     * @return true in the case described above.
-     */
-    public boolean contentEquals(InsnList b) {
-        if (b == null) return false;
-
-        int sz = size();
-
-        if (sz != b.size()) return false;
-
-        for (int i = 0; i < sz; i++) {
-            if (!get(i).contentEquals(b.get(i))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the registers in each instruction are offset by the given
-     * amount. Mutability of the result is inherited from the
-     * original.
-     *
-     * @param delta the amount to offset register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public InsnList withRegisterOffset(int delta) {
-        int sz = size();
-        InsnList result = new InsnList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            Insn one = (Insn) get0(i);
-            if (one != null) {
-                result.set0(i, one.withRegisterOffset(delta));
-            }
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/LocalItem.java b/dx/src/main/java/com/android/dx/rop/code/LocalItem.java
deleted file mode 100644
index d238f21..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/LocalItem.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.CstString;
-
-/**
- * A local variable item: either a name or a signature or both.
- */
-public class LocalItem implements Comparable<LocalItem> {
-    /** {@code null-ok;} local variable name */
-    private final CstString name;
-
-    /** {@code null-ok;} local variable signature */
-    private final CstString signature;
-
-    /**
-     * Make a new item. If both name and signature are null, null is returned.
-     *
-     * TODO: intern these
-     *
-     * @param name {@code null-ok;} local variable name
-     * @param signature {@code null-ok;} local variable signature
-     * @return {@code non-null;} appropriate instance.
-     */
-    public static LocalItem make(CstString name, CstString signature) {
-        if (name == null && signature == null) {
-            return null;
-        }
-
-        return new LocalItem (name, signature);
-    }
-
-    /**
-     * Constructs instance.
-     *
-     * @param name {@code null-ok;} local variable name
-     * @param signature {@code null-ok;} local variable signature
-     */
-    private LocalItem(CstString name, CstString signature) {
-        this.name = name;
-        this.signature = signature;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof LocalItem)) {
-            return false;
-        }
-
-        LocalItem local = (LocalItem) other;
-
-        return 0 == compareTo(local);
-    }
-
-    /**
-     * Compares two strings like String.compareTo(), excepts treats a null
-     * as the least-possible string value.
-     *
-     * @return negative integer, zero, or positive integer in accordance
-     * with Comparable.compareTo()
-     */
-    private static int compareHandlesNulls(CstString a, CstString b) {
-        if (a == b) {
-            return 0;
-        } else if (a == null) {
-            return -1;
-        } else if (b == null) {
-            return 1;
-        } else {
-            return a.compareTo(b);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(LocalItem local) {
-        int ret;
-
-        ret = compareHandlesNulls(name, local.name);
-
-        if (ret != 0) {
-            return ret;
-        }
-
-        ret = compareHandlesNulls(signature, local.signature);
-
-        return ret;
-    }
-
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return (name == null ? 0 : name.hashCode()) * 31
-                + (signature == null ? 0 : signature.hashCode());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        if (name != null && signature == null) {
-            return name.toQuoted();
-        } else if (name == null && signature == null) {
-            return "";
-        }
-
-        return "[" + (name == null ? "" : name.toQuoted())
-                + "|" + (signature == null ? "" : signature.toQuoted());
-    }
-
-    /**
-     * Gets name.
-     *
-     * @return {@code null-ok;} name
-     */
-    public CstString getName() {
-        return name;
-    }
-
-    /**
-     * Gets signature.
-     *
-     * @return {@code null-ok;} signature
-     */
-    public CstString getSignature() {
-        return signature;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/LocalVariableExtractor.java b/dx/src/main/java/com/android/dx/rop/code/LocalVariableExtractor.java
deleted file mode 100644
index c2c4021..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/LocalVariableExtractor.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.Bits;
-import com.android.dx.util.IntList;
-
-/**
- * Code to figure out which local variables are active at which points in
- * a method.
- */
-public final class LocalVariableExtractor {
-    /** {@code non-null;} method being extracted from */
-    private final RopMethod method;
-
-    /** {@code non-null;} block list for the method */
-    private final BasicBlockList blocks;
-
-    /** {@code non-null;} result in-progress */
-    private final LocalVariableInfo resultInfo;
-
-    /** {@code non-null;} work set indicating blocks needing to be processed */
-    private final int[] workSet;
-
-    /**
-     * Extracts out all the local variable information from the given method.
-     *
-     * @param method {@code non-null;} the method to extract from
-     * @return {@code non-null;} the extracted information
-     */
-    public static LocalVariableInfo extract(RopMethod method) {
-        LocalVariableExtractor lve = new LocalVariableExtractor(method);
-        return lve.doit();
-    }
-
-    /**
-     * Constructs an instance. This method is private. Use {@link #extract}.
-     *
-     * @param method {@code non-null;} the method to extract from
-     */
-    private LocalVariableExtractor(RopMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        BasicBlockList blocks = method.getBlocks();
-        int maxLabel = blocks.getMaxLabel();
-
-        this.method = method;
-        this.blocks = blocks;
-        this.resultInfo = new LocalVariableInfo(method);
-        this.workSet = Bits.makeBitSet(maxLabel);
-    }
-
-    /**
-     * Does the extraction.
-     *
-     * @return {@code non-null;} the extracted information
-     */
-    private LocalVariableInfo doit() {
-        for (int label = method.getFirstLabel();
-             label >= 0;
-             label = Bits.findFirst(workSet, 0)) {
-            Bits.clear(workSet, label);
-            processBlock(label);
-        }
-
-        resultInfo.setImmutable();
-        return resultInfo;
-    }
-
-    /**
-     * Processes a single block.
-     *
-     * @param label {@code >= 0;} label of the block to process
-     */
-    private void processBlock(int label) {
-        RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label);
-        BasicBlock block = blocks.labelToBlock(label);
-        InsnList insns = block.getInsns();
-        int insnSz = insns.size();
-
-        /*
-         * We may have to treat the last instruction specially: If it
-         * can (but doesn't always) throw, and the exception can be
-         * caught within the same method, then we need to use the
-         * state *before* executing it to be what is merged into
-         * exception targets.
-         */
-        boolean canThrowDuringLastInsn = block.hasExceptionHandlers() &&
-            (insns.getLast().getResult() != null);
-        int freezeSecondaryStateAt = insnSz - 1;
-        RegisterSpecSet secondaryState = primaryState;
-
-        /*
-         * Iterate over the instructions, adding information for each place
-         * that the active variable set changes.
-         */
-
-        for (int i = 0; i < insnSz; i++) {
-            if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {
-                // Until this point, primaryState == secondaryState.
-                primaryState.setImmutable();
-                primaryState = primaryState.mutableCopy();
-            }
-
-            Insn insn = insns.get(i);
-            RegisterSpec result;
-
-            result = insn.getLocalAssignment();
-
-            if (result == null) {
-                /*
-                 * If an assignment assigns over an existing local, make
-                 * sure to mark the local as going out of scope.
-                 */
-
-                result = insn.getResult();
-
-                if (result != null
-                        && primaryState.get(result.getReg()) != null) {
-                    primaryState.remove(primaryState.get(result.getReg()));
-                }
-                continue;
-            }
-
-            result = result.withSimpleType();
-
-            RegisterSpec already = primaryState.get(result);
-            /*
-             * The equals() check ensures we only add new info if
-             * the instruction causes a change to the set of
-             * active variables.
-             */
-            if (!result.equals(already)) {
-                /*
-                 * If this insn represents a local moving from one register
-                 * to another, remove the association between the old register
-                 * and the local.
-                 */
-                RegisterSpec previous
-                        = primaryState.localItemToSpec(result.getLocalItem());
-
-                if (previous != null
-                        && (previous.getReg() != result.getReg())) {
-
-                    primaryState.remove(previous);
-                }
-
-                resultInfo.addAssignment(insn, result);
-                primaryState.put(result);
-            }
-        }
-
-        primaryState.setImmutable();
-
-        /*
-         * Merge this state into the start state for each successor,
-         * and update the work set where required (that is, in cases
-         * where the start state for a block changes).
-         */
-
-        IntList successors = block.getSuccessors();
-        int succSz = successors.size();
-        int primarySuccessor = block.getPrimarySuccessor();
-
-        for (int i = 0; i < succSz; i++) {
-            int succ = successors.get(i);
-            RegisterSpecSet state = (succ == primarySuccessor) ?
-                primaryState : secondaryState;
-
-            if (resultInfo.mergeStarts(succ, state)) {
-                Bits.set(workSet, succ);
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/LocalVariableInfo.java b/dx/src/main/java/com/android/dx/rop/code/LocalVariableInfo.java
deleted file mode 100644
index 5d2b995..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/LocalVariableInfo.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.util.MutabilityControl;
-
-import java.util.HashMap;
-
-/**
- * Container for local variable information for a particular {@link
- * RopMethod}.
- */
-public final class LocalVariableInfo
-        extends MutabilityControl {
-    /** {@code >= 0;} the register count for the method */
-    private final int regCount;
-
-    /**
-     * {@code non-null;} {@link RegisterSpecSet} to use when indicating a block
-     * that has no locals; it is empty and immutable but has an appropriate
-     * max size for the method
-     */
-    private final RegisterSpecSet emptySet;
-
-    /**
-     * {@code non-null;} array consisting of register sets representing the
-     * sets of variables already assigned upon entry to each block,
-     * where array indices correspond to block labels
-     */
-    private final RegisterSpecSet[] blockStarts;
-
-    /** {@code non-null;} map from instructions to the variable each assigns */
-    private final HashMap<Insn, RegisterSpec> insnAssignments;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the method being represented by this instance
-     */
-    public LocalVariableInfo(RopMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        BasicBlockList blocks = method.getBlocks();
-        int maxLabel = blocks.getMaxLabel();
-
-        this.regCount = blocks.getRegCount();
-        this.emptySet = new RegisterSpecSet(regCount);
-        this.blockStarts = new RegisterSpecSet[maxLabel];
-        this.insnAssignments =
-            new HashMap<Insn, RegisterSpec>(blocks.getInstructionCount());
-
-        emptySet.setImmutable();
-    }
-
-    /**
-     * Sets the register set associated with the start of the block with
-     * the given label.
-     *
-     * @param label {@code >= 0;} the block label
-     * @param specs {@code non-null;} the register set to associate with the block
-     */
-    public void setStarts(int label, RegisterSpecSet specs) {
-        throwIfImmutable();
-
-        if (specs == null) {
-            throw new NullPointerException("specs == null");
-        }
-
-        try {
-            blockStarts[label] = specs;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus label");
-        }
-    }
-
-    /**
-     * Merges the given register set into the set for the block with the
-     * given label. If there was not already an associated set, then this
-     * is the same as calling {@link #setStarts}. Otherwise, this will
-     * merge the two sets and call {@link #setStarts} on the result of the
-     * merge.
-     *
-     * @param label {@code >= 0;} the block label
-     * @param specs {@code non-null;} the register set to merge into the start set
-     * for the block
-     * @return {@code true} if the merge resulted in an actual change
-     * to the associated set (including storing one for the first time) or
-     * {@code false} if there was no change
-     */
-    public boolean mergeStarts(int label, RegisterSpecSet specs) {
-        RegisterSpecSet start = getStarts0(label);
-        boolean changed = false;
-
-        if (start == null) {
-            setStarts(label, specs);
-            return true;
-        }
-
-        RegisterSpecSet newStart = start.mutableCopy();
-        if (start.size() != 0) {
-            newStart.intersect(specs, true);
-        } else {
-            newStart = specs.mutableCopy();
-        }
-
-        if (start.equals(newStart)) {
-            return false;
-        }
-
-        newStart.setImmutable();
-        setStarts(label, newStart);
-
-        return true;
-    }
-
-    /**
-     * Gets the register set associated with the start of the block
-     * with the given label. This returns an empty set with the appropriate
-     * max size if no set was associated with the block in question.
-     *
-     * @param label {@code >= 0;} the block label
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet getStarts(int label) {
-        RegisterSpecSet result = getStarts0(label);
-
-        return (result != null) ? result : emptySet;
-    }
-
-    /**
-     * Gets the register set associated with the start of the given
-     * block. This is just convenient shorthand for
-     * {@code getStarts(block.getLabel())}.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet getStarts(BasicBlock block) {
-        return getStarts(block.getLabel());
-    }
-
-    /**
-     * Gets a mutable copy of the register set associated with the
-     * start of the block with the given label. This returns a
-     * newly-allocated empty {@link RegisterSpecSet} of appropriate
-     * max size if there is not yet any set associated with the block.
-     *
-     * @param label {@code >= 0;} the block label
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet mutableCopyOfStarts(int label) {
-        RegisterSpecSet result = getStarts0(label);
-
-        return (result != null) ?
-            result.mutableCopy() : new RegisterSpecSet(regCount);
-    }
-
-    /**
-     * Adds an assignment association for the given instruction and
-     * register spec. This throws an exception if the instruction
-     * doesn't actually perform a named variable assignment.
-     *
-     * <b>Note:</b> Although the instruction contains its own spec for
-     * the result, it still needs to be passed in explicitly to this
-     * method, since the spec that is stored here should always have a
-     * simple type and the one in the instruction can be an arbitrary
-     * {@link TypeBearer} (such as a constant value).
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @param spec {@code non-null;} the associated register spec
-     */
-    public void addAssignment(Insn insn, RegisterSpec spec) {
-        throwIfImmutable();
-
-        if (insn == null) {
-            throw new NullPointerException("insn == null");
-        }
-
-        if (spec == null) {
-            throw new NullPointerException("spec == null");
-        }
-
-        insnAssignments.put(insn, spec);
-    }
-
-    /**
-     * Gets the named register being assigned by the given instruction, if
-     * previously stored in this instance.
-     *
-     * @param insn {@code non-null;} instruction in question
-     * @return {@code null-ok;} the named register being assigned, if any
-     */
-    public RegisterSpec getAssignment(Insn insn) {
-        return insnAssignments.get(insn);
-    }
-
-    /**
-     * Gets the number of assignments recorded by this instance.
-     *
-     * @return {@code >= 0;} the number of assignments
-     */
-    public int getAssignmentCount() {
-        return insnAssignments.size();
-    }
-
-    public void debugDump() {
-        for (int label = 0 ; label < blockStarts.length; label++) {
-            if (blockStarts[label] == null) {
-                continue;
-            }
-
-            if (blockStarts[label] == emptySet) {
-                System.out.printf("%04x: empty set\n", label);
-            } else {
-                System.out.printf("%04x: %s\n", label, blockStarts[label]);
-            }
-        }
-    }
-
-    /**
-     * Helper method, to get the starts for a label, throwing the
-     * right exception for range problems.
-     *
-     * @param label {@code >= 0;} the block label
-     * @return {@code null-ok;} associated register set or {@code null} if there
-     * is none
-     */
-    private RegisterSpecSet getStarts0(int label) {
-        try {
-            return blockStarts[label];
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus label");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/PlainCstInsn.java b/dx/src/main/java/com/android/dx/rop/code/PlainCstInsn.java
deleted file mode 100644
index fffa76b..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/PlainCstInsn.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * Instruction which contains an explicit reference to a constant
- * but which cannot throw an exception.
- */
-public final class PlainCstInsn
-        extends CstInsn {
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param sources {@code non-null;} specs for all the sources
-     * @param cst {@code non-null;} the constant
-     */
-    public PlainCstInsn(Rop opcode, SourcePosition position,
-                        RegisterSpec result, RegisterSpecList sources,
-                        Constant cst) {
-        super(opcode, position, result, sources, cst);
-
-        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return StdTypeList.EMPTY;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitPlainCstInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new PlainCstInsn(getOpcode(), getPosition(),
-                                getResult().withOffset(delta),
-                                getSources().withOffset(delta),
-                                getConstant());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new PlainCstInsn(getOpcode(), getPosition(),
-                                result,
-                                sources,
-                                getConstant());
-
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/PlainInsn.java b/dx/src/main/java/com/android/dx/rop/code/PlainInsn.java
deleted file mode 100644
index 3b52efa..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/PlainInsn.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstInteger;
-
-/**
- * Plain instruction, which has no embedded data and which cannot possibly
- * throw an exception.
- */
-public final class PlainInsn
-        extends Insn {
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param sources {@code non-null;} specs for all the sources
-     */
-    public PlainInsn(Rop opcode, SourcePosition position,
-                     RegisterSpec result, RegisterSpecList sources) {
-        super(opcode, position, result, sources);
-
-        switch (opcode.getBranchingness()) {
-            case Rop.BRANCH_SWITCH:
-            case Rop.BRANCH_THROW: {
-                throw new IllegalArgumentException("bogus branchingness");
-            }
-        }
-
-        if (result != null && opcode.getBranchingness() != Rop.BRANCH_NONE) {
-            // move-result-pseudo is required here
-            throw new IllegalArgumentException
-                    ("can't mix branchingness with result");
-        }
-    }
-
-    /**
-     * Constructs a single-source instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param source {@code non-null;} spec for the source
-     */
-    public PlainInsn(Rop opcode, SourcePosition position, RegisterSpec result,
-                     RegisterSpec source) {
-        this(opcode, position, result, RegisterSpecList.make(source));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return StdTypeList.EMPTY;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitPlainInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new PlainInsn(getOpcode(), getPosition(),
-                             getResult().withOffset(delta),
-                             getSources().withOffset(delta));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withSourceLiteral() {
-        RegisterSpecList sources = getSources();
-        int szSources = sources.size();
-
-        if (szSources == 0) {
-            return this;
-        }
-
-        TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();
-
-        if (!lastType.isConstant()) {
-            // Check for reverse subtraction, where first source is constant
-            TypeBearer firstType = sources.get(0).getTypeBearer();
-            if (szSources == 2 && firstType.isConstant()) {
-                Constant cst = (Constant) firstType;
-                RegisterSpecList newSources = sources.withoutFirst();
-                Rop newRop = Rops.ropFor(getOpcode().getOpcode(), getResult(),
-                                             newSources, cst);
-                return new PlainCstInsn(newRop, getPosition(), getResult(),
-                                            newSources, cst);
-            }
-            return this;
-        } else {
-
-            Constant cst = (Constant) lastType;
-
-            RegisterSpecList newSources = sources.withoutLast();
-
-            Rop newRop;
-            try {
-                // Check for constant subtraction and flip it to be addition
-                int opcode = getOpcode().getOpcode();
-                if (opcode == RegOps.SUB && cst instanceof CstInteger) {
-                    opcode = RegOps.ADD;
-                    cst = CstInteger.make(-((CstInteger)cst).getValue());
-                }
-                newRop = Rops.ropFor(opcode, getResult(), newSources, cst);
-            } catch (IllegalArgumentException ex) {
-                // There's no rop for this case
-                return this;
-            }
-
-            return new PlainCstInsn(newRop, getPosition(),
-                    getResult(), newSources, cst);
-        }
-    }
-
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new PlainInsn(getOpcode(), getPosition(),
-                             result,
-                             sources);
-
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/RegOps.java b/dx/src/main/java/com/android/dx/rop/code/RegOps.java
deleted file mode 100644
index c81398d..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/RegOps.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.Hex;
-
-/**
- * All the register-based opcodes, and related utilities.
- *
- * <p><b>Note:</b> Opcode descriptions use a rough pseudocode. {@code r}
- * is the result register, {@code x} is the first argument,
- * {@code y} is the second argument, and {@code z} is the
- * third argument. The expression which describes
- * the operation uses Java-ish syntax but is preceded by type indicators for
- * each of the values.
- */
-public final class RegOps {
-    /** {@code nop()} */
-    public static final int NOP = 1;
-
-    /** {@code T: any type; r,x: T :: r = x;} */
-    public static final int MOVE = 2;
-
-    /** {@code T: any type; r,param(x): T :: r = param(x)} */
-    public static final int MOVE_PARAM = 3;
-
-    /**
-     * {@code T: Throwable; r: T :: r = caught_exception}.
-     * <b>Note:</b> This opcode should only ever be used in the
-     * first instruction of a block, and such blocks must be
-     * the start of an exception handler.
-     */
-    public static final int MOVE_EXCEPTION = 4;
-
-    /** {@code T: any type; r, literal: T :: r = literal;} */
-    public static final int CONST = 5;
-
-    /** {@code goto label} */
-    public static final int GOTO = 6;
-
-    /**
-     * {@code T: int or Object; x,y: T :: if (x == y) goto
-     * label}
-     */
-    public static final int IF_EQ = 7;
-
-    /**
-     * {@code T: int or Object; x,y: T :: if (x != y) goto
-     * label}
-     */
-    public static final int IF_NE = 8;
-
-    /** {@code x,y: int :: if (x < y) goto label} */
-    public static final int IF_LT = 9;
-
-    /** {@code x,y: int :: if (x >= y) goto label} */
-    public static final int IF_GE = 10;
-
-    /** {@code x,y: int :: if (x <= y) goto label} */
-    public static final int IF_LE = 11;
-
-    /** {@code x,y: int :: if (x > y) goto label} */
-    public static final int IF_GT = 12;
-
-    /** {@code x: int :: goto table[x]} */
-    public static final int SWITCH = 13;
-
-    /** {@code T: any numeric type; r,x,y: T :: r = x + y} */
-    public static final int ADD = 14;
-
-    /** {@code T: any numeric type; r,x,y: T :: r = x - y} */
-    public static final int SUB = 15;
-
-    /** {@code T: any numeric type; r,x,y: T :: r = x * y} */
-    public static final int MUL = 16;
-
-    /** {@code T: any numeric type; r,x,y: T :: r = x / y} */
-    public static final int DIV = 17;
-
-    /**
-     * {@code T: any numeric type; r,x,y: T :: r = x % y}
-     * (Java-style remainder)
-     */
-    public static final int REM = 18;
-
-    /** {@code T: any numeric type; r,x: T :: r = -x} */
-    public static final int NEG = 19;
-
-    /** {@code T: any integral type; r,x,y: T :: r = x & y} */
-    public static final int AND = 20;
-
-    /** {@code T: any integral type; r,x,y: T :: r = x | y} */
-    public static final int OR = 21;
-
-    /** {@code T: any integral type; r,x,y: T :: r = x ^ y} */
-    public static final int XOR = 22;
-
-    /**
-     * {@code T: any integral type; r,x: T; y: int :: r = x << y}
-     */
-    public static final int SHL = 23;
-
-    /**
-     * {@code T: any integral type; r,x: T; y: int :: r = x >> y}
-     * (signed right-shift)
-     */
-    public static final int SHR = 24;
-
-    /**
-     * {@code T: any integral type; r,x: T; y: int :: r = x >>> y}
-     * (unsigned right-shift)
-     */
-    public static final int USHR = 25;
-
-    /** {@code T: any integral type; r,x: T :: r = ~x} */
-    public static final int NOT = 26;
-
-    /**
-     * {@code T: any numeric type; r: int; x,y: T :: r = (x == y) ? 0
-     * : (x > y) ? 1 : -1} (Java-style "cmpl" where a NaN is
-     * considered "less than" all other values; also used for integral
-     * comparisons)
-     */
-    public static final int CMPL = 27;
-
-    /**
-     * {@code T: any floating point type; r: int; x,y: T :: r = (x == y) ? 0
-     * : (x < y) ? -1 : 1} (Java-style "cmpg" where a NaN is
-     * considered "greater than" all other values)
-     */
-    public static final int CMPG = 28;
-
-    /**
-     * {@code T: any numeric type; U: any numeric type; r: T; x: U ::
-     * r = (T) x} (numeric type conversion between the four
-     * "real" numeric types)
-     */
-    public static final int CONV = 29;
-
-    /**
-     * {@code r,x: int :: r = (x << 24) >> 24} (Java-style
-     * convert int to byte)
-     */
-    public static final int TO_BYTE = 30;
-
-    /**
-     * {@code r,x: int :: r = x & 0xffff} (Java-style convert int to char)
-     */
-    public static final int TO_CHAR = 31;
-
-    /**
-     * {@code r,x: int :: r = (x << 16) >> 16} (Java-style
-     * convert int to short)
-     */
-    public static final int TO_SHORT = 32;
-
-    /** {@code T: return type for the method; x: T; return x} */
-    public static final int RETURN = 33;
-
-    /** {@code T: any type; r: int; x: T[]; :: r = x.length} */
-    public static final int ARRAY_LENGTH = 34;
-
-    /** {@code x: Throwable :: throw(x)} */
-    public static final int THROW = 35;
-
-    /** {@code x: Object :: monitorenter(x)} */
-    public static final int MONITOR_ENTER = 36;
-
-    /** {@code x: Object :: monitorexit(x)} */
-    public static final int MONITOR_EXIT = 37;
-
-    /** {@code T: any type; r: T; x: T[]; y: int :: r = x[y]} */
-    public static final int AGET = 38;
-
-    /** {@code T: any type; x: T; y: T[]; z: int :: x[y] = z} */
-    public static final int APUT = 39;
-
-    /**
-     * {@code T: any non-array object type :: r =
-     * alloc(T)} (allocate heap space for an object)
-     */
-    public static final int NEW_INSTANCE = 40;
-
-    /** {@code T: any array type; r: T; x: int :: r = new T[x]} */
-    public static final int NEW_ARRAY = 41;
-
-    /**
-     * {@code T: any array type; r: T; x: int; v0..vx: T :: r = new T[x]
-     * {v0, ..., vx}}
-     */
-    public static final int FILLED_NEW_ARRAY = 42;
-
-    /**
-     * {@code T: any object type; x: Object :: (T) x} (can
-     * throw {@code ClassCastException})
-     */
-    public static final int CHECK_CAST = 43;
-
-    /**
-     * {@code T: any object type; x: Object :: x instanceof T}
-     */
-    public static final int INSTANCE_OF = 44;
-
-    /**
-     * {@code T: any type; r: T; x: Object; f: instance field spec of
-     * type T :: r = x.f}
-     */
-    public static final int GET_FIELD = 45;
-
-    /**
-     * {@code T: any type; r: T; f: static field spec of type T :: r =
-     * f}
-     */
-    public static final int GET_STATIC = 46;
-
-    /**
-     * {@code T: any type; x: T; y: Object; f: instance field spec of type
-     * T :: y.f = x}
-     */
-    public static final int PUT_FIELD = 47;
-
-    /**
-     * {@code T: any type; f: static field spec of type T; x: T :: f = x}
-     */
-    public static final int PUT_STATIC = 48;
-
-    /**
-     * {@code Tr, T0, T1...: any types; r: Tr; m: static method spec;
-     * y0: T0; y1: T1 ... :: r = m(y0, y1, ...)} (call static
-     * method)
-     */
-    public static final int INVOKE_STATIC = 49;
-
-    /**
-     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method
-     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call normal
-     * virtual method)
-     */
-    public static final int INVOKE_VIRTUAL = 50;
-
-    /**
-     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method
-     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call
-     * superclass virtual method)
-     */
-    public static final int INVOKE_SUPER = 51;
-
-    /**
-     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: instance method
-     * spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1, ...)} (call
-     * direct/special method)
-     */
-    public static final int INVOKE_DIRECT = 52;
-
-    /**
-     * {@code Tr, T0, T1...: any types; r: Tr; x: Object; m: interface
-     * (instance) method spec; y0: T0; y1: T1 ... :: r = x.m(y0, y1,
-     * ...)} (call interface method)
-     */
-    public static final int INVOKE_INTERFACE = 53;
-
-    /**
-     * {@code T0: any type; name: local variable name  :: mark(name,T0)}
-     * (mark beginning or end of local variable name)
-     */
-    public static final int MARK_LOCAL = 54;
-
-    /**
-     * {@code T: Any type; r: T :: r = return_type}.
-     * <b>Note:</b> This opcode should only ever be used in the
-     * first instruction of a block following an invoke-*.
-     */
-    public static final int MOVE_RESULT = 55;
-
-    /**
-     * {@code T: Any type; r: T :: r = return_type}.
-     * <b>Note:</b> This opcode should only ever be used in the
-     * first instruction of a block following a non-invoke throwing insn
-     */
-    public static final int MOVE_RESULT_PSEUDO = 56;
-
-    /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */
-    public static final int FILL_ARRAY_DATA = 57;
-
-    /**
-     * This class is uninstantiable.
-     */
-    private RegOps() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Gets the name of the given opcode.
-     *
-     * @param opcode the opcode
-     * @return {@code non-null;} its name
-     */
-    public static String opName(int opcode) {
-        switch (opcode) {
-            case NOP: return "nop";
-            case MOVE: return "move";
-            case MOVE_PARAM: return "move-param";
-            case MOVE_EXCEPTION: return "move-exception";
-            case CONST: return "const";
-            case GOTO: return "goto";
-            case IF_EQ: return "if-eq";
-            case IF_NE: return "if-ne";
-            case IF_LT: return "if-lt";
-            case IF_GE: return "if-ge";
-            case IF_LE: return "if-le";
-            case IF_GT: return "if-gt";
-            case SWITCH: return "switch";
-            case ADD: return "add";
-            case SUB: return "sub";
-            case MUL: return "mul";
-            case DIV: return "div";
-            case REM: return "rem";
-            case NEG: return "neg";
-            case AND: return "and";
-            case OR: return "or";
-            case XOR: return "xor";
-            case SHL: return "shl";
-            case SHR: return "shr";
-            case USHR: return "ushr";
-            case NOT: return "not";
-            case CMPL: return "cmpl";
-            case CMPG: return "cmpg";
-            case CONV: return "conv";
-            case TO_BYTE: return "to-byte";
-            case TO_CHAR: return "to-char";
-            case TO_SHORT: return "to-short";
-            case RETURN: return "return";
-            case ARRAY_LENGTH: return "array-length";
-            case THROW: return "throw";
-            case MONITOR_ENTER: return "monitor-enter";
-            case MONITOR_EXIT: return "monitor-exit";
-            case AGET: return "aget";
-            case APUT: return "aput";
-            case NEW_INSTANCE: return "new-instance";
-            case NEW_ARRAY: return "new-array";
-            case FILLED_NEW_ARRAY: return "filled-new-array";
-            case CHECK_CAST: return "check-cast";
-            case INSTANCE_OF: return "instance-of";
-            case GET_FIELD: return "get-field";
-            case GET_STATIC: return "get-static";
-            case PUT_FIELD: return "put-field";
-            case PUT_STATIC: return "put-static";
-            case INVOKE_STATIC: return "invoke-static";
-            case INVOKE_VIRTUAL: return "invoke-virtual";
-            case INVOKE_SUPER: return "invoke-super";
-            case INVOKE_DIRECT: return "invoke-direct";
-            case INVOKE_INTERFACE: return "invoke-interface";
-            case MOVE_RESULT: return "move-result";
-            case MOVE_RESULT_PSEUDO: return "move-result-pseudo";
-            case FILL_ARRAY_DATA: return "fill-array-data";
-        }
-
-        return "unknown-" + Hex.u1(opcode);
-    }
-
-    /**
-     * Given an IF_* RegOp, returns the right-to-left flipped version. For
-     * example, IF_GT becomes IF_LT.
-     *
-     * @param opcode An IF_* RegOp
-     * @return flipped IF Regop
-     */
-    public static int flippedIfOpcode(final int opcode) {
-        switch (opcode) {
-            case RegOps.IF_EQ:
-            case RegOps.IF_NE:
-                return opcode;
-            case RegOps.IF_LT:
-                return RegOps.IF_GT;
-            case RegOps.IF_GE:
-                return RegOps.IF_LE;
-            case RegOps.IF_LE:
-                return RegOps.IF_GE;
-            case RegOps.IF_GT:
-                return RegOps.IF_LT;
-            default:
-                throw new RuntimeException("Unrecognized IF regop: " + opcode);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/RegisterSpec.java b/dx/src/main/java/com/android/dx/rop/code/RegisterSpec.java
deleted file mode 100644
index e5f908b..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/RegisterSpec.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.util.ToHuman;
-
-import java.util.HashMap;
-
-/**
- * Combination of a register number and a type, used as the sources and
- * destinations of register-based operations.
- */
-public final class RegisterSpec
-        implements TypeBearer, ToHuman, Comparable<RegisterSpec> {
-    /** {@code non-null;} string to prefix register numbers with */
-    public static final String PREFIX = "v";
-
-    /** {@code non-null;} intern table for instances */
-    private static final HashMap<Object, RegisterSpec> theInterns =
-        new HashMap<Object, RegisterSpec>(1000);
-
-    /** {@code non-null;} common comparison instance used while interning */
-    private static final ForComparison theInterningItem = new ForComparison();
-
-    /** {@code >= 0;} register number */
-    private final int reg;
-
-    /** {@code non-null;} type loaded or stored */
-    private final TypeBearer type;
-
-    /**
-     * {@code null-ok;} local variable info associated with this register,
-     * if any
-     */
-    private final LocalItem local;
-
-    /**
-     * Intern the given triple as an instance of this class.
-     *
-     * @param reg {@code >= 0;} the register number
-     * @param type {@code non-null;} the type (or possibly actual value) which
-     * is loaded from or stored to the indicated register
-     * @param local {@code null-ok;} the associated local variable, if any
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    private static RegisterSpec intern(int reg, TypeBearer type,
-            LocalItem local) {
-        synchronized (theInterns) {
-            theInterningItem.set(reg, type, local);
-            RegisterSpec found = theInterns.get(theInterningItem);
-
-            if (found != null) {
-                return found;
-            }
-
-            found = theInterningItem.toRegisterSpec();
-            theInterns.put(found, found);
-            return found;
-        }
-    }
-
-    /**
-     * Returns an instance for the given register number and type, with
-     * no variable info. This method is allowed to return shared
-     * instances (but doesn't necessarily do so).
-     *
-     * @param reg {@code >= 0;} the register number
-     * @param type {@code non-null;} the type (or possibly actual value) which
-     * is loaded from or stored to the indicated register
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpec make(int reg, TypeBearer type) {
-        return intern(reg, type, null);
-    }
-
-    /**
-     * Returns an instance for the given register number, type, and
-     * variable info. This method is allowed to return shared
-     * instances (but doesn't necessarily do so).
-     *
-     * @param reg {@code >= 0;} the register number
-     * @param type {@code non-null;} the type (or possibly actual value) which
-     * is loaded from or stored to the indicated register
-     * @param local {@code non-null;} the associated local variable
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpec make(int reg, TypeBearer type,
-            LocalItem local) {
-        if (local == null) {
-            throw new NullPointerException("local  == null");
-        }
-
-        return intern(reg, type, local);
-    }
-
-    /**
-     * Returns an instance for the given register number, type, and
-     * variable info. This method is allowed to return shared
-     * instances (but doesn't necessarily do so).
-     *
-     * @param reg {@code >= 0;} the register number
-     * @param type {@code non-null;} the type (or possibly actual value) which
-     * is loaded from or stored to the indicated register
-     * @param local {@code null-ok;} the associated variable info or null for
-     * none
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpec makeLocalOptional(
-            int reg, TypeBearer type, LocalItem local) {
-
-        return intern(reg, type, local);
-    }
-
-    /**
-     * Gets the string form for the given register number.
-     *
-     * @param reg {@code >= 0;} the register number
-     * @return {@code non-null;} the string form
-     */
-    public static String regString(int reg) {
-        return PREFIX + reg;
-    }
-
-    /**
-     * Constructs an instance. This constructor is private. Use
-     * {@link #make}.
-     *
-     * @param reg {@code >= 0;} the register number
-     * @param type {@code non-null;} the type (or possibly actual value) which
-     * is loaded from or stored to the indicated register
-     * @param local {@code null-ok;} the associated local variable, if any
-     */
-    private RegisterSpec(int reg, TypeBearer type, LocalItem local) {
-        if (reg < 0) {
-            throw new IllegalArgumentException("reg < 0");
-        }
-
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        this.reg = reg;
-        this.type = type;
-        this.local = local;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof RegisterSpec)) {
-            if (other instanceof ForComparison) {
-                ForComparison fc = (ForComparison) other;
-                return equals(fc.reg, fc.type, fc.local);
-            }
-            return false;
-        }
-
-        RegisterSpec spec = (RegisterSpec) other;
-        return equals(spec.reg, spec.type, spec.local);
-    }
-
-    /**
-     * Like {@code equals}, but only consider the simple types of the
-     * registers. That is, this compares {@code getType()} on the types
-     * to ignore whatever arbitrary extra stuff might be carried around
-     * by an outer {@link TypeBearer}.
-     *
-     * @param other {@code null-ok;} spec to compare to
-     * @return {@code true} iff {@code this} and {@code other} are equal
-     * in the stated way
-     */
-    public boolean equalsUsingSimpleType(RegisterSpec other) {
-        if (!matchesVariable(other)) {
-            return false;
-        }
-
-        return (reg == other.reg);
-    }
-
-    /**
-     * Like {@link #equalsUsingSimpleType} but ignoring the register number.
-     * This is useful to determine if two instances refer to the "same"
-     * local variable.
-     *
-     * @param other {@code null-ok;} spec to compare to
-     * @return {@code true} iff {@code this} and {@code other} are equal
-     * in the stated way
-     */
-    public boolean matchesVariable(RegisterSpec other) {
-        if (other == null) {
-            return false;
-        }
-
-        return type.getType().equals(other.type.getType())
-            && ((local == other.local)
-                    || ((local != null) && local.equals(other.local)));
-    }
-
-    /**
-     * Helper for {@link #equals} and {@link #ForComparison.equals},
-     * which actually does the test.
-     *
-     * @param reg value of the instance variable, for another instance
-     * @param type value of the instance variable, for another instance
-     * @param local value of the instance variable, for another instance
-     * @return whether this instance is equal to one with the given
-     * values
-     */
-    private boolean equals(int reg, TypeBearer type, LocalItem local) {
-        return (this.reg == reg)
-            && this.type.equals(type)
-            && ((this.local == local)
-                    || ((this.local != null) && this.local.equals(local)));
-    }
-
-    /**
-     * Compares by (in priority order) register number, unwrapped type
-     * (that is types not {@link TypeBearer}s, and local info.
-     *
-     * @param other {@code non-null;} spec to compare to
-     * @return {@code -1..1;} standard result of comparison
-     */
-    public int compareTo(RegisterSpec other) {
-        if (this.reg < other.reg) {
-            return -1;
-        } else if (this.reg > other.reg) {
-            return 1;
-        }
-
-        int compare = type.getType().compareTo(other.type.getType());
-
-        if (compare != 0) {
-            return compare;
-        }
-
-        if (this.local == null) {
-            return (other.local == null) ? 0 : -1;
-        } else if (other.local == null) {
-            return 1;
-        }
-
-        return this.local.compareTo(other.local);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return hashCodeOf(reg, type, local);
-    }
-
-    /**
-     * Helper for {@link #hashCode} and {@link #ForComparison.hashCode},
-     * which actually does the calculation.
-     *
-     * @param reg value of the instance variable
-     * @param type value of the instance variable
-     * @param local value of the instance variable
-     * @return the hash code
-     */
-    private static int hashCodeOf(int reg, TypeBearer type, LocalItem local) {
-        int hash = (local != null) ? local.hashCode() : 0;
-
-        hash = (hash * 31 + type.hashCode()) * 31 + reg;
-        return hash;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return toString0(false);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return toString0(true);
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return type.getType();
-    }
-
-    /** {@inheritDoc} */
-    public TypeBearer getFrameType() {
-        return type.getFrameType();
-    }
-
-    /** {@inheritDoc} */
-    public final int getBasicType() {
-        return type.getBasicType();
-    }
-
-    /** {@inheritDoc} */
-    public final int getBasicFrameType() {
-        return type.getBasicFrameType();
-    }
-
-    /** {@inheritDoc} */
-    public final boolean isConstant() {
-        return false;
-    }
-
-    /**
-     * Gets the register number.
-     *
-     * @return {@code >= 0;} the register number
-     */
-    public int getReg() {
-        return reg;
-    }
-
-    /**
-     * Gets the type (or actual value) which is loaded from or stored
-     * to the register associated with this instance.
-     *
-     * @return {@code non-null;} the type
-     */
-    public TypeBearer getTypeBearer() {
-        return type;
-    }
-
-    /**
-     * Gets the variable info associated with this instance, if any.
-     *
-     * @return {@code null-ok;} the variable info, or {@code null} if this
-     * instance has none
-     */
-    public LocalItem getLocalItem() {
-        return local;
-    }
-
-    /**
-     * Gets the next available register number after the one in this
-     * instance. This is equal to the register number plus the width
-     * (category) of the type used. Among other things, this may also
-     * be used to determine the minimum required register count
-     * implied by this instance.
-     *
-     * @return {@code >= 0;} the required registers size
-     */
-    public int getNextReg() {
-        return reg + getCategory();
-    }
-
-    /**
-     * Gets the category of this instance's type. This is just a convenient
-     * shorthand for {@code getType().getCategory()}.
-     *
-     * @see #isCategory1
-     * @see #isCategory2
-     * @return {@code 1..2;} the category of this instance's type
-     */
-    public int getCategory() {
-        return type.getType().getCategory();
-    }
-
-    /**
-     * Gets whether this instance's type is category 1. This is just a
-     * convenient shorthand for {@code getType().isCategory1()}.
-     *
-     * @see #getCategory
-     * @see #isCategory2
-     * @return whether or not this instance's type is of category 1
-     */
-    public boolean isCategory1() {
-        return type.getType().isCategory1();
-    }
-
-    /**
-     * Gets whether this instance's type is category 2. This is just a
-     * convenient shorthand for {@code getType().isCategory2()}.
-     *
-     * @see #getCategory
-     * @see #isCategory1
-     * @return whether or not this instance's type is of category 2
-     */
-    public boolean isCategory2() {
-        return type.getType().isCategory2();
-    }
-
-    /**
-     * Gets the string form for just the register number of this instance.
-     *
-     * @return {@code non-null;} the register string form
-     */
-    public String regString() {
-        return regString(reg);
-    }
-
-    /**
-     * Returns an instance that is the intersection between this instance
-     * and the given one, if any. The intersection is defined as follows:
-     *
-     * <ul>
-     *   <li>If {@code other} is {@code null}, then the result
-     *     is {@code null}.
-     *   <li>If the register numbers don't match, then the intersection
-     *     is {@code null}. Otherwise, the register number of the
-     *     intersection is the same as the one in the two instances.</li>
-     *   <li>If the types returned by {@code getType()} are not
-     *     {@code equals()}, then the intersection is null.</li>
-     *   <li>If the type bearers returned by {@code getTypeBearer()}
-     *     are {@code equals()}, then the intersection's type bearer
-     *     is the one from this instance. Otherwise, the intersection's
-     *     type bearer is the {@code getType()} of this instance.</li>
-     *   <li>If the locals are {@code equals()}, then the local info
-     *     of the intersection is the local info of this instance. Otherwise,
-     *     the local info of the intersection is {@code null}.</li>
-     * </ul>
-     *
-     * @param other {@code null-ok;} instance to intersect with (or {@code null})
-     * @param localPrimary whether local variables are primary to the
-     * intersection; if {@code true}, then the only non-null
-     * results occur when registers being intersected have equal local
-     * infos (or both have {@code null} local infos)
-     * @return {@code null-ok;} the intersection
-     */
-    public RegisterSpec intersect(RegisterSpec other, boolean localPrimary) {
-        if (this == other) {
-            // Easy out.
-            return this;
-        }
-
-        if ((other == null) || (reg != other.getReg())) {
-            return null;
-        }
-
-        LocalItem resultLocal =
-            ((local == null) || !local.equals(other.getLocalItem()))
-            ? null : local;
-        boolean sameName = (resultLocal == local);
-
-        if (localPrimary && !sameName) {
-            return null;
-        }
-
-        Type thisType = getType();
-        Type otherType = other.getType();
-
-        // Note: Types are always interned.
-        if (thisType != otherType) {
-            return null;
-        }
-
-        TypeBearer resultTypeBearer =
-            type.equals(other.getTypeBearer()) ? type : thisType;
-
-        if ((resultTypeBearer == type) && sameName) {
-            // It turns out that the intersection is "this" after all.
-            return this;
-        }
-
-        return (resultLocal == null) ? make(reg, resultTypeBearer) :
-            make(reg, resultTypeBearer, resultLocal);
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that the
-     * register number is replaced by the given one.
-     *
-     * @param newReg {@code >= 0;} the new register number
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpec withReg(int newReg) {
-        if (reg == newReg) {
-            return this;
-        }
-
-        return makeLocalOptional(newReg, type, local);
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the type is replaced by the given one.
-     *
-     * @param newType {@code non-null;} the new type
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpec withType(TypeBearer newType) {
-        return makeLocalOptional(reg, newType, local);
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that the
-     * register number is offset by the given amount.
-     *
-     * @param delta the amount to offset the register number by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpec withOffset(int delta) {
-        if (delta == 0) {
-            return this;
-        }
-
-        return withReg(reg + delta);
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the type bearer is replaced by the actual underlying type
-     * (thereby stripping off non-type information) with any
-     * initialization information stripped away as well.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpec withSimpleType() {
-        TypeBearer orig = type;
-        Type newType;
-
-        if (orig instanceof Type) {
-            newType = (Type) orig;
-        } else {
-            newType = orig.getType();
-        }
-
-        if (newType.isUninitialized()) {
-            newType = newType.getInitializedType();
-        }
-
-        if (newType == orig) {
-            return this;
-        }
-
-        return makeLocalOptional(reg, newType, local);
-    }
-
-    /**
-     * Returns an instance that is identical to this one except that the
-     * local variable is as specified in the parameter.
-     *
-     * @param local {@code null-ok;} the local item or null for none
-     * @return an appropriate instance
-     */
-    public RegisterSpec withLocalItem(LocalItem local) {
-        if ((this.local== local)
-                    || ((this.local != null) && this.local.equals(local))) {
-
-            return this;
-        }
-
-        return makeLocalOptional(reg, type, local);
-    }
-
-
-    /**
-     * Helper for {@link #toString} and {@link #toHuman}.
-     *
-     * @param human whether to be human-oriented
-     * @return {@code non-null;} the string form
-     */
-    private String toString0(boolean human) {
-        StringBuffer sb = new StringBuffer(40);
-
-        sb.append(regString());
-        sb.append(":");
-
-        if (local != null) {
-            sb.append(local.toString());
-        }
-
-        Type justType = type.getType();
-        sb.append(justType);
-
-        if (justType != type) {
-            sb.append("=");
-            if (human && (type instanceof CstString)) {
-                sb.append(((CstString) type).toQuoted());
-            } else if (human && (type instanceof Constant)) {
-                sb.append(type.toHuman());
-            } else {
-                sb.append(type);
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Holder of register spec data for the purposes of comparison (so that
-     * {@code RegisterSpec} itself can still keep {@code final}
-     * instance variables.
-     */
-    private static class ForComparison {
-        /** {@code >= 0;} register number */
-        private int reg;
-
-        /** {@code non-null;} type loaded or stored */
-        private TypeBearer type;
-
-        /**
-         * {@code null-ok;} local variable associated with this
-         * register, if any
-         */
-        private LocalItem local;
-
-        /**
-         * Set all the instance variables.
-         *
-         * @param reg {@code >= 0;} the register number
-         * @param type {@code non-null;} the type (or possibly actual
-         * value) which is loaded from or stored to the indicated
-         * register
-         * @param local {@code null-ok;} the associated local variable, if any
-         * @return {@code non-null;} an appropriately-constructed instance
-         */
-        public void set(int reg, TypeBearer type, LocalItem local) {
-            this.reg = reg;
-            this.type = type;
-            this.local = local;
-        }
-
-        /**
-         * Construct a {@code RegisterSpec} of this instance's
-         * contents.
-         *
-         * @return {@code non-null;} an appropriately-constructed instance
-         */
-        public RegisterSpec toRegisterSpec() {
-            return new RegisterSpec(reg, type, local);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof RegisterSpec)) {
-                return false;
-            }
-
-            RegisterSpec spec = (RegisterSpec) other;
-            return spec.equals(reg, type, local);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public int hashCode() {
-            return hashCodeOf(reg, type, local);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/RegisterSpecList.java b/dx/src/main/java/com/android/dx/rop/code/RegisterSpecList.java
deleted file mode 100644
index 3d891fd..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/RegisterSpecList.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.FixedSizeList;
-
-import java.util.BitSet;
-
-/**
- * List of {@link RegisterSpec} instances.
- */
-public final class RegisterSpecList
-        extends FixedSizeList implements TypeList {
-    /** {@code non-null;} no-element instance */
-    public static final RegisterSpecList EMPTY = new RegisterSpecList(0);
-
-    /**
-     * Makes a single-element instance.
-     *
-     * @param spec {@code non-null;} the element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpecList make(RegisterSpec spec) {
-        RegisterSpecList result = new RegisterSpecList(1);
-        result.set(0, spec);
-        return result;
-    }
-
-    /**
-     * Makes a two-element instance.
-     *
-     * @param spec0 {@code non-null;} the first element
-     * @param spec1 {@code non-null;} the second element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpecList make(RegisterSpec spec0,
-                                        RegisterSpec spec1) {
-        RegisterSpecList result = new RegisterSpecList(2);
-        result.set(0, spec0);
-        result.set(1, spec1);
-        return result;
-    }
-
-    /**
-     * Makes a three-element instance.
-     *
-     * @param spec0 {@code non-null;} the first element
-     * @param spec1 {@code non-null;} the second element
-     * @param spec2 {@code non-null;} the third element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1,
-                                        RegisterSpec spec2) {
-        RegisterSpecList result = new RegisterSpecList(3);
-        result.set(0, spec0);
-        result.set(1, spec1);
-        result.set(2, spec2);
-        return result;
-    }
-
-    /**
-     * Makes a four-element instance.
-     *
-     * @param spec0 {@code non-null;} the first element
-     * @param spec1 {@code non-null;} the second element
-     * @param spec2 {@code non-null;} the third element
-     * @param spec3 {@code non-null;} the fourth element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1,
-                                        RegisterSpec spec2,
-                                        RegisterSpec spec3) {
-        RegisterSpecList result = new RegisterSpecList(4);
-        result.set(0, spec0);
-        result.set(1, spec1);
-        result.set(2, spec2);
-        result.set(3, spec3);
-        return result;
-    }
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public RegisterSpecList(int size) {
-        super(size);
-    }
-
-    /** {@inheritDoc} */
-    public Type getType(int n) {
-        return get(n).getType().getType();
-    }
-
-    /** {@inheritDoc} */
-    public int getWordCount() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            result += getType(i).getCategory();
-        }
-
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    public TypeList withAddedType(Type type) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /**
-     * Gets the indicated element. It is an error to call this with the
-     * index for an element which was never set; if you do that, this
-     * will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return {@code non-null;} the indicated element
-     */
-    public RegisterSpec get(int n) {
-        return (RegisterSpec) get0(n);
-    }
-
-    /**
-     * Returns a RegisterSpec in this list that uses the specified register,
-     * or null if there is none in this list.
-     * @param reg Register to find
-     * @return RegisterSpec that uses argument or null.
-     */
-    public RegisterSpec specForRegister(int reg) {
-        int sz = size();
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec rs;
-
-            rs = get(i);
-
-            if (rs.getReg() == reg) {
-                return rs;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the index of a RegisterSpec in this list that uses the specified
-     * register, or -1 if none in this list uses the register.
-     * @param reg Register to find
-     * @return index of RegisterSpec or -1
-     */
-    public int indexOfRegister(int reg) {
-        int sz = size();
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec rs;
-
-            rs = get(i);
-
-            if (rs.getReg() == reg) {
-                return i;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Sets the element at the given index.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @param spec {@code non-null;} the value to store
-     */
-    public void set(int n, RegisterSpec spec) {
-        set0(n, spec);
-    }
-
-    /**
-     * Gets the minimum required register count implied by this
-     * instance. This is equal to the highest register number referred
-     * to plus the widest width (largest category) of the type used in
-     * that register.
-     *
-     * @return {@code >= 0;} the required registers size
-     */
-    public int getRegistersSize() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec spec = (RegisterSpec) get0(i);
-            if (spec != null) {
-                int min = spec.getNextReg();
-                if (min > result) {
-                    result = min;
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a new instance, which is the same as this instance,
-     * except that it has an additional element prepended to the original.
-     * Mutability of the result is inherited from the original.
-     *
-     * @param spec {@code non-null;} the new first spec (to prepend)
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList withFirst(RegisterSpec spec) {
-        int sz = size();
-        RegisterSpecList result = new RegisterSpecList(sz + 1);
-
-        for (int i = 0; i < sz; i++) {
-            result.set0(i + 1, get0(i));
-        }
-
-        result.set0(0, spec);
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a new instance, which is the same as this instance,
-     * except that its first element is removed. Mutability of the
-     * result is inherited from the original.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList withoutFirst() {
-        int newSize = size() - 1;
-
-        if (newSize == 0) {
-            return EMPTY;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(newSize);
-
-        for (int i = 0; i < newSize; i++) {
-            result.set0(i, get0(i + 1));
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a new instance, which is the same as this instance,
-     * except that its last element is removed. Mutability of the
-     * result is inherited from the original.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList withoutLast() {
-        int newSize = size() - 1;
-
-        if (newSize == 0) {
-            return EMPTY;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(newSize);
-
-        for (int i = 0; i < newSize; i++) {
-            result.set0(i, get0(i));
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns a new instance, which contains a subset of the elements
-     * specified by the given BitSet. Indexes in the BitSet with a zero
-     * are included, while indexes with a one are excluded. Mutability
-     * of the result is inherited from the original.
-     *
-     * @param exclusionSet {@code non-null;} set of registers to exclude
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList subset(BitSet exclusionSet) {
-        int newSize = size() - exclusionSet.cardinality();
-
-        if (newSize == 0) {
-            return EMPTY;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(newSize);
-
-        int newIndex = 0;
-        for (int oldIndex = 0; oldIndex < size(); oldIndex++) {
-            if (!exclusionSet.get(oldIndex)) {
-                result.set0(newIndex, get0(oldIndex));
-                newIndex++;
-            }
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * all register numbers are offset by the given amount. Mutability
-     * of the result is inherited from the original.
-     *
-     * @param delta the amount to offset the register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList withOffset(int delta) {
-        int sz = size();
-
-        if (sz == 0) {
-            // Don't bother making a new zero-element instance.
-            return this;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec one = (RegisterSpec) get0(i);
-            if (one != null) {
-                result.set0(i, one.withOffset(delta));
-            }
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * all incompatible register numbers are renumbered sequentially from
-     * the given base, with the first number duplicated if indicated. If
-     * a null BitSet is given, it indicates all registers are compatible.
-     *
-     * @param base the base register number
-     * @param duplicateFirst whether to duplicate the first number
-     * @param compatRegs {@code null-ok;} either a {@code non-null} set of
-     * compatible registers, or {@code null} to indicate all registers are
-     * compatible
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecList withExpandedRegisters(int base,
-                                                  boolean duplicateFirst,
-                                                  BitSet compatRegs) {
-        int sz = size();
-
-        if (sz == 0) {
-            // Don't bother making a new zero-element instance.
-            return this;
-        }
-
-        RegisterSpecList result = new RegisterSpecList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec one = (RegisterSpec) get0(i);
-            boolean replace = (compatRegs == null) ? true : !compatRegs.get(i);
-
-            if (replace) {
-                result.set0(i, one.withReg(base));
-                if (!duplicateFirst) {
-                    base += one.getCategory();
-                }
-            } else {
-                result.set0(i, one);
-            }
-
-            if (duplicateFirst) {
-                duplicateFirst = false;
-            }
-        }
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/RegisterSpecSet.java b/dx/src/main/java/com/android/dx/rop/code/RegisterSpecSet.java
deleted file mode 100644
index 14ef778..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/RegisterSpecSet.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.MutabilityControl;
-
-/**
- * Set of {@link RegisterSpec} instances, where a given register number
- * may appear only once in the set.
- */
-public final class RegisterSpecSet
-        extends MutabilityControl {
-    /** {@code non-null;} no-element instance */
-    public static final RegisterSpecSet EMPTY = new RegisterSpecSet(0);
-
-    /**
-     * {@code non-null;} array of register specs, where each element is
-     * {@code null} or is an instance whose {@code reg}
-     * matches the array index
-     */
-    private final RegisterSpec[] specs;
-
-    /** {@code >= -1;} size of the set or {@code -1} if not yet calculated */
-    private int size;
-
-    /**
-     * Constructs an instance. The instance is initially empty.
-     *
-     * @param maxSize {@code >= 0;} the maximum register number (exclusive) that
-     * may be represented in this instance
-     */
-    public RegisterSpecSet(int maxSize) {
-        super(maxSize != 0);
-
-        this.specs = new RegisterSpec[maxSize];
-        this.size = 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof RegisterSpecSet)) {
-            return false;
-        }
-
-        RegisterSpecSet otherSet = (RegisterSpecSet) other;
-        RegisterSpec[] otherSpecs = otherSet.specs;
-        int len = specs.length;
-
-        if ((len != otherSpecs.length) || (size() != otherSet.size())) {
-            return false;
-        }
-
-        for (int i = 0; i < len; i++) {
-            RegisterSpec s1 = specs[i];
-            RegisterSpec s2 = otherSpecs[i];
-
-            if (s1 == s2) {
-                continue;
-            }
-
-            if ((s1 == null) || !s1.equals(s2)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        int len = specs.length;
-        int hash = 0;
-
-        for (int i = 0; i < len; i++) {
-            RegisterSpec spec = specs[i];
-            int oneHash = (spec == null) ? 0 : spec.hashCode();
-            hash = (hash * 31) + oneHash;
-        }
-
-        return hash;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int len = specs.length;
-        StringBuffer sb = new StringBuffer(len * 25);
-
-        sb.append('{');
-
-        boolean any = false;
-        for (int i = 0; i < len; i++) {
-            RegisterSpec spec = specs[i];
-            if (spec != null) {
-                if (any) {
-                    sb.append(", ");
-                } else {
-                    any = true;
-                }
-                sb.append(spec);
-            }
-        }
-
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /**
-     * Gets the maximum number of registers that may be in this instance, which
-     * is also the maximum-plus-one of register numbers that may be
-     * represented.
-     *
-     * @return {@code >= 0;} the maximum size
-     */
-    public int getMaxSize() {
-        return specs.length;
-    }
-
-    /**
-     * Gets the current size of this instance.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int size() {
-        int result = size;
-
-        if (result < 0) {
-            int len = specs.length;
-
-            result = 0;
-            for (int i = 0; i < len; i++) {
-                if (specs[i] != null) {
-                    result++;
-                }
-            }
-
-            size = result;
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the element with the given register number, if any.
-     *
-     * @param reg {@code >= 0;} the desired register number
-     * @return {@code null-ok;} the element with the given register number or
-     * {@code null} if there is none
-     */
-    public RegisterSpec get(int reg) {
-        try {
-            return specs[reg];
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus reg");
-        }
-    }
-
-    /**
-     * Gets the element with the same register number as the given
-     * spec, if any. This is just a convenient shorthand for
-     * {@code get(spec.getReg())}.
-     *
-     * @param spec {@code non-null;} spec with the desired register number
-     * @return {@code null-ok;} the element with the matching register number or
-     * {@code null} if there is none
-     */
-    public RegisterSpec get(RegisterSpec spec) {
-        return get(spec.getReg());
-    }
-
-    /**
-     * Returns the spec in this set that's currently associated with a
-     * given local (type, name, and signature), or {@code null} if there is
-     * none. This ignores the register number of the given spec but
-     * matches on everything else.
-     *
-     * @param spec {@code non-null;} local to look for
-     * @return {@code null-ok;} first register found that matches, if any
-     */
-    public RegisterSpec findMatchingLocal(RegisterSpec spec) {
-        int length = specs.length;
-
-        for (int reg = 0; reg < length; reg++) {
-            RegisterSpec s = specs[reg];
-
-            if (s == null) {
-                continue;
-            }
-
-            if (spec.matchesVariable(s)) {
-                return s;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the spec in this set that's currently associated with a given
-     * local (name and signature), or {@code null} if there is none.
-     *
-     * @param local {@code non-null;} local item to search for
-     * @return {@code null-ok;} first register found with matching name and signature
-     */
-    public RegisterSpec localItemToSpec(LocalItem local) {
-        int length = specs.length;
-
-        for (int reg = 0; reg < length; reg++) {
-            RegisterSpec spec = specs[reg];
-
-            if ((spec != null) && local.equals(spec.getLocalItem())) {
-                return spec;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Removes a spec from the set. Only the register number
-     * of the parameter is significant.
-     *
-     * @param toRemove {@code non-null;} register to remove.
-     */
-    public void remove(RegisterSpec toRemove) {
-        try {
-            specs[toRemove.getReg()] = null;
-            size = -1;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus reg");
-        }
-    }
-
-    /**
-     * Puts the given spec into the set. If there is already an element in
-     * the set with the same register number, it is replaced. Additionally,
-     * if the previous element is for a category-2 register, then that
-     * previous element is nullified. Finally, if the given spec is for
-     * a category-2 register, then the immediately subsequent element
-     * is nullified.
-     *
-     * @param spec {@code non-null;} the register spec to put in the instance
-     */
-    public void put(RegisterSpec spec) {
-        throwIfImmutable();
-
-        if (spec == null) {
-            throw new NullPointerException("spec == null");
-        }
-
-        size = -1;
-
-        try {
-            int reg = spec.getReg();
-            specs[reg] = spec;
-
-            if (reg > 0) {
-                int prevReg = reg - 1;
-                RegisterSpec prevSpec = specs[prevReg];
-                if ((prevSpec != null) && (prevSpec.getCategory() == 2)) {
-                    specs[prevReg] = null;
-                }
-            }
-
-            if (spec.getCategory() == 2) {
-                specs[reg + 1] = null;
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("spec.getReg() out of range");
-        }
-    }
-
-    /**
-     * Put the entire contents of the given set into this one.
-     *
-     * @param set {@code non-null;} the set to put into this instance
-     */
-    public void putAll(RegisterSpecSet set) {
-        int max = set.getMaxSize();
-
-        for (int i = 0; i < max; i++) {
-            RegisterSpec spec = set.get(i);
-            if (spec != null) {
-                put(spec);
-            }
-        }
-    }
-
-    /**
-     * Intersects this instance with the given one, modifying this
-     * instance. The intersection consists of the pairwise
-     * {@link RegisterSpec#intersect} of corresponding elements from
-     * this instance and the given one where both are non-null.
-     *
-     * @param other {@code non-null;} set to intersect with
-     * @param localPrimary whether local variables are primary to
-     * the intersection; if {@code true}, then the only non-null
-     * result elements occur when registers being intersected have
-     * equal names (or both have {@code null} names)
-     */
-    public void intersect(RegisterSpecSet other, boolean localPrimary) {
-        throwIfImmutable();
-
-        RegisterSpec[] otherSpecs = other.specs;
-        int thisLen = specs.length;
-        int len = Math.min(thisLen, otherSpecs.length);
-
-        size = -1;
-
-        for (int i = 0; i < len; i++) {
-            RegisterSpec spec = specs[i];
-
-            if (spec == null) {
-                continue;
-            }
-
-            RegisterSpec intersection =
-                spec.intersect(otherSpecs[i], localPrimary);
-            if (intersection != spec) {
-                specs[i] = intersection;
-            }
-        }
-
-        for (int i = len; i < thisLen; i++) {
-            specs[i] = null;
-        }
-    }
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * all register numbers are offset by the given amount. Mutability
-     * of the result is inherited from the original.
-     *
-     * @param delta the amount to offset the register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RegisterSpecSet withOffset(int delta) {
-        int len = specs.length;
-        RegisterSpecSet result = new RegisterSpecSet(len + delta);
-
-        for (int i = 0; i < len; i++) {
-            RegisterSpec spec = specs[i];
-            if (spec != null) {
-                result.put(spec.withOffset(delta));
-            }
-        }
-
-        result.size = size;
-
-        if (isImmutable()) {
-            result.setImmutable();
-        }
-
-        return result;
-    }
-
-    /**
-     * Makes and return a mutable copy of this instance.
-     *
-     * @return {@code non-null;} the mutable copy
-     */
-    public RegisterSpecSet mutableCopy() {
-        int len = specs.length;
-        RegisterSpecSet copy = new RegisterSpecSet(len);
-
-        for (int i = 0; i < len; i++) {
-            RegisterSpec spec = specs[i];
-            if (spec != null) {
-                copy.put(spec);
-            }
-        }
-
-        copy.size = size;
-
-        return copy;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/Rop.java b/dx/src/main/java/com/android/dx/rop/code/Rop.java
deleted file mode 100644
index 8224584..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/Rop.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.Hex;
-
-/**
- * Class that describes all the immutable parts of register-based operations.
- */
-public final class Rop {
-    /** minimum {@code BRANCH_*} value */
-    public static final int BRANCH_MIN = 1;
-
-    /** indicates a non-branching op */
-    public static final int BRANCH_NONE = 1;
-
-    /** indicates a function/method return */
-    public static final int BRANCH_RETURN = 2;
-
-    /** indicates an unconditional goto */
-    public static final int BRANCH_GOTO = 3;
-
-    /** indicates a two-way branch */
-    public static final int BRANCH_IF = 4;
-
-    /** indicates a switch-style branch */
-    public static final int BRANCH_SWITCH = 5;
-
-    /** indicates a throw-style branch (both always-throws and may-throw) */
-    public static final int BRANCH_THROW = 6;
-
-    /** maximum {@code BRANCH_*} value */
-    public static final int BRANCH_MAX = 6;
-
-    /** the opcode; one of the constants in {@link RegOps} */
-    private final int opcode;
-
-    /**
-     * {@code non-null;} result type of this operation; {@link Type#VOID} for
-     * no-result operations
-     */
-    private final Type result;
-
-    /** {@code non-null;} types of all the sources of this operation */
-    private final TypeList sources;
-
-    /** {@code non-null;} list of possible types thrown by this operation */
-    private final TypeList exceptions;
-
-    /**
-     * the branchingness of this op; one of the {@code BRANCH_*}
-     * constants in this class
-     */
-    private final int branchingness;
-
-    /** whether this is a function/method call op or similar */
-    private final boolean isCallLike;
-
-    /** {@code null-ok;} nickname, if specified (used for debugging) */
-    private final String nickname;
-
-    /**
-     * Constructs an instance. This method is private. Use one of the
-     * public constructors.
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param result {@code non-null;} result type of this operation; {@link
-     * Type#VOID} for no-result operations
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param exceptions {@code non-null;} list of possible types thrown by this
-     * operation
-     * @param branchingness the branchingness of this op; one of the
-     * {@code BRANCH_*} constants
-     * @param isCallLike whether the op is a function/method call or similar
-     * @param nickname {@code null-ok;} optional nickname (used for debugging)
-     */
-    public Rop(int opcode, Type result, TypeList sources,
-               TypeList exceptions, int branchingness, boolean isCallLike,
-               String nickname) {
-        if (result == null) {
-            throw new NullPointerException("result == null");
-        }
-
-        if (sources == null) {
-            throw new NullPointerException("sources == null");
-        }
-
-        if (exceptions == null) {
-            throw new NullPointerException("exceptions == null");
-        }
-
-        if ((branchingness < BRANCH_MIN) || (branchingness > BRANCH_MAX)) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-
-        if ((exceptions.size() != 0) && (branchingness != BRANCH_THROW)) {
-            throw new IllegalArgumentException("exceptions / branchingness " +
-                                               "mismatch");
-        }
-
-        this.opcode = opcode;
-        this.result = result;
-        this.sources = sources;
-        this.exceptions = exceptions;
-        this.branchingness = branchingness;
-        this.isCallLike = isCallLike;
-        this.nickname = nickname;
-    }
-
-    /**
-     * Constructs an instance. The constructed instance is never a
-     * call-like op (see {@link #isCallLike}).
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param result {@code non-null;} result type of this operation; {@link
-     * Type#VOID} for no-result operations
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param exceptions {@code non-null;} list of possible types thrown by this
-     * operation
-     * @param branchingness the branchingness of this op; one of the
-     * {@code BRANCH_*} constants
-     * @param nickname {@code null-ok;} optional nickname (used for debugging)
-     */
-    public Rop(int opcode, Type result, TypeList sources,
-               TypeList exceptions, int branchingness, String nickname) {
-        this(opcode, result, sources, exceptions, branchingness, false,
-             nickname);
-    }
-
-    /**
-     * Constructs a no-exception instance. The constructed instance is never a
-     * call-like op (see {@link #isCallLike}).
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param result {@code non-null;} result type of this operation; {@link
-     * Type#VOID} for no-result operations
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param branchingness the branchingness of this op; one of the
-     * {@code BRANCH_*} constants
-     * @param nickname {@code null-ok;} optional nickname (used for debugging)
-     */
-    public Rop(int opcode, Type result, TypeList sources, int branchingness,
-               String nickname) {
-        this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false,
-             nickname);
-    }
-
-    /**
-     * Constructs a non-branching no-exception instance. The
-     * {@code branchingness} is always {@code BRANCH_NONE},
-     * and it is never a call-like op (see {@link #isCallLike}).
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param result {@code non-null;} result type of this operation; {@link
-     * Type#VOID} for no-result operations
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param nickname {@code null-ok;} optional nickname (used for debugging)
-     */
-    public Rop(int opcode, Type result, TypeList sources, String nickname) {
-        this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE,
-             false, nickname);
-    }
-
-    /**
-     * Constructs a non-empty exceptions instance. Its
-     * {@code branchingness} is always {@code BRANCH_THROW},
-     * but it is never a call-like op (see {@link #isCallLike}).
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param result {@code non-null;} result type of this operation; {@link
-     * Type#VOID} for no-result operations
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param exceptions {@code non-null;} list of possible types thrown by this
-     * operation
-     * @param nickname {@code null-ok;} optional nickname (used for debugging)
-     */
-    public Rop(int opcode, Type result, TypeList sources, TypeList exceptions,
-               String nickname) {
-        this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false,
-             nickname);
-    }
-
-    /**
-     * Constructs a non-nicknamed instance with non-empty exceptions, which
-     * is always a call-like op (see {@link #isCallLike}). Its
-     * {@code branchingness} is always {@code BRANCH_THROW}.
-     *
-     * @param opcode the opcode; one of the constants in {@link RegOps}
-     * @param sources {@code non-null;} types of all the sources of this operation
-     * @param exceptions {@code non-null;} list of possible types thrown by this
-     * operation
-     */
-    public Rop(int opcode, TypeList sources, TypeList exceptions) {
-        this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true,
-             null);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            // Easy out.
-            return true;
-        }
-
-        if (!(other instanceof Rop)) {
-            return false;
-        }
-
-        Rop rop = (Rop) other;
-
-        return (opcode == rop.opcode) &&
-            (branchingness == rop.branchingness) &&
-            (result == rop.result) &&
-            sources.equals(rop.sources) &&
-            exceptions.equals(rop.exceptions);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        int h = (opcode * 31) + branchingness;
-        h = (h * 31) + result.hashCode();
-        h = (h * 31) + sources.hashCode();
-        h = (h * 31) + exceptions.hashCode();
-
-        return h;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(40);
-
-        sb.append("Rop{");
-
-        sb.append(RegOps.opName(opcode));
-
-        if (result != Type.VOID) {
-            sb.append(" ");
-            sb.append(result);
-        } else {
-            sb.append(" .");
-        }
-
-        sb.append(" <-");
-
-        int sz = sources.size();
-        if (sz == 0) {
-            sb.append(" .");
-        } else {
-            for (int i = 0; i < sz; i++) {
-                sb.append(' ');
-                sb.append(sources.getType(i));
-            }
-        }
-
-        if (isCallLike) {
-            sb.append(" call");
-        }
-
-        sz = exceptions.size();
-        if (sz != 0) {
-            sb.append(" throws");
-            for (int i = 0; i < sz; i++) {
-                sb.append(' ');
-                Type one = exceptions.getType(i);
-                if (one == Type.THROWABLE) {
-                    sb.append("<any>");
-                } else {
-                    sb.append(exceptions.getType(i));
-                }
-            }
-        } else {
-            switch (branchingness) {
-                case BRANCH_NONE:   sb.append(" flows"); break;
-                case BRANCH_RETURN: sb.append(" returns"); break;
-                case BRANCH_GOTO:   sb.append(" gotos"); break;
-                case BRANCH_IF:     sb.append(" ifs"); break;
-                case BRANCH_SWITCH: sb.append(" switches"); break;
-                default: sb.append(" " + Hex.u1(branchingness)); break;
-            }
-        }
-
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets the opcode.
-     *
-     * @return the opcode
-     */
-    public int getOpcode() {
-        return opcode;
-    }
-
-    /**
-     * Gets the result type. A return value of {@link Type#VOID}
-     * means this operation returns nothing.
-     *
-     * @return {@code null-ok;} the result spec
-     */
-    public Type getResult() {
-        return result;
-    }
-
-    /**
-     * Gets the source types.
-     *
-     * @return {@code non-null;} the source types
-     */
-    public TypeList getSources() {
-        return sources;
-    }
-
-    /**
-     * Gets the list of exception types that might be thrown.
-     *
-     * @return {@code non-null;} the list of exception types
-     */
-    public TypeList getExceptions() {
-        return exceptions;
-    }
-
-    /**
-     * Gets the branchingness of this instance.
-     *
-     * @return the branchingness
-     */
-    public int getBranchingness() {
-        return branchingness;
-    }
-
-    /**
-     * Gets whether this opcode is a function/method call or similar.
-     *
-     * @return {@code true} iff this opcode is call-like
-     */
-    public boolean isCallLike() {
-        return isCallLike;
-    }
-
-
-    /**
-     * Gets whether this opcode is commutative (the order of its sources are
-     * unimportant) or not. All commutative Rops have exactly two sources and
-     * have no branchiness.
-     *
-     * @return true if rop is commutative
-     */
-    public boolean isCommutative() {
-        switch (opcode) {
-            case RegOps.AND:
-            case RegOps.OR:
-            case RegOps.XOR:
-            case RegOps.ADD:
-            case RegOps.MUL:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Gets the nickname. If this instance has no nickname, this returns
-     * the result of calling {@link #toString}.
-     *
-     * @return {@code non-null;} the nickname
-     */
-    public String getNickname() {
-        if (nickname != null) {
-            return nickname;
-        }
-
-        return toString();
-    }
-
-    /**
-     * Gets whether this operation can possibly throw an exception. This
-     * is just a convenient wrapper for
-     * {@code getExceptions().size() != 0}.
-     *
-     * @return {@code true} iff this operation can possibly throw
-     */
-    public final boolean canThrow() {
-        return (exceptions.size() != 0);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/RopMethod.java b/dx/src/main/java/com/android/dx/rop/code/RopMethod.java
deleted file mode 100644
index 591d325..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/RopMethod.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.util.Bits;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-
-/**
- * All of the parts that make up a method at the rop layer.
- */
-public final class RopMethod {
-    /** {@code non-null;} basic block list of the method */
-    private final BasicBlockList blocks;
-
-    /** {@code >= 0;} label for the block which starts the method */
-    private final int firstLabel;
-
-    /**
-     * {@code null-ok;} array of predecessors for each block, indexed by block
-     * label
-     */
-    private IntList[] predecessors;
-
-    /**
-     * {@code null-ok;} the predecessors for the implicit "exit" block, that is
-     * the labels for the blocks that return, if calculated
-     */
-    private IntList exitPredecessors;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param blocks {@code non-null;} basic block list of the method
-     * @param firstLabel {@code >= 0;} the label of the first block to execute
-     */
-    public RopMethod(BasicBlockList blocks, int firstLabel) {
-        if (blocks == null) {
-            throw new NullPointerException("blocks == null");
-        }
-
-        if (firstLabel < 0) {
-            throw new IllegalArgumentException("firstLabel < 0");
-        }
-
-        this.blocks = blocks;
-        this.firstLabel = firstLabel;
-
-        this.predecessors = null;
-        this.exitPredecessors = null;
-    }
-
-    /**
-     * Gets the basic block list for this method.
-     *
-     * @return {@code non-null;} the list
-     */
-    public BasicBlockList getBlocks() {
-        return blocks;
-    }
-
-    /**
-     * Gets the label for the first block in the method that this list
-     * represents.
-     *
-     * @return {@code >= 0;} the first-block label
-     */
-    public int getFirstLabel() {
-        return firstLabel;
-    }
-
-    /**
-     * Gets the predecessors associated with the given block. This throws
-     * an exception if there is no block with the given label.
-     *
-     * @param label {@code >= 0;} the label of the block in question
-     * @return {@code non-null;} the predecessors of that block
-     */
-    public IntList labelToPredecessors(int label) {
-        if (exitPredecessors == null) {
-            calcPredecessors();
-        }
-
-        IntList result = predecessors[label];
-
-        if (result == null) {
-            throw new RuntimeException("no such block: " + Hex.u2(label));
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets the exit predecessors for this instance.
-     *
-     * @return {@code non-null;} the exit predecessors
-     */
-    public IntList getExitPredecessors() {
-        if (exitPredecessors == null) {
-            calcPredecessors();
-        }
-
-        return exitPredecessors;
-    }
-
-
-    /**
-     * Returns an instance that is identical to this one, except that
-     * the registers in each instruction are offset by the given
-     * amount.
-     *
-     * @param delta the amount to offset register numbers by
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public RopMethod withRegisterOffset(int delta) {
-        RopMethod result = new RopMethod(blocks.withRegisterOffset(delta),
-                                         firstLabel);
-
-        if (exitPredecessors != null) {
-            /*
-             * The predecessors have been calculated. It's safe to
-             * inject these into the new instance, since the
-             * transformation being applied doesn't affect the
-             * predecessors.
-             */
-            result.exitPredecessors = exitPredecessors;
-            result.predecessors = predecessors;
-        }
-
-        return result;
-    }
-
-    /**
-     * Calculates the predecessor sets for each block as well as for the
-     * exit.
-     */
-    private void calcPredecessors() {
-        int maxLabel = blocks.getMaxLabel();
-        IntList[] predecessors = new IntList[maxLabel];
-        IntList exitPredecessors = new IntList(10);
-        int sz = blocks.size();
-
-        /*
-         * For each block, find its successors, and add the block's label to
-         * the successor's predecessors.
-         */
-        for (int i = 0; i < sz; i++) {
-            BasicBlock one = blocks.get(i);
-            int label = one.getLabel();
-            IntList successors = one.getSuccessors();
-            int ssz = successors.size();
-            if (ssz == 0) {
-                // This block exits.
-                exitPredecessors.add(label);
-            } else {
-                for (int j = 0; j < ssz; j++) {
-                    int succLabel = successors.get(j);
-                    IntList succPreds = predecessors[succLabel];
-                    if (succPreds == null) {
-                        succPreds = new IntList(10);
-                        predecessors[succLabel] = succPreds;
-                    }
-                    succPreds.add(label);
-                }
-            }
-        }
-
-        // Sort and immutablize all the predecessor lists.
-        for (int i = 0; i < maxLabel; i++) {
-            IntList preds = predecessors[i];
-            if (preds != null) {
-                preds.sort();
-                preds.setImmutable();
-            }
-        }
-
-        exitPredecessors.sort();
-        exitPredecessors.setImmutable();
-
-        /*
-         * The start label might not ever have had any predecessors
-         * added to it (probably doesn't, because of how Java gets
-         * translated into rop form). So, check for this and rectify
-         * the situation if required.
-         */
-        if (predecessors[firstLabel] == null) {
-            predecessors[firstLabel] = IntList.EMPTY;
-        }
-
-        this.predecessors = predecessors;
-        this.exitPredecessors = exitPredecessors;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/Rops.java b/dx/src/main/java/com/android/dx/rop/code/Rops.java
deleted file mode 100644
index c1f4f46..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/Rops.java
+++ /dev/null
@@ -1,2090 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstBaseMethodRef;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * Standard instances of {@link Rop}.
- */
-public final class Rops {
-    /** {@code nop()} */
-    public static final Rop NOP =
-        new Rop(RegOps.NOP, Type.VOID, StdTypeList.EMPTY, "nop");
-
-    /** {@code r,x: int :: r = x;} */
-    public static final Rop MOVE_INT =
-        new Rop(RegOps.MOVE, Type.INT, StdTypeList.INT, "move-int");
-
-    /** {@code r,x: long :: r = x;} */
-    public static final Rop MOVE_LONG =
-        new Rop(RegOps.MOVE, Type.LONG, StdTypeList.LONG, "move-long");
-
-    /** {@code r,x: float :: r = x;} */
-    public static final Rop MOVE_FLOAT =
-        new Rop(RegOps.MOVE, Type.FLOAT, StdTypeList.FLOAT, "move-float");
-
-    /** {@code r,x: double :: r = x;} */
-    public static final Rop MOVE_DOUBLE =
-        new Rop(RegOps.MOVE, Type.DOUBLE, StdTypeList.DOUBLE, "move-double");
-
-    /** {@code r,x: Object :: r = x;} */
-    public static final Rop MOVE_OBJECT =
-        new Rop(RegOps.MOVE, Type.OBJECT, StdTypeList.OBJECT, "move-object");
-
-    /**
-     * {@code r,x: ReturnAddress :: r = x;}
-     *
-     * Note that this rop-form instruction has no dex-form equivilent and
-     * must be removed before the dex conversion.
-     */
-    public static final Rop MOVE_RETURN_ADDRESS =
-        new Rop(RegOps.MOVE, Type.RETURN_ADDRESS,
-                StdTypeList.RETURN_ADDRESS, "move-return-address");
-
-    /** {@code r,param(x): int :: r = param(x);} */
-    public static final Rop MOVE_PARAM_INT =
-        new Rop(RegOps.MOVE_PARAM, Type.INT, StdTypeList.EMPTY,
-                "move-param-int");
-
-    /** {@code r,param(x): long :: r = param(x);} */
-    public static final Rop MOVE_PARAM_LONG =
-        new Rop(RegOps.MOVE_PARAM, Type.LONG, StdTypeList.EMPTY,
-                "move-param-long");
-
-    /** {@code r,param(x): float :: r = param(x);} */
-    public static final Rop MOVE_PARAM_FLOAT =
-        new Rop(RegOps.MOVE_PARAM, Type.FLOAT, StdTypeList.EMPTY,
-                "move-param-float");
-
-    /** {@code r,param(x): double :: r = param(x);} */
-    public static final Rop MOVE_PARAM_DOUBLE =
-        new Rop(RegOps.MOVE_PARAM, Type.DOUBLE, StdTypeList.EMPTY,
-                "move-param-double");
-
-    /** {@code r,param(x): Object :: r = param(x);} */
-    public static final Rop MOVE_PARAM_OBJECT =
-        new Rop(RegOps.MOVE_PARAM, Type.OBJECT, StdTypeList.EMPTY,
-                "move-param-object");
-
-    /** {@code r, literal: int :: r = literal;} */
-    public static final Rop CONST_INT =
-        new Rop(RegOps.CONST, Type.INT, StdTypeList.EMPTY, "const-int");
-
-    /** {@code r, literal: long :: r = literal;} */
-    public static final Rop CONST_LONG =
-        new Rop(RegOps.CONST, Type.LONG, StdTypeList.EMPTY, "const-long");
-
-    /** {@code r, literal: float :: r = literal;} */
-    public static final Rop CONST_FLOAT =
-        new Rop(RegOps.CONST, Type.FLOAT, StdTypeList.EMPTY, "const-float");
-
-    /** {@code r, literal: double :: r = literal;} */
-    public static final Rop CONST_DOUBLE =
-        new Rop(RegOps.CONST, Type.DOUBLE, StdTypeList.EMPTY, "const-double");
-
-    /** {@code r, literal: Object :: r = literal;} */
-    public static final Rop CONST_OBJECT =
-        new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "const-object");
-
-    /** {@code r, literal: Object :: r = literal;} */
-    public static final Rop CONST_OBJECT_NOTHROW =
-        new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,
-                "const-object-nothrow");
-
-    /** {@code goto label} */
-    public static final Rop GOTO =
-        new Rop(RegOps.GOTO, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_GOTO,
-                "goto");
-
-    /** {@code x: int :: if (x == 0) goto label} */
-    public static final Rop IF_EQZ_INT =
-        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-eqz-int");
-
-    /** {@code x: int :: if (x != 0) goto label} */
-    public static final Rop IF_NEZ_INT =
-        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-nez-int");
-
-    /** {@code x: int :: if (x < 0) goto label} */
-    public static final Rop IF_LTZ_INT =
-        new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-ltz-int");
-
-    /** {@code x: int :: if (x >= 0) goto label} */
-    public static final Rop IF_GEZ_INT =
-        new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-gez-int");
-
-    /** {@code x: int :: if (x <= 0) goto label} */
-    public static final Rop IF_LEZ_INT =
-        new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-lez-int");
-
-    /** {@code x: int :: if (x > 0) goto label} */
-    public static final Rop IF_GTZ_INT =
-        new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
-                "if-gtz-int");
-
-    /** {@code x: Object :: if (x == null) goto label} */
-    public static final Rop IF_EQZ_OBJECT =
-        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,
-                "if-eqz-object");
-
-    /** {@code x: Object :: if (x != null) goto label} */
-    public static final Rop IF_NEZ_OBJECT =
-        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,
-                "if-nez-object");
-
-    /** {@code x,y: int :: if (x == y) goto label} */
-    public static final Rop IF_EQ_INT =
-        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-eq-int");
-
-    /** {@code x,y: int :: if (x != y) goto label} */
-    public static final Rop IF_NE_INT =
-        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-ne-int");
-
-    /** {@code x,y: int :: if (x < y) goto label} */
-    public static final Rop IF_LT_INT =
-        new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-lt-int");
-
-    /** {@code x,y: int :: if (x >= y) goto label} */
-    public static final Rop IF_GE_INT =
-        new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-ge-int");
-
-    /** {@code x,y: int :: if (x <= y) goto label} */
-    public static final Rop IF_LE_INT =
-        new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-le-int");
-
-    /** {@code x,y: int :: if (x > y) goto label} */
-    public static final Rop IF_GT_INT =
-        new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
-                "if-gt-int");
-
-    /** {@code x,y: Object :: if (x == y) goto label} */
-    public static final Rop IF_EQ_OBJECT =
-        new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT_OBJECT,
-                Rop.BRANCH_IF, "if-eq-object");
-
-    /** {@code x,y: Object :: if (x != y) goto label} */
-    public static final Rop IF_NE_OBJECT =
-        new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT_OBJECT,
-                Rop.BRANCH_IF, "if-ne-object");
-
-    /** {@code x: int :: goto switchtable[x]} */
-    public static final Rop SWITCH =
-        new Rop(RegOps.SWITCH, Type.VOID, StdTypeList.INT, Rop.BRANCH_SWITCH,
-                "switch");
-
-    /** {@code r,x,y: int :: r = x + y;} */
-    public static final Rop ADD_INT =
-        new Rop(RegOps.ADD, Type.INT, StdTypeList.INT_INT, "add-int");
-
-    /** {@code r,x,y: long :: r = x + y;} */
-    public static final Rop ADD_LONG =
-        new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG_LONG, "add-long");
-
-    /** {@code r,x,y: float :: r = x + y;} */
-    public static final Rop ADD_FLOAT =
-        new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "add-float");
-
-    /** {@code r,x,y: double :: r = x + y;} */
-    public static final Rop ADD_DOUBLE =
-        new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
-                Rop.BRANCH_NONE, "add-double");
-
-    /** {@code r,x,y: int :: r = x - y;} */
-    public static final Rop SUB_INT =
-        new Rop(RegOps.SUB, Type.INT, StdTypeList.INT_INT, "sub-int");
-
-    /** {@code r,x,y: long :: r = x - y;} */
-    public static final Rop SUB_LONG =
-        new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG_LONG, "sub-long");
-
-    /** {@code r,x,y: float :: r = x - y;} */
-    public static final Rop SUB_FLOAT =
-        new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "sub-float");
-
-    /** {@code r,x,y: double :: r = x - y;} */
-    public static final Rop SUB_DOUBLE =
-        new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
-                Rop.BRANCH_NONE, "sub-double");
-
-    /** {@code r,x,y: int :: r = x * y;} */
-    public static final Rop MUL_INT =
-        new Rop(RegOps.MUL, Type.INT, StdTypeList.INT_INT, "mul-int");
-
-    /** {@code r,x,y: long :: r = x * y;} */
-    public static final Rop MUL_LONG =
-        new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG_LONG, "mul-long");
-
-    /** {@code r,x,y: float :: r = x * y;} */
-    public static final Rop MUL_FLOAT =
-        new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "mul-float");
-
-    /** {@code r,x,y: double :: r = x * y;} */
-    public static final Rop MUL_DOUBLE =
-        new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
-                Rop.BRANCH_NONE, "mul-double");
-
-    /** {@code r,x,y: int :: r = x / y;} */
-    public static final Rop DIV_INT =
-        new Rop(RegOps.DIV, Type.INT, StdTypeList.INT_INT,
-                Exceptions.LIST_Error_ArithmeticException, "div-int");
-
-    /** {@code r,x,y: long :: r = x / y;} */
-    public static final Rop DIV_LONG =
-        new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG_LONG,
-                Exceptions.LIST_Error_ArithmeticException, "div-long");
-
-    /** {@code r,x,y: float :: r = x / y;} */
-    public static final Rop DIV_FLOAT =
-        new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "div-float");
-
-    /** {@code r,x,y: double :: r = x / y;} */
-    public static final Rop DIV_DOUBLE =
-        new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
-                "div-double");
-
-    /** {@code r,x,y: int :: r = x % y;} */
-    public static final Rop REM_INT =
-        new Rop(RegOps.REM, Type.INT, StdTypeList.INT_INT,
-                Exceptions.LIST_Error_ArithmeticException, "rem-int");
-
-    /** {@code r,x,y: long :: r = x % y;} */
-    public static final Rop REM_LONG =
-        new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG_LONG,
-                Exceptions.LIST_Error_ArithmeticException, "rem-long");
-
-    /** {@code r,x,y: float :: r = x % y;} */
-    public static final Rop REM_FLOAT =
-        new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "rem-float");
-
-    /** {@code r,x,y: double :: r = x % y;} */
-    public static final Rop REM_DOUBLE =
-        new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
-                "rem-double");
-
-    /** {@code r,x: int :: r = -x;} */
-    public static final Rop NEG_INT =
-        new Rop(RegOps.NEG, Type.INT, StdTypeList.INT, "neg-int");
-
-    /** {@code r,x: long :: r = -x;} */
-    public static final Rop NEG_LONG =
-        new Rop(RegOps.NEG, Type.LONG, StdTypeList.LONG, "neg-long");
-
-    /** {@code r,x: float :: r = -x;} */
-    public static final Rop NEG_FLOAT =
-        new Rop(RegOps.NEG, Type.FLOAT, StdTypeList.FLOAT, "neg-float");
-
-    /** {@code r,x: double :: r = -x;} */
-    public static final Rop NEG_DOUBLE =
-        new Rop(RegOps.NEG, Type.DOUBLE, StdTypeList.DOUBLE, "neg-double");
-
-    /** {@code r,x,y: int :: r = x & y;} */
-    public static final Rop AND_INT =
-        new Rop(RegOps.AND, Type.INT, StdTypeList.INT_INT, "and-int");
-
-    /** {@code r,x,y: long :: r = x & y;} */
-    public static final Rop AND_LONG =
-        new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG_LONG, "and-long");
-
-    /** {@code r,x,y: int :: r = x | y;} */
-    public static final Rop OR_INT =
-        new Rop(RegOps.OR, Type.INT, StdTypeList.INT_INT, "or-int");
-
-    /** {@code r,x,y: long :: r = x | y;} */
-    public static final Rop OR_LONG =
-        new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG_LONG, "or-long");
-
-    /** {@code r,x,y: int :: r = x ^ y;} */
-    public static final Rop XOR_INT =
-        new Rop(RegOps.XOR, Type.INT, StdTypeList.INT_INT, "xor-int");
-
-    /** {@code r,x,y: long :: r = x ^ y;} */
-    public static final Rop XOR_LONG =
-        new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG_LONG, "xor-long");
-
-    /** {@code r,x,y: int :: r = x << y;} */
-    public static final Rop SHL_INT =
-        new Rop(RegOps.SHL, Type.INT, StdTypeList.INT_INT, "shl-int");
-
-    /** {@code r,x: long; y: int :: r = x << y;} */
-    public static final Rop SHL_LONG =
-        new Rop(RegOps.SHL, Type.LONG, StdTypeList.LONG_INT, "shl-long");
-
-    /** {@code r,x,y: int :: r = x >> y;} */
-    public static final Rop SHR_INT =
-        new Rop(RegOps.SHR, Type.INT, StdTypeList.INT_INT, "shr-int");
-
-    /** {@code r,x: long; y: int :: r = x >> y;} */
-    public static final Rop SHR_LONG =
-        new Rop(RegOps.SHR, Type.LONG, StdTypeList.LONG_INT, "shr-long");
-
-    /** {@code r,x,y: int :: r = x >>> y;} */
-    public static final Rop USHR_INT =
-        new Rop(RegOps.USHR, Type.INT, StdTypeList.INT_INT, "ushr-int");
-
-    /** {@code r,x: long; y: int :: r = x >>> y;} */
-    public static final Rop USHR_LONG =
-        new Rop(RegOps.USHR, Type.LONG, StdTypeList.LONG_INT, "ushr-long");
-
-    /** {@code r,x: int :: r = ~x;} */
-    public static final Rop NOT_INT =
-        new Rop(RegOps.NOT, Type.INT, StdTypeList.INT, "not-int");
-
-    /** {@code r,x: long :: r = ~x;} */
-    public static final Rop NOT_LONG =
-        new Rop(RegOps.NOT, Type.LONG, StdTypeList.LONG, "not-long");
-
-    /** {@code r,x,c: int :: r = x + c;} */
-    public static final Rop ADD_CONST_INT =
-        new Rop(RegOps.ADD, Type.INT, StdTypeList.INT, "add-const-int");
-
-    /** {@code r,x,c: long :: r = x + c;} */
-    public static final Rop ADD_CONST_LONG =
-        new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG, "add-const-long");
-
-    /** {@code r,x,c: float :: r = x + c;} */
-    public static final Rop ADD_CONST_FLOAT =
-        new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT, "add-const-float");
-
-    /** {@code r,x,c: double :: r = x + c;} */
-    public static final Rop ADD_CONST_DOUBLE =
-        new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE,
-                "add-const-double");
-
-    /** {@code r,x,c: int :: r = x - c;} */
-    public static final Rop SUB_CONST_INT =
-        new Rop(RegOps.SUB, Type.INT, StdTypeList.INT, "sub-const-int");
-
-    /** {@code r,x,c: long :: r = x - c;} */
-    public static final Rop SUB_CONST_LONG =
-        new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG, "sub-const-long");
-
-    /** {@code r,x,c: float :: r = x - c;} */
-    public static final Rop SUB_CONST_FLOAT =
-        new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT, "sub-const-float");
-
-    /** {@code r,x,c: double :: r = x - c;} */
-    public static final Rop SUB_CONST_DOUBLE =
-        new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE,
-                "sub-const-double");
-
-    /** {@code r,x,c: int :: r = x * c;} */
-    public static final Rop MUL_CONST_INT =
-        new Rop(RegOps.MUL, Type.INT, StdTypeList.INT, "mul-const-int");
-
-    /** {@code r,x,c: long :: r = x * c;} */
-    public static final Rop MUL_CONST_LONG =
-        new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG, "mul-const-long");
-
-    /** {@code r,x,c: float :: r = x * c;} */
-    public static final Rop MUL_CONST_FLOAT =
-        new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT, "mul-const-float");
-
-    /** {@code r,x,c: double :: r = x * c;} */
-    public static final Rop MUL_CONST_DOUBLE =
-        new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE,
-                "mul-const-double");
-
-    /** {@code r,x,c: int :: r = x / c;} */
-    public static final Rop DIV_CONST_INT =
-        new Rop(RegOps.DIV, Type.INT, StdTypeList.INT,
-                Exceptions.LIST_Error_ArithmeticException, "div-const-int");
-
-    /** {@code r,x,c: long :: r = x / c;} */
-    public static final Rop DIV_CONST_LONG =
-        new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG,
-                Exceptions.LIST_Error_ArithmeticException, "div-const-long");
-
-    /** {@code r,x,c: float :: r = x / c;} */
-    public static final Rop DIV_CONST_FLOAT =
-        new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT, "div-const-float");
-
-    /** {@code r,x,c: double :: r = x / c;} */
-    public static final Rop DIV_CONST_DOUBLE =
-        new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE,
-                "div-const-double");
-
-    /** {@code r,x,c: int :: r = x % c;} */
-    public static final Rop REM_CONST_INT =
-        new Rop(RegOps.REM, Type.INT, StdTypeList.INT,
-                Exceptions.LIST_Error_ArithmeticException, "rem-const-int");
-
-    /** {@code r,x,c: long :: r = x % c;} */
-    public static final Rop REM_CONST_LONG =
-        new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG,
-                Exceptions.LIST_Error_ArithmeticException, "rem-const-long");
-
-    /** {@code r,x,c: float :: r = x % c;} */
-    public static final Rop REM_CONST_FLOAT =
-        new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT, "rem-const-float");
-
-    /** {@code r,x,c: double :: r = x % c;} */
-    public static final Rop REM_CONST_DOUBLE =
-        new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE,
-                "rem-const-double");
-
-    /** {@code r,x,c: int :: r = x & c;} */
-    public static final Rop AND_CONST_INT =
-        new Rop(RegOps.AND, Type.INT, StdTypeList.INT, "and-const-int");
-
-    /** {@code r,x,c: long :: r = x & c;} */
-    public static final Rop AND_CONST_LONG =
-        new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG, "and-const-long");
-
-    /** {@code r,x,c: int :: r = x | c;} */
-    public static final Rop OR_CONST_INT =
-        new Rop(RegOps.OR, Type.INT, StdTypeList.INT, "or-const-int");
-
-    /** {@code r,x,c: long :: r = x | c;} */
-    public static final Rop OR_CONST_LONG =
-        new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG, "or-const-long");
-
-    /** {@code r,x,c: int :: r = x ^ c;} */
-    public static final Rop XOR_CONST_INT =
-        new Rop(RegOps.XOR, Type.INT, StdTypeList.INT, "xor-const-int");
-
-    /** {@code r,x,c: long :: r = x ^ c;} */
-    public static final Rop XOR_CONST_LONG =
-        new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG, "xor-const-long");
-
-    /** {@code r,x,c: int :: r = x << c;} */
-    public static final Rop SHL_CONST_INT =
-        new Rop(RegOps.SHL, Type.INT, StdTypeList.INT, "shl-const-int");
-
-    /** {@code r,x: long; c: int :: r = x << c;} */
-    public static final Rop SHL_CONST_LONG =
-        new Rop(RegOps.SHL, Type.LONG, StdTypeList.INT, "shl-const-long");
-
-    /** {@code r,x,c: int :: r = x >> c;} */
-    public static final Rop SHR_CONST_INT =
-        new Rop(RegOps.SHR, Type.INT, StdTypeList.INT, "shr-const-int");
-
-    /** {@code r,x: long; c: int :: r = x >> c;} */
-    public static final Rop SHR_CONST_LONG =
-        new Rop(RegOps.SHR, Type.LONG, StdTypeList.INT, "shr-const-long");
-
-    /** {@code r,x,c: int :: r = x >>> c;} */
-    public static final Rop USHR_CONST_INT =
-        new Rop(RegOps.USHR, Type.INT, StdTypeList.INT, "ushr-const-int");
-
-    /** {@code r,x: long; c: int :: r = x >>> c;} */
-    public static final Rop USHR_CONST_LONG =
-        new Rop(RegOps.USHR, Type.LONG, StdTypeList.INT, "ushr-const-long");
-
-    /** {@code r: int; x,y: long :: r = cmp(x, y);} */
-    public static final Rop CMPL_LONG =
-        new Rop(RegOps.CMPL, Type.INT, StdTypeList.LONG_LONG, "cmpl-long");
-
-    /** {@code r: int; x,y: float :: r = cmpl(x, y);} */
-    public static final Rop CMPL_FLOAT =
-        new Rop(RegOps.CMPL, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpl-float");
-
-    /** {@code r: int; x,y: double :: r = cmpl(x, y);} */
-    public static final Rop CMPL_DOUBLE =
-        new Rop(RegOps.CMPL, Type.INT, StdTypeList.DOUBLE_DOUBLE,
-                "cmpl-double");
-
-    /** {@code r: int; x,y: float :: r = cmpg(x, y);} */
-    public static final Rop CMPG_FLOAT =
-        new Rop(RegOps.CMPG, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpg-float");
-
-    /** {@code r: int; x,y: double :: r = cmpg(x, y);} */
-    public static final Rop CMPG_DOUBLE =
-        new Rop(RegOps.CMPG, Type.INT, StdTypeList.DOUBLE_DOUBLE,
-                "cmpg-double");
-
-    /** {@code r: int; x: long :: r = (int) x} */
-    public static final Rop CONV_L2I =
-        new Rop(RegOps.CONV, Type.INT, StdTypeList.LONG, "conv-l2i");
-
-    /** {@code r: int; x: float :: r = (int) x} */
-    public static final Rop CONV_F2I =
-        new Rop(RegOps.CONV, Type.INT, StdTypeList.FLOAT, "conv-f2i");
-
-    /** {@code r: int; x: double :: r = (int) x} */
-    public static final Rop CONV_D2I =
-        new Rop(RegOps.CONV, Type.INT, StdTypeList.DOUBLE, "conv-d2i");
-
-    /** {@code r: long; x: int :: r = (long) x} */
-    public static final Rop CONV_I2L =
-        new Rop(RegOps.CONV, Type.LONG, StdTypeList.INT, "conv-i2l");
-
-    /** {@code r: long; x: float :: r = (long) x} */
-    public static final Rop CONV_F2L =
-        new Rop(RegOps.CONV, Type.LONG, StdTypeList.FLOAT, "conv-f2l");
-
-    /** {@code r: long; x: double :: r = (long) x} */
-    public static final Rop CONV_D2L =
-        new Rop(RegOps.CONV, Type.LONG, StdTypeList.DOUBLE, "conv-d2l");
-
-    /** {@code r: float; x: int :: r = (float) x} */
-    public static final Rop CONV_I2F =
-        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.INT, "conv-i2f");
-
-    /** {@code r: float; x: long :: r = (float) x} */
-    public static final Rop CONV_L2F =
-        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.LONG, "conv-l2f");
-
-    /** {@code r: float; x: double :: r = (float) x} */
-    public static final Rop CONV_D2F =
-        new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.DOUBLE, "conv-d2f");
-
-    /** {@code r: double; x: int :: r = (double) x} */
-    public static final Rop CONV_I2D =
-        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.INT, "conv-i2d");
-
-    /** {@code r: double; x: long :: r = (double) x} */
-    public static final Rop CONV_L2D =
-        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.LONG, "conv-l2d");
-
-    /** {@code r: double; x: float :: r = (double) x} */
-    public static final Rop CONV_F2D =
-        new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.FLOAT, "conv-f2d");
-
-    /**
-     * {@code r,x: int :: r = (x << 24) >> 24} (Java-style
-     * convert int to byte)
-     */
-    public static final Rop TO_BYTE =
-        new Rop(RegOps.TO_BYTE, Type.INT, StdTypeList.INT, "to-byte");
-
-    /**
-     * {@code r,x: int :: r = x & 0xffff} (Java-style
-     * convert int to char)
-     */
-    public static final Rop TO_CHAR =
-        new Rop(RegOps.TO_CHAR, Type.INT, StdTypeList.INT, "to-char");
-
-    /**
-     * {@code r,x: int :: r = (x << 16) >> 16} (Java-style
-     * convert int to short)
-     */
-    public static final Rop TO_SHORT =
-        new Rop(RegOps.TO_SHORT, Type.INT, StdTypeList.INT, "to-short");
-
-    /** {@code return void} */
-    public static final Rop RETURN_VOID =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_RETURN,
-                "return-void");
-
-    /** {@code x: int; return x} */
-    public static final Rop RETURN_INT =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.INT, Rop.BRANCH_RETURN,
-                "return-int");
-
-    /** {@code x: long; return x} */
-    public static final Rop RETURN_LONG =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.LONG, Rop.BRANCH_RETURN,
-                "return-long");
-
-    /** {@code x: float; return x} */
-    public static final Rop RETURN_FLOAT =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.FLOAT, Rop.BRANCH_RETURN,
-                "return-float");
-
-    /** {@code x: double; return x} */
-    public static final Rop RETURN_DOUBLE =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.DOUBLE,
-                Rop.BRANCH_RETURN, "return-double");
-
-    /** {@code x: Object; return x} */
-    public static final Rop RETURN_OBJECT =
-        new Rop(RegOps.RETURN, Type.VOID, StdTypeList.OBJECT,
-                Rop.BRANCH_RETURN, "return-object");
-
-    /** {@code T: any type; r: int; x: T[]; :: r = x.length} */
-    public static final Rop ARRAY_LENGTH =
-        new Rop(RegOps.ARRAY_LENGTH, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "array-length");
-
-    /** {@code x: Throwable :: throw(x)} */
-    public static final Rop THROW =
-        new Rop(RegOps.THROW, Type.VOID, StdTypeList.THROWABLE,
-                StdTypeList.THROWABLE, "throw");
-
-    /** {@code x: Object :: monitorenter(x)} */
-    public static final Rop MONITOR_ENTER =
-        new Rop(RegOps.MONITOR_ENTER, Type.VOID, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "monitor-enter");
-
-    /** {@code x: Object :: monitorexit(x)} */
-    public static final Rop MONITOR_EXIT =
-        new Rop(RegOps.MONITOR_EXIT, Type.VOID, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_Null_IllegalMonitorStateException,
-                "monitor-exit");
-
-    /** {@code r,y: int; x: int[] :: r = x[y]} */
-    public static final Rop AGET_INT =
-        new Rop(RegOps.AGET, Type.INT, StdTypeList.INTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-int");
-
-    /** {@code r: long; x: long[]; y: int :: r = x[y]} */
-    public static final Rop AGET_LONG =
-        new Rop(RegOps.AGET, Type.LONG, StdTypeList.LONGARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-long");
-
-    /** {@code r: float; x: float[]; y: int :: r = x[y]} */
-    public static final Rop AGET_FLOAT =
-        new Rop(RegOps.AGET, Type.FLOAT, StdTypeList.FLOATARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-float");
-
-    /** {@code r: double; x: double[]; y: int :: r = x[y]} */
-    public static final Rop AGET_DOUBLE =
-        new Rop(RegOps.AGET, Type.DOUBLE, StdTypeList.DOUBLEARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-double");
-
-    /** {@code r: Object; x: Object[]; y: int :: r = x[y]} */
-    public static final Rop AGET_OBJECT =
-        new Rop(RegOps.AGET, Type.OBJECT, StdTypeList.OBJECTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-object");
-
-    /** {@code r: boolean; x: boolean[]; y: int :: r = x[y]} */
-    public static final Rop AGET_BOOLEAN =
-        new Rop(RegOps.AGET, Type.INT, StdTypeList.BOOLEANARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-boolean");
-
-    /** {@code r: byte; x: byte[]; y: int :: r = x[y]} */
-    public static final Rop AGET_BYTE =
-        new Rop(RegOps.AGET, Type.INT, StdTypeList.BYTEARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-byte");
-
-    /** {@code r: char; x: char[]; y: int :: r = x[y]} */
-    public static final Rop AGET_CHAR =
-        new Rop(RegOps.AGET, Type.INT, StdTypeList.CHARARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-char");
-
-    /** {@code r: short; x: short[]; y: int :: r = x[y]} */
-    public static final Rop AGET_SHORT =
-        new Rop(RegOps.AGET, Type.INT, StdTypeList.SHORTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aget-short");
-
-    /** {@code x,z: int; y: int[] :: y[z] = x} */
-    public static final Rop APUT_INT =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_INTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-int");
-
-    /** {@code x: long; y: long[]; z: int :: y[z] = x} */
-    public static final Rop APUT_LONG =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.LONG_LONGARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-long");
-
-    /** {@code x: float; y: float[]; z: int :: y[z] = x} */
-    public static final Rop APUT_FLOAT =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.FLOAT_FLOATARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aput-float");
-
-    /** {@code x: double; y: double[]; z: int :: y[z] = x} */
-    public static final Rop APUT_DOUBLE =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.DOUBLE_DOUBLEARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
-                "aput-double");
-
-    /** {@code x: Object; y: Object[]; z: int :: y[z] = x} */
-    public static final Rop APUT_OBJECT =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.OBJECT_OBJECTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
-                "aput-object");
-
-    /** {@code x: boolean; y: boolean[]; z: int :: y[z] = x} */
-    public static final Rop APUT_BOOLEAN =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BOOLEANARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
-                "aput-boolean");
-
-    /** {@code x: byte; y: byte[]; z: int :: y[z] = x} */
-    public static final Rop APUT_BYTE =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BYTEARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-byte");
-
-    /** {@code x: char; y: char[]; z: int :: y[z] = x} */
-    public static final Rop APUT_CHAR =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_CHARARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-char");
-
-    /** {@code x: short; y: short[]; z: int :: y[z] = x} */
-    public static final Rop APUT_SHORT =
-        new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_SHORTARR_INT,
-                Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
-                "aput-short");
-
-    /**
-     * {@code T: any non-array object type :: r =
-     * alloc(T)} (allocate heap space for an object)
-     */
-    public static final Rop NEW_INSTANCE =
-        new Rop(RegOps.NEW_INSTANCE, Type.OBJECT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "new-instance");
-
-    /** {@code r: int[]; x: int :: r = new int[x]} */
-    public static final Rop NEW_ARRAY_INT =
-        new Rop(RegOps.NEW_ARRAY, Type.INT_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-int");
-
-    /** {@code r: long[]; x: int :: r = new long[x]} */
-    public static final Rop NEW_ARRAY_LONG =
-        new Rop(RegOps.NEW_ARRAY, Type.LONG_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-long");
-
-    /** {@code r: float[]; x: int :: r = new float[x]} */
-    public static final Rop NEW_ARRAY_FLOAT =
-        new Rop(RegOps.NEW_ARRAY, Type.FLOAT_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-float");
-
-    /** {@code r: double[]; x: int :: r = new double[x]} */
-    public static final Rop NEW_ARRAY_DOUBLE =
-        new Rop(RegOps.NEW_ARRAY, Type.DOUBLE_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-double");
-
-    /** {@code r: boolean[]; x: int :: r = new boolean[x]} */
-    public static final Rop NEW_ARRAY_BOOLEAN =
-        new Rop(RegOps.NEW_ARRAY, Type.BOOLEAN_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-boolean");
-
-    /** {@code r: byte[]; x: int :: r = new byte[x]} */
-    public static final Rop NEW_ARRAY_BYTE =
-        new Rop(RegOps.NEW_ARRAY, Type.BYTE_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-byte");
-
-    /** {@code r: char[]; x: int :: r = new char[x]} */
-    public static final Rop NEW_ARRAY_CHAR =
-        new Rop(RegOps.NEW_ARRAY, Type.CHAR_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-char");
-
-    /** {@code r: short[]; x: int :: r = new short[x]} */
-    public static final Rop NEW_ARRAY_SHORT =
-        new Rop(RegOps.NEW_ARRAY, Type.SHORT_ARRAY, StdTypeList.INT,
-                Exceptions.LIST_Error_NegativeArraySizeException,
-                "new-array-short");
-
-    /**
-     * {@code T: any non-array object type; x: Object :: (T) x} (can
-     * throw {@code ClassCastException})
-     */
-    public static final Rop CHECK_CAST =
-        new Rop(RegOps.CHECK_CAST, Type.VOID, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_ClassCastException, "check-cast");
-
-    /**
-     * {@code T: any non-array object type; x: Object :: x instanceof
-     * T}. Note: This is listed as throwing {@code Error}
-     * explicitly because the op <i>can</i> throw, but there are no
-     * other predefined exceptions for it.
-     */
-    public static final Rop INSTANCE_OF =
-        new Rop(RegOps.INSTANCE_OF, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error, "instance-of");
-
-    /**
-     * {@code r: int; x: Object; f: instance field spec of
-     * type int :: r = x.f}
-     */
-    public static final Rop GET_FIELD_INT =
-        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "get-field-int");
-
-    /**
-     * {@code r: long; x: Object; f: instance field spec of
-     * type long :: r = x.f}
-     */
-    public static final Rop GET_FIELD_LONG =
-        new Rop(RegOps.GET_FIELD, Type.LONG, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "get-field-long");
-
-    /**
-     * {@code r: float; x: Object; f: instance field spec of
-     * type float :: r = x.f}
-     */
-    public static final Rop GET_FIELD_FLOAT =
-        new Rop(RegOps.GET_FIELD, Type.FLOAT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-float");
-
-    /**
-     * {@code r: double; x: Object; f: instance field spec of
-     * type double :: r = x.f}
-     */
-    public static final Rop GET_FIELD_DOUBLE =
-        new Rop(RegOps.GET_FIELD, Type.DOUBLE, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-double");
-
-    /**
-     * {@code r: Object; x: Object; f: instance field spec of
-     * type Object :: r = x.f}
-     */
-    public static final Rop GET_FIELD_OBJECT =
-        new Rop(RegOps.GET_FIELD, Type.OBJECT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-object");
-
-    /**
-     * {@code r: boolean; x: Object; f: instance field spec of
-     * type boolean :: r = x.f}
-     */
-    public static final Rop GET_FIELD_BOOLEAN =
-        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-boolean");
-
-    /**
-     * {@code r: byte; x: Object; f: instance field spec of
-     * type byte :: r = x.f}
-     */
-    public static final Rop GET_FIELD_BYTE =
-        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-byte");
-
-    /**
-     * {@code r: char; x: Object; f: instance field spec of
-     * type char :: r = x.f}
-     */
-    public static final Rop GET_FIELD_CHAR =
-        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-char");
-
-    /**
-     * {@code r: short; x: Object; f: instance field spec of
-     * type short :: r = x.f}
-     */
-    public static final Rop GET_FIELD_SHORT =
-        new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "get-field-short");
-
-    /** {@code r: int; f: static field spec of type int :: r = f} */
-    public static final Rop GET_STATIC_INT =
-        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-static-int");
-
-    /** {@code r: long; f: static field spec of type long :: r = f} */
-    public static final Rop GET_STATIC_LONG =
-        new Rop(RegOps.GET_STATIC, Type.LONG, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-static-long");
-
-    /** {@code r: float; f: static field spec of type float :: r = f} */
-    public static final Rop GET_STATIC_FLOAT =
-        new Rop(RegOps.GET_STATIC, Type.FLOAT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-static-float");
-
-    /** {@code r: double; f: static field spec of type double :: r = f} */
-    public static final Rop GET_STATIC_DOUBLE =
-        new Rop(RegOps.GET_STATIC, Type.DOUBLE, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-static-double");
-
-    /** {@code r: Object; f: static field spec of type Object :: r = f} */
-    public static final Rop GET_STATIC_OBJECT =
-        new Rop(RegOps.GET_STATIC, Type.OBJECT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-static-object");
-
-    /** {@code r: boolean; f: static field spec of type boolean :: r = f} */
-    public static final Rop GET_STATIC_BOOLEAN =
-        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-field-boolean");
-
-    /** {@code r: byte; f: static field spec of type byte :: r = f} */
-    public static final Rop GET_STATIC_BYTE =
-        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-field-byte");
-
-    /** {@code r: char; f: static field spec of type char :: r = f} */
-    public static final Rop GET_STATIC_CHAR =
-        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-field-char");
-
-    /** {@code r: short; f: static field spec of type short :: r = f} */
-    public static final Rop GET_STATIC_SHORT =
-        new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
-                Exceptions.LIST_Error, "get-field-short");
-
-    /**
-     * {@code x: int; y: Object; f: instance field spec of type
-     * int :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_INT =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "put-field-int");
-
-    /**
-     * {@code x: long; y: Object; f: instance field spec of type
-     * long :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_LONG =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.LONG_OBJECT,
-                Exceptions.LIST_Error_NullPointerException, "put-field-long");
-
-    /**
-     * {@code x: float; y: Object; f: instance field spec of type
-     * float :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_FLOAT =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.FLOAT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-float");
-
-    /**
-     * {@code x: double; y: Object; f: instance field spec of type
-     * double :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_DOUBLE =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.DOUBLE_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-double");
-
-    /**
-     * {@code x: Object; y: Object; f: instance field spec of type
-     * Object :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_OBJECT =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.OBJECT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-object");
-
-    /**
-     * {@code x: int; y: Object; f: instance field spec of type
-     * boolean :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_BOOLEAN =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-boolean");
-
-    /**
-     * {@code x: int; y: Object; f: instance field spec of type
-     * byte :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_BYTE =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-byte");
-
-    /**
-     * {@code x: int; y: Object; f: instance field spec of type
-     * char :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_CHAR =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-char");
-
-    /**
-     * {@code x: int; y: Object; f: instance field spec of type
-     * short :: y.f = x}
-     */
-    public static final Rop PUT_FIELD_SHORT =
-        new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
-                Exceptions.LIST_Error_NullPointerException,
-                "put-field-short");
-
-    /** {@code f: static field spec of type int; x: int :: f = x} */
-    public static final Rop PUT_STATIC_INT =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
-                Exceptions.LIST_Error, "put-static-int");
-
-    /** {@code f: static field spec of type long; x: long :: f = x} */
-    public static final Rop PUT_STATIC_LONG =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.LONG,
-                Exceptions.LIST_Error, "put-static-long");
-
-    /** {@code f: static field spec of type float; x: float :: f = x} */
-    public static final Rop PUT_STATIC_FLOAT =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.FLOAT,
-                Exceptions.LIST_Error, "put-static-float");
-
-    /** {@code f: static field spec of type double; x: double :: f = x} */
-    public static final Rop PUT_STATIC_DOUBLE =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.DOUBLE,
-                Exceptions.LIST_Error, "put-static-double");
-
-    /** {@code f: static field spec of type Object; x: Object :: f = x} */
-    public static final Rop PUT_STATIC_OBJECT =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.OBJECT,
-                Exceptions.LIST_Error, "put-static-object");
-
-    /**
-     * {@code f: static field spec of type boolean; x: boolean :: f =
-     * x}
-     */
-    public static final Rop PUT_STATIC_BOOLEAN =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
-                Exceptions.LIST_Error, "put-static-boolean");
-
-    /** {@code f: static field spec of type byte; x: byte :: f = x} */
-    public static final Rop PUT_STATIC_BYTE =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
-                Exceptions.LIST_Error, "put-static-byte");
-
-    /** {@code f: static field spec of type char; x: char :: f = x} */
-    public static final Rop PUT_STATIC_CHAR =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
-                Exceptions.LIST_Error, "put-static-char");
-
-    /** {@code f: static field spec of type short; x: short :: f = x} */
-    public static final Rop PUT_STATIC_SHORT =
-        new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
-                Exceptions.LIST_Error, "put-static-short");
-
-    /** {@code x: Int :: local variable begins in x} */
-    public static final Rop MARK_LOCAL_INT =
-            new Rop (RegOps.MARK_LOCAL, Type.VOID,
-                    StdTypeList.INT, "mark-local-int");
-
-    /** {@code x: Long :: local variable begins in x} */
-    public static final Rop MARK_LOCAL_LONG =
-            new Rop (RegOps.MARK_LOCAL, Type.VOID,
-                    StdTypeList.LONG, "mark-local-long");
-
-    /** {@code x: Float :: local variable begins in x} */
-    public static final Rop MARK_LOCAL_FLOAT =
-            new Rop (RegOps.MARK_LOCAL, Type.VOID,
-                    StdTypeList.FLOAT, "mark-local-float");
-
-    /** {@code x: Double :: local variable begins in x} */
-    public static final Rop MARK_LOCAL_DOUBLE =
-            new Rop (RegOps.MARK_LOCAL, Type.VOID,
-                    StdTypeList.DOUBLE, "mark-local-double");
-
-    /** {@code x: Object :: local variable begins in x} */
-    public static final Rop MARK_LOCAL_OBJECT =
-            new Rop (RegOps.MARK_LOCAL, Type.VOID,
-                    StdTypeList.OBJECT, "mark-local-object");
-
-    /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */
-    public static final Rop FILL_ARRAY_DATA =
-        new Rop(RegOps.FILL_ARRAY_DATA, Type.VOID, StdTypeList.EMPTY,
-                "fill-array-data");
-
-    /**
-     * Returns the appropriate rop for the given opcode, destination,
-     * and sources. The result is typically, but not necessarily, a
-     * shared instance.
-     *
-     * <p><b>Note:</b> This method does not do complete error checking on
-     * its arguments, and so it may return an instance which seemed "right
-     * enough" even though in actuality the passed arguments don't quite
-     * match what is returned. TODO: Revisit this issue.</p>
-     *
-     * @param opcode the opcode
-     * @param dest {@code non-null;} destination (result) type, or
-     * {@link Type#VOID} if none
-     * @param sources {@code non-null;} list of source types
-     * @param cst {@code null-ok;} associated constant, if any
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop ropFor(int opcode, TypeBearer dest, TypeList sources,
-            Constant cst) {
-        switch (opcode) {
-            case RegOps.NOP: return NOP;
-            case RegOps.MOVE: return opMove(dest);
-            case RegOps.MOVE_PARAM: return opMoveParam(dest);
-            case RegOps.MOVE_EXCEPTION: return opMoveException(dest);
-            case RegOps.CONST: return opConst(dest);
-            case RegOps.GOTO: return GOTO;
-            case RegOps.IF_EQ: return opIfEq(sources);
-            case RegOps.IF_NE: return opIfNe(sources);
-            case RegOps.IF_LT: return opIfLt(sources);
-            case RegOps.IF_GE: return opIfGe(sources);
-            case RegOps.IF_LE: return opIfLe(sources);
-            case RegOps.IF_GT: return opIfGt(sources);
-            case RegOps.SWITCH: return SWITCH;
-            case RegOps.ADD: return opAdd(sources);
-            case RegOps.SUB: return opSub(sources);
-            case RegOps.MUL: return opMul(sources);
-            case RegOps.DIV: return opDiv(sources);
-            case RegOps.REM: return opRem(sources);
-            case RegOps.NEG: return opNeg(dest);
-            case RegOps.AND: return opAnd(sources);
-            case RegOps.OR: return opOr(sources);
-            case RegOps.XOR: return opXor(sources);
-            case RegOps.SHL: return opShl(sources);
-            case RegOps.SHR: return opShr(sources);
-            case RegOps.USHR: return opUshr(sources);
-            case RegOps.NOT: return opNot(dest);
-            case RegOps.CMPL: return opCmpl(sources.getType(0));
-            case RegOps.CMPG: return opCmpg(sources.getType(0));
-            case RegOps.CONV: return opConv(dest, sources.getType(0));
-            case RegOps.TO_BYTE: return TO_BYTE;
-            case RegOps.TO_CHAR: return TO_CHAR;
-            case RegOps.TO_SHORT: return TO_SHORT;
-            case RegOps.RETURN: {
-                if (sources.size() == 0) {
-                    return RETURN_VOID;
-                }
-                return opReturn(sources.getType(0));
-            }
-            case RegOps.ARRAY_LENGTH: return ARRAY_LENGTH;
-            case RegOps.THROW: return THROW;
-            case RegOps.MONITOR_ENTER: return MONITOR_ENTER;
-            case RegOps.MONITOR_EXIT: return MONITOR_EXIT;
-            case RegOps.AGET: {
-                Type source = sources.getType(0);
-                Type componentType;
-                if (source == Type.KNOWN_NULL) {
-                    /*
-                     * Treat a known-null as an array of the expected
-                     * result type.
-                     */
-                    componentType = dest.getType();
-                } else {
-                    componentType = source.getComponentType();
-                }
-                return opAget(componentType);
-            }
-            case RegOps.APUT: {
-                Type source = sources.getType(1);
-                Type componentType;
-                if (source == Type.KNOWN_NULL) {
-                    /*
-                     * Treat a known-null as an array of the type being
-                     * stored.
-                     */
-                    componentType = sources.getType(0);
-                } else {
-                    componentType = source.getComponentType();
-                }
-                return opAput(componentType);
-            }
-            case RegOps.NEW_INSTANCE: return NEW_INSTANCE;
-            case RegOps.NEW_ARRAY: return opNewArray(dest.getType());
-            case RegOps.CHECK_CAST: return CHECK_CAST;
-            case RegOps.INSTANCE_OF: return INSTANCE_OF;
-            case RegOps.GET_FIELD: return opGetField(dest);
-            case RegOps.GET_STATIC: return opGetStatic(dest);
-            case RegOps.PUT_FIELD: return opPutField(sources.getType(0));
-            case RegOps.PUT_STATIC: return opPutStatic(sources.getType(0));
-            case RegOps.INVOKE_STATIC: {
-                return opInvokeStatic(((CstMethodRef) cst).getPrototype());
-            }
-            case RegOps.INVOKE_VIRTUAL: {
-                CstBaseMethodRef cstMeth = (CstMethodRef) cst;
-                Prototype meth = cstMeth.getPrototype();
-                CstType definer = cstMeth.getDefiningClass();
-                meth = meth.withFirstParameter(definer.getClassType());
-                return opInvokeVirtual(meth);
-            }
-            case RegOps.INVOKE_SUPER: {
-                CstBaseMethodRef cstMeth = (CstMethodRef) cst;
-                Prototype meth = cstMeth.getPrototype();
-                CstType definer = cstMeth.getDefiningClass();
-                meth = meth.withFirstParameter(definer.getClassType());
-                return opInvokeSuper(meth);
-            }
-            case RegOps.INVOKE_DIRECT: {
-                CstBaseMethodRef cstMeth = (CstMethodRef) cst;
-                Prototype meth = cstMeth.getPrototype();
-                CstType definer = cstMeth.getDefiningClass();
-                meth = meth.withFirstParameter(definer.getClassType());
-                return opInvokeDirect(meth);
-            }
-            case RegOps.INVOKE_INTERFACE: {
-                CstBaseMethodRef cstMeth = (CstMethodRef) cst;
-                Prototype meth = cstMeth.getPrototype();
-                CstType definer = cstMeth.getDefiningClass();
-                meth = meth.withFirstParameter(definer.getClassType());
-                return opInvokeInterface(meth);
-            }
-        }
-
-        throw new RuntimeException("unknown opcode " + RegOps.opName(opcode));
-    }
-
-    /**
-     * Returns the appropriate {@code move} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being moved
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMove(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return MOVE_INT;
-            case Type.BT_LONG:   return MOVE_LONG;
-            case Type.BT_FLOAT:  return MOVE_FLOAT;
-            case Type.BT_DOUBLE: return MOVE_DOUBLE;
-            case Type.BT_OBJECT: return MOVE_OBJECT;
-            case Type.BT_ADDR:   return MOVE_RETURN_ADDRESS;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code move-param} rop for the
-     * given type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being moved
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMoveParam(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return MOVE_PARAM_INT;
-            case Type.BT_LONG:   return MOVE_PARAM_LONG;
-            case Type.BT_FLOAT:  return MOVE_PARAM_FLOAT;
-            case Type.BT_DOUBLE: return MOVE_PARAM_DOUBLE;
-            case Type.BT_OBJECT: return MOVE_PARAM_OBJECT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code move-exception} rop for the
-     * given type. The result may be a shared instance.
-     *
-     * @param type {@code non-null;} type of the exception
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMoveException(TypeBearer type) {
-        return new Rop(RegOps.MOVE_EXCEPTION, type.getType(),
-                       StdTypeList.EMPTY, (String) null);
-    }
-
-    /**
-     * Returns the appropriate {@code move-result} rop for the
-     * given type. The result may be a shared instance.
-     *
-     * @param type {@code non-null;} type of the parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMoveResult(TypeBearer type) {
-        return new Rop(RegOps.MOVE_RESULT, type.getType(),
-                       StdTypeList.EMPTY, (String) null);
-    }
-
-    /**
-     * Returns the appropriate {@code move-result-pseudo} rop for the
-     * given type. The result may be a shared instance.
-     *
-     * @param type {@code non-null;} type of the parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMoveResultPseudo(TypeBearer type) {
-        return new Rop(RegOps.MOVE_RESULT_PSEUDO, type.getType(),
-                       StdTypeList.EMPTY, (String) null);
-    }
-
-    /**
-     * Returns the appropriate {@code const} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of the constant
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opConst(TypeBearer type) {
-        if (type.getType() == Type.KNOWN_NULL) {
-            return CONST_OBJECT_NOTHROW;
-        }
-
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return CONST_INT;
-            case Type.BT_LONG:   return CONST_LONG;
-            case Type.BT_FLOAT:  return CONST_FLOAT;
-            case Type.BT_DOUBLE: return CONST_DOUBLE;
-            case Type.BT_OBJECT: return CONST_OBJECT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code if-eq} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfEq(TypeList types) {
-        return pickIf(types, IF_EQZ_INT, IF_EQZ_OBJECT,
-                      IF_EQ_INT, IF_EQ_OBJECT);
-    }
-
-    /**
-     * Returns the appropriate {@code if-ne} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfNe(TypeList types) {
-        return pickIf(types, IF_NEZ_INT, IF_NEZ_OBJECT,
-                      IF_NE_INT, IF_NE_OBJECT);
-    }
-
-    /**
-     * Returns the appropriate {@code if-lt} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfLt(TypeList types) {
-        return pickIf(types, IF_LTZ_INT, null, IF_LT_INT, null);
-    }
-
-    /**
-     * Returns the appropriate {@code if-ge} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfGe(TypeList types) {
-        return pickIf(types, IF_GEZ_INT, null, IF_GE_INT, null);
-    }
-
-    /**
-     * Returns the appropriate {@code if-gt} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfGt(TypeList types) {
-        return pickIf(types, IF_GTZ_INT, null, IF_GT_INT, null);
-    }
-
-    /**
-     * Returns the appropriate {@code if-le} rop for the given
-     * sources. The result is a shared instance.
-     *
-     * @param types {@code non-null;} source types
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opIfLe(TypeList types) {
-        return pickIf(types, IF_LEZ_INT, null, IF_LE_INT, null);
-    }
-
-    /**
-     * Helper for all the {@code if*}-related methods, which
-     * checks types and picks one of the four variants, throwing if
-     * there's a problem.
-     *
-     * @param types {@code non-null;} the types
-     * @param intZ {@code non-null;} the int-to-0 comparison
-     * @param objZ {@code null-ok;} the object-to-null comparison
-     * @param intInt {@code non-null;} the int-to-int comparison
-     * @param objObj {@code non-null;} the object-to-object comparison
-     * @return {@code non-null;} the appropriate instance
-     */
-    private static Rop pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt,
-                              Rop objObj) {
-        switch(types.size()) {
-            case 1: {
-                switch (types.getType(0).getBasicFrameType()) {
-                    case Type.BT_INT: {
-                        return intZ;
-                    }
-                    case Type.BT_OBJECT: {
-                        if (objZ != null) {
-                            return objZ;
-                        }
-                    }
-                }
-                break;
-            }
-            case 2: {
-                int bt = types.getType(0).getBasicFrameType();
-                if (bt == types.getType(1).getBasicFrameType()) {
-                    switch (bt) {
-                        case Type.BT_INT: {
-                            return intInt;
-                        }
-                        case Type.BT_OBJECT: {
-                            if (objObj != null) {
-                                return objObj;
-                            }
-                        }
-                    }
-                }
-                break;
-            }
-        }
-
-        return throwBadTypes(types);
-    }
-
-    /**
-     * Returns the appropriate {@code add} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opAdd(TypeList types) {
-        return pickBinaryOp(types, ADD_CONST_INT, ADD_CONST_LONG,
-                            ADD_CONST_FLOAT, ADD_CONST_DOUBLE, ADD_INT,
-                            ADD_LONG, ADD_FLOAT, ADD_DOUBLE);
-    }
-
-    /**
-     * Returns the appropriate {@code sub} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opSub(TypeList types) {
-        return pickBinaryOp(types, SUB_CONST_INT, SUB_CONST_LONG,
-                            SUB_CONST_FLOAT, SUB_CONST_DOUBLE, SUB_INT,
-                            SUB_LONG, SUB_FLOAT, SUB_DOUBLE);
-    }
-
-    /**
-     * Returns the appropriate {@code mul} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMul(TypeList types) {
-        return pickBinaryOp(types, MUL_CONST_INT, MUL_CONST_LONG,
-                            MUL_CONST_FLOAT, MUL_CONST_DOUBLE, MUL_INT,
-                            MUL_LONG, MUL_FLOAT, MUL_DOUBLE);
-    }
-
-    /**
-     * Returns the appropriate {@code div} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opDiv(TypeList types) {
-        return pickBinaryOp(types, DIV_CONST_INT, DIV_CONST_LONG,
-                            DIV_CONST_FLOAT, DIV_CONST_DOUBLE, DIV_INT,
-                            DIV_LONG, DIV_FLOAT, DIV_DOUBLE);
-    }
-
-    /**
-     * Returns the appropriate {@code rem} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opRem(TypeList types) {
-        return pickBinaryOp(types, REM_CONST_INT, REM_CONST_LONG,
-                            REM_CONST_FLOAT, REM_CONST_DOUBLE, REM_INT,
-                            REM_LONG, REM_FLOAT, REM_DOUBLE);
-    }
-
-    /**
-     * Returns the appropriate {@code and} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opAnd(TypeList types) {
-        return pickBinaryOp(types, AND_CONST_INT, AND_CONST_LONG, null, null,
-                            AND_INT, AND_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate {@code or} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opOr(TypeList types) {
-        return pickBinaryOp(types, OR_CONST_INT, OR_CONST_LONG, null, null,
-                            OR_INT, OR_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate {@code xor} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opXor(TypeList types) {
-        return pickBinaryOp(types, XOR_CONST_INT, XOR_CONST_LONG, null, null,
-                            XOR_INT, XOR_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate {@code shl} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opShl(TypeList types) {
-        return pickBinaryOp(types, SHL_CONST_INT, SHL_CONST_LONG, null, null,
-                            SHL_INT, SHL_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate {@code shr} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opShr(TypeList types) {
-        return pickBinaryOp(types, SHR_CONST_INT, SHR_CONST_LONG, null, null,
-                            SHR_INT, SHR_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate {@code ushr} rop for the given
-     * types. The result is a shared instance.
-     *
-     * @param types {@code non-null;} types of the sources
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opUshr(TypeList types) {
-        return pickBinaryOp(types, USHR_CONST_INT, USHR_CONST_LONG, null, null,
-                            USHR_INT, USHR_LONG, null, null);
-    }
-
-    /**
-     * Returns the appropriate binary arithmetic rop for the given type
-     * and arguments. The result is a shared instance.
-     *
-     * @param types {@code non-null;} sources of the operation
-     * @param int1 {@code non-null;} the int-to-constant rop
-     * @param long1 {@code non-null;} the long-to-constant rop
-     * @param float1 {@code null-ok;} the float-to-constant rop, if any
-     * @param double1 {@code null-ok;} the double-to-constant rop, if any
-     * @param int2 {@code non-null;} the int-to-int rop
-     * @param long2 {@code non-null;} the long-to-long or long-to-int rop
-     * @param float2 {@code null-ok;} the float-to-float rop, if any
-     * @param double2 {@code null-ok;} the double-to-double rop, if any
-     * @return {@code non-null;} an appropriate instance
-     */
-    private static Rop pickBinaryOp(TypeList types, Rop int1, Rop long1,
-                                    Rop float1, Rop double1, Rop int2,
-                                    Rop long2, Rop float2, Rop double2) {
-        int bt1 = types.getType(0).getBasicFrameType();
-        Rop result = null;
-
-        switch (types.size()) {
-            case 1: {
-                switch(bt1) {
-                    case Type.BT_INT:    return int1;
-                    case Type.BT_LONG:   return long1;
-                    case Type.BT_FLOAT:  result = float1; break;
-                    case Type.BT_DOUBLE: result = double1; break;
-                }
-                break;
-            }
-            case 2: {
-                switch(bt1) {
-                    case Type.BT_INT:    return int2;
-                    case Type.BT_LONG:   return long2;
-                    case Type.BT_FLOAT:  result = float2; break;
-                    case Type.BT_DOUBLE: result = double2; break;
-                }
-                break;
-            }
-        }
-
-        if (result == null) {
-            return throwBadTypes(types);
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the appropriate {@code neg} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being operated on
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opNeg(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return NEG_INT;
-            case Type.BT_LONG:   return NEG_LONG;
-            case Type.BT_FLOAT:  return NEG_FLOAT;
-            case Type.BT_DOUBLE: return NEG_DOUBLE;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code not} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being operated on
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opNot(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:  return NOT_INT;
-            case Type.BT_LONG: return NOT_LONG;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code cmpl} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being compared
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opCmpl(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_LONG:   return CMPL_LONG;
-            case Type.BT_FLOAT:  return CMPL_FLOAT;
-            case Type.BT_DOUBLE: return CMPL_DOUBLE;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code cmpg} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being compared
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opCmpg(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_FLOAT:  return CMPG_FLOAT;
-            case Type.BT_DOUBLE: return CMPG_DOUBLE;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code conv} rop for the given types. The
-     * result is a shared instance.
-     *
-     * @param dest {@code non-null;} target value type
-     * @param source {@code non-null;} source value type
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opConv(TypeBearer dest, TypeBearer source) {
-        int dbt = dest.getBasicFrameType();
-        switch (source.getBasicFrameType()) {
-            case Type.BT_INT: {
-                switch (dbt) {
-                    case Type.BT_LONG:   return CONV_I2L;
-                    case Type.BT_FLOAT:  return CONV_I2F;
-                    case Type.BT_DOUBLE: return CONV_I2D;
-                    default:             break;
-                }
-            }
-            case Type.BT_LONG: {
-                switch (dbt) {
-                    case Type.BT_INT:    return CONV_L2I;
-                    case Type.BT_FLOAT:  return CONV_L2F;
-                    case Type.BT_DOUBLE: return CONV_L2D;
-                    default:             break;
-                }
-            }
-            case Type.BT_FLOAT: {
-                switch (dbt) {
-                    case Type.BT_INT:    return CONV_F2I;
-                    case Type.BT_LONG:   return CONV_F2L;
-                    case Type.BT_DOUBLE: return CONV_F2D;
-                    default:             break;
-                }
-            }
-            case Type.BT_DOUBLE: {
-                switch (dbt) {
-                    case Type.BT_INT:    return CONV_D2I;
-                    case Type.BT_LONG:   return CONV_D2L;
-                    case Type.BT_FLOAT:  return CONV_D2F;
-                    default:             break;
-                }
-            }
-        }
-
-        return throwBadTypes(StdTypeList.make(dest.getType(),
-                                              source.getType()));
-    }
-
-    /**
-     * Returns the appropriate {@code return} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being returned
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opReturn(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return RETURN_INT;
-            case Type.BT_LONG:   return RETURN_LONG;
-            case Type.BT_FLOAT:  return RETURN_FLOAT;
-            case Type.BT_DOUBLE: return RETURN_DOUBLE;
-            case Type.BT_OBJECT: return RETURN_OBJECT;
-            case Type.BT_VOID:   return RETURN_VOID;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code aget} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} element type of array being accessed
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opAget(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return AGET_INT;
-            case Type.BT_LONG:    return AGET_LONG;
-            case Type.BT_FLOAT:   return AGET_FLOAT;
-            case Type.BT_DOUBLE:  return AGET_DOUBLE;
-            case Type.BT_OBJECT:  return AGET_OBJECT;
-            case Type.BT_BOOLEAN: return AGET_BOOLEAN;
-            case Type.BT_BYTE:    return AGET_BYTE;
-            case Type.BT_CHAR:    return AGET_CHAR;
-            case Type.BT_SHORT:   return AGET_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code aput} rop for the given type. The
-     * result is a shared instance.
-     *
-     * @param type {@code non-null;} element type of array being accessed
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opAput(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return APUT_INT;
-            case Type.BT_LONG:    return APUT_LONG;
-            case Type.BT_FLOAT:   return APUT_FLOAT;
-            case Type.BT_DOUBLE:  return APUT_DOUBLE;
-            case Type.BT_OBJECT:  return APUT_OBJECT;
-            case Type.BT_BOOLEAN: return APUT_BOOLEAN;
-            case Type.BT_BYTE:    return APUT_BYTE;
-            case Type.BT_CHAR:    return APUT_CHAR;
-            case Type.BT_SHORT:   return APUT_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code new-array} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param arrayType {@code non-null;} array type of array being created
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opNewArray(TypeBearer arrayType) {
-        Type type = arrayType.getType();
-        Type elementType = type.getComponentType();
-
-        switch (elementType.getBasicType()) {
-            case Type.BT_INT:     return NEW_ARRAY_INT;
-            case Type.BT_LONG:    return NEW_ARRAY_LONG;
-            case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
-            case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
-            case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
-            case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
-            case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
-            case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
-            case Type.BT_OBJECT: {
-                return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
-                        Exceptions.LIST_Error_NegativeArraySizeException,
-                        "new-array-object");
-            }
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code filled-new-array} rop for the given
-     * type. The result may be a shared instance.
-     *
-     * @param arrayType {@code non-null;} type of array being created
-     * @param count {@code >= 0;} number of elements that the array should have
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opFilledNewArray(TypeBearer arrayType, int count) {
-        Type type = arrayType.getType();
-        Type elementType = type.getComponentType();
-
-        if (elementType.isCategory2()) {
-            return throwBadType(arrayType);
-        }
-
-        if (count < 0) {
-            throw new IllegalArgumentException("count < 0");
-        }
-
-        StdTypeList sourceTypes = new StdTypeList(count);
-
-        for (int i = 0; i < count; i++) {
-            sourceTypes.set(i, elementType);
-        }
-
-        // Note: The resulting rop is considered call-like.
-        return new Rop(RegOps.FILLED_NEW_ARRAY,
-                       sourceTypes,
-                       Exceptions.LIST_Error);
-    }
-
-    /**
-     * Returns the appropriate {@code get-field} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of the field in question
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opGetField(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return GET_FIELD_INT;
-            case Type.BT_LONG:    return GET_FIELD_LONG;
-            case Type.BT_FLOAT:   return GET_FIELD_FLOAT;
-            case Type.BT_DOUBLE:  return GET_FIELD_DOUBLE;
-            case Type.BT_OBJECT:  return GET_FIELD_OBJECT;
-            case Type.BT_BOOLEAN: return GET_FIELD_BOOLEAN;
-            case Type.BT_BYTE:    return GET_FIELD_BYTE;
-            case Type.BT_CHAR:    return GET_FIELD_CHAR;
-            case Type.BT_SHORT:   return GET_FIELD_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code put-field} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of the field in question
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opPutField(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return PUT_FIELD_INT;
-            case Type.BT_LONG:    return PUT_FIELD_LONG;
-            case Type.BT_FLOAT:   return PUT_FIELD_FLOAT;
-            case Type.BT_DOUBLE:  return PUT_FIELD_DOUBLE;
-            case Type.BT_OBJECT:  return PUT_FIELD_OBJECT;
-            case Type.BT_BOOLEAN: return PUT_FIELD_BOOLEAN;
-            case Type.BT_BYTE:    return PUT_FIELD_BYTE;
-            case Type.BT_CHAR:    return PUT_FIELD_CHAR;
-            case Type.BT_SHORT:   return PUT_FIELD_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code get-static} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of the field in question
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opGetStatic(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return GET_STATIC_INT;
-            case Type.BT_LONG:    return GET_STATIC_LONG;
-            case Type.BT_FLOAT:   return GET_STATIC_FLOAT;
-            case Type.BT_DOUBLE:  return GET_STATIC_DOUBLE;
-            case Type.BT_OBJECT:  return GET_STATIC_OBJECT;
-            case Type.BT_BOOLEAN: return GET_STATIC_BOOLEAN;
-            case Type.BT_BYTE:    return GET_STATIC_BYTE;
-            case Type.BT_CHAR:    return GET_STATIC_CHAR;
-            case Type.BT_SHORT:   return GET_STATIC_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code put-static} rop for the given
-     * type. The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of the field in question
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opPutStatic(TypeBearer type) {
-        switch (type.getBasicType()) {
-            case Type.BT_INT:     return PUT_STATIC_INT;
-            case Type.BT_LONG:    return PUT_STATIC_LONG;
-            case Type.BT_FLOAT:   return PUT_STATIC_FLOAT;
-            case Type.BT_DOUBLE:  return PUT_STATIC_DOUBLE;
-            case Type.BT_OBJECT:  return PUT_STATIC_OBJECT;
-            case Type.BT_BOOLEAN: return PUT_STATIC_BOOLEAN;
-            case Type.BT_BYTE:    return PUT_STATIC_BYTE;
-            case Type.BT_CHAR:    return PUT_STATIC_CHAR;
-            case Type.BT_SHORT:   return PUT_STATIC_SHORT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * Returns the appropriate {@code invoke-static} rop for the
-     * given type. The result is typically a newly-allocated instance.
-     *
-     * @param meth {@code non-null;} descriptor of the method
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opInvokeStatic(Prototype meth) {
-        return new Rop(RegOps.INVOKE_STATIC,
-                       meth.getParameterFrameTypes(),
-                       StdTypeList.THROWABLE);
-    }
-
-    /**
-     * Returns the appropriate {@code invoke-virtual} rop for the
-     * given type. The result is typically a newly-allocated instance.
-     *
-     * @param meth {@code non-null;} descriptor of the method, including the
-     * {@code this} parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opInvokeVirtual(Prototype meth) {
-        return new Rop(RegOps.INVOKE_VIRTUAL,
-                       meth.getParameterFrameTypes(),
-                       StdTypeList.THROWABLE);
-    }
-
-    /**
-     * Returns the appropriate {@code invoke-super} rop for the
-     * given type. The result is typically a newly-allocated instance.
-     *
-     * @param meth {@code non-null;} descriptor of the method, including the
-     * {@code this} parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opInvokeSuper(Prototype meth) {
-        return new Rop(RegOps.INVOKE_SUPER,
-                       meth.getParameterFrameTypes(),
-                       StdTypeList.THROWABLE);
-    }
-
-    /**
-     * Returns the appropriate {@code invoke-direct} rop for the
-     * given type. The result is typically a newly-allocated instance.
-     *
-     * @param meth {@code non-null;} descriptor of the method, including the
-     * {@code this} parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opInvokeDirect(Prototype meth) {
-        return new Rop(RegOps.INVOKE_DIRECT,
-                       meth.getParameterFrameTypes(),
-                       StdTypeList.THROWABLE);
-    }
-
-    /**
-     * Returns the appropriate {@code invoke-interface} rop for the
-     * given type. The result is typically a newly-allocated instance.
-     *
-     * @param meth {@code non-null;} descriptor of the method, including the
-     * {@code this} parameter
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opInvokeInterface(Prototype meth) {
-        return new Rop(RegOps.INVOKE_INTERFACE,
-                       meth.getParameterFrameTypes(),
-                       StdTypeList.THROWABLE);
-    }
-
-    /**
-     * Returns the appropriate {@code mark-local} rop for the given type.
-     * The result is a shared instance.
-     *
-     * @param type {@code non-null;} type of value being marked
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static Rop opMarkLocal(TypeBearer type) {
-        switch (type.getBasicFrameType()) {
-            case Type.BT_INT:    return MARK_LOCAL_INT;
-            case Type.BT_LONG:   return MARK_LOCAL_LONG;
-            case Type.BT_FLOAT:  return MARK_LOCAL_FLOAT;
-            case Type.BT_DOUBLE: return MARK_LOCAL_DOUBLE;
-            case Type.BT_OBJECT: return MARK_LOCAL_OBJECT;
-        }
-
-        return throwBadType(type);
-    }
-
-    /**
-     * This class is uninstantiable.
-     */
-    private Rops() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Throws the right exception to complain about a bogus type.
-     *
-     * @param type {@code non-null;} the bad type
-     * @return never
-     */
-    private static Rop throwBadType(TypeBearer type) {
-        throw new IllegalArgumentException("bad type: " + type);
-    }
-
-    /**
-     * Throws the right exception to complain about a bogus list of types.
-     *
-     * @param types {@code non-null;} the bad types
-     * @return never
-     */
-    private static Rop throwBadTypes(TypeList types) {
-        throw new IllegalArgumentException("bad types: " + types);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/SourcePosition.java b/dx/src/main/java/com/android/dx/rop/code/SourcePosition.java
deleted file mode 100644
index 11ac992..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/SourcePosition.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.util.Hex;
-
-/**
- * Information about a source position for code, which includes both a
- * line number and original bytecode address.
- */
-public final class SourcePosition {
-    /** {@code non-null;} convenient "no information known" instance */
-    public static final SourcePosition NO_INFO =
-        new SourcePosition(null, -1, -1);
-
-    /** {@code null-ok;} name of the file of origin or {@code null} if unknown */
-    private final CstString sourceFile;
-
-    /**
-     * {@code >= -1;} the bytecode address, or {@code -1} if that
-     * information is unknown
-     */
-    private final int address;
-
-    /**
-     * {@code >= -1;} the line number, or {@code -1} if that
-     * information is unknown
-     */
-    private final int line;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param sourceFile {@code null-ok;} name of the file of origin or
-     * {@code null} if unknown
-     * @param address {@code >= -1;} original bytecode address or {@code -1}
-     * if unknown
-     * @param line {@code >= -1;} original line number or {@code -1} if
-     * unknown
-     */
-    public SourcePosition(CstString sourceFile, int address, int line) {
-        if (address < -1) {
-            throw new IllegalArgumentException("address < -1");
-        }
-
-        if (line < -1) {
-            throw new IllegalArgumentException("line < -1");
-        }
-
-        this.sourceFile = sourceFile;
-        this.address = address;
-        this.line = line;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(50);
-
-        if (sourceFile != null) {
-            sb.append(sourceFile.toHuman());
-            sb.append(":");
-        }
-
-        if (line >= 0) {
-            sb.append(line);
-        }
-
-        sb.append('@');
-
-        if (address < 0) {
-            sb.append("????");
-        } else {
-            sb.append(Hex.u2(address));
-        }
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof SourcePosition)) {
-            return false;
-        }
-
-        if (this == other) {
-            return true;
-        }
-
-        SourcePosition pos = (SourcePosition) other;
-
-        return (address == pos.address) && sameLineAndFile(pos);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return sourceFile.hashCode() + address + line;
-    }
-
-    /**
-     * Returns whether the lines match between this instance and
-     * the one given.
-     *
-     * @param other {@code non-null;} the instance to compare to
-     * @return {@code true} iff the lines match
-     */
-    public boolean sameLine(SourcePosition other) {
-        return (line == other.line);
-    }
-
-    /**
-     * Returns whether the lines and files match between this instance and
-     * the one given.
-     *
-     * @param other {@code non-null;} the instance to compare to
-     * @return {@code true} iff the lines and files match
-     */
-    public boolean sameLineAndFile(SourcePosition other) {
-        return (line == other.line) &&
-            ((sourceFile == other.sourceFile) ||
-             ((sourceFile != null) && sourceFile.equals(other.sourceFile)));
-    }
-
-    /**
-     * Gets the source file, if known.
-     *
-     * @return {@code null-ok;} the source file or {@code null} if unknown
-     */
-    public CstString getSourceFile() {
-        return sourceFile;
-    }
-
-    /**
-     * Gets the original bytecode address.
-     *
-     * @return {@code >= -1;} the address or {@code -1} if unknown
-     */
-    public int getAddress() {
-        return address;
-    }
-
-    /**
-     * Gets the original line number.
-     *
-     * @return {@code >= -1;} the original line number or {@code -1} if
-     * unknown
-     */
-    public int getLine() {
-        return line;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/SwitchInsn.java b/dx/src/main/java/com/android/dx/rop/code/SwitchInsn.java
deleted file mode 100644
index 31bb94d..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/SwitchInsn.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-import com.android.dx.util.IntList;
-
-/**
- * Instruction which contains switch cases.
- */
-public final class SwitchInsn
-        extends Insn {
-    /** {@code non-null;} list of switch cases */
-    private final IntList cases;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param result {@code null-ok;} spec for the result, if any
-     * @param sources {@code non-null;} specs for all the sources
-     * @param cases {@code non-null;} list of switch cases
-     */
-    public SwitchInsn(Rop opcode, SourcePosition position, RegisterSpec result,
-                      RegisterSpecList sources, IntList cases) {
-        super(opcode, position, result, sources);
-
-        if (opcode.getBranchingness() != Rop.BRANCH_SWITCH) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-
-        if (cases == null) {
-            throw new NullPointerException("cases == null");
-        }
-
-        this.cases = cases;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getInlineString() {
-        return cases.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return StdTypeList.EMPTY;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitSwitchInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        throw new UnsupportedOperationException("unsupported");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new SwitchInsn(getOpcode(), getPosition(),
-                              getResult().withOffset(delta),
-                              getSources().withOffset(delta),
-                              cases);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p> SwitchInsn always compares false. The current use for this method
-     * never encounters {@code SwitchInsn}s
-     */
-    @Override
-    public boolean contentEquals(Insn b) {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new SwitchInsn(getOpcode(), getPosition(),
-                              result,
-                              sources,
-                              cases);
-    }
-
-    /**
-     * Gets the list of switch cases.
-     *
-     * @return {@code non-null;} the case list
-     */
-    public IntList getCases() {
-        return cases;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/ThrowingCstInsn.java b/dx/src/main/java/com/android/dx/rop/code/ThrowingCstInsn.java
deleted file mode 100644
index dee01b5..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/ThrowingCstInsn.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * Instruction which contains an explicit reference to a constant
- * and which might throw an exception.
- */
-public final class ThrowingCstInsn
-        extends CstInsn {
-    /** {@code non-null;} list of exceptions caught */
-    private final TypeList catches;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param sources {@code non-null;} specs for all the sources
-     * @param catches {@code non-null;} list of exceptions caught
-     * @param cst {@code non-null;} the constant
-     */
-    public ThrowingCstInsn(Rop opcode, SourcePosition position,
-                           RegisterSpecList sources,
-                           TypeList catches, Constant cst) {
-        super(opcode, position, null, sources, cst);
-
-        if (opcode.getBranchingness() != Rop.BRANCH_THROW) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-
-        if (catches == null) {
-            throw new NullPointerException("catches == null");
-        }
-
-        this.catches = catches;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getInlineString() {
-        Constant cst = getConstant();
-        String constantString = cst.toHuman();
-        if (cst instanceof CstString) {
-            constantString = ((CstString) cst).toQuoted();
-        }
-        return constantString + " " + ThrowingInsn.toCatchString(catches);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return catches;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitThrowingCstInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        return new ThrowingCstInsn(getOpcode(), getPosition(),
-                                   getSources(), catches.withAddedType(type),
-                                   getConstant());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new ThrowingCstInsn(getOpcode(), getPosition(),
-                                   getSources().withOffset(delta),
-                                   catches,
-                                   getConstant());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new ThrowingCstInsn(getOpcode(), getPosition(),
-                                   sources,
-                                   catches,
-                                   getConstant());
-    }
-
-
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/ThrowingInsn.java b/dx/src/main/java/com/android/dx/rop/code/ThrowingInsn.java
deleted file mode 100644
index 6561d41..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/ThrowingInsn.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * Instruction which possibly throws. The {@code successors} list in the
- * basic block an instance of this class is inside corresponds in-order to
- * the list of exceptions handled by this instruction, with the
- * no-exception case appended as the final target.
- */
-public final class ThrowingInsn
-        extends Insn {
-    /** {@code non-null;} list of exceptions caught */
-    private final TypeList catches;
-
-    /**
-     * Gets the string form of a register spec list to be used as a catches
-     * list.
-     *
-     * @param catches {@code non-null;} the catches list
-     * @return {@code non-null;} the string form
-     */
-    public static String toCatchString(TypeList catches) {
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append("catch");
-
-        int sz = catches.size();
-        for (int i = 0; i < sz; i++) {
-            sb.append(" ");
-            sb.append(catches.getType(i).toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param position {@code non-null;} source position
-     * @param sources {@code non-null;} specs for all the sources
-     * @param catches {@code non-null;} list of exceptions caught
-     */
-    public ThrowingInsn(Rop opcode, SourcePosition position,
-                        RegisterSpecList sources,
-                        TypeList catches) {
-        super(opcode, position, null, sources);
-
-        if (opcode.getBranchingness() != Rop.BRANCH_THROW) {
-            throw new IllegalArgumentException("bogus branchingness");
-        }
-
-        if (catches == null) {
-            throw new NullPointerException("catches == null");
-        }
-
-        this.catches = catches;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getInlineString() {
-        return toCatchString(catches);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public TypeList getCatches() {
-        return catches;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor visitor) {
-        visitor.visitThrowingInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withAddedCatch(Type type) {
-        return new ThrowingInsn(getOpcode(), getPosition(),
-                                getSources(), catches.withAddedType(type));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withRegisterOffset(int delta) {
-        return new ThrowingInsn(getOpcode(), getPosition(),
-                                getSources().withOffset(delta),
-                                catches);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn withNewRegisters(RegisterSpec result,
-            RegisterSpecList sources) {
-
-        return new ThrowingInsn(getOpcode(), getPosition(),
-                                sources,
-                                catches);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/code/TranslationAdvice.java b/dx/src/main/java/com/android/dx/rop/code/TranslationAdvice.java
deleted file mode 100644
index 832d84d..0000000
--- a/dx/src/main/java/com/android/dx/rop/code/TranslationAdvice.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.code;
-
-/**
- * Interface for "advice" passed from the late stage of translation back
- * to the early stage. This allows for the final target architecture to
- * exert its influence early in the translation process without having
- * the early stage code be explicitly tied to the target.
- */
-public interface TranslationAdvice {
-    /**
-     * Returns an indication of whether the target can directly represent an
-     * instruction with the given opcode operating on the given arguments,
-     * where the last source argument is used as a constant. (That is, the
-     * last argument must have a type which indicates it is a known constant.)
-     * The instruction associated must have exactly two sources.
-     *
-     * @param opcode {@code non-null;} the opcode
-     * @param sourceA {@code non-null;} the first source
-     * @param sourceB {@code non-null;} the second source
-     * @return {@code true} iff the target can represent the operation
-     * using a constant for the last argument
-     */
-    public boolean hasConstantOperation(Rop opcode,
-            RegisterSpec sourceA, RegisterSpec sourceB);
-
-    /**
-     * Returns true if the translation target requires the sources of the
-     * specified opcode to be in order and contiguous (eg, for an invoke-range)
-     *
-     * @param opcode {@code non-null;} opcode
-     * @param sources {@code non-null;} source list
-     * @return {@code true} iff the target requires the sources to be
-     * in order and contiguous.
-     */
-    public boolean requiresSourcesInOrder(Rop opcode, RegisterSpecList sources);
-
-    /**
-     * Gets the maximum register width that can be represented optimally.
-     * For example, Dex bytecode does not have instruction forms that take
-     * register numbers larger than 15 for all instructions so
-     * DexTranslationAdvice returns 15 here.
-     *
-     * @return register count noted above
-     */
-    public int getMaxOptimalRegisterCount();
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/Constant.java b/dx/src/main/java/com/android/dx/rop/cst/Constant.java
deleted file mode 100644
index 3ef035e..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/Constant.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.util.ToHuman;
-
-/**
- * Base class for constants of all sorts.
- */
-public abstract class Constant
-        implements ToHuman, Comparable<Constant> {
-    /**
-     * Returns {@code true} if this instance is a category-2 constant,
-     * meaning it takes up two slots in the constant pool, or
-     * {@code false} if this instance is category-1.
-     *
-     * @return {@code true} iff this instance is category-2
-     */
-    public abstract boolean isCategory2();
-
-    /**
-     * Returns the human name for the particular type of constant
-     * this instance is.
-     *
-     * @return {@code non-null;} the name
-     */
-    public abstract String typeName();
-
-    /**
-     * {@inheritDoc}
-     *
-     * This compares in class-major and value-minor order.
-     */
-    public final int compareTo(Constant other) {
-        Class clazz = getClass();
-        Class otherClazz = other.getClass();
-
-        if (clazz != otherClazz) {
-            return clazz.getName().compareTo(otherClazz.getName());
-        }
-
-        return compareTo0(other);
-    }
-
-    /**
-     * Compare the values of this and another instance, which are guaranteed
-     * to be of the same class. Subclasses must implement this.
-     *
-     * @param other {@code non-null;} the instance to compare to
-     * @return {@code -1}, {@code 0}, or {@code 1}, as usual
-     * for a comparison
-     */
-    protected abstract int compareTo0(Constant other);
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/ConstantPool.java b/dx/src/main/java/com/android/dx/rop/cst/ConstantPool.java
deleted file mode 100644
index efc394d..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/ConstantPool.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Interface for constant pools, which are, more or less, just lists of
- * {@link Constant} objects.
- */
-public interface ConstantPool {
-    /**
-     * Get the "size" of the constant pool. This corresponds to the
-     * class file field {@code constant_pool_count}, and is in fact
-     * always at least one more than the actual size of the constant pool,
-     * as element {@code 0} is always invalid.
-     *
-     * @return {@code >= 1;} the size
-     */
-    public int size();
-
-    /**
-     * Get the {@code n}th entry in the constant pool, which must
-     * be valid.
-     *
-     * @param n {@code n >= 0, n < size();} the constant pool index
-     * @return {@code non-null;} the corresponding entry
-     * @throws IllegalArgumentException thrown if {@code n} is
-     * in-range but invalid
-     */
-    public Constant get(int n);
-
-    /**
-     * Get the {@code n}th entry in the constant pool, which must
-     * be valid unless {@code n == 0}, in which case {@code null}
-     * is returned.
-     *
-     * @param n {@code n >= 0, n < size();} the constant pool index
-     * @return {@code null-ok;} the corresponding entry, if {@code n != 0}
-     * @throws IllegalArgumentException thrown if {@code n} is
-     * in-range and non-zero but invalid
-     */
-    public Constant get0Ok(int n);
-
-    /**
-     * Get the {@code n}th entry in the constant pool, or
-     * {@code null} if the index is in-range but invalid. In
-     * particular, {@code null} is returned for index {@code 0}
-     * as well as the index after any entry which is defined to take up
-     * two slots (that is, {@code Long} and {@code Double}
-     * entries).
-     *
-     * @param n {@code n >= 0, n < size();} the constant pool index
-     * @return {@code null-ok;} the corresponding entry, or {@code null} if
-     * the index is in-range but invalid
-     */
-    public Constant getOrNull(int n);
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstAnnotation.java b/dx/src/main/java/com/android/dx/rop/cst/CstAnnotation.java
deleted file mode 100644
index 8cdf1df..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstAnnotation.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.annotation.Annotation;
-
-/**
- * Constant type that represents an annotation.
- */
-public final class CstAnnotation extends Constant {
-    /** {@code non-null;} the actual annotation */
-    private final Annotation annotation;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param annotation {@code non-null;} the annotation to hold
-     */
-    public CstAnnotation(Annotation annotation) {
-        if (annotation == null) {
-            throw new NullPointerException("annotation == null");
-        }
-
-        annotation.throwIfMutable();
-
-        this.annotation = annotation;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (! (other instanceof CstAnnotation)) {
-            return false;
-        }
-
-        return annotation.equals(((CstAnnotation) other).annotation);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return annotation.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        return annotation.compareTo(((CstAnnotation) other).annotation);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return annotation.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "annotation";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return annotation.toString();
-    }
-
-    /**
-     * Get the underlying annotation.
-     *
-     * @return {@code non-null;} the annotation
-     */
-    public Annotation getAnnotation() {
-        return annotation;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstArray.java b/dx/src/main/java/com/android/dx/rop/cst/CstArray.java
deleted file mode 100644
index 2766b5f..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstArray.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.FixedSizeList;
-
-/**
- * Constant type to represent a fixed array of other constants.
- */
-public final class CstArray extends Constant {
-    /** {@code non-null;} the actual list of contents */
-    private final List list;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param list {@code non-null;} the actual list of contents
-     */
-    public CstArray(List list) {
-        if (list == null) {
-            throw new NullPointerException("list == null");
-        }
-
-        list.throwIfMutable();
-
-        this.list = list;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (! (other instanceof CstArray)) {
-            return false;
-        }
-
-        return list.equals(((CstArray) other).list);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return list.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        return list.compareTo(((CstArray) other).list);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return list.toString("array{", ", ", "}");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "array";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return list.toHuman("{", ", ", "}");
-    }
-
-    /**
-     * Get the underlying list.
-     *
-     * @return {@code non-null;} the list
-     */
-    public List getList() {
-        return list;
-    }
-
-    /**
-     * List of {@link Constant} instances.
-     */
-    public static final class List
-            extends FixedSizeList implements Comparable<List> {
-        /**
-         * Constructs an instance. All indices initially contain
-         * {@code null}.
-         *
-         * @param size the size of the list
-         */
-        public List(int size) {
-            super(size);
-        }
-
-        /** {@inheritDoc} */
-        public int compareTo(List other) {
-            int thisSize = size();
-            int otherSize = other.size();
-            int compareSize = (thisSize < otherSize) ? thisSize : otherSize;
-
-            for (int i = 0; i < compareSize; i++) {
-                Constant thisItem = (Constant) get0(i);
-                Constant otherItem = (Constant) other.get0(i);
-                int compare = thisItem.compareTo(otherItem);
-                if (compare != 0) {
-                    return compare;
-                }
-            }
-
-            if (thisSize < otherSize) {
-                return -1;
-            } else if (thisSize > otherSize) {
-                return 1;
-            }
-
-            return 0;
-        }
-
-        /**
-         * Gets the element at the given index. It is an error to call
-         * this with the index for an element which was never set; if you
-         * do that, this will throw {@code NullPointerException}.
-         *
-         * @param n {@code >= 0, < size();} which index
-         * @return {@code non-null;} element at that index
-         */
-        public Constant get(int n) {
-            return (Constant) get0(n);
-        }
-
-        /**
-         * Sets the element at the given index.
-         *
-         * @param n {@code >= 0, < size();} which index
-         * @param a {@code null-ok;} the element to set at {@code n}
-         */
-        public void set(int n, Constant a) {
-            set0(n, a);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstBaseMethodRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstBaseMethodRef.java
deleted file mode 100644
index 5b0aeb6..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstBaseMethodRef.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-
-/**
- * Base class for constants of "methodish" type.
- *
- * <p><b>Note:</b> As a {@link TypeBearer}, this class bears the return type
- * of the method.</p>
- */
-public abstract class CstBaseMethodRef
-        extends CstMemberRef {
-    /** {@code non-null;} the raw prototype for this method */
-    private final Prototype prototype;
-
-    /**
-     * {@code null-ok;} the prototype for this method taken to be an instance
-     * method, or {@code null} if not yet calculated
-     */
-    private Prototype instancePrototype;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param definingClass {@code non-null;} the type of the defining class
-     * @param nat {@code non-null;} the name-and-type
-     */
-    /*package*/ CstBaseMethodRef(CstType definingClass, CstNat nat) {
-        super(definingClass, nat);
-
-        String descriptor = getNat().getDescriptor().getString();
-        this.prototype = Prototype.intern(descriptor);
-        this.instancePrototype = null;
-    }
-
-    /**
-     * Gets the raw prototype of this method. This doesn't include a
-     * {@code this} argument.
-     *
-     * @return {@code non-null;} the method prototype
-     */
-    public final Prototype getPrototype() {
-        return prototype;
-    }
-
-    /**
-     * Gets the prototype of this method as either a
-     * {@code static} or instance method. In the case of a
-     * {@code static} method, this is the same as the raw
-     * prototype. In the case of an instance method, this has an
-     * appropriately-typed {@code this} argument as the first
-     * one.
-     *
-     * @param isStatic whether the method should be considered static
-     * @return {@code non-null;} the method prototype
-     */
-    public final Prototype getPrototype(boolean isStatic) {
-        if (isStatic) {
-            return prototype;
-        } else {
-            if (instancePrototype == null) {
-                Type thisType = getDefiningClass().getClassType();
-                instancePrototype = prototype.withFirstParameter(thisType);
-            }
-            return instancePrototype;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final int compareTo0(Constant other) {
-        int cmp = super.compareTo0(other);
-
-        if (cmp != 0) {
-            return cmp;
-        }
-
-        CstBaseMethodRef otherMethod = (CstBaseMethodRef) other;
-        return prototype.compareTo(otherMethod.prototype);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * In this case, this method returns the <i>return type</i> of this method.
-     *
-     * @return {@code non-null;} the method's return type
-     */
-    public final Type getType() {
-        return prototype.getReturnType();
-    }
-
-    /**
-     * Gets the number of words of parameters required by this
-     * method's descriptor. Since instances of this class have no way
-     * to know if they will be used in a {@code static} or
-     * instance context, one has to indicate this explicitly as an
-     * argument. This method is just a convenient shorthand for
-     * {@code getPrototype().getParameterTypes().getWordCount()},
-     * plus {@code 1} if the method is to be treated as an
-     * instance method.
-     *
-     * @param isStatic whether the method should be considered static
-     * @return {@code >= 0;} the argument word count
-     */
-    public final int getParameterWordCount(boolean isStatic) {
-        return getPrototype(isStatic).getParameterTypes().getWordCount();
-    }
-
-    /**
-     * Gets whether this is a reference to an instance initialization
-     * method. This is just a convenient shorthand for
-     * {@code getNat().isInstanceInit()}.
-     *
-     * @return {@code true} iff this is a reference to an
-     * instance initialization method
-     */
-    public final boolean isInstanceInit() {
-        return getNat().isInstanceInit();
-    }
-
-    /**
-     * Gets whether this is a reference to a class initialization
-     * method. This is just a convenient shorthand for
-     * {@code getNat().isClassInit()}.
-     *
-     * @return {@code true} iff this is a reference to an
-     * instance initialization method
-     */
-    public final boolean isClassInit() {
-        return getNat().isClassInit();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstBoolean.java b/dx/src/main/java/com/android/dx/rop/cst/CstBoolean.java
deleted file mode 100644
index 5ff858a..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstBoolean.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Constants of type {@code boolean}.
- */
-public final class CstBoolean
-        extends CstLiteral32 {
-    /** {@code non-null;} instance representing {@code false} */
-    public static final CstBoolean VALUE_FALSE = new CstBoolean(false);
-
-    /** {@code non-null;} instance representing {@code true} */
-    public static final CstBoolean VALUE_TRUE = new CstBoolean(true);
-
-    /**
-     * Makes an instance for the given value. This will return an
-     * already-allocated instance.
-     *
-     * @param value the {@code boolean} value
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstBoolean make(boolean value) {
-        return value ? VALUE_TRUE : VALUE_FALSE;
-    }
-
-    /**
-     * Makes an instance for the given {@code int} value. This
-     * will return an already-allocated instance.
-     *
-     * @param value must be either {@code 0} or {@code 1}
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstBoolean make(int value) {
-        if (value == 0) {
-            return VALUE_FALSE;
-        } else if (value == 1) {
-            return VALUE_TRUE;
-        } else {
-            throw new IllegalArgumentException("bogus value: " + value);
-        }
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code boolean} value
-     */
-    private CstBoolean(boolean value) {
-        super(value ? 1 : 0);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return getValue() ? "boolean{true}" : "boolean{false}";
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.BOOLEAN;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "boolean";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return getValue() ? "true" : "false";
-    }
-
-    /**
-     * Gets the {@code boolean} value.
-     *
-     * @return the value
-     */
-    public boolean getValue() {
-        return (getIntBits() == 0) ? false : true;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstByte.java b/dx/src/main/java/com/android/dx/rop/cst/CstByte.java
deleted file mode 100644
index fc8f58f..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstByte.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code byte}.
- */
-public final class CstByte
-        extends CstLiteral32 {
-    /** {@code non-null;} the value {@code 0} as an instance of this class */
-    public static final CstByte VALUE_0 = make((byte) 0);
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param value the {@code byte} value
-     */
-    public static CstByte make(byte value) {
-        return new CstByte(value);
-    }
-
-    /**
-     * Makes an instance for the given {@code int} value. This
-     * may (but does not necessarily) return an already-allocated
-     * instance.
-     *
-     * @param value the value, which must be in range for a {@code byte}
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstByte make(int value) {
-        byte cast = (byte) value;
-
-        if (cast != value) {
-            throw new IllegalArgumentException("bogus byte value: " +
-                    value);
-        }
-
-        return make(cast);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code byte} value
-     */
-    private CstByte(byte value) {
-        super(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int value = getIntBits();
-        return "byte{0x" + Hex.u1(value) + " / " + value + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.BYTE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "byte";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Integer.toString(getIntBits());
-    }
-
-    /**
-     * Gets the {@code byte} value.
-     *
-     * @return the value
-     */
-    public byte getValue() {
-        return (byte) getIntBits();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstChar.java b/dx/src/main/java/com/android/dx/rop/cst/CstChar.java
deleted file mode 100644
index 21d8b67..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstChar.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code char}.
- */
-public final class CstChar
-        extends CstLiteral32 {
-    /** {@code non-null;} the value {@code 0} as an instance of this class */
-    public static final CstChar VALUE_0 = make((char) 0);
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param value the {@code char} value
-     */
-    public static CstChar make(char value) {
-        return new CstChar(value);
-    }
-
-    /**
-     * Makes an instance for the given {@code int} value. This
-     * may (but does not necessarily) return an already-allocated
-     * instance.
-     *
-     * @param value the value, which must be in range for a {@code char}
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstChar make(int value) {
-        char cast = (char) value;
-
-        if (cast != value) {
-            throw new IllegalArgumentException("bogus char value: " +
-                    value);
-        }
-
-        return make(cast);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code char} value
-     */
-    private CstChar(char value) {
-        super(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int value = getIntBits();
-        return "char{0x" + Hex.u2(value) + " / " + value + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.CHAR;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "char";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Integer.toString(getIntBits());
-    }
-
-    /**
-     * Gets the {@code char} value.
-     *
-     * @return the value
-     */
-    public char getValue() {
-        return (char) getIntBits();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstDouble.java b/dx/src/main/java/com/android/dx/rop/cst/CstDouble.java
deleted file mode 100644
index 8f1766f..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstDouble.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code CONSTANT_Double_info}.
- */
-public final class CstDouble
-        extends CstLiteral64 {
-    /** {@code non-null;} instance representing {@code 0} */
-    public static final CstDouble VALUE_0 =
-        new CstDouble(Double.doubleToLongBits(0.0));
-
-    /** {@code non-null;} instance representing {@code 1} */
-    public static final CstDouble VALUE_1 =
-        new CstDouble(Double.doubleToLongBits(1.0));
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param bits the {@code double} value as {@code long} bits
-     */
-    public static CstDouble make(long bits) {
-        /*
-         * Note: Javadoc notwithstanding, this implementation always
-         * allocates.
-         */
-        return new CstDouble(bits);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param bits the {@code double} value as {@code long} bits
-     */
-    private CstDouble(long bits) {
-        super(bits);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        long bits = getLongBits();
-        return "double{0x" + Hex.u8(bits) + " / " +
-            Double.longBitsToDouble(bits) + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.DOUBLE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "double";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Double.toString(Double.longBitsToDouble(getLongBits()));
-    }
-
-    /**
-     * Gets the {@code double} value.
-     *
-     * @return the value
-     */
-    public double getValue() {
-        return Double.longBitsToDouble(getLongBits());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstEnumRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstEnumRef.java
deleted file mode 100644
index 641ab3f..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstEnumRef.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Constant type to represent a reference to a particular constant
- * value of an enumerated type.
- */
-public final class CstEnumRef extends CstMemberRef {
-    /** {@code null-ok;} the corresponding field ref, lazily initialized */
-    private CstFieldRef fieldRef;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param nat {@code non-null;} the name-and-type; the defining class is derived
-     * from this
-     */
-    public CstEnumRef(CstNat nat) {
-        super(new CstType(nat.getFieldType()), nat);
-
-        fieldRef = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "enum";
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <b>Note:</b> This returns the enumerated type.
-     */
-    public Type getType() {
-        return getDefiningClass().getClassType();
-    }
-
-    /**
-     * Get a {@link CstFieldRef} that corresponds with this instance.
-     *
-     * @return {@code non-null;} the corresponding field reference
-     */
-    public CstFieldRef getFieldRef() {
-        if (fieldRef == null) {
-            fieldRef = new CstFieldRef(getDefiningClass(), getNat());
-        }
-
-        return fieldRef;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstFieldRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstFieldRef.java
deleted file mode 100644
index a4d7180..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstFieldRef.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Constants of type {@code CONSTANT_Fieldref_info}.
- */
-public final class CstFieldRef extends CstMemberRef {
-    /**
-     * Returns an instance of this class that represents the static
-     * field which should hold the class corresponding to a given
-     * primitive type. For example, if given {@link Type#INT}, this
-     * method returns an instance corresponding to the field
-     * {@code java.lang.Integer.TYPE}.
-     *
-     * @param primitiveType {@code non-null;} the primitive type
-     * @return {@code non-null;} the corresponding static field
-     */
-    public static CstFieldRef forPrimitiveType(Type primitiveType) {
-        return new CstFieldRef(CstType.forBoxedPrimitiveType(primitiveType),
-                CstNat.PRIMITIVE_TYPE_NAT);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param definingClass {@code non-null;} the type of the defining class
-     * @param nat {@code non-null;} the name-and-type
-     */
-    public CstFieldRef(CstType definingClass, CstNat nat) {
-        super(definingClass, nat);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "field";
-    }
-
-    /**
-     * Returns the type of this field.
-     *
-     * @return {@code non-null;} the field's type
-     */
-    public Type getType() {
-        return getNat().getFieldType();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        int cmp = super.compareTo0(other);
-
-        if (cmp != 0) {
-            return cmp;
-        }
-
-        CstFieldRef otherField = (CstFieldRef) other;
-        CstString thisDescriptor = getNat().getDescriptor();
-        CstString otherDescriptor = otherField.getNat().getDescriptor();
-        return thisDescriptor.compareTo(otherDescriptor);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstFloat.java b/dx/src/main/java/com/android/dx/rop/cst/CstFloat.java
deleted file mode 100644
index 0a2354a..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstFloat.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code CONSTANT_Float_info}.
- */
-public final class CstFloat
-        extends CstLiteral32 {
-    /** {@code non-null;} instance representing {@code 0} */
-    public static final CstFloat VALUE_0 = make(Float.floatToIntBits(0.0f));
-
-    /** {@code non-null;} instance representing {@code 1} */
-    public static final CstFloat VALUE_1 = make(Float.floatToIntBits(1.0f));
-
-    /** {@code non-null;} instance representing {@code 2} */
-    public static final CstFloat VALUE_2 = make(Float.floatToIntBits(2.0f));
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param bits the {@code float} value as {@code int} bits
-     */
-    public static CstFloat make(int bits) {
-        /*
-         * Note: Javadoc notwithstanding, this implementation always
-         * allocates.
-         */
-        return new CstFloat(bits);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param bits the {@code float} value as {@code int} bits
-     */
-    private CstFloat(int bits) {
-        super(bits);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int bits = getIntBits();
-        return "float{0x" + Hex.u4(bits) + " / " +
-            Float.intBitsToFloat(bits) + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.FLOAT;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "float";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Float.toString(Float.intBitsToFloat(getIntBits()));
-    }
-
-    /**
-     * Gets the {@code float} value.
-     *
-     * @return the value
-     */
-    public float getValue() {
-        return Float.intBitsToFloat(getIntBits());
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstInteger.java b/dx/src/main/java/com/android/dx/rop/cst/CstInteger.java
deleted file mode 100644
index 3691fc0..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstInteger.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code CONSTANT_Integer_info}.
- */
-public final class CstInteger
-        extends CstLiteral32 {
-    /** {@code non-null;} array of cached instances */
-    private static final CstInteger[] cache = new CstInteger[511];
-
-    /** {@code non-null;} instance representing {@code -1} */
-    public static final CstInteger VALUE_M1 = make(-1);
-
-    /** {@code non-null;} instance representing {@code 0} */
-    public static final CstInteger VALUE_0 = make(0);
-
-    /** {@code non-null;} instance representing {@code 1} */
-    public static final CstInteger VALUE_1 = make(1);
-
-    /** {@code non-null;} instance representing {@code 2} */
-    public static final CstInteger VALUE_2 = make(2);
-
-    /** {@code non-null;} instance representing {@code 3} */
-    public static final CstInteger VALUE_3 = make(3);
-
-    /** {@code non-null;} instance representing {@code 4} */
-    public static final CstInteger VALUE_4 = make(4);
-
-    /** {@code non-null;} instance representing {@code 5} */
-    public static final CstInteger VALUE_5 = make(5);
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param value the {@code int} value
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstInteger make(int value) {
-        /*
-         * Note: No need to synchronize, since we don't make any sort
-         * of guarantee about ==, and it's okay to overwrite existing
-         * entries too.
-         */
-        int idx = (value & 0x7fffffff) % cache.length;
-        CstInteger obj = cache[idx];
-
-        if ((obj != null) && (obj.getValue() == value)) {
-            return obj;
-        }
-
-        obj = new CstInteger(value);
-        cache[idx] = obj;
-        return obj;
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code int} value
-     */
-    private CstInteger(int value) {
-        super(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int value = getIntBits();
-        return "int{0x" + Hex.u4(value) + " / " + value + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.INT;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "int";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Integer.toString(getIntBits());
-    }
-
-    /**
-     * Gets the {@code int} value.
-     *
-     * @return the value
-     */
-    public int getValue() {
-        return getIntBits();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstInterfaceMethodRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstInterfaceMethodRef.java
deleted file mode 100644
index 8b8cb30..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstInterfaceMethodRef.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants of type {@code CONSTANT_InterfaceMethodref_info}.
- */
-public final class CstInterfaceMethodRef
-        extends CstBaseMethodRef {
-    /**
-     * {@code null-ok;} normal {@link CstMethodRef} that corresponds to this
-     * instance, if calculated
-     */
-    private CstMethodRef methodRef;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param definingClass {@code non-null;} the type of the defining class
-     * @param nat {@code non-null;} the name-and-type
-     */
-    public CstInterfaceMethodRef(CstType definingClass, CstNat nat) {
-        super(definingClass, nat);
-        methodRef = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "ifaceMethod";
-    }
-
-    /**
-     * Gets a normal (non-interface) {@link CstMethodRef} that corresponds to
-     * this instance.
-     *
-     * @return {@code non-null;} an appropriate instance
-     */
-    public CstMethodRef toMethodRef() {
-        if (methodRef == null) {
-            methodRef = new CstMethodRef(getDefiningClass(), getNat());
-        }
-
-        return methodRef;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstKnownNull.java b/dx/src/main/java/com/android/dx/rop/cst/CstKnownNull.java
deleted file mode 100644
index a80322c..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstKnownNull.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Constant type to represent a known-{@code null} value.
- */
-public final class CstKnownNull extends CstLiteralBits {
-    /** {@code non-null;} unique instance of this class */
-    public static final CstKnownNull THE_ONE = new CstKnownNull();
-
-    /**
-     * Constructs an instance. This class is not publicly instantiable. Use
-     * {@link #THE_ONE}.
-     */
-    private CstKnownNull() {
-        // This space intentionally left blank.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        return (other instanceof CstKnownNull);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return 0x4466757a;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "known-null";
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.KNOWN_NULL;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "known-null";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return "null";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean fitsInInt() {
-        // See comment in getIntBits().
-        return true;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * As "literal bits," a known-null is always represented as the
-     * number zero.
-     */
-    @Override
-    public int getIntBits() {
-        return 0;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * As "literal bits," a known-null is always represented as the
-     * number zero.
-     */
-    @Override
-    public long getLongBits() {
-        return 0;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstLiteral32.java b/dx/src/main/java/com/android/dx/rop/cst/CstLiteral32.java
deleted file mode 100644
index 042cbd9..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstLiteral32.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants which are literal 32-bit values of some sort.
- */
-public abstract class CstLiteral32
-        extends CstLiteralBits {
-    /** the value as {@code int} bits */
-    private final int bits;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param bits the value as {@code int} bits
-     */
-    /*package*/ CstLiteral32(int bits) {
-        this.bits = bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean equals(Object other) {
-        return (other != null) &&
-            (getClass() == other.getClass()) &&
-            bits == ((CstLiteral32) other).bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int hashCode() {
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        int otherBits = ((CstLiteral32) other).bits;
-
-        if (bits < otherBits) {
-            return -1;
-        } else if (bits > otherBits) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean fitsInInt() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int getIntBits() {
-        return bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final long getLongBits() {
-        return (long) bits;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstLiteral64.java b/dx/src/main/java/com/android/dx/rop/cst/CstLiteral64.java
deleted file mode 100644
index 94cfa8c..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstLiteral64.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants which are literal 64-bit values of some sort.
- */
-public abstract class CstLiteral64
-        extends CstLiteralBits {
-    /** the value as {@code long} bits */
-    private final long bits;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param bits the value as {@code long} bits
-     */
-    /*package*/ CstLiteral64(long bits) {
-        this.bits = bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean equals(Object other) {
-        return (other != null) &&
-            (getClass() == other.getClass()) &&
-            bits == ((CstLiteral64) other).bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int hashCode() {
-        return (int) bits ^ (int) (bits >> 32);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        long otherBits = ((CstLiteral64) other).bits;
-
-        if (bits < otherBits) {
-            return -1;
-        } else if (bits > otherBits) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean isCategory2() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean fitsInInt() {
-        return (int) bits == bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int getIntBits() {
-        return (int) bits;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final long getLongBits() {
-        return bits;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstLiteralBits.java b/dx/src/main/java/com/android/dx/rop/cst/CstLiteralBits.java
deleted file mode 100644
index 8bf13a2..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstLiteralBits.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants which are literal bitwise values of some sort.
- */
-public abstract class CstLiteralBits
-        extends TypedConstant {
-    /**
-     * Returns whether or not this instance's value may be accurately
-     * represented as an {@code int}. The rule is that if there
-     * is an {@code int} which may be sign-extended to yield this
-     * instance's value, then this method returns {@code true}.
-     * Otherwise, it returns {@code false}.
-     *
-     * @return {@code true} iff this instance fits in an {@code int}
-     */
-    public abstract boolean fitsInInt();
-
-    /**
-     * Gets the value as {@code int} bits. If this instance contains
-     * more bits than fit in an {@code int}, then this returns only
-     * the low-order bits.
-     *
-     * @return the bits
-     */
-    public abstract int getIntBits();
-
-    /**
-     * Gets the value as {@code long} bits. If this instance contains
-     * fewer bits than fit in a {@code long}, then the result of this
-     * method is the sign extension of the value.
-     *
-     * @return the bits
-     */
-    public abstract long getLongBits();
-
-    /**
-     * Returns true if this value can fit in 16 bits with sign-extension.
-     *
-     * @return true if the sign-extended lower 16 bits are the same as
-     * the value.
-     */
-    public boolean fitsIn16Bits() {
-        if (! fitsInInt()) {
-            return false;
-        }
-
-        int bits = getIntBits();
-        return (short) bits == bits;
-    }
-
-    /**
-     * Returns true if this value can fit in 8 bits with sign-extension.
-     *
-     * @return true if the sign-extended lower 8 bits are the same as
-     * the value.
-     */
-    public boolean fitsIn8Bits() {
-        if (! fitsInInt()) {
-            return false;
-        }
-
-        int bits = getIntBits();
-        return (byte) bits == bits;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstLong.java b/dx/src/main/java/com/android/dx/rop/cst/CstLong.java
deleted file mode 100644
index d159529..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstLong.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code CONSTANT_Long_info}.
- */
-public final class CstLong
-        extends CstLiteral64 {
-    /** {@code non-null;} instance representing {@code 0} */
-    public static final CstLong VALUE_0 = make(0);
-
-    /** {@code non-null;} instance representing {@code 1} */
-    public static final CstLong VALUE_1 = make(1);
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param value the {@code long} value
-     */
-    public static CstLong make(long value) {
-        /*
-         * Note: Javadoc notwithstanding, this implementation always
-         * allocates.
-         */
-        return new CstLong(value);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code long} value
-     */
-    private CstLong(long value) {
-        super(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        long value = getLongBits();
-        return "long{0x" + Hex.u8(value) + " / " + value + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.LONG;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "long";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Long.toString(getLongBits());
-    }
-
-    /**
-     * Gets the {@code long} value.
-     *
-     * @return the value
-     */
-    public long getValue() {
-        return getLongBits();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstMemberRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstMemberRef.java
deleted file mode 100644
index 1775398..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstMemberRef.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants of type {@code CONSTANT_*ref_info}.
- */
-public abstract class CstMemberRef extends TypedConstant {
-    /** {@code non-null;} the type of the defining class */
-    private final CstType definingClass;
-
-    /** {@code non-null;} the name-and-type */
-    private final CstNat nat;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param definingClass {@code non-null;} the type of the defining class
-     * @param nat {@code non-null;} the name-and-type
-     */
-    /*package*/ CstMemberRef(CstType definingClass, CstNat nat) {
-        if (definingClass == null) {
-            throw new NullPointerException("definingClass == null");
-        }
-
-        if (nat == null) {
-            throw new NullPointerException("nat == null");
-        }
-
-        this.definingClass = definingClass;
-        this.nat = nat;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean equals(Object other) {
-        if ((other == null) || (getClass() != other.getClass())) {
-            return false;
-        }
-
-        CstMemberRef otherRef = (CstMemberRef) other;
-        return definingClass.equals(otherRef.definingClass) &&
-            nat.equals(otherRef.nat);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final int hashCode() {
-        return (definingClass.hashCode() * 31) ^ nat.hashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p><b>Note:</b> This implementation just compares the defining
-     * class and name, and it is up to subclasses to compare the rest
-     * after calling {@code super.compareTo0()}.</p>
-     */
-    @Override
-    protected int compareTo0(Constant other) {
-        CstMemberRef otherMember = (CstMemberRef) other;
-        int cmp = definingClass.compareTo(otherMember.definingClass);
-
-        if (cmp != 0) {
-            return cmp;
-        }
-
-        CstString thisName = nat.getName();
-        CstString otherName = otherMember.nat.getName();
-
-        return thisName.compareTo(otherName);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final String toString() {
-        return typeName() + '{' + toHuman() + '}';
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public final String toHuman() {
-        return definingClass.toHuman() + '.' + nat.toHuman();
-    }
-
-    /**
-     * Gets the type of the defining class.
-     *
-     * @return {@code non-null;} the type of defining class
-     */
-    public final CstType getDefiningClass() {
-        return definingClass;
-    }
-
-    /**
-     * Gets the defining name-and-type.
-     *
-     * @return {@code non-null;} the name-and-type
-     */
-    public final CstNat getNat() {
-        return nat;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstMethodRef.java b/dx/src/main/java/com/android/dx/rop/cst/CstMethodRef.java
deleted file mode 100644
index 075bc7c..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstMethodRef.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-/**
- * Constants of type {@code CONSTANT_Methodref_info}.
- */
-public final class CstMethodRef
-        extends CstBaseMethodRef {
-    /**
-     * Constructs an instance.
-     *
-     * @param definingClass {@code non-null;} the type of the defining class
-     * @param nat {@code non-null;} the name-and-type
-     */
-    public CstMethodRef(CstType definingClass, CstNat nat) {
-        super(definingClass, nat);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "method";
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstNat.java b/dx/src/main/java/com/android/dx/rop/cst/CstNat.java
deleted file mode 100644
index cd067e9..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstNat.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Constants of type {@code CONSTANT_NameAndType_info}.
- */
-public final class CstNat extends Constant {
-    /**
-     * {@code non-null;} the instance for name {@code TYPE} and descriptor
-     * {@code java.lang.Class}, which is useful when dealing with
-     * wrapped primitives
-     */
-    public static final CstNat PRIMITIVE_TYPE_NAT =
-        new CstNat(new CstString("TYPE"),
-                   new CstString("Ljava/lang/Class;"));
-
-    /** {@code non-null;} the name */
-    private final CstString name;
-
-    /** {@code non-null;} the descriptor (type) */
-    private final CstString descriptor;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param name {@code non-null;} the name
-     * @param descriptor {@code non-null;} the descriptor
-     */
-    public CstNat(CstString name, CstString descriptor) {
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor == null");
-        }
-
-        this.name = name;
-        this.descriptor = descriptor;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof CstNat)) {
-            return false;
-        }
-
-        CstNat otherNat = (CstNat) other;
-        return name.equals(otherNat.name) &&
-            descriptor.equals(otherNat.descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return (name.hashCode() * 31) ^ descriptor.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        CstNat otherNat = (CstNat) other;
-        int cmp = name.compareTo(otherNat.name);
-
-        if (cmp != 0) {
-            return cmp;
-        }
-
-        return descriptor.compareTo(otherNat.descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "nat{" + toHuman() + '}';
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "nat";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /**
-     * Gets the name.
-     *
-     * @return {@code non-null;} the name
-     */
-    public CstString getName() {
-        return name;
-    }
-
-    /**
-     * Gets the descriptor.
-     *
-     * @return {@code non-null;} the descriptor
-     */
-    public CstString getDescriptor() {
-        return descriptor;
-    }
-
-    /**
-     * Returns an unadorned but human-readable version of the name-and-type
-     * value.
-     *
-     * @return {@code non-null;} the human form
-     */
-    public String toHuman() {
-        return name.toHuman() + ':' + descriptor.toHuman();
-    }
-
-    /**
-     * Gets the field type corresponding to this instance's descriptor.
-     * This method is only valid to call if the descriptor in fact describes
-     * a field (and not a method).
-     *
-     * @return {@code non-null;} the field type
-     */
-    public Type getFieldType() {
-        return Type.intern(descriptor.getString());
-    }
-
-    /**
-     * Gets whether this instance has the name of a standard instance
-     * initialization method. This is just a convenient shorthand for
-     * {@code getName().getString().equals("<init>")}.
-     *
-     * @return {@code true} iff this is a reference to an
-     * instance initialization method
-     */
-    public final boolean isInstanceInit() {
-        return name.getString().equals("<init>");
-    }
-
-    /**
-     * Gets whether this instance has the name of a standard class
-     * initialization method. This is just a convenient shorthand for
-     * {@code getName().getString().equals("<clinit>")}.
-     *
-     * @return {@code true} iff this is a reference to an
-     * instance initialization method
-     */
-    public final boolean isClassInit() {
-        return name.getString().equals("<clinit>");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstShort.java b/dx/src/main/java/com/android/dx/rop/cst/CstShort.java
deleted file mode 100644
index 5be1022..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstShort.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code short}.
- */
-public final class CstShort
-        extends CstLiteral32 {
-    /** {@code non-null;} the value {@code 0} as an instance of this class */
-    public static final CstShort VALUE_0 = make((short) 0);
-
-    /**
-     * Makes an instance for the given value. This may (but does not
-     * necessarily) return an already-allocated instance.
-     *
-     * @param value the {@code short} value
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstShort make(short value) {
-        return new CstShort(value);
-    }
-
-    /**
-     * Makes an instance for the given {@code int} value. This
-     * may (but does not necessarily) return an already-allocated
-     * instance.
-     *
-     * @param value the value, which must be in range for a {@code short}
-     * @return {@code non-null;} the appropriate instance
-     */
-    public static CstShort make(int value) {
-        short cast = (short) value;
-
-        if (cast != value) {
-            throw new IllegalArgumentException("bogus short value: " +
-                    value);
-        }
-
-        return make(cast);
-    }
-
-    /**
-     * Constructs an instance. This constructor is private; use {@link #make}.
-     *
-     * @param value the {@code short} value
-     */
-    private CstShort(short value) {
-        super(value);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        int value = getIntBits();
-        return "short{0x" + Hex.u2(value) + " / " + value + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.SHORT;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "short";
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return Integer.toString(getIntBits());
-    }
-
-    /**
-     * Gets the {@code short} value.
-     *
-     * @return the value
-     */
-    public short getValue() {
-        return (short) getIntBits();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstString.java b/dx/src/main/java/com/android/dx/rop/cst/CstString.java
deleted file mode 100644
index a778e97..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstString.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.ByteArray;
-import com.android.dx.util.Hex;
-
-/**
- * Constants of type {@code CONSTANT_Utf8_info} or {@code CONSTANT_String_info}.
- */
-public final class CstString extends TypedConstant {
-    /**
-     * {@code non-null;} instance representing {@code ""}, that is, the
-     * empty string
-     */
-    public static final CstString EMPTY_STRING = new CstString("");
-
-    /** {@code non-null;} the UTF-8 value as a string */
-    private final String string;
-
-    /** {@code non-null;} the UTF-8 value as bytes */
-    private final ByteArray bytes;
-
-    /**
-     * Converts a string into its MUTF-8 form. MUTF-8 differs from normal UTF-8
-     * in the handling of character '\0' and surrogate pairs.
-     *
-     * @param string {@code non-null;} the string to convert
-     * @return {@code non-null;} the UTF-8 bytes for it
-     */
-    public static byte[] stringToUtf8Bytes(String string) {
-        int len = string.length();
-        byte[] bytes = new byte[len * 3]; // Avoid having to reallocate.
-        int outAt = 0;
-
-        for (int i = 0; i < len; i++) {
-            char c = string.charAt(i);
-            if ((c != 0) && (c < 0x80)) {
-                bytes[outAt] = (byte) c;
-                outAt++;
-            } else if (c < 0x800) {
-                bytes[outAt] = (byte) (((c >> 6) & 0x1f) | 0xc0);
-                bytes[outAt + 1] = (byte) ((c & 0x3f) | 0x80);
-                outAt += 2;
-            } else {
-                bytes[outAt] = (byte) (((c >> 12) & 0x0f) | 0xe0);
-                bytes[outAt + 1] = (byte) (((c >> 6) & 0x3f) | 0x80);
-                bytes[outAt + 2] = (byte) ((c & 0x3f) | 0x80);
-                outAt += 3;
-            }
-        }
-
-        byte[] result = new byte[outAt];
-        System.arraycopy(bytes, 0, result, 0, outAt);
-        return result;
-    }
-
-    /**
-     * Converts an array of UTF-8 bytes into a string.
-     *
-     * @param bytes {@code non-null;} the bytes to convert
-     * @return {@code non-null;} the converted string
-     */
-    public static String utf8BytesToString(ByteArray bytes) {
-        int length = bytes.size();
-        char[] chars = new char[length]; // This is sized to avoid a realloc.
-        int outAt = 0;
-
-        for (int at = 0; length > 0; /*at*/) {
-            int v0 = bytes.getUnsignedByte(at);
-            char out;
-            switch (v0 >> 4) {
-                case 0x00: case 0x01: case 0x02: case 0x03:
-                case 0x04: case 0x05: case 0x06: case 0x07: {
-                    // 0XXXXXXX -- single-byte encoding
-                    length--;
-                    if (v0 == 0) {
-                        // A single zero byte is illegal.
-                        return throwBadUtf8(v0, at);
-                    }
-                    out = (char) v0;
-                    at++;
-                    break;
-                }
-                case 0x0c: case 0x0d: {
-                    // 110XXXXX -- two-byte encoding
-                    length -= 2;
-                    if (length < 0) {
-                        return throwBadUtf8(v0, at);
-                    }
-                    int v1 = bytes.getUnsignedByte(at + 1);
-                    if ((v1 & 0xc0) != 0x80) {
-                        return throwBadUtf8(v1, at + 1);
-                    }
-                    int value = ((v0 & 0x1f) << 6) | (v1 & 0x3f);
-                    if ((value != 0) && (value < 0x80)) {
-                        /*
-                         * This should have been represented with
-                         * one-byte encoding.
-                         */
-                        return throwBadUtf8(v1, at + 1);
-                    }
-                    out = (char) value;
-                    at += 2;
-                    break;
-                }
-                case 0x0e: {
-                    // 1110XXXX -- three-byte encoding
-                    length -= 3;
-                    if (length < 0) {
-                        return throwBadUtf8(v0, at);
-                    }
-                    int v1 = bytes.getUnsignedByte(at + 1);
-                    if ((v1 & 0xc0) != 0x80) {
-                        return throwBadUtf8(v1, at + 1);
-                    }
-                    int v2 = bytes.getUnsignedByte(at + 2);
-                    if ((v1 & 0xc0) != 0x80) {
-                        return throwBadUtf8(v2, at + 2);
-                    }
-                    int value = ((v0 & 0x0f) << 12) | ((v1 & 0x3f) << 6) |
-                        (v2 & 0x3f);
-                    if (value < 0x800) {
-                        /*
-                         * This should have been represented with one- or
-                         * two-byte encoding.
-                         */
-                        return throwBadUtf8(v2, at + 2);
-                    }
-                    out = (char) value;
-                    at += 3;
-                    break;
-                }
-                default: {
-                    // 10XXXXXX, 1111XXXX -- illegal
-                    return throwBadUtf8(v0, at);
-                }
-            }
-            chars[outAt] = out;
-            outAt++;
-        }
-
-        return new String(chars, 0, outAt);
-    }
-
-    /**
-     * Helper for {@link #utf8BytesToString}, which throws the right
-     * exception for a bogus utf-8 byte.
-     *
-     * @param value the byte value
-     * @param offset the file offset
-     * @return never
-     * @throws IllegalArgumentException always thrown
-     */
-    private static String throwBadUtf8(int value, int offset) {
-        throw new IllegalArgumentException("bad utf-8 byte " + Hex.u1(value) +
-                                           " at offset " + Hex.u4(offset));
-    }
-
-    /**
-     * Constructs an instance from a {@code String}.
-     *
-     * @param string {@code non-null;} the UTF-8 value as a string
-     */
-    public CstString(String string) {
-        if (string == null) {
-            throw new NullPointerException("string == null");
-        }
-
-        this.string = string.intern();
-        this.bytes = new ByteArray(stringToUtf8Bytes(string));
-    }
-
-    /**
-     * Constructs an instance from some UTF-8 bytes.
-     *
-     * @param bytes {@code non-null;} array of the UTF-8 bytes
-     */
-    public CstString(ByteArray bytes) {
-        if (bytes == null) {
-            throw new NullPointerException("bytes == null");
-        }
-
-        this.bytes = bytes;
-        this.string = utf8BytesToString(bytes).intern();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof CstString)) {
-            return false;
-        }
-
-        return string.equals(((CstString) other).string);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return string.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        return string.compareTo(((CstString) other).string);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "string{\"" + toHuman() + "\"}";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "utf8";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        int len = string.length();
-        StringBuilder sb = new StringBuilder(len * 3 / 2);
-
-        for (int i = 0; i < len; i++) {
-            char c = string.charAt(i);
-            if ((c >= ' ') && (c < 0x7f)) {
-                if ((c == '\'') || (c == '\"') || (c == '\\')) {
-                    sb.append('\\');
-                }
-                sb.append(c);
-            } else if (c <= 0x7f) {
-                switch (c) {
-                    case '\n': sb.append("\\n"); break;
-                    case '\r': sb.append("\\r"); break;
-                    case '\t': sb.append("\\t"); break;
-                    default: {
-                        /*
-                         * Represent the character as an octal escape.
-                         * If the next character is a valid octal
-                         * digit, disambiguate by using the
-                         * three-digit form.
-                         */
-                        char nextChar =
-                            (i < (len - 1)) ? string.charAt(i + 1) : 0;
-                        boolean displayZero =
-                            (nextChar >= '0') && (nextChar <= '7');
-                        sb.append('\\');
-                        for (int shift = 6; shift >= 0; shift -= 3) {
-                            char outChar = (char) (((c >> shift) & 7) + '0');
-                            if ((outChar != '0') || displayZero) {
-                                sb.append(outChar);
-                                displayZero = true;
-                            }
-                        }
-                        if (! displayZero) {
-                            // Ironic edge case: The original value was 0.
-                            sb.append('0');
-                        }
-                        break;
-                    }
-                }
-            } else {
-                sb.append("\\u");
-                sb.append(Character.forDigit(c >> 12, 16));
-                sb.append(Character.forDigit((c >> 8) & 0x0f, 16));
-                sb.append(Character.forDigit((c >> 4) & 0x0f, 16));
-                sb.append(Character.forDigit(c & 0x0f, 16));
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets the value as a human-oriented string, surrounded by double
-     * quotes.
-     *
-     * @return {@code non-null;} the quoted string
-     */
-    public String toQuoted() {
-        return '\"' + toHuman() + '\"';
-    }
-
-    /**
-     * Gets the value as a human-oriented string, surrounded by double
-     * quotes, but ellipsizes the result if it is longer than the given
-     * maximum length
-     *
-     * @param maxLength {@code >= 5;} the maximum length of the string to return
-     * @return {@code non-null;} the quoted string
-     */
-    public String toQuoted(int maxLength) {
-        String string = toHuman();
-        int length = string.length();
-        String ellipses;
-
-        if (length <= (maxLength - 2)) {
-            ellipses = "";
-        } else {
-            string = string.substring(0, maxLength - 5);
-            ellipses = "...";
-        }
-
-        return '\"' + string + ellipses + '\"';
-    }
-
-    /**
-     * Gets the UTF-8 value as a string.
-     * The returned string is always already interned.
-     *
-     * @return {@code non-null;} the UTF-8 value as a string
-     */
-    public String getString() {
-        return string;
-    }
-
-    /**
-     * Gets the UTF-8 value as UTF-8 encoded bytes.
-     *
-     * @return {@code non-null;} an array of the UTF-8 bytes
-     */
-    public ByteArray getBytes() {
-        return bytes;
-    }
-
-    /**
-     * Gets the size of this instance as UTF-8 code points. That is,
-     * get the number of bytes in the UTF-8 encoding of this instance.
-     *
-     * @return {@code >= 0;} the UTF-8 size
-     */
-    public int getUtf8Size() {
-        return bytes.size();
-    }
-
-    /**
-     * Gets the size of this instance as UTF-16 code points. That is,
-     * get the number of 16-bit chars in the UTF-16 encoding of this
-     * instance. This is the same as the {@code length} of the
-     * Java {@code String} representation of this instance.
-     *
-     * @return {@code >= 0;} the UTF-16 size
-     */
-    public int getUtf16Size() {
-        return string.length();
-    }
-
-    public Type getType() {
-        return Type.STRING;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/CstType.java b/dx/src/main/java/com/android/dx/rop/cst/CstType.java
deleted file mode 100644
index 8624028..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/CstType.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-import java.util.HashMap;
-
-/**
- * Constants that represent an arbitrary type (reference or primitive).
- */
-public final class CstType extends TypedConstant {
-    /** {@code non-null;} map of interned types */
-    private static final HashMap<Type, CstType> interns =
-        new HashMap<Type, CstType>(100);
-
-    /** {@code non-null;} instance corresponding to the class {@code Object} */
-    public static final CstType OBJECT = intern(Type.OBJECT);
-
-    /** {@code non-null;} instance corresponding to the class {@code Boolean} */
-    public static final CstType BOOLEAN = intern(Type.BOOLEAN_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Byte} */
-    public static final CstType BYTE = intern(Type.BYTE_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Character} */
-    public static final CstType CHARACTER = intern(Type.CHARACTER_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Double} */
-    public static final CstType DOUBLE = intern(Type.DOUBLE_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Float} */
-    public static final CstType FLOAT = intern(Type.FLOAT_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Long} */
-    public static final CstType LONG = intern(Type.LONG_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Integer} */
-    public static final CstType INTEGER = intern(Type.INTEGER_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Short} */
-    public static final CstType SHORT = intern(Type.SHORT_CLASS);
-
-    /** {@code non-null;} instance corresponding to the class {@code Void} */
-    public static final CstType VOID = intern(Type.VOID_CLASS);
-
-    /** {@code non-null;} instance corresponding to the type {@code boolean[]} */
-    public static final CstType BOOLEAN_ARRAY = intern(Type.BOOLEAN_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code byte[]} */
-    public static final CstType BYTE_ARRAY = intern(Type.BYTE_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code char[]} */
-    public static final CstType CHAR_ARRAY = intern(Type.CHAR_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code double[]} */
-    public static final CstType DOUBLE_ARRAY = intern(Type.DOUBLE_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code float[]} */
-    public static final CstType FLOAT_ARRAY = intern(Type.FLOAT_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code long[]} */
-    public static final CstType LONG_ARRAY = intern(Type.LONG_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code int[]} */
-    public static final CstType INT_ARRAY = intern(Type.INT_ARRAY);
-
-    /** {@code non-null;} instance corresponding to the type {@code short[]} */
-    public static final CstType SHORT_ARRAY = intern(Type.SHORT_ARRAY);
-
-    /** {@code non-null;} the underlying type */
-    private final Type type;
-
-    /**
-     * {@code null-ok;} the type descriptor corresponding to this instance, if
-     * calculated
-     */
-    private CstString descriptor;
-
-    /**
-     * Returns an instance of this class that represents the wrapper
-     * class corresponding to a given primitive type. For example, if
-     * given {@link Type#INT}, this method returns the class reference
-     * {@code java.lang.Integer}.
-     *
-     * @param primitiveType {@code non-null;} the primitive type
-     * @return {@code non-null;} the corresponding wrapper class
-     */
-    public static CstType forBoxedPrimitiveType(Type primitiveType) {
-        switch (primitiveType.getBasicType()) {
-            case Type.BT_BOOLEAN: return BOOLEAN;
-            case Type.BT_BYTE:    return BYTE;
-            case Type.BT_CHAR:    return CHARACTER;
-            case Type.BT_DOUBLE:  return DOUBLE;
-            case Type.BT_FLOAT:   return FLOAT;
-            case Type.BT_INT:     return INTEGER;
-            case Type.BT_LONG:    return LONG;
-            case Type.BT_SHORT:   return SHORT;
-            case Type.BT_VOID:    return VOID;
-        }
-
-        throw new IllegalArgumentException("not primitive: " + primitiveType);
-    }
-
-    /**
-     * Returns an interned instance of this class for the given type.
-     *
-     * @param type {@code non-null;} the underlying type
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static CstType intern(Type type) {
-        synchronized (interns) {
-            CstType cst = interns.get(type);
-
-            if (cst == null) {
-                cst = new CstType(type);
-                interns.put(type, cst);
-            }
-
-            return cst;
-        }
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param type {@code non-null;} the underlying type
-     */
-    public CstType(Type type) {
-        if (type == null) {
-            throw new NullPointerException("type == null");
-        }
-
-        if (type == type.KNOWN_NULL) {
-            throw new UnsupportedOperationException(
-                    "KNOWN_NULL is not representable");
-        }
-
-        this.type = type;
-        this.descriptor = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof CstType)) {
-            return false;
-        }
-
-        return type == ((CstType) other).type;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return type.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected int compareTo0(Constant other) {
-        String thisDescriptor = type.getDescriptor();
-        String otherDescriptor = ((CstType) other).type.getDescriptor();
-        return thisDescriptor.compareTo(otherDescriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "type{" + toHuman() + '}';
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return Type.CLASS;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String typeName() {
-        return "type";
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCategory2() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return type.toHuman();
-    }
-
-    /**
-     * Gets the underlying type (as opposed to the type corresponding
-     * to this instance as a constant, which is always
-     * {@code Class}).
-     *
-     * @return {@code non-null;} the type corresponding to the name
-     */
-    public Type getClassType() {
-        return type;
-    }
-
-    /**
-     * Gets the type descriptor for this instance.
-     *
-     * @return {@code non-null;} the descriptor
-     */
-    public CstString getDescriptor() {
-        if (descriptor == null) {
-            descriptor = new CstString(type.getDescriptor());
-        }
-
-        return descriptor;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/StdConstantPool.java b/dx/src/main/java/com/android/dx/rop/cst/StdConstantPool.java
deleted file mode 100644
index 244395d..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/StdConstantPool.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.util.ExceptionWithContext;
-import com.android.dx.util.Hex;
-import com.android.dx.util.MutabilityControl;
-
-/**
- * Standard implementation of {@link ConstantPool}, which directly stores
- * an array of {@link Constant} objects and can be made immutable.
- */
-public final class StdConstantPool
-        extends MutabilityControl implements ConstantPool {
-    /** {@code non-null;} array of entries */
-    private final Constant[] entries;
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the pool; this corresponds to the
-     * class file field {@code constant_pool_count}, and is in fact
-     * always at least one more than the actual size of the constant pool,
-     * as element {@code 0} is always invalid.
-     */
-    public StdConstantPool(int size) {
-        super(size > 1);
-
-        if (size < 1) {
-            throw new IllegalArgumentException("size < 1");
-        }
-
-        entries = new Constant[size];
-    }
-
-    /** {@inheritDoc} */
-    public int size() {
-        return entries.length;
-    }
-
-    /** {@inheritDoc} */
-    public Constant getOrNull(int n) {
-        try {
-            return entries[n];
-        } catch (IndexOutOfBoundsException ex) {
-            // Translate the exception.
-            return throwInvalid(n);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public Constant get0Ok(int n) {
-        if (n == 0) {
-            return null;
-        }
-
-        return get(n);
-    }
-
-    /** {@inheritDoc} */
-    public Constant get(int n) {
-        try {
-            Constant result = entries[n];
-
-            if (result == null) {
-                throwInvalid(n);
-            }
-
-            return result;
-        } catch (IndexOutOfBoundsException ex) {
-            // Translate the exception.
-            return throwInvalid(n);
-        }
-    }
-
-    /**
-     * Sets the entry at the given index.
-     *
-     * @param n {@code >= 1, < size();} which entry
-     * @param cst {@code null-ok;} the constant to store
-     */
-    public void set(int n, Constant cst) {
-        throwIfImmutable();
-
-        boolean cat2 = (cst != null) && cst.isCategory2();
-
-        if (n < 1) {
-            throw new IllegalArgumentException("n < 1");
-        }
-
-        if (cat2) {
-            // Storing a category-2 entry nulls out the next index.
-            if (n == (entries.length - 1)) {
-                throw new IllegalArgumentException("(n == size - 1) && " +
-                                                   "cst.isCategory2()");
-            }
-            entries[n + 1] = null;
-        }
-
-        if ((cst != null) && (entries[n] == null)) {
-            /*
-             * Overwriting the second half of a category-2 entry nulls out
-             * the first half.
-             */
-            Constant prev = entries[n - 1];
-            if ((prev != null) && prev.isCategory2()) {
-                entries[n - 1] = null;
-            }
-        }
-
-        entries[n] = cst;
-    }
-
-    /**
-     * Throws the right exception for an invalid cpi.
-     *
-     * @param idx the bad cpi
-     * @return never
-     * @throws ExceptionWithContext always thrown
-     */
-    private static Constant throwInvalid(int idx) {
-        throw new ExceptionWithContext("invalid constant pool index " +
-                                       Hex.u2(idx));
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/TypedConstant.java b/dx/src/main/java/com/android/dx/rop/cst/TypedConstant.java
deleted file mode 100644
index 1c738ee..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/TypedConstant.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.cst;
-
-import com.android.dx.rop.type.TypeBearer;
-
-/**
- * Base class for constants which implement {@link TypeBearer}.
- */
-public abstract class TypedConstant
-        extends Constant implements TypeBearer {
-    /**
-     * {@inheritDoc}
-     *
-     * This implementation always returns {@code this}.
-     */
-    public final TypeBearer getFrameType() {
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    public final int getBasicType() {
-        return getType().getBasicType();
-    }
-
-    /** {@inheritDoc} */
-    public final int getBasicFrameType() {
-        return getType().getBasicFrameType();
-    }
-
-    /** {@inheritDoc} */
-    public final boolean isConstant() {
-        return true;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/cst/Zeroes.java b/dx/src/main/java/com/android/dx/rop/cst/Zeroes.java
deleted file mode 100644
index 7250b5a..0000000
--- a/dx/src/main/java/com/android/dx/rop/cst/Zeroes.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008 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.rop.cst;
-
-import com.android.dx.rop.type.Type;
-
-/**
- * Utility for turning types into zeroes.
- */
-public final class Zeroes {
-    /**
-     * This class is uninstantiable.
-     */
-    private Zeroes() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Gets the "zero" (or {@code null}) value for the given type.
-     *
-     * @param type {@code non-null;} the type in question
-     * @return {@code non-null;} its "zero" value
-     */
-    public static Constant zeroFor(Type type) {
-        switch (type.getBasicType()) {
-            case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;
-            case Type.BT_BYTE:    return CstByte.VALUE_0;
-            case Type.BT_CHAR:    return CstChar.VALUE_0;
-            case Type.BT_DOUBLE:  return CstDouble.VALUE_0;
-            case Type.BT_FLOAT:   return CstFloat.VALUE_0;
-            case Type.BT_INT:     return CstInteger.VALUE_0;
-            case Type.BT_LONG:    return CstLong.VALUE_0;
-            case Type.BT_SHORT:   return CstShort.VALUE_0;
-            case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;
-            default: {
-                throw new UnsupportedOperationException("no zero for type: " +
-                        type.toHuman());
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/type/Prototype.java b/dx/src/main/java/com/android/dx/rop/type/Prototype.java
deleted file mode 100644
index 3fc5d82..0000000
--- a/dx/src/main/java/com/android/dx/rop/type/Prototype.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.type;
-
-import java.util.HashMap;
-
-/**
- * Representation of a method descriptor. Instances of this class are
- * generally interned and may be usefully compared with each other
- * using {@code ==}.
- */
-public final class Prototype implements Comparable<Prototype> {
-    /** {@code non-null;} intern table mapping string descriptors to instances */
-    private static final HashMap<String, Prototype> internTable =
-        new HashMap<String, Prototype>(500);
-
-    /** {@code non-null;} method descriptor */
-    private final String descriptor;
-
-    /** {@code non-null;} return type */
-    private final Type returnType;
-
-    /** {@code non-null;} list of parameter types */
-    private final StdTypeList parameterTypes;
-
-    /** {@code null-ok;} list of parameter frame types, if calculated */
-    private StdTypeList parameterFrameTypes;
-
-    /**
-     * Returns the unique instance corresponding to the
-     * given method descriptor. See vmspec-2 sec4.3.3 for details on the
-     * field descriptor syntax.
-     *
-     * @param descriptor {@code non-null;} the descriptor
-     * @return {@code non-null;} the corresponding instance
-     * @throws IllegalArgumentException thrown if the descriptor has
-     * invalid syntax
-     */
-    public static Prototype intern(String descriptor) {
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor == null");
-        }
-
-        Prototype result;
-        synchronized (internTable) {
-            result = internTable.get(descriptor);
-        }
-        if (result != null) {
-            return result;
-        }
-
-        Type[] params = makeParameterArray(descriptor);
-        int paramCount = 0;
-        int at = 1;
-
-        for (;;) {
-            int startAt = at;
-            char c = descriptor.charAt(at);
-            if (c == ')') {
-                at++;
-                break;
-            }
-
-            // Skip array markers.
-            while (c == '[') {
-                at++;
-                c = descriptor.charAt(at);
-            }
-
-            if (c == 'L') {
-                // It looks like the start of a class name; find the end.
-                int endAt = descriptor.indexOf(';', at);
-                if (endAt == -1) {
-                    throw new IllegalArgumentException("bad descriptor");
-                }
-                at = endAt + 1;
-            } else {
-                at++;
-            }
-
-            params[paramCount] =
-                Type.intern(descriptor.substring(startAt, at));
-            paramCount++;
-        }
-
-        Type returnType = Type.internReturnType(descriptor.substring(at));
-        StdTypeList parameterTypes = new StdTypeList(paramCount);
-
-        for (int i = 0; i < paramCount; i++) {
-            parameterTypes.set(i, params[i]);
-        }
-
-        result = new Prototype(descriptor, returnType, parameterTypes);
-        return putIntern(result);
-    }
-
-    /**
-     * Helper for {@link #intern} which returns an empty array to
-     * populate with parsed parameter types, and which also ensures
-     * that there is a '(' at the start of the descriptor and a
-     * single ')' somewhere before the end.
-     *
-     * @param descriptor {@code non-null;} the descriptor string
-     * @return {@code non-null;} array large enough to hold all parsed parameter
-     * types, but which is likely actually larger than needed
-     */
-    private static Type[] makeParameterArray(String descriptor) {
-        int length = descriptor.length();
-
-        if (descriptor.charAt(0) != '(') {
-            throw new IllegalArgumentException("bad descriptor");
-        }
-
-        /*
-         * This is a cheesy way to establish an upper bound on the
-         * number of parameters: Just count capital letters.
-         */
-        int closeAt = 0;
-        int maxParams = 0;
-        for (int i = 1; i < length; i++) {
-            char c = descriptor.charAt(i);
-            if (c == ')') {
-                closeAt = i;
-                break;
-            }
-            if ((c >= 'A') && (c <= 'Z')) {
-                maxParams++;
-            }
-        }
-
-        if ((closeAt == 0) || (closeAt == (length - 1))) {
-            throw new IllegalArgumentException("bad descriptor");
-        }
-
-        if (descriptor.indexOf(')', closeAt + 1) != -1) {
-            throw new IllegalArgumentException("bad descriptor");
-        }
-
-        return new Type[maxParams];
-    }
-
-    /**
-     * Interns an instance, adding to the descriptor as necessary based
-     * on the given definer, name, and flags. For example, an init
-     * method has an uninitialized object of type {@code definer}
-     * as its first argument.
-     *
-     * @param descriptor {@code non-null;} the descriptor string
-     * @param definer {@code non-null;} class the method is defined on
-     * @param isStatic whether this is a static method
-     * @param isInit whether this is an init method
-     * @return {@code non-null;} the interned instance
-     */
-    public static Prototype intern(String descriptor, Type definer,
-            boolean isStatic, boolean isInit) {
-        Prototype base = intern(descriptor);
-
-        if (isStatic) {
-            return base;
-        }
-
-        if (isInit) {
-            definer = definer.asUninitialized(Integer.MAX_VALUE);
-        }
-
-        return base.withFirstParameter(definer);
-    }
-
-    /**
-     * Interns an instance which consists of the given number of
-     * {@code int}s along with the given return type
-     *
-     * @param returnType {@code non-null;} the return type
-     * @param count {@code > 0;} the number of elements in the prototype
-     * @return {@code non-null;} the interned instance
-     */
-    public static Prototype internInts(Type returnType, int count) {
-        // Make the descriptor...
-
-        StringBuffer sb = new StringBuffer(100);
-
-        sb.append('(');
-
-        for (int i = 0; i < count; i++) {
-            sb.append('I');
-        }
-
-        sb.append(')');
-        sb.append(returnType.getDescriptor());
-
-        // ...and intern it.
-        return intern(sb.toString());
-    }
-
-    /**
-     * Constructs an instance. This is a private constructor; use one
-     * of the public static methods to get instances.
-     *
-     * @param descriptor {@code non-null;} the descriptor string
-     */
-    private Prototype(String descriptor, Type returnType,
-            StdTypeList parameterTypes) {
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor == null");
-        }
-
-        if (returnType == null) {
-            throw new NullPointerException("returnType == null");
-        }
-
-        if (parameterTypes == null) {
-            throw new NullPointerException("parameterTypes == null");
-        }
-
-        this.descriptor = descriptor;
-        this.returnType = returnType;
-        this.parameterTypes = parameterTypes;
-        this.parameterFrameTypes = null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            /*
-             * Since externally-visible instances are interned, this
-             * check helps weed out some easy cases.
-             */
-            return true;
-        }
-
-        if (!(other instanceof Prototype)) {
-            return false;
-        }
-
-        return descriptor.equals(((Prototype) other).descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return descriptor.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(Prototype other) {
-        if (this == other) {
-            return 0;
-        }
-
-        /*
-         * The return type is the major order, and then args in order,
-         * and then the shorter list comes first (similar to string
-         * sorting).
-         */
-
-        int result = returnType.compareTo(other.returnType);
-
-        if (result != 0) {
-            return result;
-        }
-
-        int thisSize = parameterTypes.size();
-        int otherSize = other.parameterTypes.size();
-        int size = Math.min(thisSize, otherSize);
-
-        for (int i = 0; i < size; i++) {
-            Type thisType = parameterTypes.get(i);
-            Type otherType = other.parameterTypes.get(i);
-
-            result = thisType.compareTo(otherType);
-
-            if (result != 0) {
-                return result;
-            }
-        }
-
-        if (thisSize < otherSize) {
-            return -1;
-        } else if (thisSize > otherSize) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return descriptor;
-    }
-
-    /**
-     * Gets the descriptor string.
-     *
-     * @return {@code non-null;} the descriptor
-     */
-    public String getDescriptor() {
-        return descriptor;
-    }
-
-    /**
-     * Gets the return type.
-     *
-     * @return {@code non-null;} the return type
-     */
-    public Type getReturnType() {
-        return returnType;
-    }
-
-    /**
-     * Gets the list of parameter types.
-     *
-     * @return {@code non-null;} the list of parameter types
-     */
-    public StdTypeList getParameterTypes() {
-        return parameterTypes;
-    }
-
-    /**
-     * Gets the list of frame types corresponding to the list of parameter
-     * types. The difference between the two lists (if any) is that all
-     * "intlike" types (see {@link Type#isIntlike}) are replaced by
-     * {@link Type#INT}.
-     *
-     * @return {@code non-null;} the list of parameter frame types
-     */
-    public StdTypeList getParameterFrameTypes() {
-        if (parameterFrameTypes == null) {
-            int sz = parameterTypes.size();
-            StdTypeList list = new StdTypeList(sz);
-            boolean any = false;
-            for (int i = 0; i < sz; i++) {
-                Type one = parameterTypes.get(i);
-                if (one.isIntlike()) {
-                    any = true;
-                    one = Type.INT;
-                }
-                list.set(i, one);
-            }
-            parameterFrameTypes = any ? list : parameterTypes;
-        }
-
-        return parameterFrameTypes;
-    }
-
-    /**
-     * Returns a new interned instance, which is the same as this instance,
-     * except that it has an additional parameter prepended to the original's
-     * argument list.
-     *
-     * @param param {@code non-null;} the new first parameter
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public Prototype withFirstParameter(Type param) {
-        String newDesc = "(" + param.getDescriptor() + descriptor.substring(1);
-        StdTypeList newParams = parameterTypes.withFirst(param);
-
-        newParams.setImmutable();
-
-        Prototype result =
-            new Prototype(newDesc, returnType, newParams);
-
-        return putIntern(result);
-    }
-
-    /**
-     * Puts the given instance in the intern table if it's not already
-     * there. If a conflicting value is already in the table, then leave it.
-     * Return the interned value.
-     *
-     * @param desc {@code non-null;} instance to make interned
-     * @return {@code non-null;} the actual interned object
-     */
-    private static Prototype putIntern(Prototype desc) {
-        synchronized (internTable) {
-            String descriptor = desc.getDescriptor();
-            Prototype already = internTable.get(descriptor);
-            if (already != null) {
-                return already;
-            }
-            internTable.put(descriptor, desc);
-            return desc;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/type/StdTypeList.java b/dx/src/main/java/com/android/dx/rop/type/StdTypeList.java
deleted file mode 100644
index fe6647c..0000000
--- a/dx/src/main/java/com/android/dx/rop/type/StdTypeList.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.type;
-
-import com.android.dx.util.FixedSizeList;
-
-/**
- * Standard implementation of {@link TypeList}.
- */
-public final class StdTypeList
-        extends FixedSizeList implements TypeList {
-    /** {@code non-null;} no-element instance */
-    public static final StdTypeList EMPTY = new StdTypeList(0);
-
-    /** {@code non-null;} the list {@code [int]} */
-    public static final StdTypeList INT = StdTypeList.make(Type.INT);
-
-    /** {@code non-null;} the list {@code [long]} */
-    public static final StdTypeList LONG = StdTypeList.make(Type.LONG);
-
-    /** {@code non-null;} the list {@code [float]} */
-    public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT);
-
-    /** {@code non-null;} the list {@code [double]} */
-    public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE);
-
-    /** {@code non-null;} the list {@code [Object]} */
-    public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [ReturnAddress]} */
-    public static final StdTypeList RETURN_ADDRESS
-            = StdTypeList.make(Type.RETURN_ADDRESS);
-
-    /** {@code non-null;} the list {@code [Throwable]} */
-    public static final StdTypeList THROWABLE =
-        StdTypeList.make(Type.THROWABLE);
-
-    /** {@code non-null;} the list {@code [int, int]} */
-    public static final StdTypeList INT_INT =
-        StdTypeList.make(Type.INT, Type.INT);
-
-    /** {@code non-null;} the list {@code [long, long]} */
-    public static final StdTypeList LONG_LONG =
-        StdTypeList.make(Type.LONG, Type.LONG);
-
-    /** {@code non-null;} the list {@code [float, float]} */
-    public static final StdTypeList FLOAT_FLOAT =
-        StdTypeList.make(Type.FLOAT, Type.FLOAT);
-
-    /** {@code non-null;} the list {@code [double, double]} */
-    public static final StdTypeList DOUBLE_DOUBLE =
-        StdTypeList.make(Type.DOUBLE, Type.DOUBLE);
-
-    /** {@code non-null;} the list {@code [Object, Object]} */
-    public static final StdTypeList OBJECT_OBJECT =
-        StdTypeList.make(Type.OBJECT, Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [int, Object]} */
-    public static final StdTypeList INT_OBJECT =
-        StdTypeList.make(Type.INT, Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [long, Object]} */
-    public static final StdTypeList LONG_OBJECT =
-        StdTypeList.make(Type.LONG, Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [float, Object]} */
-    public static final StdTypeList FLOAT_OBJECT =
-        StdTypeList.make(Type.FLOAT, Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [double, Object]} */
-    public static final StdTypeList DOUBLE_OBJECT =
-        StdTypeList.make(Type.DOUBLE, Type.OBJECT);
-
-    /** {@code non-null;} the list {@code [long, int]} */
-    public static final StdTypeList LONG_INT =
-        StdTypeList.make(Type.LONG, Type.INT);
-
-    /** {@code non-null;} the list {@code [int[], int]} */
-    public static final StdTypeList INTARR_INT =
-        StdTypeList.make(Type.INT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [long[], int]} */
-    public static final StdTypeList LONGARR_INT =
-        StdTypeList.make(Type.LONG_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [float[], int]} */
-    public static final StdTypeList FLOATARR_INT =
-        StdTypeList.make(Type.FLOAT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [double[], int]} */
-    public static final StdTypeList DOUBLEARR_INT =
-        StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [Object[], int]} */
-    public static final StdTypeList OBJECTARR_INT =
-        StdTypeList.make(Type.OBJECT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [boolean[], int]} */
-    public static final StdTypeList BOOLEANARR_INT =
-        StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [byte[], int]} */
-    public static final StdTypeList BYTEARR_INT =
-        StdTypeList.make(Type.BYTE_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [char[], int]} */
-    public static final StdTypeList CHARARR_INT =
-        StdTypeList.make(Type.CHAR_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [short[], int]} */
-    public static final StdTypeList SHORTARR_INT =
-        StdTypeList.make(Type.SHORT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [int, int[], int]} */
-    public static final StdTypeList INT_INTARR_INT =
-        StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [long, long[], int]} */
-    public static final StdTypeList LONG_LONGARR_INT =
-        StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [float, float[], int]} */
-    public static final StdTypeList FLOAT_FLOATARR_INT =
-        StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [double, double[], int]} */
-    public static final StdTypeList DOUBLE_DOUBLEARR_INT =
-        StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [Object, Object[], int]} */
-    public static final StdTypeList OBJECT_OBJECTARR_INT =
-        StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [int, boolean[], int]} */
-    public static final StdTypeList INT_BOOLEANARR_INT =
-        StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [int, byte[], int]} */
-    public static final StdTypeList INT_BYTEARR_INT =
-        StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [int, char[], int]} */
-    public static final StdTypeList INT_CHARARR_INT =
-        StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT);
-
-    /** {@code non-null;} the list {@code [int, short[], int]} */
-    public static final StdTypeList INT_SHORTARR_INT =
-        StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT);
-
-    /**
-     * Makes a single-element instance.
-     *
-     * @param type {@code non-null;} the element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static StdTypeList make(Type type) {
-        StdTypeList result = new StdTypeList(1);
-        result.set(0, type);
-        return result;
-    }
-
-    /**
-     * Makes a two-element instance.
-     *
-     * @param type0 {@code non-null;} the first element
-     * @param type1 {@code non-null;} the second element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static StdTypeList make(Type type0, Type type1) {
-        StdTypeList result = new StdTypeList(2);
-        result.set(0, type0);
-        result.set(1, type1);
-        return result;
-    }
-
-    /**
-     * Makes a three-element instance.
-     *
-     * @param type0 {@code non-null;} the first element
-     * @param type1 {@code non-null;} the second element
-     * @param type2 {@code non-null;} the third element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static StdTypeList make(Type type0, Type type1, Type type2) {
-        StdTypeList result = new StdTypeList(3);
-        result.set(0, type0);
-        result.set(1, type1);
-        result.set(2, type2);
-        return result;
-    }
-
-    /**
-     * Makes a four-element instance.
-     *
-     * @param type0 {@code non-null;} the first element
-     * @param type1 {@code non-null;} the second element
-     * @param type2 {@code non-null;} the third element
-     * @param type3 {@code non-null;} the fourth element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static StdTypeList make(Type type0, Type type1, Type type2,
-                                   Type type3) {
-        StdTypeList result = new StdTypeList(4);
-        result.set(0, type0);
-        result.set(1, type1);
-        result.set(2, type2);
-        result.set(3, type3);
-        return result;
-    }
-
-    /**
-     * Returns the given list as a comma-separated list of human forms. This
-     * is a static method so as to work on arbitrary {@link TypeList}
-     * instances.
-     *
-     * @param list {@code non-null;} the list to convert
-     * @return {@code non-null;} the human form
-     */
-    public static String toHuman(TypeList list) {
-        int size = list.size();
-
-        if (size == 0) {
-            return "<empty>";
-        }
-
-        StringBuffer sb = new StringBuffer(100);
-
-        for (int i = 0; i < size; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(list.getType(i).toHuman());
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Returns a hashcode of the contents of the given list. This
-     * is a static method so as to work on arbitrary {@link TypeList}
-     * instances.
-     *
-     * @param list {@code non-null;} the list to inspect
-     * @return {@code non-null;} the hash code
-     */
-    public static int hashContents(TypeList list) {
-        int size = list.size();
-        int hash = 0;
-
-        for (int i = 0; i < size; i++) {
-            hash = (hash * 31) + list.getType(i).hashCode();
-        }
-
-        return hash;
-    }
-
-    /**
-     * Compares the contents of the given two instances for equality. This
-     * is a static method so as to work on arbitrary {@link TypeList}
-     * instances.
-     *
-     * @param list1 {@code non-null;} one list to compare
-     * @param list2 {@code non-null;} another list to compare
-     * @return whether the two lists contain corresponding equal elements
-     */
-    public static boolean equalContents(TypeList list1, TypeList list2) {
-        int size = list1.size();
-
-        if (list2.size() != size) {
-            return false;
-        }
-
-        for (int i = 0; i < size; i++) {
-            if (! list1.getType(i).equals(list2.getType(i))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Compares the contents of the given two instances for ordering. This
-     * is a static method so as to work on arbitrary {@link TypeList}
-     * instances.
-     *
-     * @param list1 {@code non-null;} one list to compare
-     * @param list2 {@code non-null;} another list to compare
-     * @return the order of the two lists
-     */
-    public static int compareContents(TypeList list1, TypeList list2) {
-        int size1 = list1.size();
-        int size2 = list2.size();
-        int size = Math.min(size1, size2);
-
-        for (int i = 0; i < size; i++) {
-            int comparison = list1.getType(i).compareTo(list2.getType(i));
-            if (comparison != 0) {
-                return comparison;
-            }
-        }
-
-        if (size1 == size2) {
-            return 0;
-        } else if (size1 < size2) {
-            return -1;
-        } else {
-            return 1;
-        }
-    }
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public StdTypeList(int size) {
-        super(size);
-    }
-
-    /** {@inheritDoc} */
-    public Type getType(int n) {
-        return get(n);
-    }
-
-    /** {@inheritDoc} */
-    public int getWordCount() {
-        int sz = size();
-        int result = 0;
-
-        for (int i = 0; i < sz; i++) {
-            result += get(i).getCategory();
-        }
-
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    public TypeList withAddedType(Type type) {
-        int sz = size();
-        StdTypeList result = new StdTypeList(sz + 1);
-
-        for (int i = 0; i < sz; i++) {
-            result.set0(i, get0(i));
-        }
-
-        result.set(sz, type);
-        result.setImmutable();
-        return result;
-    }
-
-    /**
-     * Gets the indicated element. It is an error to call this with the
-     * index for an element which was never set; if you do that, this
-     * will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return {@code non-null;} the indicated element
-     */
-    public Type get(int n) {
-        return (Type) get0(n);
-    }
-
-    /**
-     * Sets the type at the given index.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @param type {@code non-null;} the type to store
-     */
-    public void set(int n, Type type) {
-        set0(n, type);
-    }
-
-    /**
-     * Returns a new instance, which is the same as this instance,
-     * except that it has an additional type prepended to the
-     * original.
-     *
-     * @param type {@code non-null;} the new first element
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public StdTypeList withFirst(Type type) {
-        int sz = size();
-        StdTypeList result = new StdTypeList(sz + 1);
-
-        result.set0(0, type);
-        for (int i = 0; i < sz; i++) {
-            result.set0(i + 1, getOrNull0(i));
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/type/Type.java b/dx/src/main/java/com/android/dx/rop/type/Type.java
deleted file mode 100644
index c564fab..0000000
--- a/dx/src/main/java/com/android/dx/rop/type/Type.java
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.type;
-
-import com.android.dx.util.Hex;
-
-import java.util.HashMap;
-
-/**
- * Representation of a value type, such as may appear in a field, in a
- * local, on a stack, or in a method descriptor. Instances of this
- * class are generally interned and may be usefully compared with each
- * other using {@code ==}.
- */
-public final class Type implements TypeBearer, Comparable<Type> {
-    /**
-     * {@code non-null;} intern table mapping string descriptors to
-     * instances
-     */
-    private static final HashMap<String, Type> internTable =
-        new HashMap<String, Type>(500);
-
-    /** basic type constant for {@code void} */
-    public static final int BT_VOID = 0;
-
-    /** basic type constant for {@code boolean} */
-    public static final int BT_BOOLEAN = 1;
-
-    /** basic type constant for {@code byte} */
-    public static final int BT_BYTE = 2;
-
-    /** basic type constant for {@code char} */
-    public static final int BT_CHAR = 3;
-
-    /** basic type constant for {@code double} */
-    public static final int BT_DOUBLE = 4;
-
-    /** basic type constant for {@code float} */
-    public static final int BT_FLOAT = 5;
-
-    /** basic type constant for {@code int} */
-    public static final int BT_INT = 6;
-
-    /** basic type constant for {@code long} */
-    public static final int BT_LONG = 7;
-
-    /** basic type constant for {@code short} */
-    public static final int BT_SHORT = 8;
-
-    /** basic type constant for {@code Object} */
-    public static final int BT_OBJECT = 9;
-
-    /** basic type constant for a return address */
-    public static final int BT_ADDR = 10;
-
-    /** count of basic type constants */
-    public static final int BT_COUNT = 11;
-
-    /** {@code non-null;} instance representing {@code boolean} */
-    public static final Type BOOLEAN = new Type("Z", BT_BOOLEAN);
-
-    /** {@code non-null;} instance representing {@code byte} */
-    public static final Type BYTE = new Type("B", BT_BYTE);
-
-    /** {@code non-null;} instance representing {@code char} */
-    public static final Type CHAR = new Type("C", BT_CHAR);
-
-    /** {@code non-null;} instance representing {@code double} */
-    public static final Type DOUBLE = new Type("D", BT_DOUBLE);
-
-    /** {@code non-null;} instance representing {@code float} */
-    public static final Type FLOAT = new Type("F", BT_FLOAT);
-
-    /** {@code non-null;} instance representing {@code int} */
-    public static final Type INT = new Type("I", BT_INT);
-
-    /** {@code non-null;} instance representing {@code long} */
-    public static final Type LONG = new Type("J", BT_LONG);
-
-    /** {@code non-null;} instance representing {@code short} */
-    public static final Type SHORT = new Type("S", BT_SHORT);
-
-    /** {@code non-null;} instance representing {@code void} */
-    public static final Type VOID = new Type("V", BT_VOID);
-
-    /** {@code non-null;} instance representing a known-{@code null} */
-    public static final Type KNOWN_NULL = new Type("<null>", BT_OBJECT);
-
-    /** {@code non-null;} instance representing a subroutine return address */
-    public static final Type RETURN_ADDRESS = new Type("<addr>", BT_ADDR);
-
-    static {
-        /*
-         * Put all the primitive types into the intern table. This needs
-         * to happen before the array types below get interned.
-         */
-        putIntern(BOOLEAN);
-        putIntern(BYTE);
-        putIntern(CHAR);
-        putIntern(DOUBLE);
-        putIntern(FLOAT);
-        putIntern(INT);
-        putIntern(LONG);
-        putIntern(SHORT);
-        /*
-         * Note: VOID isn't put in the intern table, since it's special and
-         * shouldn't be found by a normal call to intern().
-         */
-    }
-
-    /**
-     * {@code non-null;} instance representing
-     * {@code java.lang.annotation.Annotation}
-     */
-    public static final Type ANNOTATION =
-        intern("Ljava/lang/annotation/Annotation;");
-
-    /** {@code non-null;} instance representing {@code java.lang.Class} */
-    public static final Type CLASS = intern("Ljava/lang/Class;");
-
-    /** {@code non-null;} instance representing {@code java.lang.Cloneable} */
-    public static final Type CLONEABLE = intern("Ljava/lang/Cloneable;");
-
-    /** {@code non-null;} instance representing {@code java.lang.Object} */
-    public static final Type OBJECT = intern("Ljava/lang/Object;");
-
-    /** {@code non-null;} instance representing {@code java.io.Serializable} */
-    public static final Type SERIALIZABLE = intern("Ljava/io/Serializable;");
-
-    /** {@code non-null;} instance representing {@code java.lang.String} */
-    public static final Type STRING = intern("Ljava/lang/String;");
-
-    /** {@code non-null;} instance representing {@code java.lang.Throwable} */
-    public static final Type THROWABLE = intern("Ljava/lang/Throwable;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Boolean}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type BOOLEAN_CLASS = intern("Ljava/lang/Boolean;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Byte}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type BYTE_CLASS = intern("Ljava/lang/Byte;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Character}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type CHARACTER_CLASS = intern("Ljava/lang/Character;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Double}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type DOUBLE_CLASS = intern("Ljava/lang/Double;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Float}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type FLOAT_CLASS = intern("Ljava/lang/Float;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Integer}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type INTEGER_CLASS = intern("Ljava/lang/Integer;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Long}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type LONG_CLASS = intern("Ljava/lang/Long;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Short}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type SHORT_CLASS = intern("Ljava/lang/Short;");
-
-    /**
-     * {@code non-null;} instance representing {@code java.lang.Void}; the
-     * suffix on the name helps disambiguate this from the instance
-     * representing a primitive type
-     */
-    public static final Type VOID_CLASS = intern("Ljava/lang/Void;");
-
-    /** {@code non-null;} instance representing {@code boolean[]} */
-    public static final Type BOOLEAN_ARRAY = BOOLEAN.getArrayType();
-
-    /** {@code non-null;} instance representing {@code byte[]} */
-    public static final Type BYTE_ARRAY = BYTE.getArrayType();
-
-    /** {@code non-null;} instance representing {@code char[]} */
-    public static final Type CHAR_ARRAY = CHAR.getArrayType();
-
-    /** {@code non-null;} instance representing {@code double[]} */
-    public static final Type DOUBLE_ARRAY = DOUBLE.getArrayType();
-
-    /** {@code non-null;} instance representing {@code float[]} */
-    public static final Type FLOAT_ARRAY = FLOAT.getArrayType();
-
-    /** {@code non-null;} instance representing {@code int[]} */
-    public static final Type INT_ARRAY = INT.getArrayType();
-
-    /** {@code non-null;} instance representing {@code long[]} */
-    public static final Type LONG_ARRAY = LONG.getArrayType();
-
-    /** {@code non-null;} instance representing {@code Object[]} */
-    public static final Type OBJECT_ARRAY = OBJECT.getArrayType();
-
-    /** {@code non-null;} instance representing {@code short[]} */
-    public static final Type SHORT_ARRAY = SHORT.getArrayType();
-
-    /** {@code non-null;} field descriptor for the type */
-    private final String descriptor;
-
-    /**
-     * basic type corresponding to this type; one of the
-     * {@code BT_*} constants
-     */
-    private final int basicType;
-
-    /**
-     * {@code >= -1;} for an uninitialized type, bytecode index that this
-     * instance was allocated at; {@code Integer.MAX_VALUE} if it
-     * was an incoming uninitialized instance; {@code -1} if this
-     * is an <i>inititialized</i> instance
-     */
-    private final int newAt;
-
-    /**
-     * {@code null-ok;} the internal-form class name corresponding to
-     * this type, if calculated; only valid if {@code this} is a
-     * reference type and additionally not a return address
-     */
-    private String className;
-
-    /**
-     * {@code null-ok;} the type corresponding to an array of this type, if
-     * calculated
-     */
-    private Type arrayType;
-
-    /**
-     * {@code null-ok;} the type corresponding to elements of this type, if
-     * calculated; only valid if {@code this} is an array type
-     */
-    private Type componentType;
-
-    /**
-     * {@code null-ok;} the type corresponding to the initialized version of
-     * this type, if this instance is in fact an uninitialized type
-     */
-    private Type initializedType;
-
-    /**
-     * Returns the unique instance corresponding to the type with the
-     * given descriptor. See vmspec-2 sec4.3.2 for details on the
-     * field descriptor syntax. This method does <i>not</i> allow
-     * {@code "V"} (that is, type {@code void}) as a valid
-     * descriptor.
-     *
-     * @param descriptor {@code non-null;} the descriptor
-     * @return {@code non-null;} the corresponding instance
-     * @throws IllegalArgumentException thrown if the descriptor has
-     * invalid syntax
-     */
-    public static Type intern(String descriptor) {
-        Type result;
-        synchronized (internTable) {
-            result = internTable.get(descriptor);
-        }
-        if (result != null) {
-            return result;
-        }
-
-        char firstChar;
-        try {
-            firstChar = descriptor.charAt(0);
-        } catch (IndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("descriptor is empty");
-        } catch (NullPointerException ex) {
-            // Elucidate the exception.
-            throw new NullPointerException("descriptor == null");
-        }
-
-        if (firstChar == '[') {
-            /*
-             * Recursively strip away array markers to get at the underlying
-             * type, and build back on to form the result.
-             */
-            result = intern(descriptor.substring(1));
-            return result.getArrayType();
-        }
-
-        /*
-         * If the first character isn't '[' and it wasn't found in the
-         * intern cache, then it had better be the descriptor for a class.
-         */
-
-        int length = descriptor.length();
-        if ((firstChar != 'L') ||
-            (descriptor.charAt(length - 1) != ';')) {
-            throw new IllegalArgumentException("bad descriptor: " + descriptor);
-        }
-
-        /*
-         * Validate the characters of the class name itself. Note that
-         * vmspec-2 does not have a coherent definition for valid
-         * internal-form class names, and the definition here is fairly
-         * liberal: A name is considered valid as long as it doesn't
-         * contain any of '[' ';' '.' '(' ')', and it has no more than one
-         * '/' in a row, and no '/' at either end.
-         */
-
-        int limit = (length - 1); // Skip the final ';'.
-        for (int i = 1; i < limit; i++) {
-            char c = descriptor.charAt(i);
-            switch (c) {
-                case '[':
-                case ';':
-                case '.':
-                case '(':
-                case ')': {
-                    throw new IllegalArgumentException("bad descriptor: " + descriptor);
-                }
-                case '/': {
-                    if ((i == 1) ||
-                        (i == (length - 1)) ||
-                        (descriptor.charAt(i - 1) == '/')) {
-                        throw new IllegalArgumentException("bad descriptor: " + descriptor);
-                    }
-                    break;
-                }
-            }
-        }
-
-        result = new Type(descriptor, BT_OBJECT);
-        return putIntern(result);
-    }
-
-    /**
-     * Returns the unique instance corresponding to the type with the
-     * given descriptor, allowing {@code "V"} to return the type
-     * for {@code void}. Other than that one caveat, this method
-     * is identical to {@link #intern}.
-     *
-     * @param descriptor {@code non-null;} the descriptor
-     * @return {@code non-null;} the corresponding instance
-     * @throws IllegalArgumentException thrown if the descriptor has
-     * invalid syntax
-     */
-    public static Type internReturnType(String descriptor) {
-        try {
-            if (descriptor.equals("V")) {
-                // This is the one special case where void may be returned.
-                return VOID;
-            }
-        } catch (NullPointerException ex) {
-            // Elucidate the exception.
-            throw new NullPointerException("descriptor == null");
-        }
-
-        return intern(descriptor);
-    }
-
-    /**
-     * Returns the unique instance corresponding to the type of the
-     * class with the given name. Calling this method is equivalent to
-     * calling {@code intern(name)} if {@code name} begins
-     * with {@code "["} and calling {@code intern("L" + name + ";")}
-     * in all other cases.
-     *
-     * @param name {@code non-null;} the name of the class whose type
-     * is desired
-     * @return {@code non-null;} the corresponding type
-     * @throws IllegalArgumentException thrown if the name has
-     * invalid syntax
-     */
-    public static Type internClassName(String name) {
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-
-        if (name.startsWith("[")) {
-            return intern(name);
-        }
-
-        return intern('L' + name + ';');
-    }
-
-    /**
-     * Constructs an instance corresponding to an "uninitialized type."
-     * This is a private constructor; use one of the public static
-     * methods to get instances.
-     *
-     * @param descriptor {@code non-null;} the field descriptor for the type
-     * @param basicType basic type corresponding to this type; one of the
-     * {@code BT_*} constants
-     * @param newAt {@code >= -1;} allocation bytecode index
-     */
-    private Type(String descriptor, int basicType, int newAt) {
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor == null");
-        }
-
-        if ((basicType < 0) || (basicType >= BT_COUNT)) {
-            throw new IllegalArgumentException("bad basicType");
-        }
-
-        if (newAt < -1) {
-            throw new IllegalArgumentException("newAt < -1");
-        }
-
-        this.descriptor = descriptor;
-        this.basicType = basicType;
-        this.newAt = newAt;
-        this.arrayType = null;
-        this.componentType = null;
-        this.initializedType = null;
-    }
-
-    /**
-     * Constructs an instance corresponding to an "initialized type."
-     * This is a private constructor; use one of the public static
-     * methods to get instances.
-     *
-     * @param descriptor {@code non-null;} the field descriptor for the type
-     * @param basicType basic type corresponding to this type; one of the
-     * {@code BT_*} constants
-     */
-    private Type(String descriptor, int basicType) {
-        this(descriptor, basicType, -1);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            /*
-             * Since externally-visible types are interned, this check
-             * helps weed out some easy cases.
-             */
-            return true;
-        }
-
-        if (!(other instanceof Type)) {
-            return false;
-        }
-
-        return descriptor.equals(((Type) other).descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return descriptor.hashCode();
-    }
-
-    /** {@inheritDoc} */
-    public int compareTo(Type other) {
-        return descriptor.compareTo(other.descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return descriptor;
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        switch (basicType) {
-            case BT_VOID:    return "void";
-            case BT_BOOLEAN: return "boolean";
-            case BT_BYTE:    return "byte";
-            case BT_CHAR:    return "char";
-            case BT_DOUBLE:  return "double";
-            case BT_FLOAT:   return "float";
-            case BT_INT:     return "int";
-            case BT_LONG:    return "long";
-            case BT_SHORT:   return "short";
-            case BT_OBJECT:  break;
-            default:         return descriptor;
-        }
-
-        if (isArray()) {
-            return getComponentType().toHuman() + "[]";
-        }
-
-        // Remove the "L...;" around the type and convert "/" to ".".
-        return getClassName().replace("/", ".");
-    }
-
-    /** {@inheritDoc} */
-    public Type getType() {
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    public Type getFrameType() {
-        switch (basicType) {
-            case BT_BOOLEAN:
-            case BT_BYTE:
-            case BT_CHAR:
-            case BT_INT:
-            case BT_SHORT: {
-                return INT;
-            }
-        }
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    public int getBasicType() {
-        return basicType;
-    }
-
-    /** {@inheritDoc} */
-    public int getBasicFrameType() {
-        switch (basicType) {
-            case BT_BOOLEAN:
-            case BT_BYTE:
-            case BT_CHAR:
-            case BT_INT:
-            case BT_SHORT: {
-                return BT_INT;
-            }
-        }
-
-        return basicType;
-    }
-
-    /** {@inheritDoc} */
-    public boolean isConstant() {
-        return false;
-    }
-
-    /**
-     * Gets the descriptor.
-     *
-     * @return {@code non-null;} the descriptor
-     */
-    public String getDescriptor() {
-        return descriptor;
-    }
-
-    /**
-     * Gets the name of the class this type corresponds to, in internal
-     * form. This method is only valid if this instance is for a
-     * normal reference type (that is, a reference type and
-     * additionally not a return address).
-     *
-     * @return {@code non-null;} the internal-form class name
-     */
-    public String getClassName() {
-        if (className == null) {
-            if (!isReference()) {
-                throw new IllegalArgumentException("not an object type: " +
-                                                   descriptor);
-            }
-
-            if (descriptor.charAt(0) == '[') {
-                className = descriptor;
-            } else {
-                className = descriptor.substring(1, descriptor.length() - 1);
-            }
-        }
-
-        return className;
-    }
-
-    /**
-     * Gets the category. Most instances are category 1. {@code long}
-     * and {@code double} are the only category 2 types.
-     *
-     * @see #isCategory1
-     * @see #isCategory2
-     * @return the category
-     */
-    public int getCategory() {
-        switch (basicType) {
-            case BT_LONG:
-            case BT_DOUBLE: {
-                return 2;
-            }
-        }
-
-        return 1;
-    }
-
-    /**
-     * Returns whether or not this is a category 1 type.
-     *
-     * @see #getCategory
-     * @see #isCategory2
-     * @return whether or not this is a category 1 type
-     */
-    public boolean isCategory1() {
-        switch (basicType) {
-            case BT_LONG:
-            case BT_DOUBLE: {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns whether or not this is a category 2 type.
-     *
-     * @see #getCategory
-     * @see #isCategory1
-     * @return whether or not this is a category 2 type
-     */
-    public boolean isCategory2() {
-        switch (basicType) {
-            case BT_LONG:
-            case BT_DOUBLE: {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Gets whether this type is "intlike." An intlike type is one which, when
-     * placed on a stack or in a local, is automatically converted to an
-     * {@code int}.
-     *
-     * @return whether this type is "intlike"
-     */
-    public boolean isIntlike() {
-        switch (basicType) {
-            case BT_BOOLEAN:
-            case BT_BYTE:
-            case BT_CHAR:
-            case BT_INT:
-            case BT_SHORT: {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Gets whether this type is a primitive type. All types are either
-     * primitive or reference types.
-     *
-     * @return whether this type is primitive
-     */
-    public boolean isPrimitive() {
-        switch (basicType) {
-            case BT_BOOLEAN:
-            case BT_BYTE:
-            case BT_CHAR:
-            case BT_DOUBLE:
-            case BT_FLOAT:
-            case BT_INT:
-            case BT_LONG:
-            case BT_SHORT:
-            case BT_VOID: {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Gets whether this type is a normal reference type. A normal
-     * reference type is a reference type that is not a return
-     * address. This method is just convenient shorthand for
-     * {@code getBasicType() == Type.BT_OBJECT}.
-     *
-     * @return whether this type is a normal reference type
-     */
-    public boolean isReference() {
-        return (basicType == BT_OBJECT);
-    }
-
-    /**
-     * Gets whether this type is an array type. If this method returns
-     * {@code true}, then it is safe to use {@link #getComponentType}
-     * to determine the component type.
-     *
-     * @return whether this type is an array type
-     */
-    public boolean isArray() {
-        return (descriptor.charAt(0) == '[');
-    }
-
-    /**
-     * Gets whether this type is an array type or is a known-null, and
-     * hence is compatible with array types.
-     *
-     * @return whether this type is an array type
-     */
-    public boolean isArrayOrKnownNull() {
-        return isArray() || equals(KNOWN_NULL);
-    }
-
-    /**
-     * Gets whether this type represents an uninitialized instance. An
-     * uninitialized instance is what one gets back from the {@code new}
-     * opcode, and remains uninitialized until a valid constructor is
-     * invoked on it.
-     *
-     * @return whether this type is "uninitialized"
-     */
-    public boolean isUninitialized() {
-        return (newAt >= 0);
-    }
-
-    /**
-     * Gets the bytecode index at which this uninitialized type was
-     * allocated.  This returns {@code Integer.MAX_VALUE} if this
-     * type is an uninitialized incoming parameter (i.e., the
-     * {@code this} of an {@code <init>} method) or
-     * {@code -1} if this type is in fact <i>initialized</i>.
-     *
-     * @return {@code >= -1;} the allocation bytecode index
-     */
-    public int getNewAt() {
-        return newAt;
-    }
-
-    /**
-     * Gets the initialized type corresponding to this instance, but only
-     * if this instance is in fact an uninitialized object type.
-     *
-     * @return {@code non-null;} the initialized type
-     */
-    public Type getInitializedType() {
-        if (initializedType == null) {
-            throw new IllegalArgumentException("initialized type: " +
-                                               descriptor);
-        }
-
-        return initializedType;
-    }
-
-    /**
-     * Gets the type corresponding to an array of this type.
-     *
-     * @return {@code non-null;} the array type
-     */
-    public Type getArrayType() {
-        if (arrayType == null) {
-            arrayType = putIntern(new Type('[' + descriptor, BT_OBJECT));
-        }
-
-        return arrayType;
-    }
-
-    /**
-     * Gets the component type of this type. This method is only valid on
-     * array types.
-     *
-     * @return {@code non-null;} the component type
-     */
-    public Type getComponentType() {
-        if (componentType == null) {
-            if (descriptor.charAt(0) != '[') {
-                throw new IllegalArgumentException("not an array type: " +
-                                                   descriptor);
-            }
-            componentType = intern(descriptor.substring(1));
-        }
-
-        return componentType;
-    }
-
-    /**
-     * Returns a new interned instance which is identical to this one, except
-     * it is indicated as uninitialized and allocated at the given bytecode
-     * index. This instance must be an initialized object type.
-     *
-     * @param newAt {@code >= 0;} the allocation bytecode index
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public Type asUninitialized(int newAt) {
-        if (newAt < 0) {
-            throw new IllegalArgumentException("newAt < 0");
-        }
-
-        if (!isReference()) {
-            throw new IllegalArgumentException("not a reference type: " +
-                                               descriptor);
-        }
-
-        if (isUninitialized()) {
-            /*
-             * Dealing with uninitialized types as a starting point is
-             * a pain, and it's not clear that it'd ever be used, so
-             * just disallow it.
-             */
-            throw new IllegalArgumentException("already uninitialized: " +
-                                               descriptor);
-        }
-
-        /*
-         * Create a new descriptor that is unique and shouldn't conflict
-         * with "normal" type descriptors
-         */
-        String newDesc = 'N' + Hex.u2(newAt) + descriptor;
-        Type result = new Type(newDesc, BT_OBJECT, newAt);
-        result.initializedType = this;
-        return putIntern(result);
-    }
-
-    /**
-     * Puts the given instance in the intern table if it's not already
-     * there. If a conflicting value is already in the table, then leave it.
-     * Return the interned value.
-     *
-     * @param type {@code non-null;} instance to make interned
-     * @return {@code non-null;} the actual interned object
-     */
-    private static Type putIntern(Type type) {
-        synchronized (internTable) {
-            String descriptor = type.getDescriptor();
-            Type already = internTable.get(descriptor);
-            if (already != null) {
-                return already;
-            }
-            internTable.put(descriptor, type);
-            return type;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/rop/type/TypeBearer.java b/dx/src/main/java/com/android/dx/rop/type/TypeBearer.java
deleted file mode 100644
index b03dbaf..0000000
--- a/dx/src/main/java/com/android/dx/rop/type/TypeBearer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.type;
-
-import com.android.dx.util.ToHuman;
-
-/**
- * Object which has an associated type, possibly itself.
- */
-public interface TypeBearer
-        extends ToHuman {
-    /**
-     * Gets the type associated with this instance.
-     *
-     * @return {@code non-null;} the type
-     */
-    public Type getType();
-
-    /**
-     * Gets the frame type corresponding to this type. This method returns
-     * {@code this}, except if {@link Type#isIntlike} on the underlying
-     * type returns {@code true} but the underlying type is not in
-     * fact {@link Type#INT}, in which case this method returns an instance
-     * whose underlying type <i>is</i> {@code INT}.
-     *
-     * @return {@code non-null;} the frame type for this instance
-     */
-    public TypeBearer getFrameType();
-
-    /**
-     * Gets the basic type corresponding to this instance.
-     *
-     * @return the basic type; one of the {@code BT_*} constants
-     * defined by {@link Type}
-     */
-    public int getBasicType();
-
-    /**
-     * Gets the basic type corresponding to this instance's frame type. This
-     * is equivalent to {@code getFrameType().getBasicType()}, and
-     * is the same as calling {@code getFrameType()} unless this
-     * instance is an int-like type, in which case this method returns
-     * {@code BT_INT}.
-     *
-     * @see #getBasicType
-     * @see #getFrameType
-     *
-     * @return the basic frame type; one of the {@code BT_*} constants
-     * defined by {@link Type}
-     */
-    public int getBasicFrameType();
-
-    /**
-     * Returns whether this instance represents a constant value.
-     *
-     * @return {@code true} if this instance represents a constant value
-     * and {@code false} if not
-     */
-    public boolean isConstant();
-}
diff --git a/dx/src/main/java/com/android/dx/rop/type/TypeList.java b/dx/src/main/java/com/android/dx/rop/type/TypeList.java
deleted file mode 100644
index de2d62e..0000000
--- a/dx/src/main/java/com/android/dx/rop/type/TypeList.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2007 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.rop.type;
-
-/**
- * List of {@link Type} instances (or of things that contain types).
- */
-public interface TypeList {
-    /**
-     * Returns whether this instance is mutable. Note that the
-     * {@code TypeList} interface itself doesn't provide any
-     * means of mutation, but that doesn't mean that there isn't an
-     * extra-interface way of mutating an instance.
-     *
-     * @return {@code true} if this instance is mutable or
-     * {@code false} if it is immutable
-     */
-    public boolean isMutable();
-
-    /**
-     * Gets the size of this list.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int size();
-
-    /**
-     * Gets the indicated element. It is an error to call this with the
-     * index for an element which was never set; if you do that, this
-     * will throw {@code NullPointerException}.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return {@code non-null;} the indicated element
-     */
-    public Type getType(int n);
-
-    /**
-     * Gets the number of 32-bit words required to hold instances of
-     * all the elements of this list. This is a sum of the widths (categories)
-     * of all the elements.
-     *
-     * @return {@code >= 0;} the required number of words
-     */
-    public int getWordCount();
-
-    /**
-     * Returns a new instance which is identical to this one, except that
-     * the given item is appended to the end and it is guaranteed to be
-     * immutable.
-     *
-     * @param type {@code non-null;} item to append
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public TypeList withAddedType(Type type);
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/BasicRegisterMapper.java b/dx/src/main/java/com/android/dx/ssa/BasicRegisterMapper.java
deleted file mode 100644
index 83045b2..0000000
--- a/dx/src/main/java/com/android/dx/ssa/BasicRegisterMapper.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.IntList;
-
-/**
- * This class maps one register space into another, with
- * each mapping built up individually and added via addMapping()
- */
-public class BasicRegisterMapper extends RegisterMapper {
-    /** indexed by old register, containing new name */
-    private IntList oldToNew;
-
-    /** running count of used registers in new namespace */
-    private int runningCountNewRegisters;
-
-    /**
-     * Creates a new OneToOneRegisterMapper.
-     *
-     * @param countOldRegisters the number of registers in the old name space
-     */
-    public BasicRegisterMapper(int countOldRegisters) {
-        oldToNew = new IntList(countOldRegisters);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getNewRegisterCount() {
-        return runningCountNewRegisters;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public RegisterSpec map(RegisterSpec registerSpec) {
-        if (registerSpec == null) {
-            return null;
-        }
-
-        int newReg;
-        try {
-            newReg = oldToNew.get(registerSpec.getReg());
-        } catch (IndexOutOfBoundsException ex) {
-            newReg = -1;
-        }
-
-        if (newReg < 0) {
-            throw new RuntimeException("no mapping specified for register");
-        }
-
-        return registerSpec.withReg(newReg);
-    }
-
-    /**
-     * Returns the new-namespace mapping for the specified
-     * old-namespace register, or -1 if one exists.
-     *
-     * @param oldReg {@code >= 0;} old-namespace register
-     * @return new-namespace register or -1 if none
-     */
-    public int oldToNew(int oldReg) {
-        if (oldReg >= oldToNew.size()) {
-            return -1;
-        }
-
-        return oldToNew.get(oldReg);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("Old\tNew\n");
-        int sz = oldToNew.size();
-
-        for (int i = 0; i < sz; i++) {
-            sb.append(i);
-            sb.append('\t');
-            sb.append(oldToNew.get(i));
-            sb.append('\n');
-        }
-
-        sb.append("new reg count:");
-
-        sb.append(runningCountNewRegisters);
-        sb.append('\n');
-
-        return sb.toString();
-    }
-
-    /**
-     * Adds a mapping to the mapper. If oldReg has already been mapped,
-     * overwrites previous mapping with new mapping.
-     *
-     * @param oldReg {@code >= 0;} old register
-     * @param newReg {@code >= 0;} new register
-     * @param category {@code 1..2;} width of reg
-     */
-    public void addMapping(int oldReg, int newReg, int category) {
-        if (oldReg >= oldToNew.size()) {
-            // expand the array as necessary
-            for (int i = oldReg - oldToNew.size(); i >= 0; i--) {
-                oldToNew.add(-1);
-            }
-        }
-
-        oldToNew.set(oldReg, newReg);
-
-        if (runningCountNewRegisters < (newReg + category)) {
-            runningCountNewRegisters = newReg + category;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/ConstCollector.java b/dx/src/main/java/com/android/dx/ssa/ConstCollector.java
deleted file mode 100644
index 62d629f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/ConstCollector.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2008 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.ssa;
-
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.code.PlainCstInsn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-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.cst.Constant;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.TypedConstant;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.TypeBearer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-/**
- * Collects constants that are used more than once at the top of the
- * method block. This increases register usage by about 5% but decreases
- * insn size by about 3%.
- */
-public class ConstCollector {
-    /** Maximum constants to collect per method. Puts cap on reg use */
-    private static final int MAX_COLLECTED_CONSTANTS = 5;
-
-    /**
-     * Also collect string consts, although they can throw exceptions.
-     * This is off now because it just doesn't seem to gain a whole lot.
-     * TODO if you turn this on, you must change SsaInsn.hasSideEffect()
-     * to return false for const-string insns whose exceptions are not
-     * caught in the current method.
-     */
-    private static boolean COLLECT_STRINGS = false;
-
-    /**
-     * If true, allow one local var to be involved with a collected const.
-     * Turned off because it mostly just inserts more moves.
-     */
-    private static boolean COLLECT_ONE_LOCAL = false;
-
-    /** method we're processing */
-    private final SsaMethod ssaMeth;
-
-    /**
-     * Processes a method.
-     *
-     * @param ssaMethod {@code non-null;} method to process
-     */
-    public static void process(SsaMethod ssaMethod) {
-        ConstCollector cc = new ConstCollector(ssaMethod);
-        cc.run();
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ssaMethod {@code non-null;} method to process
-     */
-    private ConstCollector(SsaMethod ssaMethod) {
-        this.ssaMeth = ssaMethod;
-    }
-
-    /**
-     * Applies the optimization.
-     */
-    private void run() {
-        int regSz = ssaMeth.getRegCount();
-
-        ArrayList<TypedConstant> constantList
-                = getConstsSortedByCountUse();
-
-        int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
-
-        SsaBasicBlock start = ssaMeth.getEntryBlock();
-
-        // Constant to new register containing the constant
-        HashMap<TypedConstant, RegisterSpec> newRegs
-                = new HashMap<TypedConstant, RegisterSpec> (toCollect);
-
-        for (int i = 0; i < toCollect; i++) {
-            TypedConstant cst = constantList.get(i);
-            RegisterSpec result
-                    = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
-
-            Rop constRop = Rops.opConst(cst);
-
-            if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
-                start.addInsnToHead(
-                        new PlainCstInsn(Rops.opConst(cst),
-                                SourcePosition.NO_INFO, result,
-                                RegisterSpecList.EMPTY, cst));
-            } else {
-                // We need two new basic blocks along with the new insn
-                SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
-                SsaBasicBlock successorBlock
-                        = entryBlock.getPrimarySuccessor();
-
-                // Insert a block containing the const insn.
-                SsaBasicBlock constBlock
-                        = entryBlock.insertNewSuccessor(successorBlock);
-
-                constBlock.replaceLastInsn(
-                        new ThrowingCstInsn(constRop, SourcePosition.NO_INFO,
-                                RegisterSpecList.EMPTY,
-                                StdTypeList.EMPTY, cst));
-
-                // Insert a block containing the move-result-pseudo insn.
-
-                SsaBasicBlock resultBlock
-                        = constBlock.insertNewSuccessor(successorBlock);
-                PlainInsn insn
-                    = new PlainInsn(
-                            Rops.opMoveResultPseudo(result.getTypeBearer()),
-                            SourcePosition.NO_INFO,
-                            result, RegisterSpecList.EMPTY);
-
-                resultBlock.addInsnToHead(insn);
-            }
-
-            newRegs.put(cst, result);
-        }
-
-        updateConstUses(newRegs, regSz);
-    }
-
-    /**
-     * Gets all of the collectable constant values used in this method,
-     * sorted by most used first. Skips non-collectable consts, such as
-     * non-string object constants
-     *
-     * @return {@code non-null;} list of constants in most-to-least used order
-     */
-    private ArrayList<TypedConstant> getConstsSortedByCountUse() {
-        int regSz = ssaMeth.getRegCount();
-
-        final HashMap<TypedConstant, Integer> countUses
-                = new HashMap<TypedConstant, Integer>();
-
-        /*
-         * Each collected constant can be used by just one local
-         * (used only if COLLECT_ONE_LOCAL is true).
-         */
-        final HashSet<TypedConstant> usedByLocal
-                = new HashSet<TypedConstant>();
-
-        // Count how many times each const value is used.
-        for (int i = 0; i < regSz; i++) {
-            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
-
-            if (insn == null || insn.getOpcode() == null) continue;
-
-            RegisterSpec result = insn.getResult();
-            TypeBearer typeBearer = result.getTypeBearer();
-
-            if (!typeBearer.isConstant()) continue;
-
-            TypedConstant cst = (TypedConstant) typeBearer;
-
-            // Find defining instruction for move-result-pseudo instructions
-            if (insn.getOpcode().getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
-                int pred = insn.getBlock().getPredecessors().nextSetBit(0);
-                ArrayList<SsaInsn> predInsns;
-                predInsns = ssaMeth.getBlocks().get(pred).getInsns();
-                insn = predInsns.get(predInsns.size()-1);
-            }
-
-            if (insn.canThrow()) {
-                /*
-                 * Don't move anything other than strings -- the risk
-                 * of changing where an exception is thrown is too high.
-                 */
-                if (!(cst instanceof CstString) || !COLLECT_STRINGS) {
-                    continue;
-                }
-                /*
-                 * We can't move any throwable const whose throw will be
-                 * caught, so don't count them.
-                 */
-                if (insn.getBlock().getSuccessors().cardinality() > 1) {
-                    continue;
-                }
-            }
-
-            /*
-             * TODO: Might be nice to try and figure out which local
-             * wins most when collected.
-             */
-            if (ssaMeth.isRegALocal(result)) {
-                if (!COLLECT_ONE_LOCAL) {
-                    continue;
-                } else {
-                    if (usedByLocal.contains(cst)) {
-                        // Count one local usage only.
-                        continue;
-                    } else {
-                        usedByLocal.add(cst);
-                    }
-                }
-            }
-
-            Integer has = countUses.get(cst);
-            if (has == null) {
-                countUses.put(cst, 1);
-            } else {
-                countUses.put(cst, has + 1);
-            }
-        }
-
-        // Collect constants that have been reused.
-        ArrayList<TypedConstant> constantList = new ArrayList<TypedConstant>();
-        for (Map.Entry<TypedConstant, Integer> entry : countUses.entrySet()) {
-            if (entry.getValue() > 1) {
-                constantList.add(entry.getKey());
-            }
-        }
-
-        // Sort by use, with most used at the beginning of the list.
-        Collections.sort(constantList, new Comparator<Constant>() {
-            public int compare(Constant a, Constant b) {
-                int ret;
-                ret = countUses.get(b) - countUses.get(a);
-
-                if (ret == 0) {
-                    /*
-                     * Provide sorting determinisim for constants with same
-                     * usage count.
-                     */
-                    ret = a.compareTo(b);
-                }
-
-                return ret;
-            }
-
-            @Override
-            public boolean equals (Object obj) {
-                return obj == this;
-            }
-        });
-
-        return constantList;
-    }
-
-    /**
-     * Inserts mark-locals if necessary when changing a register. If
-     * the definition of {@code origReg} is associated with a local
-     * variable, then insert a mark-local for {@code newReg} just below
-     * it. We expect the definition of  {@code origReg} to ultimately
-     * be removed by the dead code eliminator
-     *
-     * @param origReg {@code non-null;} original register
-     * @param newReg {@code non-null;} new register that will replace
-     * {@code origReg}
-     */
-    private void fixLocalAssignment(RegisterSpec origReg,
-            RegisterSpec newReg) {
-        for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
-            RegisterSpec localAssignment = use.getLocalAssignment();
-            if (localAssignment == null) {
-                continue;
-            }
-
-            if (use.getResult() == null) {
-                /*
-                 * This is a mark-local. it will be updated when all uses
-                 * are updated.
-                 */
-                continue;
-            }
-
-            LocalItem local = localAssignment.getLocalItem();
-
-            // Un-associate original use.
-            use.setResultLocal(null);
-
-            // Now add a mark-local to the new reg immediately after.
-            newReg = newReg.withLocalItem(local);
-
-            SsaInsn newInsn
-                    = SsaInsn.makeFromRop(
-                        new PlainInsn(Rops.opMarkLocal(newReg),
-                        SourcePosition.NO_INFO, null,
-                                RegisterSpecList.make(newReg)),
-                    use.getBlock());
-
-            ArrayList<SsaInsn> insns = use.getBlock().getInsns();
-
-            insns.add(insns.indexOf(use) + 1, newInsn);
-        }
-    }
-
-    /**
-     * Updates all uses of various consts to use the values in the newly
-     * assigned registers.
-     *
-     * @param newRegs {@code non-null;} mapping between constant and new reg
-     * @param origRegCount {@code >=0;} original SSA reg count, not including
-     * newly added constant regs
-     */
-    private void updateConstUses(HashMap<TypedConstant, RegisterSpec> newRegs,
-            int origRegCount) {
-
-        /*
-         * set of constants associated with a local variable; used
-         * only if COLLECT_ONE_LOCAL is true.
-         */
-        final HashSet<TypedConstant> usedByLocal
-                = new HashSet<TypedConstant>();
-
-        final ArrayList<SsaInsn>[] useList = ssaMeth.getUseListCopy();
-
-        for (int i = 0; i < origRegCount; i++) {
-            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
-
-            if (insn == null) {
-                continue;
-            }
-
-            final RegisterSpec origReg = insn.getResult();
-            TypeBearer typeBearer = insn.getResult().getTypeBearer();
-
-            if (!typeBearer.isConstant()) continue;
-
-            TypedConstant cst = (TypedConstant) typeBearer;
-            final RegisterSpec newReg = newRegs.get(cst);
-
-            if (newReg == null) {
-                continue;
-            }
-
-            if (ssaMeth.isRegALocal(origReg)) {
-                if (!COLLECT_ONE_LOCAL) {
-                    continue;
-                } else {
-                    /*
-                     * TODO: If the same local gets the same cst
-                     * multiple times, it would be nice to reuse the
-                     * register.
-                     */
-                    if (usedByLocal.contains(cst)) {
-                        continue;
-                    } else {
-                        usedByLocal.add(cst);
-                        fixLocalAssignment(origReg, newRegs.get(cst));
-                    }
-                }
-            }
-
-            // maps an original const register to the new collected register
-            RegisterMapper mapper = new RegisterMapper() {
-                @Override
-                public int getNewRegisterCount() {
-                    return ssaMeth.getRegCount();
-                }
-
-                @Override
-                public RegisterSpec map(RegisterSpec registerSpec) {
-                    if (registerSpec.getReg() == origReg.getReg()) {
-                        return newReg.withLocalItem(
-                                registerSpec.getLocalItem());
-                    }
-
-                    return registerSpec;
-                }
-            };
-
-            for (SsaInsn use : useList[origReg.getReg()]) {
-                if (use.canThrow()
-                        && use.getBlock().getSuccessors().cardinality() > 1) {
-                    continue;
-                }
-                use.mapSourceRegisters(mapper);
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/DeadCodeRemover.java b/dx/src/main/java/com/android/dx/ssa/DeadCodeRemover.java
deleted file mode 100644
index 07fb553..0000000
--- a/dx/src/main/java/com/android/dx/ssa/DeadCodeRemover.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.code.Insn;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashSet;
-
-/**
- * A variation on Appel Algorithm 19.12 "Dead code elimination in SSA form".
- *
- * TODO this algorithm is more efficient if run in reverse from exit
- * block to entry block.
- */
-public class DeadCodeRemover {
-    /** method we're processing */
-    private final SsaMethod ssaMeth;
-
-    /** ssaMeth.getRegCount() */
-    private final int regCount;
-
-    /**
-     * indexed by register: whether reg should be examined
-     * (does it correspond to a no-side-effect insn?)
-     */
-    private final BitSet worklist;
-
-    /** use list indexed by register; modified during operation */
-    private final ArrayList<SsaInsn>[] useList;
-
-    /**
-     * Process a method with the dead-code remver
-     *
-     * @param ssaMethod method to process
-     */
-    public static void process(SsaMethod ssaMethod) {
-        DeadCodeRemover dc = new DeadCodeRemover(ssaMethod);
-        dc.run();
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ssaMethod method to process
-     */
-    private DeadCodeRemover(SsaMethod ssaMethod) {
-        this.ssaMeth = ssaMethod;
-
-        regCount = ssaMethod.getRegCount();
-        worklist = new BitSet(regCount);
-        useList = ssaMeth.getUseListCopy();
-    }
-
-    /**
-     * Runs the dead code remover.
-     */
-    private void run() {
-        pruneDeadInstructions();
-
-        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
-
-        ssaMeth.forEachInsn(new NoSideEffectVisitor(worklist));
-
-        int regV;
-
-        while ( 0 <= (regV = worklist.nextSetBit(0)) ) {
-            worklist.clear(regV);
-
-            if (useList[regV].size() == 0
-                    || isCircularNoSideEffect(regV, null)) {
-
-                SsaInsn insnS = ssaMeth.getDefinitionForRegister(regV);
-
-                // This insn has already been deleted.
-                if (deletedInsns.contains(insnS)) {
-                    continue;
-                }
-
-                RegisterSpecList sources = insnS.getSources();
-
-                int sz = sources.size();
-                for (int i = 0; i < sz; i++) {
-                    // Delete this insn from all usage lists.
-                    RegisterSpec source = sources.get(i);
-                    useList[source.getReg()].remove(insnS);
-
-                    if (!hasSideEffect(
-                            ssaMeth.getDefinitionForRegister(
-                                    source.getReg()))) {
-                        /*
-                         * Only registers whose definition has no side effect
-                         * should be added back to the worklist.
-                         */
-                        worklist.set(source.getReg());
-                    }
-                }
-
-                // Schedule this insn for later deletion.
-                deletedInsns.add(insnS);
-            }
-        }
-
-        ssaMeth.deleteInsns(deletedInsns);
-    }
-
-    /**
-     * Removes all instructions from every unreachable block.
-     */
-    private void pruneDeadInstructions() {
-        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
-
-        ssaMeth.computeReachability();
-
-        for (SsaBasicBlock block : ssaMeth.getBlocks()) {
-            if (block.isReachable()) continue;
-
-            // Prune instructions from unreachable blocks
-            for (int i = 0; i < block.getInsns().size(); i++) {
-                SsaInsn insn = block.getInsns().get(i);
-                RegisterSpecList sources = insn.getSources();
-                int sourcesSize = sources.size();
-
-                // Delete this instruction completely if it has sources
-                if (sourcesSize != 0) {
-                    deletedInsns.add(insn);
-                }
-
-                // Delete this instruction from all usage lists.
-                for (int j = 0; j < sourcesSize; j++) {
-                    RegisterSpec source = sources.get(j);
-                    useList[source.getReg()].remove(insn);
-                }
-
-                // Remove this instruction result from the sources of any phis
-                RegisterSpec result = insn.getResult();
-                if (result == null) continue;
-                for (SsaInsn use : useList[result.getReg()]) {
-                    if (use instanceof PhiInsn) {
-                        PhiInsn phiUse = (PhiInsn) use;
-                        phiUse.removePhiRegister(result);
-                    }
-                }
-            }
-        }
-
-        ssaMeth.deleteInsns(deletedInsns);
-    }
-
-    /**
-     * Returns true if the only uses of this register form a circle of
-     * operations with no side effects.
-     *
-     * @param regV register to examine
-     * @param set a set of registers that we've already determined
-     * are only used as sources in operations with no side effect or null
-     * if this is the first recursion
-     * @return true if usage is circular without side effect
-     */
-    private boolean isCircularNoSideEffect(int regV, BitSet set) {
-        if ((set != null) && set.get(regV)) {
-            return true;
-        }
-
-        for (SsaInsn use : useList[regV]) {
-            if (hasSideEffect(use)) {
-                return false;
-            }
-        }
-
-        if (set == null) {
-            set = new BitSet(regCount);
-        }
-
-        // This register is only used in operations that have no side effect.
-        set.set(regV);
-
-        for (SsaInsn use : useList[regV]) {
-            RegisterSpec result = use.getResult();
-
-            if (result == null
-                    || !isCircularNoSideEffect(result.getReg(), set)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if this insn has a side-effect. Returns true
-     * if the insn is null for reasons stated in the code block.
-     *
-     * @param insn {@code null-ok;} instruction in question
-     * @return true if it has a side-effect
-     */
-    private static boolean hasSideEffect(SsaInsn insn) {
-        if (insn == null) {
-            /* While false would seem to make more sense here, true
-             * prevents us from adding this back to a worklist unnecessarally.
-             */
-            return true;
-        }
-
-        return insn.hasSideEffect();
-    }
-
-    /**
-     * A callback class used to build up the initial worklist of
-     * registers defined by an instruction with no side effect.
-     */
-    static private class NoSideEffectVisitor implements SsaInsn.Visitor {
-        BitSet noSideEffectRegs;
-
-        /**
-         * Passes in data structures that will be filled out after
-         * ssaMeth.forEachInsn() is called with this instance.
-         *
-         * @param noSideEffectRegs to-build bitset of regs that are
-         * results of regs with no side effects
-         */
-        public NoSideEffectVisitor(BitSet noSideEffectRegs) {
-            this.noSideEffectRegs = noSideEffectRegs;
-        }
-
-        /** {@inheritDoc} */
-        public void visitMoveInsn (NormalSsaInsn insn) {
-            // If we're tracking local vars, some moves have side effects.
-            if (!hasSideEffect(insn)) {
-                noSideEffectRegs.set(insn.getResult().getReg());
-            }
-        }
-
-        /** {@inheritDoc} */
-        public void visitPhiInsn (PhiInsn phi) {
-            // If we're tracking local vars, then some phis have side effects.
-            if (!hasSideEffect(phi)) {
-                noSideEffectRegs.set(phi.getResult().getReg());
-            }
-        }
-
-        /** {@inheritDoc} */
-        public void visitNonMoveInsn (NormalSsaInsn insn) {
-            RegisterSpec result = insn.getResult();
-            if (!hasSideEffect(insn) && result != null) {
-                noSideEffectRegs.set(result.getReg());
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/DomFront.java b/dx/src/main/java/com/android/dx/ssa/DomFront.java
deleted file mode 100644
index 941a317..0000000
--- a/dx/src/main/java/com/android/dx/ssa/DomFront.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.util.IntSet;
-import com.android.dx.util.BitIntSet;
-import com.android.dx.util.ListIntSet;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-
-/**
- * Calculates the dominance-frontiers of a methot's basic blocks.
- * Algorithm from "A Simple, Fast Dominance Algorithm" by Cooper,
- * Harvey, and Kennedy; transliterated to Java.
- */
-public class DomFront {
-    /** local debug flag */
-    private static boolean DEBUG = false;
-
-    /** {@code non-null;} method being processed */
-    private final SsaMethod meth;
-
-    private final ArrayList<SsaBasicBlock> nodes;
-
-    private final DomInfo[] domInfos;
-
-    /**
-     * Dominance-frontier information for a single basic block.
-     */
-    public static class DomInfo {
-        /**
-         * {@code null-ok;} the dominance frontier set indexed by
-         * block index
-         */
-        public IntSet dominanceFrontiers;
-
-        /** {@code >= 0 after run();} the index of the immediate dominator */
-        public int idom = -1;
-    }
-
-    /**
-     * Constructs instance. Call {@link DomFront#run} to process.
-     *
-     * @param meth {@code non-null;} method to process
-     */
-    public DomFront(SsaMethod meth) {
-        this.meth = meth;
-        nodes = meth.getBlocks();
-
-        int szNodes = nodes.size();
-        domInfos = new DomInfo[szNodes];
-
-        for (int i = 0; i < szNodes; i++) {
-            domInfos[i] = new DomInfo();
-        }
-    }
-
-    /**
-     * Calculates the dominance frontier information for the method.
-     *
-     * @return {@code non-null;} an array of DomInfo structures
-     */
-    public DomInfo[] run() {
-        int szNodes = nodes.size();
-
-        if (DEBUG) {
-            for (int i = 0; i < szNodes; i++) {
-                SsaBasicBlock node = nodes.get(i);
-                System.out.println("pred[" + i + "]: "
-                        + node.getPredecessors());
-            }
-        }
-
-        Dominators methDom = Dominators.make(meth, domInfos, false);
-
-        if (DEBUG) {
-            for (int i = 0; i < szNodes; i++) {
-                DomInfo info = domInfos[i];
-                System.out.println("idom[" + i + "]: "
-                        + info.idom);
-            }
-        }
-
-        buildDomTree();
-
-        if (DEBUG) {
-            debugPrintDomChildren();
-        }
-
-        for (int i = 0; i < szNodes; i++) {
-            domInfos[i].dominanceFrontiers
-                    = SetFactory.makeDomFrontSet(szNodes);
-        }
-
-        calcDomFronts();
-
-        if (DEBUG) {
-            for (int i = 0; i < szNodes; i++) {
-                System.out.println("df[" + i + "]: "
-                        + domInfos[i].dominanceFrontiers);
-            }
-        }
-
-        return domInfos;
-    }
-
-    private void debugPrintDomChildren() {
-        int szNodes = nodes.size();
-
-        for (int i = 0; i < szNodes; i++) {
-            SsaBasicBlock node = nodes.get(i);
-            StringBuffer sb = new StringBuffer();
-
-            sb.append('{');
-            boolean comma = false;
-            for (SsaBasicBlock child : node.getDomChildren()) {
-                if (comma) {
-                    sb.append(',');
-                }
-                sb.append(child);
-                comma = true;
-            }
-            sb.append('}');
-
-            System.out.println("domChildren[" + node + "]: "
-                    + sb);
-        }
-    }
-
-    /**
-     * The dominators algorithm leaves us knowing who the immediate dominator
-     * is for each node. This sweeps the node list and builds the proper
-     * dominance tree.
-     */
-    private void buildDomTree() {
-        int szNodes = nodes.size();
-
-        for (int i = 0; i < szNodes; i++) {
-            DomInfo info = domInfos[i];
-
-            if (info.idom == -1) continue;
-
-            SsaBasicBlock domParent = nodes.get(info.idom);
-            domParent.addDomChild(nodes.get(i));
-        }
-    }
-
-    /**
-     * Calculates the dominance-frontier set.
-     * from "A Simple, Fast Dominance Algorithm" by Cooper,
-     * Harvey, and Kennedy; transliterated to Java.
-     */
-    private void calcDomFronts() {
-        int szNodes = nodes.size();
-
-        for (int b = 0; b < szNodes; b++) {
-            SsaBasicBlock nb = nodes.get(b);
-            DomInfo nbInfo = domInfos[b];
-            BitSet pred = nb.getPredecessors();
-
-            if (pred.cardinality() > 1) {
-                for (int i = pred.nextSetBit(0); i >= 0;
-                     i = pred.nextSetBit(i + 1)) {
-
-                    for (int runnerIndex = i;
-                         runnerIndex != nbInfo.idom; /* empty */) {
-                        /*
-                         * We can stop if we hit a block we already
-                         * added label to, since we must be at a part
-                         * of the dom tree we have seen before.
-                         */
-                        if (runnerIndex == -1) break;
-
-                        DomInfo runnerInfo = domInfos[runnerIndex];
-
-                        if (runnerInfo.dominanceFrontiers.has(b)) {
-                            break;
-                        }
-
-                        // Add b to runner's dominance frontier set.
-                        runnerInfo.dominanceFrontiers.add(b);
-                        runnerIndex = runnerInfo.idom;
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/Dominators.java b/dx/src/main/java/com/android/dx/ssa/Dominators.java
deleted file mode 100644
index 503e857..0000000
--- a/dx/src/main/java/com/android/dx/ssa/Dominators.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashSet;
-
-/**
- * This class computes dominator and post-dominator information using the
- * Lengauer-Tarjan method.
- *
- * See A Fast Algorithm for Finding Dominators in a Flowgraph
- * T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
- *
- * This implementation runs in time O(n log n).  The time bound
- * could be changed to O(n * ack(n)) with a small change to the link and eval,
- * and an addition of a child field to the DFS info. In reality, the constant
- * overheads are high enough that the current method is faster in all but the
- * strangest artificially constructed examples.
- *
- * The basic idea behind this algorithm is to perform a DFS walk, keeping track
- * of various info about parents.  We then use this info to calculate the
- * dominators, using union-find structures to link together the DFS info,
- * then finally evaluate the union-find results to get the dominators.
- * This implementation is m log n because it does not perform union by
- * rank to keep the union-find tree balanced.
- */
-public final class Dominators {
-    /* postdom is true if we want post dominators */
-    private final boolean postdom;
-
-    /* {@code non-null;} method being processed */
-    private final SsaMethod meth;
-
-    /* Method's basic blocks. */
-    private final ArrayList<SsaBasicBlock> blocks;
-
-    /** indexed by basic block index */
-    private final DFSInfo[] info;
-
-    private final ArrayList<SsaBasicBlock> vertex;
-
-    /** {@code non-null;} the raw dominator info */
-    private final DomFront.DomInfo domInfos[];
-
-    /**
-     * Constructs an instance.
-     *
-     * @param meth {@code non-null;} method to process
-     * @param domInfos {@code non-null;} the raw dominator info
-     * @param postdom true for postdom information, false for normal dom info
-     */
-    private Dominators(SsaMethod meth, DomFront.DomInfo[] domInfos,
-            boolean postdom) {
-        this.meth = meth;
-        this.domInfos = domInfos;
-        this.postdom = postdom;
-        this.blocks = meth.getBlocks();
-        this.info = new DFSInfo[blocks.size() + 2];
-        this.vertex = new ArrayList<SsaBasicBlock>();
-    }
-
-    /**
-     * Constructs a fully-initialized instance. (This method exists so as
-     * to avoid calling a large amount of code in the constructor.)
-     *
-     * @param meth {@code non-null;} method to process
-     * @param domInfos {@code non-null;} the raw dominator info
-     * @param postdom true for postdom information, false for normal dom info
-     */
-    public static Dominators make(SsaMethod meth, DomFront.DomInfo[] domInfos,
-            boolean postdom) {
-        Dominators result = new Dominators(meth, domInfos, postdom);
-
-        result.run();
-        return result;
-    }
-
-    private BitSet getSuccs(SsaBasicBlock block) {
-        if (postdom) {
-            return block.getPredecessors();
-        } else {
-            return block.getSuccessors();
-        }
-    }
-
-    private BitSet getPreds(SsaBasicBlock block) {
-        if (postdom) {
-            return block.getSuccessors();
-        } else {
-            return block.getPredecessors();
-        }
-    }
-
-    /**
-     * Performs path compress on the DFS info.
-     *
-     * @param in Basic block whose DFS info we are path compressing.
-     */
-    private void compress(SsaBasicBlock in) {
-        DFSInfo bbInfo = info[in.getIndex()];
-        DFSInfo ancestorbbInfo = info[bbInfo.ancestor.getIndex()];
-
-        if (ancestorbbInfo.ancestor != null) {
-            ArrayList<SsaBasicBlock> worklist = new ArrayList<SsaBasicBlock>();
-            HashSet<SsaBasicBlock> visited = new HashSet<SsaBasicBlock>();
-            worklist.add(in);
-
-            while (!worklist.isEmpty()) {
-                int wsize = worklist.size();
-                SsaBasicBlock v = worklist.get(wsize - 1);
-                DFSInfo vbbInfo = info[v.getIndex()];
-                SsaBasicBlock vAncestor = vbbInfo.ancestor;
-                DFSInfo vabbInfo = info[vAncestor.getIndex()];
-
-                // Make sure we process our ancestor before ourselves.
-                if (visited.add(vAncestor) && vabbInfo.ancestor != null) {
-                    worklist.add(vAncestor);
-                    continue;
-                }
-                worklist.remove(wsize - 1);
-
-                // Update based on ancestor info.
-                if (vabbInfo.ancestor == null) {
-                    continue;
-                }
-                SsaBasicBlock vAncestorRep = vabbInfo.rep;
-                SsaBasicBlock vRep = vbbInfo.rep;
-                if (info[vAncestorRep.getIndex()].semidom
-                        < info[vRep.getIndex()].semidom) {
-                    vbbInfo.rep = vAncestorRep;
-                }
-                vbbInfo.ancestor = vabbInfo.ancestor;
-            }
-        }
-    }
-
-    private SsaBasicBlock eval(SsaBasicBlock v) {
-        DFSInfo bbInfo = info[v.getIndex()];
-
-        if (bbInfo.ancestor == null) {
-            return v;
-        }
-
-        compress(v);
-        return bbInfo.rep;
-    }
-
-    /**
-     * Performs dominator/post-dominator calculation for the control
-     * flow graph.
-     *
-     * @param meth {@code non-null;} method to analyze
-     */
-    private void run() {
-        SsaBasicBlock root = postdom
-                ? meth.getExitBlock() : meth.getEntryBlock();
-
-        if (root != null) {
-            vertex.add(root);
-            domInfos[root.getIndex()].idom = root.getIndex();
-        }
-
-        /*
-         * First we perform a DFS numbering of the blocks, by
-         * numbering the dfs tree roots.
-         */
-
-        DfsWalker walker = new DfsWalker();
-        meth.forEachBlockDepthFirst(postdom, walker);
-
-        // the largest semidom number assigned
-        int dfsMax = vertex.size() - 1;
-
-        // Now calculate semidominators.
-        for (int i = dfsMax; i >= 2; --i) {
-            SsaBasicBlock w = vertex.get(i);
-            DFSInfo wInfo = info[w.getIndex()];
-
-            BitSet preds = getPreds(w);
-            for (int j = preds.nextSetBit(0);
-                 j >= 0;
-                 j = preds.nextSetBit(j + 1)) {
-                SsaBasicBlock predBlock = blocks.get(j);
-                DFSInfo predInfo = info[predBlock.getIndex()];
-
-                /*
-                 * PredInfo may not exist in case the predecessor is
-                 * not reachable.
-                 */
-                if (predInfo != null) {
-                    int predSemidom = info[eval(predBlock).getIndex()].semidom;
-                    if (predSemidom < wInfo.semidom) {
-                        wInfo.semidom = predSemidom;
-                    }
-                }
-            }
-            info[vertex.get(wInfo.semidom).getIndex()].bucket.add(w);
-
-            /*
-             * Normally we would call link here, but in our O(m log n)
-             * implementation this is equivalent to the following
-             * single line.
-             */
-            wInfo.ancestor = wInfo.parent;
-
-            // Implicity define idom for each vertex.
-            ArrayList<SsaBasicBlock> wParentBucket;
-            wParentBucket = info[wInfo.parent.getIndex()].bucket;
-
-            while (!wParentBucket.isEmpty()) {
-                int lastItem = wParentBucket.size() - 1;
-                SsaBasicBlock last = wParentBucket.remove(lastItem);
-                SsaBasicBlock U = eval(last);
-                if (info[U.getIndex()].semidom
-                        < info[last.getIndex()].semidom) {
-                    domInfos[last.getIndex()].idom = U.getIndex();
-                } else {
-                    domInfos[last.getIndex()].idom = wInfo.parent.getIndex();
-                }
-            }
-        }
-
-        // Now explicitly define the immediate dominator of each vertex
-        for (int i =  2; i <= dfsMax; ++i) {
-            SsaBasicBlock w = vertex.get(i);
-            if (domInfos[w.getIndex()].idom
-                    != vertex.get(info[w.getIndex()].semidom).getIndex()) {
-                domInfos[w.getIndex()].idom
-                        = domInfos[domInfos[w.getIndex()].idom].idom;
-            }
-        }
-    }
-
-    /**
-     * Callback for depth-first walk through control flow graph (either
-     * from the entry block or the exit block). Records the traversal order
-     * in the {@code info}list.
-     */
-    private class DfsWalker implements SsaBasicBlock.Visitor {
-        private int dfsNum = 0;
-
-        public void visitBlock(SsaBasicBlock v, SsaBasicBlock parent) {
-            DFSInfo bbInfo = new DFSInfo();
-            bbInfo.semidom = ++dfsNum;
-            bbInfo.rep = v;
-            bbInfo.parent = parent;
-            vertex.add(v);
-            info[v.getIndex()] = bbInfo;
-        }
-    }
-
-    private static final class DFSInfo {
-        public int semidom;
-        public SsaBasicBlock parent;
-
-        /**
-         * rep(resentative) is known as "label" in the paper. It is the node
-         * that our block's DFS info has been unioned to.
-         */
-        public SsaBasicBlock rep;
-
-        public SsaBasicBlock ancestor;
-        public ArrayList<SsaBasicBlock> bucket;
-
-        public DFSInfo() {
-            bucket = new ArrayList<SsaBasicBlock>();
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/EscapeAnalysis.java b/dx/src/main/java/com/android/dx/ssa/EscapeAnalysis.java
deleted file mode 100644
index b02c929..0000000
--- a/dx/src/main/java/com/android/dx/ssa/EscapeAnalysis.java
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * Copyright (C) 2010 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.ssa;
-
-import com.android.dx.rop.code.Exceptions;
-import com.android.dx.rop.code.FillArrayDataInsn;
-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.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.ThrowingCstInsn;
-import com.android.dx.rop.code.ThrowingInsn;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-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.cst.CstType;
-import com.android.dx.rop.cst.TypedConstant;
-import com.android.dx.rop.cst.Zeroes;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Simple intraprocedural escape analysis. Finds new arrays that don't escape
- * the method they are created in and replaces the array values with registers.
- */
-public class EscapeAnalysis {
-    /**
-     * Struct used to generate and maintain escape analysis results.
-     */
-    static class EscapeSet {
-        /** set containing all registers related to an object */
-        BitSet regSet;
-        /** escape state of the object */
-        EscapeState escape;
-        /** list of objects that are put into this object */
-        ArrayList<EscapeSet> childSets;
-        /** list of objects that this object is put into */
-        ArrayList<EscapeSet> parentSets;
-        /** flag to indicate this object is a scalar replaceable array */
-        boolean replaceableArray;
-
-        /**
-         * Constructs an instance of an EscapeSet
-         *
-         * @param reg the SSA register that defines the object
-         * @param size the number of registers in the method
-         * @param escState the lattice value to initially set this to
-         */
-        EscapeSet(int reg, int size, EscapeState escState) {
-            regSet = new BitSet(size);
-            regSet.set(reg);
-            escape = escState;
-            childSets = new ArrayList<EscapeSet>();
-            parentSets = new ArrayList<EscapeSet>();
-            replaceableArray = false;
-        }
-    }
-
-    /**
-     * Lattice values used to indicate escape state for an object. Analysis can
-     * only raise escape state values, not lower them.
-     *
-     * TOP - Used for objects that haven't been analyzed yet
-     * NONE - Object does not escape, and is eligible for scalar replacement.
-     * METHOD - Object remains local to method, but can't be scalar replaced.
-     * INTER - Object is passed between methods. (treated as globally escaping
-     *         since this is an intraprocedural analysis)
-     * GLOBAL - Object escapes globally.
-     */
-    public enum EscapeState {
-        TOP, NONE, METHOD, INTER, GLOBAL
-    }
-
-    /** method we're processing */
-    private SsaMethod ssaMeth;
-    /** ssaMeth.getRegCount() */
-    private int regCount;
-    /** Lattice values for each object register group */
-    private ArrayList<EscapeSet> latticeValues;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ssaMeth method to process
-     */
-    private EscapeAnalysis(SsaMethod ssaMeth) {
-        this.ssaMeth = ssaMeth;
-        this.regCount = ssaMeth.getRegCount();
-        this.latticeValues = new ArrayList<EscapeSet>();
-    }
-
-    /**
-     * Finds the index in the lattice for a particular register.
-     * Returns the size of the lattice if the register wasn't found.
-     *
-     * @param reg {@code non-null;} register being looked up
-     * @return index of the register or size of the lattice if it wasn't found.
-     */
-    private int findSetIndex(RegisterSpec reg) {
-        int i;
-        for (i = 0; i < latticeValues.size(); i++) {
-            EscapeSet e = latticeValues.get(i);
-            if (e.regSet.get(reg.getReg())) {
-                return i;
-            }
-        }
-        return i;
-    }
-
-    /**
-     * Finds the corresponding instruction for a given move result
-     *
-     * @param moveInsn {@code non-null;} a move result instruction
-     * @return {@code non-null;} the instruction that produces the result for
-     * the move
-     */
-    private SsaInsn getInsnForMove(SsaInsn moveInsn) {
-        int pred = moveInsn.getBlock().getPredecessors().nextSetBit(0);
-        ArrayList<SsaInsn> predInsns = ssaMeth.getBlocks().get(pred).getInsns();
-        return predInsns.get(predInsns.size()-1);
-    }
-
-    /**
-     * Finds the corresponding move result for a given instruction
-     *
-     * @param insn {@code non-null;} an instruction that must always be
-     * followed by a move result
-     * @return {@code non-null;} the move result for the given instruction
-     */
-    private SsaInsn getMoveForInsn(SsaInsn insn) {
-        int succ = insn.getBlock().getSuccessors().nextSetBit(0);
-        ArrayList<SsaInsn> succInsns = ssaMeth.getBlocks().get(succ).getInsns();
-        return succInsns.get(0);
-    }
-
-    /**
-     * Creates a link in the lattice between two EscapeSets due to a put
-     * instruction. The object being put is the child and the object being put
-     * into is the parent. A child set must always have an escape state at
-     * least as high as its parent.
-     *
-     * @param parentSet {@code non-null;} the EscapeSet for the object being put
-     * into
-     * @param childSet {@code non-null;} the EscapeSet for the object being put
-     */
-    private void addEdge(EscapeSet parentSet, EscapeSet childSet) {
-        if (!childSet.parentSets.contains(parentSet)) {
-            childSet.parentSets.add(parentSet);
-        }
-        if (!parentSet.childSets.contains(childSet)) {
-            parentSet.childSets.add(childSet);
-        }
-    }
-
-    /**
-     * Merges all links in the lattice among two EscapeSets. On return, the
-     * newNode will have its old links as well as all links from the oldNode.
-     * The oldNode has all its links removed.
-     *
-     * @param newNode {@code non-null;} the EscapeSet to merge all links into
-     * @param oldNode {@code non-null;} the EscapeSet to remove all links from
-     */
-    private void replaceNode(EscapeSet newNode, EscapeSet oldNode) {
-        for (EscapeSet e : oldNode.parentSets) {
-            e.childSets.remove(oldNode);
-            e.childSets.add(newNode);
-            newNode.parentSets.add(e);
-        }
-        for (EscapeSet e : oldNode.childSets) {
-            e.parentSets.remove(oldNode);
-            e.parentSets.add(newNode);
-            newNode.childSets.add(e);
-        }
-    }
-
-    /**
-     * Performs escape analysis on a method. Finds scalar replaceable arrays and
-     * replaces them with equivalent registers.
-     *
-     * @param ssaMethod {@code non-null;} method to process
-     */
-    public static void process(SsaMethod ssaMethod) {
-        new EscapeAnalysis(ssaMethod).run();
-    }
-
-    /**
-     * Process a single instruction, looking for new objects resulting from
-     * move result or move param.
-     *
-     * @param insn {@code non-null;} instruction to process
-     */
-    private void processInsn(SsaInsn insn) {
-        int op = insn.getOpcode().getOpcode();
-        RegisterSpec result = insn.getResult();
-        EscapeSet escSet;
-
-        // Identify new objects
-        if (op == RegOps.MOVE_RESULT_PSEUDO &&
-                result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
-            // Handle objects generated through move_result_pseudo
-            escSet = processMoveResultPseudoInsn(insn);
-            processRegister(result, escSet);
-        } else if (op == RegOps.MOVE_PARAM &&
-                      result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
-            // Track method arguments that are objects
-            escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
-            latticeValues.add(escSet);
-            processRegister(result, escSet);
-        } else if (op == RegOps.MOVE_RESULT &&
-                result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
-            // Track method return values that are objects
-            escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
-            latticeValues.add(escSet);
-            processRegister(result, escSet);
-        }
-    }
-
-    /**
-     * Determine the origin of a move result pseudo instruction that generates
-     * an object. Creates a new EscapeSet for the new object accordingly.
-     *
-     * @param insn {@code non-null;} move result pseudo instruction to process
-     * @return {@code non-null;} an EscapeSet for the object referred to by the
-     * move result pseudo instruction
-     */
-    private EscapeSet processMoveResultPseudoInsn(SsaInsn insn) {
-        RegisterSpec result = insn.getResult();
-        SsaInsn prevSsaInsn = getInsnForMove(insn);
-        int prevOpcode = prevSsaInsn.getOpcode().getOpcode();
-        EscapeSet escSet;
-        RegisterSpec prevSource;
-
-        switch(prevOpcode) {
-           // New instance / Constant
-            case RegOps.NEW_INSTANCE:
-            case RegOps.CONST:
-                escSet = new EscapeSet(result.getReg(), regCount,
-                                           EscapeState.NONE);
-                break;
-            // New array
-            case RegOps.NEW_ARRAY:
-            case RegOps.FILLED_NEW_ARRAY:
-                prevSource = prevSsaInsn.getSources().get(0);
-                if (prevSource.getTypeBearer().isConstant()) {
-                    // New fixed array
-                    escSet = new EscapeSet(result.getReg(), regCount,
-                                               EscapeState.NONE);
-                    escSet.replaceableArray = true;
-                } else {
-                    // New variable array
-                    escSet = new EscapeSet(result.getReg(), regCount,
-                                               EscapeState.GLOBAL);
-                }
-                break;
-            // Loading a static object
-            case RegOps.GET_STATIC:
-                escSet = new EscapeSet(result.getReg(), regCount,
-                                           EscapeState.GLOBAL);
-                break;
-            // Type cast / load an object from a field or array
-            case RegOps.CHECK_CAST:
-            case RegOps.GET_FIELD:
-            case RegOps.AGET:
-                prevSource = prevSsaInsn.getSources().get(0);
-                int setIndex = findSetIndex(prevSource);
-
-                // Set should already exist, try to find it
-                if (setIndex != latticeValues.size()) {
-                    escSet = latticeValues.get(setIndex);
-                    escSet.regSet.set(result.getReg());
-                    return escSet;
-                }
-
-                // Set not found, must be either null or unknown
-                if (prevSource.getType() == Type.KNOWN_NULL) {
-                    escSet = new EscapeSet(result.getReg(), regCount,
-                                               EscapeState.NONE);
-               } else {
-                    escSet = new EscapeSet(result.getReg(), regCount,
-                                               EscapeState.GLOBAL);
-                }
-                break;
-            default:
-                return null;
-        }
-
-        // Add the newly created escSet to the lattice and return it
-        latticeValues.add(escSet);
-        return escSet;
-    }
-
-    /**
-     * Iterate through all the uses of a new object.
-     *
-     * @param result {@code non-null;} register where new object is stored
-     * @param escSet {@code non-null;} EscapeSet for the new object
-     */
-    private void processRegister(RegisterSpec result, EscapeSet escSet) {
-        ArrayList<RegisterSpec> regWorklist = new ArrayList<RegisterSpec>();
-        regWorklist.add(result);
-
-        // Go through the worklist
-        while (!regWorklist.isEmpty()) {
-            int listSize = regWorklist.size() - 1;
-            RegisterSpec def = regWorklist.remove(listSize);
-            List<SsaInsn> useList = ssaMeth.getUseListForRegister(def.getReg());
-
-            // Handle all the uses of this register
-            for (SsaInsn use : useList) {
-                Rop useOpcode = use.getOpcode();
-
-                if (useOpcode == null) {
-                    // Handle phis
-                    processPhiUse(use, escSet, regWorklist);
-                } else {
-                    // Handle other opcodes
-                    processUse(def, use, escSet, regWorklist);
-                }
-            }
-        }
-    }
-
-    /**
-     * Handles phi uses of new objects. Will merge together the sources of a phi
-     * into a single EscapeSet. Adds the result of the phi to the worklist so
-     * its uses can be followed.
-     *
-     * @param use {@code non-null;} phi use being processed
-     * @param escSet {@code non-null;} EscapeSet for the object
-     * @param regWorklist {@code non-null;} worklist of instructions left to
-     * process for this object
-     */
-    private void processPhiUse(SsaInsn use, EscapeSet escSet,
-                                   ArrayList<RegisterSpec> regWorklist) {
-        int setIndex = findSetIndex(use.getResult());
-        if (setIndex != latticeValues.size()) {
-            // Check if result is in a set already
-            EscapeSet mergeSet = latticeValues.get(setIndex);
-            if (mergeSet != escSet) {
-                // If it is, merge the sets and states, then delete the copy
-                escSet.replaceableArray = false;
-                escSet.regSet.or(mergeSet.regSet);
-                if (escSet.escape.compareTo(mergeSet.escape) < 0) {
-                    escSet.escape = mergeSet.escape;
-                }
-                replaceNode(escSet, mergeSet);
-                latticeValues.remove(setIndex);
-            }
-        } else {
-            // If no set is found, add it to this escSet and the worklist
-            escSet.regSet.set(use.getResult().getReg());
-            regWorklist.add(use.getResult());
-        }
-    }
-
-    /**
-     * Handles non-phi uses of new objects. Checks to see how instruction is
-     * used and updates the escape state accordingly.
-     *
-     * @param def {@code non-null;} register holding definition of new object
-     * @param use {@code non-null;} use of object being processed
-     * @param escSet {@code non-null;} EscapeSet for the object
-     * @param regWorklist {@code non-null;} worklist of instructions left to
-     * process for this object
-     */
-    private void processUse(RegisterSpec def, SsaInsn use, EscapeSet escSet,
-                                ArrayList<RegisterSpec> regWorklist) {
-        int useOpcode = use.getOpcode().getOpcode();
-        switch (useOpcode) {
-            case RegOps.MOVE:
-                // Follow uses of the move by adding it to the worklist
-                escSet.regSet.set(use.getResult().getReg());
-                regWorklist.add(use.getResult());
-                break;
-            case RegOps.IF_EQ:
-            case RegOps.IF_NE:
-            case RegOps.CHECK_CAST:
-                // Compared objects can't be replaced, so promote if necessary
-                if (escSet.escape.compareTo(EscapeState.METHOD) < 0) {
-                    escSet.escape = EscapeState.METHOD;
-                }
-                break;
-            case RegOps.APUT:
-                // For array puts, check for a constant array index
-                RegisterSpec putIndex = use.getSources().get(2);
-                if (!putIndex.getTypeBearer().isConstant()) {
-                    // If not constant, array can't be replaced
-                    escSet.replaceableArray = false;
-                }
-                // Intentional fallthrough
-            case RegOps.PUT_FIELD:
-                // Skip non-object puts
-                RegisterSpec putValue = use.getSources().get(0);
-                if (putValue.getTypeBearer().getBasicType() != Type.BT_OBJECT) {
-                    break;
-                }
-                escSet.replaceableArray = false;
-
-                // Raise 1st object's escape state to 2nd if 2nd is higher
-                RegisterSpecList sources = use.getSources();
-                if (sources.get(0).getReg() == def.getReg()) {
-                    int setIndex = findSetIndex(sources.get(1));
-                    if (setIndex != latticeValues.size()) {
-                        EscapeSet parentSet = latticeValues.get(setIndex);
-                        addEdge(parentSet, escSet);
-                        if (escSet.escape.compareTo(parentSet.escape) < 0) {
-                            escSet.escape = parentSet.escape;
-                        }
-                    }
-                } else {
-                    int setIndex = findSetIndex(sources.get(0));
-                    if (setIndex != latticeValues.size()) {
-                        EscapeSet childSet = latticeValues.get(setIndex);
-                        addEdge(escSet, childSet);
-                        if (childSet.escape.compareTo(escSet.escape) < 0) {
-                            childSet.escape = escSet.escape;
-                        }
-                    }
-                }
-                break;
-            case RegOps.AGET:
-                // For array gets, check for a constant array index
-                RegisterSpec getIndex = use.getSources().get(1);
-                if (!getIndex.getTypeBearer().isConstant()) {
-                    // If not constant, array can't be replaced
-                    escSet.replaceableArray = false;
-                }
-                break;
-            case RegOps.PUT_STATIC:
-                // Static puts cause an object to escape globally
-                escSet.escape = EscapeState.GLOBAL;
-                break;
-            case RegOps.INVOKE_STATIC:
-            case RegOps.INVOKE_VIRTUAL:
-            case RegOps.INVOKE_SUPER:
-            case RegOps.INVOKE_DIRECT:
-            case RegOps.INVOKE_INTERFACE:
-            case RegOps.RETURN:
-            case RegOps.THROW:
-                // These operations cause an object to escape interprocedurally
-                escSet.escape = EscapeState.INTER;
-                break;
-            default:
-                break;
-        }
-    }
-
-    /**
-     * Performs scalar replacement on all eligible arrays.
-     */
-    private void scalarReplacement() {
-        // Iterate through lattice, looking for non-escaping replaceable arrays
-        for (EscapeSet escSet : latticeValues) {
-            if (!escSet.replaceableArray || escSet.escape != EscapeState.NONE) {
-                continue;
-            }
-
-            // Get the instructions for the definition and move of the array
-            int e = escSet.regSet.nextSetBit(0);
-            SsaInsn def = ssaMeth.getDefinitionForRegister(e);
-            SsaInsn prev = getInsnForMove(def);
-
-            // Create a map for the new registers that will be created
-            TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
-            int length = ((CstLiteralBits) lengthReg).getIntBits();
-            ArrayList<RegisterSpec> newRegs =
-                new ArrayList<RegisterSpec>(length);
-            HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
-
-            // Replace the definition of the array with registers
-            replaceDef(def, prev, length, newRegs);
-
-            // Mark definition instructions for deletion
-            deletedInsns.add(prev);
-            deletedInsns.add(def);
-
-            // Go through all uses of the array
-            List<SsaInsn> useList = ssaMeth.getUseListForRegister(e);
-            for (SsaInsn use : useList) {
-                // Replace the use with scalars and then mark it for deletion
-                replaceUse(use, prev, newRegs, deletedInsns);
-                deletedInsns.add(use);
-            }
-
-            // Delete all marked instructions
-            ssaMeth.deleteInsns(deletedInsns);
-            ssaMeth.onInsnsChanged();
-
-            // Convert the method back to SSA form
-            SsaConverter.updateSsaMethod(ssaMeth, regCount);
-
-            // Propagate and remove extra moves added by scalar replacement
-            movePropagate();
-        }
-    }
-
-    /**
-     * Replaces the instructions that define an array with equivalent registers.
-     * For each entry in the array, a register is created, initialized to zero.
-     * A mapping between this register and the corresponding array index is
-     * added.
-     *
-     * @param def {@code non-null;} move result instruction for array
-     * @param prev {@code non-null;} instruction for instantiating new array
-     * @param length size of the new array
-     * @param newRegs {@code non-null;} mapping of array indices to new
-     * registers to be populated
-     */
-    private void replaceDef(SsaInsn def, SsaInsn prev, int length,
-                                ArrayList<RegisterSpec> newRegs) {
-        Type resultType = def.getResult().getType();
-
-        // Create new zeroed out registers for each element in the array
-        for (int i = 0; i < length; i++) {
-            Constant newZero = Zeroes.zeroFor(resultType.getComponentType());
-            TypedConstant typedZero = (TypedConstant) newZero;
-            RegisterSpec newReg =
-                RegisterSpec.make(ssaMeth.makeNewSsaReg(), typedZero);
-            newRegs.add(newReg);
-            insertPlainInsnBefore(def, RegisterSpecList.EMPTY, newReg,
-                                      RegOps.CONST, newZero);
-        }
-    }
-
-    /**
-     * Replaces the use for a scalar replaceable array. Gets and puts become
-     * move instructions, and array lengths and fills are handled. Can also
-     * identify ArrayIndexOutOfBounds exceptions and throw them if detected.
-     *
-     * @param use {@code non-null;} move result instruction for array
-     * @param prev {@code non-null;} instruction for instantiating new array
-     * @param newRegs {@code non-null;} mapping of array indices to new
-     * registers
-     * @param deletedInsns {@code non-null;} set of instructions marked for
-     * deletion
-     */
-    private void replaceUse(SsaInsn use, SsaInsn prev,
-                                ArrayList<RegisterSpec> newRegs,
-                                HashSet<SsaInsn> deletedInsns) {
-        int index;
-        int length = newRegs.size();
-        SsaInsn next;
-        RegisterSpecList sources;
-        RegisterSpec source, result;
-        CstLiteralBits indexReg;
-
-        switch (use.getOpcode().getOpcode()) {
-            case RegOps.AGET:
-                // Replace array gets with moves
-                next = getMoveForInsn(use);
-                sources = use.getSources();
-                indexReg = ((CstLiteralBits) sources.get(1).getTypeBearer());
-                index = indexReg.getIntBits();
-                if (index < length) {
-                    source = newRegs.get(index);
-                    result = source.withReg(next.getResult().getReg());
-                    insertPlainInsnBefore(next, RegisterSpecList.make(source),
-                                              result, RegOps.MOVE, null);
-                } else {
-                    // Throw an exception if the index is out of bounds
-                    insertExceptionThrow(next, sources.get(1), deletedInsns);
-                    deletedInsns.add(next.getBlock().getInsns().get(2));
-                }
-                deletedInsns.add(next);
-                break;
-            case RegOps.APUT:
-                // Replace array puts with moves
-                sources = use.getSources();
-                indexReg = ((CstLiteralBits) sources.get(2).getTypeBearer());
-                index = indexReg.getIntBits();
-                if (index < length) {
-                    source = sources.get(0);
-                    result = source.withReg(newRegs.get(index).getReg());
-                    insertPlainInsnBefore(use, RegisterSpecList.make(source),
-                                              result, RegOps.MOVE, null);
-                    // Update the newReg entry to mark value as unknown now
-                    newRegs.set(index, result.withSimpleType());
-                } else {
-                    // Throw an exception if the index is out of bounds
-                    insertExceptionThrow(use, sources.get(2), deletedInsns);
-                }
-                break;
-            case RegOps.ARRAY_LENGTH:
-                // Replace array lengths with const instructions
-                TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
-                //CstInteger lengthReg = CstInteger.make(length);
-                next = getMoveForInsn(use);
-                insertPlainInsnBefore(next, RegisterSpecList.EMPTY,
-                                          next.getResult(), RegOps.CONST,
-                                          (Constant) lengthReg);
-                deletedInsns.add(next);
-                break;
-            case RegOps.MARK_LOCAL:
-                // Remove mark local instructions
-                break;
-            case RegOps.FILL_ARRAY_DATA:
-                // Create const instructions for each fill value
-                Insn ropUse = use.getOriginalRopInsn();
-                FillArrayDataInsn fill = (FillArrayDataInsn) ropUse;
-                ArrayList<Constant> constList = fill.getInitValues();
-                for (int i = 0; i < length; i++) {
-                    RegisterSpec newFill =
-                        RegisterSpec.make(newRegs.get(i).getReg(),
-                                              (TypeBearer) constList.get(i));
-                    insertPlainInsnBefore(use, RegisterSpecList.EMPTY, newFill,
-                                              RegOps.CONST, constList.get(i));
-                    // Update the newRegs to hold the new const value
-                    newRegs.set(i, newFill);
-                }
-                break;
-            default:
-        }
-    }
-
-    /**
-     * Identifies extra moves added by scalar replacement and propagates the
-     * source of the move to any users of the result.
-     */
-    private void movePropagate() {
-        for (int i = 0; i < ssaMeth.getRegCount(); i++) {
-            SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
-
-            // Look for move instructions only
-            if (insn == null || insn.getOpcode() == null ||
-                insn.getOpcode().getOpcode() != RegOps.MOVE) {
-                continue;
-            }
-
-            final ArrayList<SsaInsn>[] useList = ssaMeth.getUseListCopy();
-            final RegisterSpec source = insn.getSources().get(0);
-            final RegisterSpec result = insn.getResult();
-
-            // Ignore moves that weren't added due to scalar replacement
-            if (source.getReg() < regCount && result.getReg() < regCount) {
-                continue;
-            }
-
-            // Create a mapping from source to result
-            RegisterMapper mapper = new RegisterMapper() {
-                @Override
-                public int getNewRegisterCount() {
-                    return ssaMeth.getRegCount();
-                }
-
-                @Override
-                public RegisterSpec map(RegisterSpec registerSpec) {
-                    if (registerSpec.getReg() == result.getReg()) {
-                        return source;
-                    }
-
-                    return registerSpec;
-                }
-            };
-
-            // Modify all uses of the move to use the source of the move instead
-            for (SsaInsn use : useList[result.getReg()]) {
-                use.mapSourceRegisters(mapper);
-            }
-        }
-    }
-
-    /**
-     * Runs escape analysis and scalar replacement of arrays.
-     */
-    private void run() {
-        ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {
-            public void visitBlock (SsaBasicBlock block,
-                    SsaBasicBlock unused) {
-                block.forEachInsn(new SsaInsn.Visitor() {
-                    public void visitMoveInsn(NormalSsaInsn insn) {
-                        // do nothing
-                    }
-
-                    public void visitPhiInsn(PhiInsn insn) {
-                        // do nothing
-                    }
-
-                    public void visitNonMoveInsn(NormalSsaInsn insn) {
-                        processInsn(insn);
-                    }
-                });
-            }
-        });
-
-        // Go through lattice and promote fieldSets as necessary
-        for (EscapeSet e : latticeValues) {
-            if (e.escape != EscapeState.NONE) {
-                for (EscapeSet field : e.childSets) {
-                    if (e.escape.compareTo(field.escape) > 0) {
-                        field.escape = e.escape;
-                    }
-                }
-            }
-        }
-
-        // Perform scalar replacement for arrays
-        scalarReplacement();
-    }
-
-    /**
-     * Replaces instructions that trigger an ArrayIndexOutofBounds exception
-     * with an actual throw of the exception.
-     *
-     * @param insn {@code non-null;} instruction causing the exception
-     * @param index {@code non-null;} index value that is out of bounds
-     * @param deletedInsns {@code non-null;} set of instructions marked for
-     * deletion
-     */
-    private void insertExceptionThrow(SsaInsn insn, RegisterSpec index,
-                                          HashSet<SsaInsn> deletedInsns) {
-        // Create a new ArrayIndexOutOfBoundsException
-        CstType exception =
-            new CstType(Exceptions.TYPE_ArrayIndexOutOfBoundsException);
-        insertThrowingInsnBefore(insn, RegisterSpecList.EMPTY, null,
-                                     RegOps.NEW_INSTANCE, exception);
-
-        // Add a successor block with a move result pseudo for the exception
-        SsaBasicBlock currBlock = insn.getBlock();
-        SsaBasicBlock newBlock =
-            currBlock.insertNewSuccessor(currBlock.getPrimarySuccessor());
-        SsaInsn newInsn = newBlock.getInsns().get(0);
-        RegisterSpec newReg =
-            RegisterSpec.make(ssaMeth.makeNewSsaReg(), exception);
-        insertPlainInsnBefore(newInsn, RegisterSpecList.EMPTY, newReg,
-                                  RegOps.MOVE_RESULT_PSEUDO, null);
-
-        // Add another successor block to initialize the exception
-        SsaBasicBlock newBlock2 =
-            newBlock.insertNewSuccessor(newBlock.getPrimarySuccessor());
-        SsaInsn newInsn2 = newBlock2.getInsns().get(0);
-        CstNat newNat = new CstNat(new CstString("<init>"), new CstString("(I)V"));
-        CstMethodRef newRef = new CstMethodRef(exception, newNat);
-        insertThrowingInsnBefore(newInsn2, RegisterSpecList.make(newReg, index),
-                                     null, RegOps.INVOKE_DIRECT, newRef);
-        deletedInsns.add(newInsn2);
-
-        // Add another successor block to throw the new exception
-        SsaBasicBlock newBlock3 =
-            newBlock2.insertNewSuccessor(newBlock2.getPrimarySuccessor());
-        SsaInsn newInsn3 = newBlock3.getInsns().get(0);
-        insertThrowingInsnBefore(newInsn3, RegisterSpecList.make(newReg), null,
-                                     RegOps.THROW, null);
-        newBlock3.replaceSuccessor(newBlock3.getPrimarySuccessorIndex(),
-                                       ssaMeth.getExitBlock().getIndex());
-        deletedInsns.add(newInsn3);
-    }
-
-    /**
-     * Inserts a new PlainInsn before the given instruction.
-     * TODO: move this somewhere more appropriate
-     *
-     * @param insn {@code non-null;} instruction to insert before
-     * @param newSources {@code non-null;} sources of new instruction
-     * @param newResult {@code non-null;} result of new instruction
-     * @param newOpcode opcode of new instruction
-     * @param cst {@code null-ok;} constant for new instruction, if any
-     */
-    private void insertPlainInsnBefore(SsaInsn insn,
-        RegisterSpecList newSources, RegisterSpec newResult, int newOpcode,
-        Constant cst) {
-
-        Insn originalRopInsn = insn.getOriginalRopInsn();
-        Rop newRop;
-        if (newOpcode == RegOps.MOVE_RESULT_PSEUDO) {
-            newRop = Rops.opMoveResultPseudo(newResult.getType());
-        } else {
-            newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);
-        }
-
-        Insn newRopInsn;
-        if (cst == null) {
-            newRopInsn = new PlainInsn(newRop,
-                    originalRopInsn.getPosition(), newResult, newSources);
-        } else {
-            newRopInsn = new PlainCstInsn(newRop,
-                originalRopInsn.getPosition(), newResult, newSources, cst);
-        }
-
-        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
-        List<SsaInsn> insns = insn.getBlock().getInsns();
-
-        insns.add(insns.lastIndexOf(insn), newInsn);
-        ssaMeth.onInsnAdded(newInsn);
-    }
-
-    /**
-     * Inserts a new ThrowingInsn before the given instruction.
-     * TODO: move this somewhere more appropriate
-     *
-     * @param insn {@code non-null;} instruction to insert before
-     * @param newSources {@code non-null;} sources of new instruction
-     * @param newResult {@code non-null;} result of new instruction
-     * @param newOpcode opcode of new instruction
-     * @param cst {@code null-ok;} constant for new instruction, if any
-     */
-    private void insertThrowingInsnBefore(SsaInsn insn,
-        RegisterSpecList newSources, RegisterSpec newResult, int newOpcode,
-        Constant cst) {
-
-        Insn origRopInsn = insn.getOriginalRopInsn();
-        Rop newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);
-        Insn newRopInsn;
-        if (cst == null) {
-            newRopInsn = new ThrowingInsn(newRop,
-                origRopInsn.getPosition(), newSources, StdTypeList.EMPTY);
-        } else {
-            newRopInsn = new ThrowingCstInsn(newRop,
-                origRopInsn.getPosition(), newSources, StdTypeList.EMPTY, cst);
-        }
-
-        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
-        List<SsaInsn> insns = insn.getBlock().getInsns();
-
-        insns.add(insns.lastIndexOf(insn), newInsn);
-        ssaMeth.onInsnAdded(newInsn);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/InterferenceRegisterMapper.java b/dx/src/main/java/com/android/dx/ssa/InterferenceRegisterMapper.java
deleted file mode 100644
index 851249b..0000000
--- a/dx/src/main/java/com/android/dx/ssa/InterferenceRegisterMapper.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.ssa.back.InterferenceGraph;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.BitIntSet;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-
-/**
- * A register mapper that keeps track of the accumulated interference
- * information for the registers in the new namespace.
- *
- * Please note that this mapper requires that the old namespace does not
- * have variable register widths/categories, and the new namespace does.
- */
-public class InterferenceRegisterMapper extends BasicRegisterMapper {
-    /**
-     * Array of interference sets. ArrayList is indexed by new namespace
-     * and BitIntSet's are indexed by old namespace.  The list expands
-     * as needed and missing items are assumed to interfere with nothing.
-     *
-     * Bit sets are always used here, unlike elsewhere, because the max
-     * size of this matrix will be (countSsaRegs * countRopRegs), which may
-     * grow to hundreds of K but not megabytes.
-     */
-    private final ArrayList<BitIntSet> newRegInterference;
-
-    /** the interference graph for the old namespace */
-    private final InterferenceGraph oldRegInterference;
-
-    /**
-     * Constructs an instance
-     *
-     * @param countOldRegisters number of registers in old namespace
-     */
-    public InterferenceRegisterMapper(InterferenceGraph oldRegInterference,
-            int countOldRegisters) {
-        super(countOldRegisters);
-
-        newRegInterference = new ArrayList<BitIntSet>();
-        this.oldRegInterference = oldRegInterference;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void addMapping(int oldReg, int newReg, int category) {
-        super.addMapping(oldReg, newReg, category);
-
-        addInterfence(newReg, oldReg);
-
-        if (category == 2) {
-            addInterfence(newReg + 1, oldReg);
-        }
-    }
-
-    /**
-     * Checks to see if old namespace reg {@code oldReg} interferes
-     * with what currently maps to {@code newReg}.
-     *
-     * @param oldReg old namespace register
-     * @param newReg new namespace register
-     * @param category category of old namespace register
-     * @return true if oldReg will interfere with newReg
-     */
-    public boolean interferes(int oldReg, int newReg, int category) {
-        if (newReg >= newRegInterference.size()) {
-            return false;
-        } else {
-            IntSet existing = newRegInterference.get(newReg);
-
-            if (existing == null) {
-                return false;
-            } else if (category == 1) {
-                return existing.has(oldReg);
-            } else {
-                return existing.has(oldReg)
-                        || (interferes(oldReg, newReg+1, category-1));
-            }
-        }
-    }
-
-    /**
-     * Checks to see if old namespace reg {@code oldReg} interferes
-     * with what currently maps to {@code newReg}.
-     *
-     * @param oldSpec {@code non-null;} old namespace register
-     * @param newReg new namespace register
-     * @return true if oldReg will interfere with newReg
-     */
-    public boolean interferes(RegisterSpec oldSpec, int newReg) {
-        return interferes(oldSpec.getReg(), newReg, oldSpec.getCategory());
-    }
-
-    /**
-     * Adds a register's interference set to the interference list,
-     * growing it if necessary.
-     *
-     * @param newReg register in new namespace
-     * @param oldReg register in old namespace
-     */
-    private void addInterfence(int newReg, int oldReg) {
-        newRegInterference.ensureCapacity(newReg + 1);
-
-        while (newReg >= newRegInterference.size()) {
-            newRegInterference.add(new BitIntSet(newReg +1));
-        }
-
-        oldRegInterference.mergeInterferenceSet(
-                oldReg, newRegInterference.get(newReg));
-    }
-
-    /**
-     * Checks to see if any of a set of old-namespace registers are
-     * pinned to the specified new-namespace reg + category. Takes into
-     * account the category of the old-namespace registers.
-     *
-     * @param oldSpecs {@code non-null;} set of old-namespace regs
-     * @param newReg {@code >= 0;} new-namespace register
-     * @param targetCategory {@code 1..2;} the number of adjacent new-namespace
-     * registers (starting at ropReg) to consider
-     * @return true if any of the old-namespace register have been mapped
-     * to the new-namespace register + category
-     */
-    public boolean areAnyPinned(RegisterSpecList oldSpecs,
-            int newReg, int targetCategory) {
-        int sz = oldSpecs.size();
-
-        for (int i = 0; i < sz; i++) {
-            RegisterSpec oldSpec = oldSpecs.get(i);
-            int r = oldToNew(oldSpec.getReg());
-
-            /*
-             * If oldSpec is a category-2 register, then check both newReg
-             * and newReg - 1.
-             */
-            if (r == newReg
-                || (oldSpec.getCategory() == 2 && (r + 1) == newReg)
-                || (targetCategory == 2 && (r == newReg + 1))) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/LiteralOpUpgrader.java b/dx/src/main/java/com/android/dx/ssa/LiteralOpUpgrader.java
deleted file mode 100644
index f3976f2..0000000
--- a/dx/src/main/java/com/android/dx/ssa/LiteralOpUpgrader.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.PlainCstInsn;
-import com.android.dx.rop.code.TranslationAdvice;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Upgrades insn to their literal (constant-immediate) equivalent if possible.
- * Also switches IF instructions that compare with a constant zero or null
- * to be their IF_*Z equivalents.
- */
-public class LiteralOpUpgrader {
-
-    /** method we're processing */
-    private final SsaMethod ssaMeth;
-
-    /**
-     * Process a method.
-     *
-     * @param ssaMethod {@code non-null;} method to process
-     */
-    public static void process(SsaMethod ssaMethod) {
-        LiteralOpUpgrader dc;
-
-        dc = new LiteralOpUpgrader(ssaMethod);
-
-        dc.run();
-    }
-
-    private LiteralOpUpgrader(SsaMethod ssaMethod) {
-        this.ssaMeth = ssaMethod;
-    }
-
-    /**
-     * Returns true if the register contains an integer 0 or a known-null
-     * object reference
-     *
-     * @param spec non-null spec
-     * @return true for 0 or null type bearers
-     */
-    private static boolean isConstIntZeroOrKnownNull(RegisterSpec spec) {
-        TypeBearer tb = spec.getTypeBearer();
-        if (tb instanceof CstLiteralBits) {
-            CstLiteralBits clb = (CstLiteralBits) tb;
-            return (clb.getLongBits() == 0);
-        }
-        return false;
-    }
-
-    /**
-     * Run the literal op upgrader
-     */
-    private void run() {
-        final TranslationAdvice advice = Optimizer.getAdvice();
-
-        ssaMeth.forEachInsn(new SsaInsn.Visitor() {
-            public void visitMoveInsn(NormalSsaInsn insn) {
-                // do nothing
-            }
-
-            public void visitPhiInsn(PhiInsn insn) {
-                // do nothing
-            }
-
-            public void visitNonMoveInsn(NormalSsaInsn insn) {
-
-                Insn originalRopInsn = insn.getOriginalRopInsn();
-                Rop opcode = originalRopInsn.getOpcode();
-                RegisterSpecList sources = insn.getSources();
-
-                // Replace insns with constant results with const insns
-                if (tryReplacingWithConstant(insn)) return;
-
-                if (sources.size() != 2 ) {
-                    // We're only dealing with two-source insns here.
-                    return;
-                }
-
-                if (opcode.getBranchingness() == Rop.BRANCH_IF) {
-                    /*
-                     * An if instruction can become an if-*z instruction.
-                     */
-                    if (isConstIntZeroOrKnownNull(sources.get(0))) {
-                        replacePlainInsn(insn, sources.withoutFirst(),
-                              RegOps.flippedIfOpcode(opcode.getOpcode()), null);
-                    } else if (isConstIntZeroOrKnownNull(sources.get(1))) {
-                        replacePlainInsn(insn, sources.withoutLast(),
-                              opcode.getOpcode(), null);
-                    }
-                } else if (advice.hasConstantOperation(
-                        opcode, sources.get(0), sources.get(1))) {
-                    insn.upgradeToLiteral();
-                } else  if (opcode.isCommutative()
-                        && advice.hasConstantOperation(
-                        opcode, sources.get(1), sources.get(0))) {
-                    /*
-                     * An instruction can be commuted to a literal operation
-                     */
-
-                    insn.setNewSources(
-                            RegisterSpecList.make(
-                                    sources.get(1), sources.get(0)));
-
-                    insn.upgradeToLiteral();
-                }
-            }
-        });
-    }
-
-    /**
-     * Tries to replace an instruction with a const instruction. The given
-     * instruction must have a constant result for it to be replaced.
-     *
-     * @param insn {@code non-null;} instruction to try to replace
-     * @return true if the instruction was replaced
-     */
-    private boolean tryReplacingWithConstant(NormalSsaInsn insn) {
-        Insn originalRopInsn = insn.getOriginalRopInsn();
-        Rop opcode = originalRopInsn.getOpcode();
-        RegisterSpec result = insn.getResult();
-
-        if (result != null && !ssaMeth.isRegALocal(result) &&
-                opcode.getOpcode() != RegOps.CONST) {
-            TypeBearer type = insn.getResult().getTypeBearer();
-            if (type.isConstant() && type.getBasicType() == Type.BT_INT) {
-                // Replace the instruction with a constant
-                replacePlainInsn(insn, RegisterSpecList.EMPTY,
-                        RegOps.CONST, (Constant) type);
-
-                // Remove the source as well if this is a move-result-pseudo
-                if (opcode.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
-                    int pred = insn.getBlock().getPredecessors().nextSetBit(0);
-                    ArrayList<SsaInsn> predInsns =
-                            ssaMeth.getBlocks().get(pred).getInsns();
-                    NormalSsaInsn sourceInsn =
-                            (NormalSsaInsn) predInsns.get(predInsns.size()-1);
-                    replacePlainInsn(sourceInsn, RegisterSpecList.EMPTY,
-                            RegOps.GOTO, null);
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The
-     * new PlainInsn is constructed with a new RegOp and new sources.
-     *
-     * TODO move this somewhere else.
-     *
-     * @param insn {@code non-null;} an SsaInsn containing a PlainInsn
-     * @param newSources {@code non-null;} new sources list for new insn
-     * @param newOpcode A RegOp from {@link RegOps}
-     * @param cst {@code null-ok;} constant for new instruction, if any
-     */
-    private void replacePlainInsn(NormalSsaInsn insn,
-            RegisterSpecList newSources, int newOpcode, Constant cst) {
-
-        Insn originalRopInsn = insn.getOriginalRopInsn();
-        Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);
-        Insn newRopInsn;
-        if (cst == null) {
-            newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(),
-                    insn.getResult(), newSources);
-        } else {
-            newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(),
-                    insn.getResult(), newSources, cst);
-        }
-        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
-
-        List<SsaInsn> insns = insn.getBlock().getInsns();
-
-        ssaMeth.onInsnRemoved(insn);
-        insns.set(insns.lastIndexOf(insn), newInsn);
-        ssaMeth.onInsnAdded(newInsn);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/LocalVariableExtractor.java b/dx/src/main/java/com/android/dx/ssa/LocalVariableExtractor.java
deleted file mode 100644
index 11d53cf..0000000
--- a/dx/src/main/java/com/android/dx/ssa/LocalVariableExtractor.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-
-/**
- * Code to figure out which local variables are active at which points in
- * a method. Stolen and retrofitted from
- * com.android.dx.rop.code.LocalVariableExtractor
- *
- * TODO remove this. Allow Rop-form LocalVariableInfo to be passed in,
- * converted, and adapted through edge-splitting.
- */
-public class LocalVariableExtractor {
-    /** {@code non-null;} method being extracted from */
-    private final SsaMethod method;
-
-    /** {@code non-null;} block list for the method */
-    private final ArrayList<SsaBasicBlock> blocks;
-
-    /** {@code non-null;} result in-progress */
-    private final LocalVariableInfo resultInfo;
-
-    /** {@code non-null;} work set indicating blocks needing to be processed */
-    private final BitSet workSet;
-
-    /**
-     * Extracts out all the local variable information from the given method.
-     *
-     * @param method {@code non-null;} the method to extract from
-     * @return {@code non-null;} the extracted information
-     */
-    public static LocalVariableInfo extract(SsaMethod method) {
-        LocalVariableExtractor lve = new LocalVariableExtractor(method);
-        return lve.doit();
-    }
-
-    /**
-     * Constructs an instance. This method is private. Use {@link #extract}.
-     *
-     * @param method {@code non-null;} the method to extract from
-     */
-    private LocalVariableExtractor(SsaMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        ArrayList<SsaBasicBlock> blocks = method.getBlocks();
-
-        this.method = method;
-        this.blocks = blocks;
-        this.resultInfo = new LocalVariableInfo(method);
-        this.workSet = new BitSet(blocks.size());
-    }
-
-    /**
-     * Does the extraction.
-     *
-     * @return {@code non-null;} the extracted information
-     */
-    private LocalVariableInfo doit() {
-
-        //FIXME why is this needed here?
-        if (method.getRegCount() > 0 ) {
-            for (int bi = method.getEntryBlockIndex();
-                 bi >= 0;
-                 bi = workSet.nextSetBit(0)) {
-                workSet.clear(bi);
-                processBlock(bi);
-            }
-        }
-
-        resultInfo.setImmutable();
-        return resultInfo;
-    }
-
-    /**
-     * Processes a single block.
-     *
-     * @param blockIndex {@code >= 0;} block index of the block to process
-     */
-    private void processBlock(int blockIndex) {
-        RegisterSpecSet primaryState
-                = resultInfo.mutableCopyOfStarts(blockIndex);
-        SsaBasicBlock block = blocks.get(blockIndex);
-        List<SsaInsn> insns = block.getInsns();
-        int insnSz = insns.size();
-
-        // The exit block has no insns and no successors
-        if (blockIndex == method.getExitBlockIndex()) {
-            return;
-        }
-
-        /*
-         * We may have to treat the last instruction specially: If it
-         * can (but doesn't always) throw, and the exception can be
-         * caught within the same method, then we need to use the
-         * state *before* executing it to be what is merged into
-         * exception targets.
-         */
-        SsaInsn lastInsn = insns.get(insnSz - 1);
-        boolean hasExceptionHandlers
-                = lastInsn.getOriginalRopInsn().getCatches().size() !=0 ;
-        boolean canThrowDuringLastInsn = hasExceptionHandlers
-                && (lastInsn.getResult() != null);
-        int freezeSecondaryStateAt = insnSz - 1;
-        RegisterSpecSet secondaryState = primaryState;
-
-        /*
-         * Iterate over the instructions, adding information for each place
-         * that the active variable set changes.
-         */
-
-        for (int i = 0; i < insnSz; i++) {
-            if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {
-                // Until this point, primaryState == secondaryState.
-                primaryState.setImmutable();
-                primaryState = primaryState.mutableCopy();
-            }
-
-            SsaInsn insn = insns.get(i);
-            RegisterSpec result;
-
-            result = insn.getLocalAssignment();
-
-            if (result == null) {
-                // We may be nuking an existing local
-
-                result = insn.getResult();
-
-                if (result != null && primaryState.get(result.getReg()) != null) {
-                    primaryState.remove(primaryState.get(result.getReg()));
-                }
-                continue;
-            }
-
-            result = result.withSimpleType();
-
-            RegisterSpec already = primaryState.get(result);
-            /*
-             * The equals() check ensures we only add new info if
-             * the instruction causes a change to the set of
-             * active variables.
-             */
-            if (!result.equals(already)) {
-                /*
-                 * If this insn represents a local moving from one register
-                 * to another, remove the association between the old register
-                 * and the local.
-                 */
-                RegisterSpec previous
-                        = primaryState.localItemToSpec(result.getLocalItem());
-
-                if (previous != null
-                        && (previous.getReg() != result.getReg())) {
-
-                    primaryState.remove(previous);
-                }
-
-                resultInfo.addAssignment(insn, result);
-                primaryState.put(result);
-            }
-        }
-
-        primaryState.setImmutable();
-
-        /*
-         * Merge this state into the start state for each successor,
-         * and update the work set where required (that is, in cases
-         * where the start state for a block changes).
-         */
-
-        IntList successors = block.getSuccessorList();
-        int succSz = successors.size();
-        int primarySuccessor = block.getPrimarySuccessorIndex();
-
-        for (int i = 0; i < succSz; i++) {
-            int succ = successors.get(i);
-            RegisterSpecSet state = (succ == primarySuccessor) ?
-                primaryState : secondaryState;
-
-            if (resultInfo.mergeStarts(succ, state)) {
-                workSet.set(succ);
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/LocalVariableInfo.java b/dx/src/main/java/com/android/dx/ssa/LocalVariableInfo.java
deleted file mode 100644
index 8845270..0000000
--- a/dx/src/main/java/com/android/dx/ssa/LocalVariableInfo.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.util.MutabilityControl;
-import com.android.dx.rop.code.RegisterSpecSet;
-import com.android.dx.rop.code.RegisterSpec;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Container for local variable information for a particular {@link
- * com.android.dx.ssa.SsaMethod}.
- * Stolen from {@link com.android.dx.rop.code.LocalVariableInfo}.
- */
-public class LocalVariableInfo         extends MutabilityControl {
-    /** {@code >= 0;} the register count for the method */
-    private final int regCount;
-
-    /**
-     * {@code non-null;} {@link com.android.dx.rop.code.RegisterSpecSet} to use when indicating a block
-     * that has no locals; it is empty and immutable but has an appropriate
-     * max size for the method
-     */
-    private final RegisterSpecSet emptySet;
-
-    /**
-     * {@code non-null;} array consisting of register sets representing the
-     * sets of variables already assigned upon entry to each block,
-     * where array indices correspond to block indices
-     */
-    private final RegisterSpecSet[] blockStarts;
-
-    /** {@code non-null;} map from instructions to the variable each assigns */
-    private final HashMap<SsaInsn, RegisterSpec> insnAssignments;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param method {@code non-null;} the method being represented by this instance
-     */
-    public LocalVariableInfo(SsaMethod method) {
-        if (method == null) {
-            throw new NullPointerException("method == null");
-        }
-
-        List<SsaBasicBlock> blocks = method.getBlocks();
-
-        this.regCount = method.getRegCount();
-        this.emptySet = new RegisterSpecSet(regCount);
-        this.blockStarts = new RegisterSpecSet[blocks.size()];
-        this.insnAssignments =
-            new HashMap<SsaInsn, RegisterSpec>(/*hint here*/);
-
-        emptySet.setImmutable();
-    }
-
-    /**
-     * Sets the register set associated with the start of the block with
-     * the given index.
-     *
-     * @param index {@code >= 0;} the block index
-     * @param specs {@code non-null;} the register set to associate with the block
-     */
-    public void setStarts(int index, RegisterSpecSet specs) {
-        throwIfImmutable();
-
-        if (specs == null) {
-            throw new NullPointerException("specs == null");
-        }
-
-        try {
-            blockStarts[index] = specs;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus index");
-        }
-    }
-
-    /**
-     * Merges the given register set into the set for the block with the
-     * given index. If there was not already an associated set, then this
-     * is the same as calling {@link #setStarts}. Otherwise, this will
-     * merge the two sets and call {@link #setStarts} on the result of the
-     * merge.
-     *
-     * @param index {@code >= 0;} the block index
-     * @param specs {@code non-null;} the register set to merge into the start set
-     * for the block
-     * @return {@code true} if the merge resulted in an actual change
-     * to the associated set (including storing one for the first time) or
-     * {@code false} if there was no change
-     */
-    public boolean mergeStarts(int index, RegisterSpecSet specs) {
-        RegisterSpecSet start = getStarts0(index);
-        boolean changed = false;
-
-        if (start == null) {
-            setStarts(index, specs);
-            return true;
-        }
-
-        RegisterSpecSet newStart = start.mutableCopy();
-        newStart.intersect(specs, true);
-
-        if (start.equals(newStart)) {
-            return false;
-        }
-
-        newStart.setImmutable();
-        setStarts(index, newStart);
-
-        return true;
-    }
-
-    /**
-     * Gets the register set associated with the start of the block
-     * with the given index. This returns an empty set with the appropriate
-     * max size if no set was associated with the block in question.
-     *
-     * @param index {@code >= 0;} the block index
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet getStarts(int index) {
-        RegisterSpecSet result = getStarts0(index);
-
-        return (result != null) ? result : emptySet;
-    }
-
-    /**
-     * Gets the register set associated with the start of the given
-     * block. This is just convenient shorthand for
-     * {@code getStarts(block.getLabel())}.
-     *
-     * @param block {@code non-null;} the block in question
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet getStarts(SsaBasicBlock block) {
-        return getStarts(block.getIndex());
-    }
-
-    /**
-     * Gets a mutable copy of the register set associated with the
-     * start of the block with the given index. This returns a
-     * newly-allocated empty {@link RegisterSpecSet} of appropriate
-     * max size if there is not yet any set associated with the block.
-     *
-     * @param index {@code >= 0;} the block index
-     * @return {@code non-null;} the associated register set
-     */
-    public RegisterSpecSet mutableCopyOfStarts(int index) {
-        RegisterSpecSet result = getStarts0(index);
-
-        return (result != null) ?
-            result.mutableCopy() : new RegisterSpecSet(regCount);
-    }
-
-    /**
-     * Adds an assignment association for the given instruction and
-     * register spec. This throws an exception if the instruction
-     * doesn't actually perform a named variable assignment.
-     *
-     * <b>Note:</b> Although the instruction contains its own spec for
-     * the result, it still needs to be passed in explicitly to this
-     * method, since the spec that is stored here should always have a
-     * simple type and the one in the instruction can be an arbitrary
-     * {@link com.android.dx.rop.type.TypeBearer} (such as a constant value).
-     *
-     * @param insn {@code non-null;} the instruction in question
-     * @param spec {@code non-null;} the associated register spec
-     */
-    public void addAssignment(SsaInsn insn, RegisterSpec spec) {
-        throwIfImmutable();
-
-        if (insn == null) {
-            throw new NullPointerException("insn == null");
-        }
-
-        if (spec == null) {
-            throw new NullPointerException("spec == null");
-        }
-
-        insnAssignments.put(insn, spec);
-    }
-
-    /**
-     * Gets the named register being assigned by the given instruction, if
-     * previously stored in this instance.
-     *
-     * @param insn {@code non-null;} instruction in question
-     * @return {@code null-ok;} the named register being assigned, if any
-     */
-    public RegisterSpec getAssignment(SsaInsn insn) {
-        return insnAssignments.get(insn);
-    }
-
-    /**
-     * Gets the number of assignments recorded by this instance.
-     *
-     * @return {@code >= 0;} the number of assignments
-     */
-    public int getAssignmentCount() {
-        return insnAssignments.size();
-    }
-
-    public void debugDump() {
-        for (int index = 0 ; index < blockStarts.length; index++) {
-            if (blockStarts[index] == null) {
-                continue;
-            }
-
-            if (blockStarts[index] == emptySet) {
-                System.out.printf("%04x: empty set\n", index);
-            } else {
-                System.out.printf("%04x: %s\n", index, blockStarts[index]);
-            }
-        }
-    }
-
-    /**
-     * Helper method, to get the starts for a index, throwing the
-     * right exception for range problems.
-     *
-     * @param index {@code >= 0;} the block index
-     * @return {@code null-ok;} associated register set or {@code null} if there
-     * is none
-     */
-    private RegisterSpecSet getStarts0(int index) {
-        try {
-            return blockStarts[index];
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("bogus index");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/MoveParamCombiner.java b/dx/src/main/java/com/android/dx/ssa/MoveParamCombiner.java
deleted file mode 100644
index 41660d2..0000000
--- a/dx/src/main/java/com/android/dx/ssa/MoveParamCombiner.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2008 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.CstInsn;
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.cst.CstInteger;
-
-import java.util.HashSet;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Combine identical move-param insns, which may result from Ropper's
- * handling of synchronized methods.
- */
-public class MoveParamCombiner {
-
-    /** method to process */
-    private final SsaMethod ssaMeth;
-
-    /**
-     * Processes a method with this optimization step.
-     *
-     * @param ssaMethod method to process
-     */
-    public static void process(SsaMethod ssaMethod) {
-        new MoveParamCombiner(ssaMethod).run();
-    }
-
-    private MoveParamCombiner(SsaMethod ssaMeth) {
-        this.ssaMeth = ssaMeth;
-    }
-
-    /**
-     * Runs this optimization step.
-     */
-    private void run() {
-        // This will contain the definition specs for each parameter
-        final RegisterSpec[] paramSpecs
-                = new RegisterSpec[ssaMeth.getParamWidth()];
-
-        // Insns to delete when all done
-        final HashSet<SsaInsn> deletedInsns = new HashSet();
-
-        ssaMeth.forEachInsn(new SsaInsn.Visitor() {
-            public void visitMoveInsn (NormalSsaInsn insn) {
-            }
-            public void visitPhiInsn (PhiInsn phi) {
-            }
-            public void visitNonMoveInsn (NormalSsaInsn insn) {
-                if (insn.getOpcode().getOpcode() != RegOps.MOVE_PARAM) {
-                    return;
-                }
-
-                int param = getParamIndex(insn);
-
-                if (paramSpecs[param] == null) {
-                    paramSpecs[param] = insn.getResult();
-                } else {
-                    final RegisterSpec specA = paramSpecs[param];
-                    final RegisterSpec specB = insn.getResult();
-                    LocalItem localA = specA.getLocalItem();
-                    LocalItem localB = specB.getLocalItem();
-                    LocalItem newLocal;
-
-                    /*
-                     * Is there local information to preserve?
-                     */
-
-                    if (localA == null) {
-                        newLocal = localB;
-                    } else if (localB == null) {
-                        newLocal = localA;
-                    } else if (localA.equals(localB)) {
-                        newLocal = localA;
-                    } else {
-                        /*
-                         * Oddly, these two identical move-params have distinct
-                         * debug info. We'll just keep them distinct.
-                         */
-                        return;
-                    }
-
-                    ssaMeth.getDefinitionForRegister(specA.getReg())
-                            .setResultLocal(newLocal);
-
-                    /*
-                     * Map all uses of specB to specA
-                     */
-
-                    RegisterMapper mapper = new RegisterMapper() {
-                        /** @inheritDoc */
-                        public int getNewRegisterCount() {
-                            return ssaMeth.getRegCount();
-                        }
-
-                        /** @inheritDoc */
-                        public RegisterSpec map(RegisterSpec registerSpec) {
-                            if (registerSpec.getReg() == specB.getReg()) {
-                                return specA;
-                            }
-
-                            return registerSpec;
-                        }
-                    };
-
-                    List<SsaInsn> uses
-                            = ssaMeth.getUseListForRegister(specB.getReg());
-
-                    // Use list is modified by mapSourceRegisters
-                    for (int i = uses.size() - 1; i >= 0; i--) {
-                        SsaInsn use = uses.get(i);
-                        use.mapSourceRegisters(mapper);
-                    }
-
-                    deletedInsns.add(insn);
-                }
-
-            }
-        });
-
-        ssaMeth.deleteInsns(deletedInsns);
-    }
-
-    /**
-     * Returns the parameter index associated with a move-param insn. Does
-     * not verify that the insn is a move-param insn.
-     *
-     * @param insn {@code non-null;} a move-param insn
-     * @return {@code >=0;} parameter index
-     */
-    private int getParamIndex(NormalSsaInsn insn) {
-        CstInsn cstInsn = (CstInsn)(insn.getOriginalRopInsn());
-
-        int param = ((CstInteger)cstInsn.getConstant()).getValue();
-        return param;
-    }
-
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/NormalSsaInsn.java b/dx/src/main/java/com/android/dx/ssa/NormalSsaInsn.java
deleted file mode 100644
index cfef400..0000000
--- a/dx/src/main/java/com/android/dx/ssa/NormalSsaInsn.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.*;
-
-/**
- * A "normal" (non-phi) instruction in SSA form. Always wraps a rop insn.
- */
-public final class NormalSsaInsn extends SsaInsn implements Cloneable {
-    /** {@code non-null;} rop insn that we're wrapping */
-    private Insn insn;
-
-    /**
-     * Creates an instance.
-     *
-     * @param insn Rop insn to wrap
-     * @param block block that contains this insn
-     */
-    NormalSsaInsn(final Insn insn, final SsaBasicBlock block) {
-        super(insn.getResult(), block);
-        this.insn = insn;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void mapSourceRegisters(RegisterMapper mapper) {
-        RegisterSpecList oldSources = insn.getSources();
-        RegisterSpecList newSources = mapper.map(oldSources);
-
-        if (newSources != oldSources) {
-            insn = insn.withNewRegisters(getResult(), newSources);
-            getBlock().getParent().onSourcesChanged(this, oldSources);
-        }
-    }
-
-    /**
-     * Changes one of the insn's sources. New source should be of same type
-     * and category.
-     *
-     * @param index {@code >=0;} index of source to change
-     * @param newSpec spec for new source
-     */
-    public final void changeOneSource(int index, RegisterSpec newSpec) {
-        RegisterSpecList origSources = insn.getSources();
-        int sz = origSources.size();
-        RegisterSpecList newSources = new RegisterSpecList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            newSources.set(i, i == index ? newSpec : origSources.get(i));
-        }
-
-        newSources.setImmutable();
-
-        RegisterSpec origSpec = origSources.get(index);
-        if (origSpec.getReg() != newSpec.getReg()) {
-            /*
-             * If the register remains unchanged, we're only changing
-             * the type or local var name so don't update use list
-             */
-            getBlock().getParent().onSourceChanged(this, origSpec, newSpec);
-        }
-
-        insn = insn.withNewRegisters(getResult(), newSources);
-    }
-
-    /**
-     * Changes the source list of the insn. New source list should be the
-     * same size and consist of sources of identical types.
-     *
-     * @param newSources non-null new sources list.
-     */
-    public final void setNewSources (RegisterSpecList newSources) {
-        RegisterSpecList origSources = insn.getSources();
-
-        if (origSources.size() != newSources.size()) {
-            throw new RuntimeException("Sources counts don't match");
-        }
-
-        insn = insn.withNewRegisters(getResult(), newSources);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public NormalSsaInsn clone() {
-        return (NormalSsaInsn) super.clone();
-    }
-
-    /**
-     * Like rop.Insn.getSources().
-     *
-     * @return {@code null-ok;} sources list
-     */
-    @Override
-    public RegisterSpecList getSources() {
-        return insn.getSources();
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return toRopInsn().toHuman();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn toRopInsn() {
-        return insn.withNewRegisters(getResult(), insn.getSources());
-    }
-
-    /**
-     * @return the Rop opcode for this insn
-     */
-    @Override
-    public Rop getOpcode() {
-        return insn.getOpcode();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Insn getOriginalRopInsn() {
-        return insn;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public RegisterSpec getLocalAssignment() {
-        RegisterSpec assignment;
-
-        if (insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {
-            assignment = insn.getSources().get(0);
-        } else {
-            assignment = getResult();
-        }
-
-        if (assignment == null) {
-            return null;
-        }
-
-        LocalItem local = assignment.getLocalItem();
-
-        if (local == null) {
-            return null;
-        }
-
-        return assignment;
-    }
-
-    /**
-     * Upgrades this insn to a version that represents the constant source
-     * literally. If the upgrade is not possible, this does nothing.
-     *
-     * @see Insn#withSourceLiteral
-     */
-    public void upgradeToLiteral() {
-        RegisterSpecList oldSources = insn.getSources();
-
-        insn = insn.withSourceLiteral();
-        getBlock().getParent().onSourcesChanged(this, oldSources);
-    }
-
-    /**
-     * @return true if this is a move (but not a move-operand) instruction
-     */
-    @Override
-    public boolean isNormalMoveInsn() {
-        return insn.getOpcode().getOpcode() == RegOps.MOVE;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isMoveException() {
-        return insn.getOpcode().getOpcode() == RegOps.MOVE_EXCEPTION;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean canThrow() {
-        return insn.canThrow();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(Visitor v) {
-        if (isNormalMoveInsn()) {
-            v.visitMoveInsn(this);
-        } else {
-            v.visitNonMoveInsn(this);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public  boolean isPhiOrMove() {
-        return isNormalMoveInsn();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * TODO: Increase the scope of this.
-     */
-    @Override
-    public boolean hasSideEffect() {
-        Rop opcode = getOpcode();
-
-        if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
-            return true;
-        }
-
-        boolean hasLocalSideEffect
-            = Optimizer.getPreserveLocals() && getLocalAssignment() != null;
-
-        switch (opcode.getOpcode()) {
-            case RegOps.MOVE_RESULT:
-            case RegOps.MOVE:
-            case RegOps.CONST:
-                return hasLocalSideEffect;
-            default:
-                return true;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/Optimizer.java b/dx/src/main/java/com/android/dx/ssa/Optimizer.java
deleted file mode 100644
index 42ae166..0000000
--- a/dx/src/main/java/com/android/dx/ssa/Optimizer.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.TranslationAdvice;
-import com.android.dx.ssa.back.LivenessAnalyzer;
-import com.android.dx.ssa.back.SsaToRop;
-
-import java.util.EnumSet;
-
-/**
- * Runs a method through the SSA form conversion, any optimization algorithms,
- * and returns it to rop form.
- */
-public class Optimizer {
-    private static boolean preserveLocals = true;
-
-    private static TranslationAdvice advice;
-
-    /** optional optimizer steps */
-    public enum OptionalStep {
-        MOVE_PARAM_COMBINER, SCCP, LITERAL_UPGRADE, CONST_COLLECTOR,
-            ESCAPE_ANALYSIS
-    }
-
-    /**
-     * @return true if local variable information should be preserved, even
-     * at code size/register size cost
-     */
-    public static boolean getPreserveLocals() {
-        return preserveLocals;
-    }
-
-    /**
-     * @return {@code non-null;} translation advice
-     */
-    public static TranslationAdvice getAdvice() {
-        return advice;
-    }
-
-    /**
-     * Runs optimization algorthims over this method, and returns a new
-     * instance of RopMethod with the changes.
-     *
-     * @param rmeth method to process
-     * @param paramWidth the total width, in register-units, of this method's
-     * parameters
-     * @param isStatic true if this method has no 'this' pointer argument.
-     * @param inPreserveLocals true if local variable info should be preserved,
-     * at the cost of some registers and insns
-     * @param inAdvice {@code non-null;} translation advice
-     * @return optimized method
-     */
-    public static RopMethod optimize(RopMethod rmeth, int paramWidth,
-            boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice) {
-
-        return optimize(rmeth, paramWidth, isStatic, inPreserveLocals, inAdvice,
-                EnumSet.allOf(OptionalStep.class));
-    }
-
-    /**
-     * Runs optimization algorthims over this method, and returns a new
-     * instance of RopMethod with the changes.
-     *
-     * @param rmeth method to process
-     * @param paramWidth the total width, in register-units, of this method's
-     * parameters
-     * @param isStatic true if this method has no 'this' pointer argument.
-     * @param inPreserveLocals true if local variable info should be preserved,
-     * at the cost of some registers and insns
-     * @param inAdvice {@code non-null;} translation advice
-     * @param steps set of optional optimization steps to run
-     * @return optimized method
-     */
-    public static RopMethod optimize(RopMethod rmeth, int paramWidth,
-            boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice, EnumSet<OptionalStep> steps) {
-        SsaMethod ssaMeth = null;
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
-        runSsaFormSteps(ssaMeth, steps);
-
-        RopMethod resultMeth = SsaToRop.convertToRopMethod(ssaMeth, false);
-
-        if (resultMeth.getBlocks().getRegCount()
-                > advice.getMaxOptimalRegisterCount()) {
-            // Try to see if we can squeeze it under the register count bar
-            resultMeth = optimizeMinimizeRegisters(rmeth, paramWidth, isStatic,
-                    steps);
-        }
-        return resultMeth;
-    }
-
-    /**
-     * Runs the optimizer with a strategy to minimize the number of rop-form
-     * registers used by the end result. Dex bytecode does not have instruction
-     * forms that take register numbers larger than 15 for all instructions.
-     * If we've produced a method that uses more than 16 registers, try again
-     * with a different strategy to see if we can get under the bar. The end
-     * result will be much more efficient.
-     *
-     * @param rmeth method to process
-     * @param paramWidth the total width, in register-units, of this method's
-     * parameters
-     * @param isStatic true if this method has no 'this' pointer argument.
-     * @param steps set of optional optimization steps to run
-     * @return optimized method
-     */
-    private static RopMethod optimizeMinimizeRegisters(RopMethod rmeth,
-            int paramWidth, boolean isStatic,
-            EnumSet<OptionalStep> steps) {
-        SsaMethod ssaMeth;
-        RopMethod resultMeth;
-
-        ssaMeth = SsaConverter.convertToSsaMethod(
-                rmeth, paramWidth, isStatic);
-
-        EnumSet<OptionalStep> newSteps = steps.clone();
-
-        /*
-         * CONST_COLLECTOR trades insns for registers, which is not an
-         * appropriate strategy here.
-         */
-        newSteps.remove(OptionalStep.CONST_COLLECTOR);
-
-        runSsaFormSteps(ssaMeth, newSteps);
-
-        resultMeth = SsaToRop.convertToRopMethod(ssaMeth, true);
-        return resultMeth;
-    }
-
-    private static void runSsaFormSteps(SsaMethod ssaMeth,
-            EnumSet<OptionalStep> steps) {
-        boolean needsDeadCodeRemover = true;
-
-        if (steps.contains(OptionalStep.MOVE_PARAM_COMBINER)) {
-            MoveParamCombiner.process(ssaMeth);
-        }
-
-        if (steps.contains(OptionalStep.SCCP)) {
-            SCCP.process(ssaMeth);
-            DeadCodeRemover.process(ssaMeth);
-            needsDeadCodeRemover = false;
-        }
-
-        if (steps.contains(OptionalStep.LITERAL_UPGRADE)) {
-            LiteralOpUpgrader.process(ssaMeth);
-            DeadCodeRemover.process(ssaMeth);
-            needsDeadCodeRemover = false;
-        }
-
-        /*
-         * ESCAPE_ANALYSIS impacts debuggability, so left off by default
-         */
-        steps.remove(OptionalStep.ESCAPE_ANALYSIS);
-        if (steps.contains(OptionalStep.ESCAPE_ANALYSIS)) {
-            EscapeAnalysis.process(ssaMeth);
-            DeadCodeRemover.process(ssaMeth);
-            needsDeadCodeRemover = false;
-        }
-
-        if (steps.contains(OptionalStep.CONST_COLLECTOR)) {
-            ConstCollector.process(ssaMeth);
-            DeadCodeRemover.process(ssaMeth);
-            needsDeadCodeRemover = false;
-        }
-
-        // dead code remover must be run before phi type resolver
-        if (needsDeadCodeRemover) {
-            DeadCodeRemover.process(ssaMeth);
-        }
-
-        PhiTypeResolver.process(ssaMeth);
-    }
-
-    public static SsaMethod debugEdgeSplit(RopMethod rmeth, int paramWidth,
-            boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice) {
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        return SsaConverter.testEdgeSplit(rmeth, paramWidth, isStatic);
-    }
-
-    public static SsaMethod debugPhiPlacement(RopMethod rmeth, int paramWidth,
-            boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice) {
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        return SsaConverter.testPhiPlacement(rmeth, paramWidth, isStatic);
-    }
-
-    public static SsaMethod debugRenaming(RopMethod rmeth, int paramWidth,
-            boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice) {
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        return SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
-    }
-
-    public static SsaMethod debugDeadCodeRemover(RopMethod rmeth,
-            int paramWidth, boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice) {
-
-        SsaMethod ssaMeth;
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
-        DeadCodeRemover.process(ssaMeth);
-
-        return ssaMeth;
-    }
-
-    public static SsaMethod debugNoRegisterAllocation(RopMethod rmeth,
-            int paramWidth, boolean isStatic, boolean inPreserveLocals,
-            TranslationAdvice inAdvice, EnumSet<OptionalStep> steps) {
-
-        SsaMethod ssaMeth;
-
-        preserveLocals = inPreserveLocals;
-        advice = inAdvice;
-
-        ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
-
-        runSsaFormSteps(ssaMeth, steps);
-
-        LivenessAnalyzer.constructInterferenceGraph(ssaMeth);
-
-        return ssaMeth;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/PhiInsn.java b/dx/src/main/java/com/android/dx/ssa/PhiInsn.java
deleted file mode 100644
index bc9c4b0..0000000
--- a/dx/src/main/java/com/android/dx/ssa/PhiInsn.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.*;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.util.Hex;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A Phi instruction (magical post-control-flow-merge) instruction
- * in SSA form. Will be converted to moves in predecessor blocks before
- * conversion back to ROP form.
- */
-public final class PhiInsn extends SsaInsn {
-    /**
-     * result register. The original result register of the phi insn
-     * is needed during the renaming process after the new result
-     * register has already been chosen.
-     */
-    private final int ropResultReg;
-
-    /**
-     * {@code non-null;} operands of the instruction; built up by
-     * {@link #addPhiOperand}
-     */
-    private final ArrayList<Operand> operands = new ArrayList<Operand>();
-
-    /** {@code null-ok;} source registers; constructed lazily */
-    private RegisterSpecList sources;
-
-    /**
-     * Constructs a new phi insn with no operands.
-     *
-     * @param resultReg the result reg for this phi insn
-     * @param block block containing this insn.
-     */
-    public PhiInsn(RegisterSpec resultReg, SsaBasicBlock block) {
-        super(resultReg, block);
-        ropResultReg = resultReg.getReg();
-    }
-
-    /**
-     * Makes a phi insn with a void result type.
-     *
-     * @param resultReg the result register for this phi insn.
-     * @param block block containing this insn.
-     */
-    public PhiInsn(final int resultReg, final SsaBasicBlock block) {
-        /*
-         * The result type here is bogus: The type depends on the
-         * operand and will be derived later.
-         */
-        super(RegisterSpec.make(resultReg, Type.VOID), block);
-        ropResultReg = resultReg;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public PhiInsn clone() {
-        throw new UnsupportedOperationException("can't clone phi");
-    }
-
-    /**
-     * Updates the TypeBearers of all the sources (phi operands) to be
-     * the current TypeBearer of the register-defining instruction's result.
-     * This is used during phi-type resolution.<p>
-     *
-     * Note that local association of operands are preserved in this step.
-     *
-     * @param ssaMeth method that contains this insn
-     */
-    public void updateSourcesToDefinitions(SsaMethod ssaMeth) {
-        for (Operand o : operands) {
-            RegisterSpec def
-                = ssaMeth.getDefinitionForRegister(
-                    o.regSpec.getReg()).getResult();
-
-            o.regSpec = o.regSpec.withType(def.getType());
-        }
-
-        sources = null;
-    }
-
-    /**
-     * Changes the result type. Used during phi type resolution
-     *
-     * @param type {@code non-null;} new TypeBearer
-     * @param local {@code null-ok;} new local info, if available
-     */
-    public void changeResultType(TypeBearer type, LocalItem local) {
-        setResult(RegisterSpec.makeLocalOptional(
-                          getResult().getReg(), type, local));
-    }
-
-    /**
-     * Gets the original rop-form result reg. This is useful during renaming.
-     *
-     * @return the original rop-form result reg
-     */
-    public int getRopResultReg() {
-        return ropResultReg;
-    }
-
-    /**
-     * Adds an operand to this phi instruction.
-     *
-     * @param registerSpec register spec, including type and reg of operand
-     * @param predBlock predecessor block to be associated with this operand
-     */
-    public void addPhiOperand(RegisterSpec registerSpec,
-            SsaBasicBlock predBlock) {
-        operands.add(new Operand(registerSpec, predBlock.getIndex(),
-                predBlock.getRopLabel()));
-
-        // Un-cache sources, in case someone has already called getSources().
-        sources = null;
-    }
-
-    /**
-     * Removes all operand uses of a register from this phi instruction.
-     *
-     * @param registerSpec register spec, including type and reg of operand
-     */
-    public void removePhiRegister(RegisterSpec registerSpec) {
-        ArrayList<Operand> operandsToRemove = new ArrayList<Operand>();
-        for (Operand o : operands) {
-            if (o.regSpec.getReg() == registerSpec.getReg()) {
-                operandsToRemove.add(o);
-            }
-        }
-
-        operands.removeAll(operandsToRemove);
-
-        // Un-cache sources, in case someone has already called getSources().
-        sources = null;
-    }
-
-    /**
-     * Gets the index of the pred block associated with the RegisterSpec
-     * at the particular getSources() index.
-     *
-     * @param sourcesIndex index of source in getSources()
-     * @return block index
-     */
-    public int predBlockIndexForSourcesIndex(int sourcesIndex) {
-        return operands.get(sourcesIndex).blockIndex;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Always returns null for {@code PhiInsn}s.
-     */
-    @Override
-    public Rop getOpcode() {
-        return null;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Always returns null for {@code PhiInsn}s.
-     */
-    @Override
-    public Insn getOriginalRopInsn() {
-        return null;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Always returns false for {@code PhiInsn}s.
-     */
-    @Override
-    public boolean canThrow() {
-        return false;
-    }
-
-    /**
-     * Gets sources. Constructed lazily from phi operand data structures and
-     * then cached.
-     *
-     * @return {@code non-null;} sources list
-     */
-    @Override
-    public RegisterSpecList getSources() {
-        if (sources != null) {
-            return sources;
-        }
-
-        if (operands.size() == 0) {
-            // How'd this happen? A phi insn with no operand?
-            return RegisterSpecList.EMPTY;
-        }
-
-        int szSources = operands.size();
-        sources = new RegisterSpecList(szSources);
-
-        for (int i = 0; i < szSources; i++) {
-            Operand o = operands.get(i);
-
-            sources.set(i, o.regSpec);
-        }
-
-        sources.setImmutable();
-        return sources;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isRegASource(int reg) {
-        /*
-         * Avoid creating a sources list in case it has not already been
-         * created.
-         */
-
-        for (Operand o : operands) {
-            if (o.regSpec.getReg() == reg) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * @return true if all operands use the same register
-     */
-    public boolean areAllOperandsEqual() {
-        if (operands.size() == 0 ) {
-            // This should never happen.
-            return true;
-        }
-
-        int firstReg = operands.get(0).regSpec.getReg();
-        for (Operand o : operands) {
-            if (firstReg != o.regSpec.getReg()) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public final void mapSourceRegisters(RegisterMapper mapper) {
-        for (Operand o : operands) {
-            RegisterSpec old = o.regSpec;
-            o.regSpec = mapper.map(old);
-            if (old != o.regSpec) {
-                getBlock().getParent().onSourceChanged(this, old, o.regSpec);
-            }
-        }
-        sources = null;
-    }
-
-    /**
-     * Always throws an exeption, since a phi insn may not be
-     * converted back to rop form.
-     *
-     * @return always throws exception
-     */
-    @Override
-    public Insn toRopInsn() {
-        throw new IllegalArgumentException(
-                "Cannot convert phi insns to rop form");
-    }
-
-    /**
-     * Returns the list of predecessor blocks associated with all operands
-     * that have {@code reg} as an operand register.
-     *
-     * @param reg register to look up
-     * @param ssaMeth method we're operating on
-     * @return list of predecessor blocks, empty if none
-     */
-    public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) {
-        ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>();
-
-        for (Operand o : operands) {
-            if (o.regSpec.getReg() == reg) {
-                ret.add(ssaMeth.getBlocks().get(o.blockIndex));
-            }
-        }
-
-        return ret;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isPhiOrMove() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean hasSideEffect() {
-        return Optimizer.getPreserveLocals() && getLocalAssignment() != null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void accept(SsaInsn.Visitor v) {
-        v.visitPhiInsn(this);
-    }
-
-    /** {@inheritDoc} */
-    public String toHuman() {
-        return toHumanWithInline(null);
-    }
-
-    /**
-     * Returns human-readable string for listing dumps. This method
-     * allows sub-classes to specify extra text.
-     *
-     * @param extra {@code null-ok;} the argument to print after the opcode
-     * @return human-readable string for listing dumps
-     */
-    protected final String toHumanWithInline(String extra) {
-        StringBuffer sb = new StringBuffer(80);
-
-        sb.append(SourcePosition.NO_INFO);
-        sb.append(": phi");
-
-        if (extra != null) {
-            sb.append("(");
-            sb.append(extra);
-            sb.append(")");
-        }
-
-        RegisterSpec result = getResult();
-
-        if (result == null) {
-            sb.append(" .");
-        } else {
-            sb.append(" ");
-            sb.append(result.toHuman());
-        }
-
-        sb.append(" <-");
-
-        int sz = getSources().size();
-        if (sz == 0) {
-            sb.append(" .");
-        } else {
-            for (int i = 0; i < sz; i++) {
-                sb.append(" ");
-                sb.append(sources.get(i).toHuman()
-                        + "[b="
-                        + Hex.u2(operands.get(i).ropLabel)  + "]");
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * A single phi operand, consiting of source register and block index
-     * for move.
-     */
-    private static class Operand {
-        public RegisterSpec regSpec;
-        public final int blockIndex;
-        public final int ropLabel;       // only used for debugging
-
-        public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) {
-            this.regSpec = regSpec;
-            this.blockIndex = blockIndex;
-            this.ropLabel = ropLabel;
-        }
-    }
-
-    /**
-     * Visitor interface for instances of this (outer) class.
-     */
-    public static interface Visitor {
-        public void visitPhiInsn(PhiInsn insn);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/PhiTypeResolver.java b/dx/src/main/java/com/android/dx/ssa/PhiTypeResolver.java
deleted file mode 100644
index 4b8b4e3..0000000
--- a/dx/src/main/java/com/android/dx/ssa/PhiTypeResolver.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.cf.code.Merger;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-
-import java.util.BitSet;
-import java.util.List;
-
-/**
- * Resolves the result types of phi instructions. When phi instructions
- * are inserted, their result types are set to BT_VOID (which is a nonsensical
- * type for a register) but must be resolve to a real type before converting
- * out of SSA form.<p>
- *
- * The resolve is done as an iterative merge of each phi's operand types.
- * Phi operands may be themselves be the result of unresolved phis,
- * and the algorithm tries to find the most-fit type (for example, if every
- * operand is the same constant value or the same local variable info, we want
- * that to be reflected).<p>
- *
- * This algorithm assumes a dead-code remover has already removed all
- * circular-only phis that may have been inserted.
- */
-public class PhiTypeResolver {
-
-    SsaMethod ssaMeth;
-    /** indexed by register; all registers still defined by unresolved phis */
-    private final BitSet worklist;
-
-    /**
-     * Resolves all phi types in the method
-     * @param ssaMeth method to process
-     */
-    public static void process (SsaMethod ssaMeth) {
-        new PhiTypeResolver(ssaMeth).run();
-    }
-
-    private PhiTypeResolver(SsaMethod ssaMeth) {
-        this.ssaMeth = ssaMeth;
-        worklist = new BitSet(ssaMeth.getRegCount());
-    }
-
-    /**
-     * Runs the phi-type resolver.
-     */
-    private void run() {
-
-        int regCount = ssaMeth.getRegCount();
-
-        for (int reg = 0; reg < regCount; reg++) {
-            SsaInsn definsn = ssaMeth.getDefinitionForRegister(reg);
-
-            if (definsn != null
-                    && (definsn.getResult().getBasicType() == Type.BT_VOID)) {
-                worklist.set(reg);
-            }
-        }
-
-        int reg;
-        while ( 0 <= (reg = worklist.nextSetBit(0))) {
-            worklist.clear(reg);
-
-            /*
-             * definitions on the worklist have a type of BT_VOID, which
-             * must have originated from a PhiInsn.
-             */
-            PhiInsn definsn = (PhiInsn)ssaMeth.getDefinitionForRegister(reg);
-
-            if (resolveResultType(definsn)) {
-                /*
-                 * If the result type has changed, re-resolve all phis
-                 * that use this.
-                 */
-
-                List<SsaInsn> useList = ssaMeth.getUseListForRegister(reg);
-
-                int sz = useList.size();
-                for (int i = 0; i < sz; i++ ) {
-                    SsaInsn useInsn = useList.get(i);
-                    RegisterSpec resultReg = useInsn.getResult();
-                    if (resultReg != null && useInsn instanceof PhiInsn) {
-                        worklist.set(resultReg.getReg());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if a and b are equal, whether
-     * or not either of them are null.
-     * @param a
-     * @param b
-     * @return true if equal
-     */
-    private static boolean equalsHandlesNulls(LocalItem a, LocalItem b) {
-        return (a == b) || ((a != null) && a.equals(b));
-    }
-
-    /**
-     * Resolves the result of a phi insn based on its operands. The "void"
-     * type, which is a nonsensical type for a register, is used for
-     * registers defined by as-of-yet-unresolved phi operations.
-     *
-     * @return true if the result type changed, false if no change
-     */
-    boolean resolveResultType(PhiInsn insn) {
-        insn.updateSourcesToDefinitions(ssaMeth);
-
-        RegisterSpecList sources = insn.getSources();
-
-        // Start by finding the first non-void operand
-        RegisterSpec first = null;
-        int firstIndex = -1;
-
-        int szSources = sources.size();
-        for (int i = 0 ; i <szSources ; i++) {
-            RegisterSpec rs = sources.get(i);
-
-            if (rs.getBasicType() != Type.BT_VOID) {
-                first = rs;
-                firstIndex = i;
-            }
-        }
-
-        if (first == null) {
-            // All operands are void -- we're not ready to resolve yet
-            return false;
-        }
-
-        LocalItem firstLocal = first.getLocalItem();
-        TypeBearer mergedType = first.getType();
-        boolean sameLocals = true;
-        for (int i = 0 ; i < szSources ; i++) {
-            if (i == firstIndex) {
-                continue;
-            }
-
-            RegisterSpec rs = sources.get(i);
-
-            // Just skip void (unresolved phi results) for now
-            if (rs.getBasicType() == Type.BT_VOID){
-                continue;
-            }
-
-            sameLocals = sameLocals
-                    && equalsHandlesNulls(firstLocal, rs.getLocalItem());
-
-            mergedType = Merger.mergeType(mergedType, rs.getType());
-        }
-
-        TypeBearer newResultType;
-
-        if (mergedType != null) {
-            newResultType = mergedType;
-        } else {
-            StringBuilder sb = new StringBuilder();
-
-            for (int i = 0; i < szSources; i++) {
-                sb.append(sources.get(i).toString());
-                sb.append(' ');
-            }
-
-            throw new RuntimeException ("Couldn't map types in phi insn:" + sb);
-        }
-
-        LocalItem newLocal = sameLocals ? firstLocal : null;
-
-        RegisterSpec result = insn.getResult();
-
-        if ((result.getTypeBearer() == newResultType)
-                && equalsHandlesNulls(newLocal, result.getLocalItem())) {
-            return false;
-        }
-
-        insn.changeResultType(newResultType, newLocal);
-
-        return true;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/RegisterMapper.java b/dx/src/main/java/com/android/dx/ssa/RegisterMapper.java
deleted file mode 100644
index bef941f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/RegisterMapper.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.ToHuman;
-
-/**
- * Represents a mapping between two register numbering schemes.
- * Subclasses of this may be mutable, and as such the mapping provided
- * is only valid for the lifetime of the method call in which
- * instances of this class are passed.
- */
-public abstract class RegisterMapper {
-    /**
-     * Gets the count of registers (really, the total register width, since
-     * category width is counted) in the new namespace.
-     * @return >= 0 width of new namespace.
-     */
-    public abstract int getNewRegisterCount();
-
-    /**
-     * @param registerSpec old register
-     * @return register in new space
-     */
-    public abstract RegisterSpec map(RegisterSpec registerSpec);
-
-    /**
-     *
-     * @param sources old register list
-     * @return new mapped register list, or old if nothing has changed.
-     */
-    public final RegisterSpecList map(RegisterSpecList sources) {
-        int sz = sources.size();
-        RegisterSpecList newSources = new RegisterSpecList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            newSources.set(i, map(sources.get(i)));
-        }
-
-        newSources.setImmutable();
-
-        // Return the old sources if nothing has changed.
-        return newSources.equals(sources) ? sources : newSources;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SCCP.java b/dx/src/main/java/com/android/dx/ssa/SCCP.java
deleted file mode 100644
index 1c869e1..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SCCP.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.CstInsn;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.cst.TypedConstant;
-import com.android.dx.rop.type.TypeBearer;
-import com.android.dx.rop.type.Type;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-
-/**
- * A small variant of Wegman and Zadeck's Sparse Conditional Constant
- * Propagation algorithm.
- */
-public class SCCP {
-    /** Lattice values  */
-    private static final int TOP = 0;
-    private static final int CONSTANT = 1;
-    private static final int VARYING = 2;
-    /** method we're processing */
-    private SsaMethod ssaMeth;
-    /** ssaMeth.getRegCount() */
-    private int regCount;
-    /** Lattice values for each SSA register */
-    private int[] latticeValues;
-    /** For those registers that are constant, this is the constant value */
-    private Constant[] latticeConstants;
-    /** Worklist of basic blocks to be processed */
-    private ArrayList<SsaBasicBlock> cfgWorklist;
-    /** Worklist of executed basic blocks with phis to be processed */
-    private ArrayList<SsaBasicBlock> cfgPhiWorklist;
-    /** Bitset containing bits for each block that has been found executable */
-    private BitSet executableBlocks;
-    /** Worklist for SSA edges.  This is a list of registers to process */
-    private ArrayList<SsaInsn> ssaWorklist;
-    /**
-     * Worklist for SSA edges that represent varying values.  It makes the
-     * algorithm much faster if you move all values to VARYING as fast as
-     * possible.
-     */
-    private ArrayList<SsaInsn> varyingWorklist;
-    /** Worklist of potential branches to convert to gotos */
-    private ArrayList<SsaInsn> branchWorklist;
-
-    private SCCP(SsaMethod ssaMeth) {
-        this.ssaMeth = ssaMeth;
-        this.regCount = ssaMeth.getRegCount();
-        this.latticeValues = new int[this.regCount];
-        this.latticeConstants = new Constant[this.regCount];
-        this.cfgWorklist = new ArrayList<SsaBasicBlock>();
-        this.cfgPhiWorklist = new ArrayList<SsaBasicBlock>();
-        this.executableBlocks = new BitSet(ssaMeth.getBlocks().size());
-        this.ssaWorklist = new ArrayList<SsaInsn>();
-        this.varyingWorklist = new ArrayList<SsaInsn>();
-        this.branchWorklist = new ArrayList<SsaInsn>();
-        for (int i = 0; i < this.regCount; i++) {
-            latticeValues[i] = TOP;
-            latticeConstants[i] = null;
-        }
-    }
-
-    /**
-     * Performs sparse conditional constant propagation on a method.
-     * @param ssaMethod Method to process
-     */
-    public static void process (SsaMethod ssaMethod) {
-        new SCCP(ssaMethod).run();
-    }
-
-    /**
-     * Adds a SSA basic block to the CFG worklist if it's unexecuted, or
-     * to the CFG phi worklist if it's already executed.
-     * @param ssaBlock Block to add
-     */
-    private void addBlockToWorklist(SsaBasicBlock ssaBlock) {
-        if (!executableBlocks.get(ssaBlock.getIndex())) {
-            cfgWorklist.add(ssaBlock);
-            executableBlocks.set(ssaBlock.getIndex());
-        } else {
-            cfgPhiWorklist.add(ssaBlock);
-        }
-    }
-
-    /**
-     * Adds an SSA register's uses to the SSA worklist.
-     * @param reg SSA register
-     * @param latticeValue new lattice value for @param reg.
-     */
-    private void addUsersToWorklist(int reg, int latticeValue) {
-        if (latticeValue == VARYING) {
-            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
-                varyingWorklist.add(insn);
-            }
-        } else {
-            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
-                ssaWorklist.add(insn);
-            }
-        }
-    }
-
-    /**
-     * Sets a lattice value for a register to value.
-     * @param reg SSA register
-     * @param value Lattice value
-     * @param cst Constant value (may be null)
-     * @return true if the lattice value changed.
-     */
-    private boolean setLatticeValueTo(int reg, int value, Constant cst) {
-        if (value != CONSTANT) {
-            if (latticeValues[reg] != value) {
-                latticeValues[reg] = value;
-                return true;
-            }
-            return false;
-        } else {
-            if (latticeValues[reg] != value
-                    || !latticeConstants[reg].equals(cst)) {
-                latticeValues[reg] = value;
-                latticeConstants[reg] = cst;
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Simulates a PHI node and set the lattice for the result
-     * to the appropriate value.
-     * Meet values:
-     * TOP x anything = TOP
-     * VARYING x anything = VARYING
-     * CONSTANT x CONSTANT = CONSTANT if equal constants, VARYING otherwise
-     * @param insn PHI to simulate.
-     */
-    private void simulatePhi(PhiInsn insn) {
-        int phiResultReg = insn.getResult().getReg();
-
-        if (latticeValues[phiResultReg] == VARYING) {
-            return;
-        }
-
-        RegisterSpecList sources = insn.getSources();
-        int phiResultValue = TOP;
-        Constant phiConstant = null;
-        int sourceSize = sources.size();
-
-        for (int i = 0; i < sourceSize; i++) {
-            int predBlockIndex = insn.predBlockIndexForSourcesIndex(i);
-            int sourceReg = sources.get(i).getReg();
-            int sourceRegValue = latticeValues[sourceReg];
-
-            if (!executableBlocks.get(predBlockIndex)) {
-                continue;
-            }
-
-            if (sourceRegValue == CONSTANT) {
-                if (phiConstant == null) {
-                    phiConstant = latticeConstants[sourceReg];
-                    phiResultValue = CONSTANT;
-                 } else if (!latticeConstants[sourceReg].equals(phiConstant)){
-                    phiResultValue = VARYING;
-                    break;
-                }
-            } else {
-                phiResultValue = sourceRegValue;
-                break;
-            }
-        }
-        if (setLatticeValueTo(phiResultReg, phiResultValue, phiConstant)) {
-            addUsersToWorklist(phiResultReg, phiResultValue);
-        }
-    }
-
-    /**
-     * Simulate a block and note the results in the lattice.
-     * @param block Block to visit
-     */
-    private void simulateBlock(SsaBasicBlock block) {
-        for (SsaInsn insn : block.getInsns()) {
-            if (insn instanceof PhiInsn) {
-                simulatePhi((PhiInsn) insn);
-            } else {
-                simulateStmt(insn);
-            }
-        }
-    }
-
-    /**
-     * Simulate the phis in a block and note the results in the lattice.
-     * @param block Block to visit
-     */
-    private void simulatePhiBlock(SsaBasicBlock block) {
-        for (SsaInsn insn : block.getInsns()) {
-            if (insn instanceof PhiInsn) {
-                simulatePhi((PhiInsn) insn);
-            } else {
-                return;
-            }
-        }
-    }
-
-    private static String latticeValName(int latticeVal) {
-        switch (latticeVal) {
-            case TOP: return "TOP";
-            case CONSTANT: return "CONSTANT";
-            case VARYING: return "VARYING";
-            default: return "UNKNOWN";
-        }
-    }
-
-    /**
-     * Simulates branch insns, if possible. Adds reachable successor blocks
-     * to the CFG worklists.
-     * @param insn branch to simulate
-     */
-    private void simulateBranch(SsaInsn insn) {
-        Rop opcode = insn.getOpcode();
-        RegisterSpecList sources = insn.getSources();
-
-        boolean constantBranch = false;
-        boolean constantSuccessor = false;
-
-        // Check if the insn is a branch with a constant condition
-        if (opcode.getBranchingness() == Rop.BRANCH_IF) {
-            Constant cA = null;
-            Constant cB = null;
-
-            RegisterSpec specA = sources.get(0);
-            int regA = specA.getReg();
-            if (!ssaMeth.isRegALocal(specA) &&
-                    latticeValues[regA] == CONSTANT) {
-                cA = latticeConstants[regA];
-            }
-
-            if (sources.size() == 2) {
-                RegisterSpec specB = sources.get(1);
-                int regB = specB.getReg();
-                if (!ssaMeth.isRegALocal(specB) &&
-                        latticeValues[regB] == CONSTANT) {
-                    cB = latticeConstants[regB];
-                }
-            }
-
-            // Calculate the result of the condition
-            if (cA != null && sources.size() == 1) {
-                switch (((TypedConstant) cA).getBasicType()) {
-                    case Type.BT_INT:
-                        constantBranch = true;
-                        int vA = ((CstInteger) cA).getValue();
-                        switch (opcode.getOpcode()) {
-                            case RegOps.IF_EQ:
-                                constantSuccessor = (vA == 0);
-                                break;
-                            case RegOps.IF_NE:
-                                constantSuccessor = (vA != 0);
-                                break;
-                            case RegOps.IF_LT:
-                                constantSuccessor = (vA < 0);
-                                break;
-                            case RegOps.IF_GE:
-                                constantSuccessor = (vA >= 0);
-                                break;
-                            case RegOps.IF_LE:
-                                constantSuccessor = (vA <= 0);
-                                break;
-                            case RegOps.IF_GT:
-                                constantSuccessor = (vA > 0);
-                                break;
-                            default:
-                                throw new RuntimeException("Unexpected op");
-                        }
-                        break;
-                    default:
-                        // not yet supported
-                }
-            } else if (cA != null && cB != null) {
-                switch (((TypedConstant) cA).getBasicType()) {
-                    case Type.BT_INT:
-                        constantBranch = true;
-                        int vA = ((CstInteger) cA).getValue();
-                        int vB = ((CstInteger) cB).getValue();
-                        switch (opcode.getOpcode()) {
-                            case RegOps.IF_EQ:
-                                constantSuccessor = (vA == vB);
-                                break;
-                            case RegOps.IF_NE:
-                                constantSuccessor = (vA != vB);
-                                break;
-                            case RegOps.IF_LT:
-                                constantSuccessor = (vA < vB);
-                                break;
-                            case RegOps.IF_GE:
-                                constantSuccessor = (vA >= vB);
-                                break;
-                            case RegOps.IF_LE:
-                                constantSuccessor = (vA <= vB);
-                                break;
-                            case RegOps.IF_GT:
-                                constantSuccessor = (vA > vB);
-                                break;
-                            default:
-                                throw new RuntimeException("Unexpected op");
-                        }
-                        break;
-                    default:
-                        // not yet supported
-                }
-            }
-        }
-
-        /*
-         * If condition is constant, add only the target block to the
-         * worklist. Otherwise, add all successors to the worklist.
-         */
-        SsaBasicBlock block = insn.getBlock();
-
-        if (constantBranch) {
-            int successorBlock;
-            if (constantSuccessor) {
-                successorBlock = block.getSuccessorList().get(1);
-            } else {
-                successorBlock = block.getSuccessorList().get(0);
-            }
-            addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));
-            branchWorklist.add(insn);
-        } else {
-            for (int i = 0; i < block.getSuccessorList().size(); i++) {
-                int successorBlock = block.getSuccessorList().get(i);
-                addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));
-            }
-        }
-    }
-
-    /**
-     * Simulates math insns, if possible.
-     *
-     * @param insn non-null insn to simulate
-     * @param resultType basic type of the result
-     * @return constant result or null if not simulatable.
-     */
-    private Constant simulateMath(SsaInsn insn, int resultType) {
-        Insn ropInsn = insn.getOriginalRopInsn();
-        int opcode = insn.getOpcode().getOpcode();
-        RegisterSpecList sources = insn.getSources();
-        int regA = sources.get(0).getReg();
-        Constant cA;
-        Constant cB;
-
-        if (latticeValues[regA] != CONSTANT) {
-            cA = null;
-        } else {
-            cA = latticeConstants[regA];
-        }
-
-        if (sources.size() == 1) {
-            CstInsn cstInsn = (CstInsn) ropInsn;
-            cB = cstInsn.getConstant();
-        } else { /* sources.size() == 2 */
-            int regB = sources.get(1).getReg();
-            if (latticeValues[regB] != CONSTANT) {
-                cB = null;
-            } else {
-                cB = latticeConstants[regB];
-            }
-        }
-
-        if (cA == null || cB == null) {
-            //TODO handle a constant of 0 with MUL or AND
-            return null;
-        }
-
-        switch (resultType) {
-            case Type.BT_INT:
-                int vR;
-                boolean skip=false;
-
-                int vA = ((CstInteger) cA).getValue();
-                int vB = ((CstInteger) cB).getValue();
-
-                switch (opcode) {
-                    case RegOps.ADD:
-                        vR = vA + vB;
-                        break;
-                    case RegOps.SUB:
-                        // 1 source for reverse sub, 2 sources for regular sub
-                        if (sources.size() == 1) {
-                            vR = vB - vA;
-                        } else {
-                            vR = vA - vB;
-                        }
-                        break;
-                    case RegOps.MUL:
-                        vR = vA * vB;
-                        break;
-                    case RegOps.DIV:
-                        if (vB == 0) {
-                            skip = true;
-                            vR = 0; // just to hide a warning
-                        } else {
-                            vR = vA / vB;
-                        }
-                        break;
-                    case RegOps.AND:
-                        vR = vA & vB;
-                        break;
-                    case RegOps.OR:
-                        vR = vA | vB;
-                        break;
-                    case RegOps.XOR:
-                        vR = vA ^ vB;
-                        break;
-                    case RegOps.SHL:
-                        vR = vA << vB;
-                        break;
-                    case RegOps.SHR:
-                        vR = vA >> vB;
-                        break;
-                    case RegOps.USHR:
-                        vR = vA >>> vB;
-                        break;
-                    case RegOps.REM:
-                        if (vB == 0) {
-                            skip = true;
-                            vR = 0; // just to hide a warning
-                        } else {
-                            vR = vA % vB;
-                        }
-                        break;
-                    default:
-                        throw new RuntimeException("Unexpected op");
-                }
-
-                return skip ? null : CstInteger.make(vR);
-
-            default:
-                // not yet supported
-                return null;
-        }
-    }
-
-    /**
-     * Simulates a statement and set the result lattice value.
-     * @param insn instruction to simulate
-     */
-    private void simulateStmt(SsaInsn insn) {
-        Insn ropInsn = insn.getOriginalRopInsn();
-        if (ropInsn.getOpcode().getBranchingness() != Rop.BRANCH_NONE
-                || ropInsn.getOpcode().isCallLike()) {
-            simulateBranch(insn);
-        }
-
-        int opcode = insn.getOpcode().getOpcode();
-        RegisterSpec result = insn.getResult();
-
-        if (result == null) {
-            // Find move-result-pseudo result for int div and int rem
-            if (opcode == RegOps.DIV || opcode == RegOps.REM) {
-                SsaBasicBlock succ = insn.getBlock().getPrimarySuccessor();
-                result = succ.getInsns().get(0).getResult();
-            } else {
-                return;
-            }
-        }
-
-        int resultReg = result.getReg();
-        int resultValue = VARYING;
-        Constant resultConstant = null;
-
-        switch (opcode) {
-            case RegOps.CONST: {
-                CstInsn cstInsn = (CstInsn)ropInsn;
-                resultValue = CONSTANT;
-                resultConstant = cstInsn.getConstant();
-                break;
-            }
-            case RegOps.MOVE: {
-                if (insn.getSources().size() == 1) {
-                    int sourceReg = insn.getSources().get(0).getReg();
-                    resultValue = latticeValues[sourceReg];
-                    resultConstant = latticeConstants[sourceReg];
-                }
-                break;
-            }
-            case RegOps.ADD:
-            case RegOps.SUB:
-            case RegOps.MUL:
-            case RegOps.DIV:
-            case RegOps.AND:
-            case RegOps.OR:
-            case RegOps.XOR:
-            case RegOps.SHL:
-            case RegOps.SHR:
-            case RegOps.USHR:
-            case RegOps.REM: {
-                resultConstant = simulateMath(insn, result.getBasicType());
-                if (resultConstant != null) {
-                    resultValue = CONSTANT;
-                }
-                break;
-            }
-            case RegOps.MOVE_RESULT_PSEUDO: {
-                if (latticeValues[resultReg] == CONSTANT) {
-                    resultValue = latticeValues[resultReg];
-                    resultConstant = latticeConstants[resultReg];
-                }
-                break;
-            }
-            // TODO: Handle non-int arithmetic.
-            // TODO: Eliminate check casts that we can prove the type of.
-            default: {}
-        }
-        if (setLatticeValueTo(resultReg, resultValue, resultConstant)) {
-            addUsersToWorklist(resultReg, resultValue);
-        }
-    }
-
-    private void run() {
-        SsaBasicBlock firstBlock = ssaMeth.getEntryBlock();
-        addBlockToWorklist(firstBlock);
-
-        /* Empty all the worklists by propagating our values */
-        while (!cfgWorklist.isEmpty()
-                || !cfgPhiWorklist.isEmpty()
-                || !ssaWorklist.isEmpty()
-                || !varyingWorklist.isEmpty()) {
-            while (!cfgWorklist.isEmpty()) {
-                int listSize = cfgWorklist.size() - 1;
-                SsaBasicBlock block = cfgWorklist.remove(listSize);
-                simulateBlock(block);
-            }
-
-            while (!cfgPhiWorklist.isEmpty()) {
-                int listSize = cfgPhiWorklist.size() - 1;
-                SsaBasicBlock block = cfgPhiWorklist.remove(listSize);
-                simulatePhiBlock(block);
-            }
-
-            while (!varyingWorklist.isEmpty()) {
-                int listSize = varyingWorklist.size() - 1;
-                SsaInsn insn = varyingWorklist.remove(listSize);
-
-                if (!executableBlocks.get(insn.getBlock().getIndex())) {
-                    continue;
-                }
-
-                if (insn instanceof PhiInsn) {
-                    simulatePhi((PhiInsn)insn);
-                } else {
-                    simulateStmt(insn);
-                }
-            }
-            while (!ssaWorklist.isEmpty()) {
-                int listSize = ssaWorklist.size() - 1;
-                SsaInsn insn = ssaWorklist.remove(listSize);
-
-                if (!executableBlocks.get(insn.getBlock().getIndex())) {
-                    continue;
-                }
-
-                if (insn instanceof PhiInsn) {
-                    simulatePhi((PhiInsn)insn);
-                } else {
-                    simulateStmt(insn);
-                }
-            }
-        }
-
-        replaceConstants();
-        replaceBranches();
-    }
-
-    /**
-     * Replaces TypeBearers in source register specs with constant type
-     * bearers if possible. These are then referenced in later optimization
-     * steps.
-     */
-    private void replaceConstants() {
-        for (int reg = 0; reg < regCount; reg++) {
-            if (latticeValues[reg] != CONSTANT) {
-                continue;
-            }
-            if (!(latticeConstants[reg] instanceof TypedConstant)) {
-                // We can't do much with these
-                continue;
-            }
-
-            SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
-            TypeBearer typeBearer = defn.getResult().getTypeBearer();
-
-            if (typeBearer.isConstant()) {
-                /*
-                 * The definition was a constant already.
-                 * The uses should be as well.
-                 */
-                continue;
-            }
-
-            // Update the destination RegisterSpec with the constant value
-            RegisterSpec dest = defn.getResult();
-            RegisterSpec newDest
-                    = dest.withType((TypedConstant)latticeConstants[reg]);
-            defn.setResult(newDest);
-
-            /*
-             * Update the sources RegisterSpec's of all non-move uses.
-             * These will be used in later steps.
-             */
-            for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
-                if (insn.isPhiOrMove()) {
-                    continue;
-                }
-
-                NormalSsaInsn nInsn = (NormalSsaInsn) insn;
-                RegisterSpecList sources = insn.getSources();
-
-                int index = sources.indexOfRegister(reg);
-
-                RegisterSpec spec = sources.get(index);
-                RegisterSpec newSpec
-                        = spec.withType((TypedConstant)latticeConstants[reg]);
-
-                nInsn.changeOneSource(index, newSpec);
-            }
-        }
-    }
-
-    /**
-     * Replaces branches that have constant conditions with gotos
-     */
-    private void replaceBranches() {
-        for (SsaInsn insn : branchWorklist) {
-            // Find if a successor block is never executed
-            int oldSuccessor = -1;
-            SsaBasicBlock block = insn.getBlock();
-            int successorSize = block.getSuccessorList().size();
-            for (int i = 0; i < successorSize; i++) {
-                int successorBlock = block.getSuccessorList().get(i);
-                if (!executableBlocks.get(successorBlock)) {
-                    oldSuccessor = successorBlock;
-                }
-            }
-
-            /*
-             * Prune branches that have already been handled and ones that no
-             * longer have constant conditions (no nonexecutable successors)
-             */
-            if (successorSize != 2 || oldSuccessor == -1) continue;
-
-            // Replace branch with goto
-            Insn originalRopInsn = insn.getOriginalRopInsn();
-            block.replaceLastInsn(new PlainInsn(Rops.GOTO,
-                originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));
-            block.removeSuccessor(oldSuccessor);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SetFactory.java b/dx/src/main/java/com/android/dx/ssa/SetFactory.java
deleted file mode 100644
index 92e965f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SetFactory.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2008 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.ssa;
-
-import com.android.dx.util.BitIntSet;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.ListIntSet;
-
-
-/**
- * Makes int sets for various parts of the optimizer.
- */
-public final class SetFactory {
-
-    /**
-     * BitIntSet/ListIntSet threshold for dominance frontier sets. These
-     * sets are kept per basic block until phi placement and tend to be,
-     * like the CFG itself, very sparse at large sizes.
-     *
-     * A value of 3072 here is somewhere around 1.125mb of total bitset size.
-     */
-    private static final int DOMFRONT_SET_THRESHOLD_SIZE = 3072;
-
-    /**
-     * BitIntSet/ListIntSet threshold for interference graph sets. These
-     * sets are kept per register until register allocation is done.
-     *
-     * A value of 3072 here is somewhere around 1.125mb of total bitset size.
-     */
-    private static final int INTERFERENCE_SET_THRESHOLD_SIZE = 3072;
-
-    /**
-     * BitIntSet/ListIntSet threshold for the live in/out sets kept by
-     * {@link SsaBasicBlock}. These are sets of SSA registers kept per basic
-     * block during register allocation.
-     *
-     * The total size of a bitset for this would be the count of blocks
-     * times the size of registers. The threshold value here is merely
-     * the register count, which is typically on the order of the block
-     * count as well.
-     */
-    private static final int LIVENESS_SET_THRESHOLD_SIZE = 3072;
-
-
-    /**
-     * Make IntSet for the dominance-frontier sets.
-     *
-     * @param szBlocks {@code >=0;} count of basic blocks in method
-     * @return {@code non-null;} appropriate set
-     */
-    /*package*/ static IntSet makeDomFrontSet(int szBlocks) {
-        return szBlocks <= DOMFRONT_SET_THRESHOLD_SIZE
-                ? new BitIntSet(szBlocks)
-                : new ListIntSet();
-    }
-
-    /**
-     * Make IntSet for the interference graph sets. Public because
-     * InterferenceGraph is in another package.
-     *
-     * @param countRegs {@code >=0;} count of SSA registers used in method
-     * @return {@code non-null;} appropriate set
-     */
-    public static IntSet makeInterferenceSet(int countRegs) {
-        return countRegs <= INTERFERENCE_SET_THRESHOLD_SIZE
-                ? new BitIntSet(countRegs)
-                : new ListIntSet();
-    }
-
-    /**
-     * Make IntSet for register live in/out sets.
-     *
-     * @param countRegs {@code >=0;} count of SSA registers used in method
-     * @return {@code non-null;} appropriate set
-     */
-    /*package*/ static IntSet makeLivenessSet(int countRegs) {
-        return countRegs <= LIVENESS_SET_THRESHOLD_SIZE
-                ? new BitIntSet(countRegs)
-                : new ListIntSet();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SsaBasicBlock.java b/dx/src/main/java/com/android/dx/ssa/SsaBasicBlock.java
deleted file mode 100644
index 499f59f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SsaBasicBlock.java
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-import com.android.dx.util.IntSet;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * An SSA representation of a basic block.
- */
-public final class SsaBasicBlock {
-    /**
-     * {@code non-null;} comparator for instances of this class that
-     * just compares block labels
-     */
-    public static final Comparator<SsaBasicBlock> LABEL_COMPARATOR =
-        new LabelComparator();
-
-    /** {@code non-null;} insn list associated with this instance */
-    private ArrayList<SsaInsn> insns;
-
-    /** {@code non-null;} predecessor set (by block list index) */
-    private BitSet predecessors;
-
-    /** {@code non-null;} successor set (by block list index) */
-    private BitSet successors;
-
-    /**
-     * {@code non-null;} ordered successor list
-     * (same block may be listed more than once)
-     */
-    private IntList successorList;
-
-    /**
-     * block list index of primary successor, or {@code -1} for no primary
-     * successor
-     */
-    private int primarySuccessor = -1;
-
-    /** label of block in rop form */
-    private int ropLabel;
-
-    /** {@code non-null;} method we belong to */
-    private SsaMethod parent;
-
-    /** our index into parent.getBlock() */
-    private int index;
-
-    /** list of dom children */
-    private final ArrayList<SsaBasicBlock> domChildren;
-
-    /**
-     * the number of moves added to the end of the block during the
-     * phi-removal process. Retained for subsequent move scheduling.
-     */
-    private int movesFromPhisAtEnd = 0;
-
-    /**
-     * the number of moves added to the beginning of the block during the
-     * phi-removal process. Retained for subsequent move scheduling.
-     */
-    private int movesFromPhisAtBeginning = 0;
-
-    /**
-     * contains last computed value of reachability of this block, or -1
-     * if reachability hasn't been calculated yet
-     */
-    private int reachable = -1;
-
-    /**
-     * {@code null-ok;} indexed by reg: the regs that are live-in at
-     * this block
-     */
-    private IntSet liveIn;
-
-    /**
-     * {@code null-ok;} indexed by reg: the regs that are live-out at
-     * this block
-     */
-    private IntSet liveOut;
-
-    /**
-     * Creates a new empty basic block.
-     *
-     * @param basicBlockIndex index this block will have
-     * @param ropLabel original rop-form label
-     * @param parent method of this block
-     */
-    public SsaBasicBlock(final int basicBlockIndex, final int ropLabel,
-            final SsaMethod parent) {
-        this.parent = parent;
-        this.index = basicBlockIndex;
-        this.insns = new ArrayList<SsaInsn>();
-        this.ropLabel = ropLabel;
-
-        this.predecessors = new BitSet(parent.getBlocks().size());
-        this.successors = new BitSet(parent.getBlocks().size());
-        this.successorList = new IntList();
-
-        domChildren = new ArrayList<SsaBasicBlock>();
-    }
-
-    /**
-     * Creates a new SSA basic block from a ROP form basic block.
-     *
-     * @param rmeth original method
-     * @param basicBlockIndex index this block will have
-     * @param parent method of this block predecessor set will be
-     * updated
-     * @return new instance
-     */
-    public static SsaBasicBlock newFromRop(RopMethod rmeth,
-            int basicBlockIndex, final SsaMethod parent) {
-        BasicBlockList ropBlocks = rmeth.getBlocks();
-        BasicBlock bb = ropBlocks.get(basicBlockIndex);
-        SsaBasicBlock result =
-            new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent);
-        InsnList ropInsns = bb.getInsns();
-
-        result.insns.ensureCapacity(ropInsns.size());
-
-        for (int i = 0, sz = ropInsns.size() ; i < sz ; i++) {
-            result.insns.add(new NormalSsaInsn (ropInsns.get(i), result));
-        }
-
-        result.predecessors = SsaMethod.bitSetFromLabelList(
-                ropBlocks,
-                rmeth.labelToPredecessors(bb.getLabel()));
-
-        result.successors
-                = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors());
-
-        result.successorList
-                = SsaMethod.indexListFromLabelList(ropBlocks,
-                    bb.getSuccessors());
-
-        if (result.successorList.size() != 0) {
-            int primarySuccessor = bb.getPrimarySuccessor();
-
-            result.primarySuccessor = (primarySuccessor < 0)
-                    ? -1 : ropBlocks.indexOfLabel(primarySuccessor);
-        }
-
-        return result;
-    }
-
-    /**
-     * Adds a basic block as a dom child for this block. Used when constructing
-     * the dom tree.
-     *
-     * @param child {@code non-null;} new dom child
-     */
-    public void addDomChild(SsaBasicBlock child) {
-        domChildren.add(child);
-    }
-
-    /**
-     * Gets the dom children for this node. Don't modify this list.
-     *
-     * @return {@code non-null;} list of dom children
-     */
-    public ArrayList<SsaBasicBlock> getDomChildren() {
-        return domChildren;
-    }
-
-    /**
-     * Adds a phi insn to the beginning of this block. The result type of
-     * the phi will be set to void, to indicate that it's currently unknown.
-     *
-     * @param reg {@code >=0;} result reg
-     */
-    public void addPhiInsnForReg(int reg) {
-        insns.add(0, new PhiInsn(reg, this));
-    }
-
-    /**
-     * Adds a phi insn to the beginning of this block. This is to be used
-     * when the result type or local-association can be determined at phi
-     * insert time.
-     *
-     * @param resultSpec {@code non-null;} reg
-     */
-    public void addPhiInsnForReg(RegisterSpec resultSpec) {
-        insns.add(0, new PhiInsn(resultSpec, this));
-    }
-
-    /**
-     * Adds an insn to the head of this basic block, just after any phi
-     * insns.
-     *
-     * @param insn {@code non-null;} rop-form insn to add
-     */
-    public void addInsnToHead(Insn insn) {
-        SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);
-        insns.add(getCountPhiInsns(), newInsn);
-        parent.onInsnAdded(newInsn);
-    }
-
-    /**
-     * Replaces the last insn in this block. The provided insn must have
-     * some branchingness.
-     *
-     * @param insn {@code non-null;} rop-form insn to add, which must branch.
-     */
-    public void replaceLastInsn(Insn insn) {
-        if (insn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {
-            throw new IllegalArgumentException("last insn must branch");
-        }
-
-        SsaInsn oldInsn = insns.get(insns.size() - 1);
-        SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);
-
-        insns.set(insns.size() - 1, newInsn);
-
-        parent.onInsnRemoved(oldInsn);
-        parent.onInsnAdded(newInsn);
-    }
-
-    /**
-     * Visits each phi insn.
-     *
-     * @param v {@code non-null;} the callback
-     */
-    public void forEachPhiInsn(PhiInsn.Visitor v) {
-        int sz = insns.size();
-
-        for (int i = 0; i < sz; i++) {
-            SsaInsn insn = insns.get(i);
-            if (insn instanceof PhiInsn) {
-                v.visitPhiInsn((PhiInsn) insn);
-            } else {
-                /*
-                 * Presently we assume PhiInsn's are in a continuous
-                 * block at the top of the list
-                 */
-                break;
-            }
-        }
-    }
-
-    /**
-     * Deletes all phi insns. Do this after adding appropriate move insns.
-     */
-    public void removeAllPhiInsns() {
-        /*
-         * Presently we assume PhiInsn's are in a continuous
-         * block at the top of the list.
-         */
-
-        insns.subList(0, getCountPhiInsns()).clear();
-    }
-
-    /**
-     * Gets the number of phi insns at the top of this basic block.
-     *
-     * @return count of phi insns
-     */
-    private int getCountPhiInsns() {
-        int countPhiInsns;
-
-        int sz = insns.size();
-        for (countPhiInsns = 0; countPhiInsns < sz; countPhiInsns++) {
-            SsaInsn insn = insns.get(countPhiInsns);
-            if (!(insn instanceof PhiInsn)) {
-                break;
-            }
-        }
-
-        return countPhiInsns;
-    }
-
-    /**
-     * @return {@code non-null;} the (mutable) instruction list for this block,
-     * with phi insns at the beginning
-     */
-    public ArrayList<SsaInsn> getInsns() {
-        return insns;
-    }
-
-    /**
-     * @return {@code non-null;} the (mutable) list of phi insns for this block
-     */
-    public List<SsaInsn> getPhiInsns() {
-        return insns.subList(0, getCountPhiInsns());
-    }
-
-    /**
-     * @return the block index of this block
-     */
-    public int getIndex() {
-        return index;
-    }
-
-    /**
-     * @return the label of this block in rop form
-     */
-    public int getRopLabel() {
-        return ropLabel;
-    }
-
-    /**
-     * @return the label of this block in rop form as a hex string
-     */
-    public String getRopLabelString() {
-        return Hex.u2(ropLabel);
-    }
-
-    /**
-     * @return {@code non-null;} predecessors set, indexed by block index
-     */
-    public BitSet getPredecessors() {
-        return predecessors;
-    }
-
-    /**
-     * @return {@code non-null;} successors set, indexed by block index
-     */
-    public BitSet getSuccessors() {
-        return successors;
-    }
-
-    /**
-     * @return {@code non-null;} ordered successor list, containing block
-     * indicies
-     */
-    public IntList getSuccessorList() {
-        return successorList;
-    }
-
-    /**
-     * @return {@code >= -1;} block index of primary successor or
-     * {@code -1} if no primary successor
-     */
-    public int getPrimarySuccessorIndex() {
-        return primarySuccessor;
-    }
-
-    /**
-     * @return rop label of primary successor
-     */
-    public int getPrimarySuccessorRopLabel() {
-        return parent.blockIndexToRopLabel(primarySuccessor);
-    }
-
-    /**
-     * @return {@code null-ok;} the primary successor block or {@code null}
-     * if there is none
-     */
-    public SsaBasicBlock getPrimarySuccessor() {
-        if (primarySuccessor < 0) {
-            return null;
-        } else {
-            return parent.getBlocks().get(primarySuccessor);
-        }
-    }
-
-    /**
-     * @return successor list of rop labels
-     */
-    public IntList getRopLabelSuccessorList() {
-        IntList result = new IntList(successorList.size());
-
-        int sz = successorList.size();
-
-        for (int i = 0; i < sz; i++) {
-            result.add(parent.blockIndexToRopLabel(successorList.get(i)));
-        }
-        return result;
-    }
-
-    /**
-     * @return {@code non-null;} method that contains this block
-     */
-    public SsaMethod getParent() {
-        return parent;
-    }
-
-    /**
-     * Inserts a new empty GOTO block as a predecessor to this block.
-     * All previous predecessors will be predecessors to the new block.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public SsaBasicBlock insertNewPredecessor() {
-        SsaBasicBlock newPred = parent.makeNewGotoBlock();
-
-        // Update the new block.
-        newPred.predecessors = predecessors;
-        newPred.successors.set(index) ;
-        newPred.successorList.add(index);
-        newPred.primarySuccessor = index;
-
-
-        // Update us.
-        predecessors = new BitSet(parent.getBlocks().size());
-        predecessors.set(newPred.index);
-
-        // Update our (soon-to-be) old predecessors.
-        for (int i = newPred.predecessors.nextSetBit(0); i >= 0;
-                i = newPred.predecessors.nextSetBit(i + 1)) {
-
-            SsaBasicBlock predBlock = parent.getBlocks().get(i);
-
-            predBlock.replaceSuccessor(index, newPred.index);
-        }
-
-        return newPred;
-    }
-
-    /**
-     * Constructs and inserts a new empty GOTO block {@code Z} between
-     * this block ({@code A}) and a current successor block
-     * ({@code B}). The new block will replace B as A's successor and
-     * A as B's predecessor. A and B will no longer be directly connected.
-     * If B is listed as a successor multiple times, all references
-     * are replaced.
-     *
-     * @param other current successor (B)
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public SsaBasicBlock insertNewSuccessor(SsaBasicBlock other) {
-        SsaBasicBlock newSucc = parent.makeNewGotoBlock();
-
-        if (!successors.get(other.index)) {
-            throw new RuntimeException("Block " + other.getRopLabelString()
-                    + " not successor of " + getRopLabelString());
-        }
-
-        // Update the new block.
-        newSucc.predecessors.set(this.index);
-        newSucc.successors.set(other.index) ;
-        newSucc.successorList.add(other.index);
-        newSucc.primarySuccessor = other.index;
-
-        // Update us.
-        for (int i = successorList.size() - 1 ;  i >= 0; i--) {
-            if (successorList.get(i) == other.index) {
-                successorList.set(i, newSucc.index);
-            }
-        }
-
-        if (primarySuccessor == other.index) {
-            primarySuccessor = newSucc.index;
-        }
-        successors.clear(other.index);
-        successors.set(newSucc.index);
-
-        // Update "other".
-        other.predecessors.set(newSucc.index);
-        other.predecessors.set(index, successors.get(other.index));
-
-        return newSucc;
-    }
-
-    /**
-     * Replaces an old successor with a new successor. This will throw
-     * RuntimeException if {@code oldIndex} was not a successor.
-     *
-     * @param oldIndex index of old successor block
-     * @param newIndex index of new successor block
-     */
-    public void replaceSuccessor(int oldIndex, int newIndex) {
-        if (oldIndex == newIndex) {
-            return;
-        }
-
-        // Update us.
-        successors.set(newIndex);
-
-        if (primarySuccessor == oldIndex) {
-            primarySuccessor = newIndex;
-        }
-
-        for (int i = successorList.size() - 1 ;  i >= 0; i--) {
-            if (successorList.get(i) == oldIndex) {
-                successorList.set(i, newIndex);
-            }
-        }
-
-        successors.clear(oldIndex);
-
-        // Update new successor.
-        parent.getBlocks().get(newIndex).predecessors.set(index);
-
-        // Update old successor.
-        parent.getBlocks().get(oldIndex).predecessors.clear(index);
-    }
-
-    /**
-     * Removes a successor from this block's successor list.
-     *
-     * @param oldIndex index of successor block to remove
-     */
-    public void removeSuccessor(int oldIndex) {
-        int removeIndex = 0;
-
-        for (int i = successorList.size() - 1; i >= 0; i--) {
-            if (successorList.get(i) == oldIndex) {
-                removeIndex = i;
-            } else {
-                primarySuccessor = successorList.get(i);
-            }
-        }
-
-        successorList.removeIndex(removeIndex);
-        successors.clear(oldIndex);
-        parent.getBlocks().get(oldIndex).predecessors.clear(index);
-    }
-
-    /**
-     * Attaches block to an exit block if necessary. If this block
-     * is not an exit predecessor or is the exit block, this block does
-     * nothing. For use by {@link com.android.dx.ssa.SsaMethod#makeExitBlock}
-     *
-     * @param exitBlock {@code non-null;} exit block
-     */
-    public void exitBlockFixup(SsaBasicBlock exitBlock) {
-        if (this == exitBlock) {
-            return;
-        }
-
-        if (successorList.size() == 0) {
-            /*
-             * This is an exit predecessor.
-             * Set the successor to the exit block
-             */
-            successors.set(exitBlock.index);
-            successorList.add(exitBlock.index);
-            primarySuccessor = exitBlock.index;
-            exitBlock.predecessors.set(this.index);
-        }
-    }
-
-    /**
-     * Adds a move instruction to the end of this basic block, just
-     * before the last instruction. If the result of the final instruction
-     * is the source in question, then the move is placed at the beginning of
-     * the primary successor block. This is for unversioned registers.
-     *
-     * @param result move destination
-     * @param source move source
-     */
-    public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {
-
-        if (result.getReg() == source.getReg()) {
-            // Sometimes we end up with no-op moves. Ignore them here.
-            return;
-        }
-
-        /*
-         * The last Insn has to be a normal SSA insn: a phi can't branch
-         * or return or cause an exception, etc.
-         */
-        NormalSsaInsn lastInsn;
-        lastInsn = (NormalSsaInsn)insns.get(insns.size()-1);
-
-        if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
-            /*
-             * The final insn in this block has a source or result
-             * register, and the moves we may need to place and
-             * schedule may interfere. We need to insert this
-             * instruction at the beginning of the primary successor
-             * block instead. We know this is safe, because when we
-             * edge-split earlier, we ensured that each successor has
-             * only us as a predecessor.
-             */
-
-            for (int i = successors.nextSetBit(0)
-                    ; i >= 0
-                    ; i = successors.nextSetBit(i + 1)) {
-
-                SsaBasicBlock succ;
-
-                succ = parent.getBlocks().get(i);
-                succ.addMoveToBeginning(result, source);
-            }
-        } else {
-            /*
-             * We can safely add a move to the end of the block just
-             * before the last instruction, because the final insn does
-             * not assign to anything.
-             */
-            RegisterSpecList sources = RegisterSpecList.make(source);
-            NormalSsaInsn toAdd = new NormalSsaInsn(
-                    new PlainInsn(Rops.opMove(result.getType()),
-                            SourcePosition.NO_INFO, result, sources), this);
-
-            insns.add(insns.size() - 1, toAdd);
-
-            movesFromPhisAtEnd++;
-        }
-    }
-
-    /**
-     * Adds a move instruction after the phi insn block.
-     *
-     * @param result move destination
-     * @param source move source
-     */
-    public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {
-        if (result.getReg() == source.getReg()) {
-            // Sometimes we end up with no-op moves. Ignore them here.
-            return;
-        }
-
-        RegisterSpecList sources = RegisterSpecList.make(source);
-        NormalSsaInsn toAdd = new NormalSsaInsn(
-                new PlainInsn(Rops.opMove(result.getType()),
-                        SourcePosition.NO_INFO, result, sources), this);
-
-        insns.add(getCountPhiInsns(), toAdd);
-        movesFromPhisAtBeginning++;
-    }
-
-    /**
-     * Sets the register as used in a bitset, taking into account its
-     * category/width.
-     *
-     * @param regsUsed set, indexed by register number
-     * @param rs register to mark as used
-     */
-    private static void setRegsUsed (BitSet regsUsed, RegisterSpec rs) {
-        regsUsed.set(rs.getReg());
-        if (rs.getCategory() > 1) {
-            regsUsed.set(rs.getReg() + 1);
-        }
-    }
-
-    /**
-     * Checks to see if the register is used in a bitset, taking
-     * into account its category/width.
-     *
-     * @param regsUsed set, indexed by register number
-     * @param rs register to mark as used
-     * @return true if register is fully or partially (for the case of wide
-     * registers) used.
-     */
-    private static boolean checkRegUsed (BitSet regsUsed, RegisterSpec rs) {
-        int reg = rs.getReg();
-        int category = rs.getCategory();
-
-        return regsUsed.get(reg)
-                || (category == 2 ? regsUsed.get(reg + 1) : false);
-    }
-
-    /**
-     * Ensures that all move operations in this block occur such that
-     * reads of any register happen before writes to that register.
-     * NOTE: caller is expected to returnSpareRegisters()!
-     *
-     * TODO: See Briggs, et al "Practical Improvements to the Construction and
-     * Destruction of Static Single Assignment Form" section 5. a) This can
-     * be done in three passes.
-     *
-     * @param toSchedule List of instructions. Must consist only of moves.
-     */
-    private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
-        BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
-
-        // TODO: Get rid of this.
-        BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
-
-        int sz = toSchedule.size();
-
-        int insertPlace = 0;
-
-        while (insertPlace < sz) {
-            int oldInsertPlace = insertPlace;
-
-            // Record all registers used as sources in this block.
-            for (int i = insertPlace; i < sz; i++) {
-                setRegsUsed(regsUsedAsSources,
-                        toSchedule.get(i).getSources().get(0));
-
-                setRegsUsed(regsUsedAsResults,
-                        toSchedule.get(i).getResult());
-            }
-
-            /*
-             * If there are no circular dependencies, then there exists
-             * n instructions where n > 1 whose result is not used as a source.
-             */
-            for (int i = insertPlace; i <sz; i++) {
-                SsaInsn insn = toSchedule.get(i);
-
-                /*
-                 * Move these n registers to the front, since they overwrite
-                 * nothing.
-                 */
-                if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
-                    Collections.swap(toSchedule, i, insertPlace++);
-                }
-            }
-
-            /*
-             * If we've made no progress in this iteration, there's a
-             * circular dependency. Split it using the temp reg.
-             */
-            if (oldInsertPlace == insertPlace) {
-
-                SsaInsn insnToSplit = null;
-
-                // Find an insn whose result is used as a source.
-                for (int i = insertPlace; i < sz; i++) {
-                    SsaInsn insn = toSchedule.get(i);
-                    if (checkRegUsed(regsUsedAsSources, insn.getResult())
-                            && checkRegUsed(regsUsedAsResults,
-                                insn.getSources().get(0))) {
-
-                        insnToSplit = insn;
-                        /*
-                         * We're going to split this insn; move it to the
-                         * front.
-                         */
-                        Collections.swap(toSchedule, insertPlace, i);
-                        break;
-                    }
-                }
-
-                // At least one insn will be set above.
-
-                RegisterSpec result = insnToSplit.getResult();
-                RegisterSpec tempSpec = result.withReg(
-                        parent.borrowSpareRegister(result.getCategory()));
-
-                NormalSsaInsn toAdd = new NormalSsaInsn(
-                        new PlainInsn(Rops.opMove(result.getType()),
-                                SourcePosition.NO_INFO,
-                                tempSpec,
-                                insnToSplit.getSources()), this);
-
-                toSchedule.add(insertPlace++, toAdd);
-
-                RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
-
-                NormalSsaInsn toReplace = new NormalSsaInsn(
-                        new PlainInsn(Rops.opMove(result.getType()),
-                                SourcePosition.NO_INFO,
-                                result,
-                                newSources), this);
-
-                toSchedule.set(insertPlace, toReplace);
-
-                // The size changed.
-                sz = toSchedule.size();
-            }
-
-            regsUsedAsSources.clear();
-            regsUsedAsResults.clear();
-        }
-    }
-
-    /**
-     * Adds {@code regV} to the live-out list for this block. This is called
-     * by the liveness analyzer.
-     *
-     * @param regV register that is live-out for this block.
-     */
-    public void addLiveOut (int regV) {
-        if (liveOut == null) {
-            liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
-        }
-
-        liveOut.add(regV);
-    }
-
-    /**
-     * Adds {@code regV} to the live-in list for this block. This is
-     * called by the liveness analyzer.
-     *
-     * @param regV register that is live-in for this block.
-     */
-    public void addLiveIn (int regV) {
-        if (liveIn == null) {
-            liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
-        }
-
-        liveIn.add(regV);
-    }
-
-    /**
-     * Returns the set of live-in registers. Valid after register
-     * interference graph has been generated, otherwise empty.
-     *
-     * @return {@code non-null;} live-in register set.
-     */
-    public IntSet getLiveInRegs() {
-        if (liveIn == null) {
-            liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
-        }
-        return liveIn;
-    }
-
-    /**
-     * Returns the set of live-out registers. Valid after register
-     * interference graph has been generated, otherwise empty.
-     *
-     * @return {@code non-null;} live-out register set
-     */
-    public IntSet getLiveOutRegs() {
-        if (liveOut == null) {
-            liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
-        }
-        return liveOut;
-    }
-
-    /**
-     * @return true if this is the one-and-only exit block for this method
-     */
-    public boolean isExitBlock() {
-        return index == parent.getExitBlockIndex();
-    }
-
-    /**
-     * Returns true if this block was last calculated to be reachable.
-     * Recalculates reachability if value has never been computed.
-     *
-     * @return {@code true} if reachable
-     */
-    public boolean isReachable() {
-        if (reachable == -1) {
-            parent.computeReachability();
-        }
-        return (reachable == 1);
-    }
-
-    /**
-     * Sets reachability of block to specified value
-     *
-     * @param reach new value of reachability for block
-     */
-    public void setReachable(int reach) {
-        reachable = reach;
-    }
-
-    /**
-     * Sorts move instructions added via {@code addMoveToEnd} during
-     * phi removal so that results don't overwrite sources that are used.
-     * For use after all phis have been removed and all calls to
-     * addMoveToEnd() have been made.<p>
-     *
-     * This is necessary because copy-propogation may have left us in a state
-     * where the same basic block has the same register as a phi operand
-     * and a result. In this case, the register in the phi operand always
-     * refers value before any other phis have executed.
-     */
-    public void scheduleMovesFromPhis() {
-        if (movesFromPhisAtBeginning > 1) {
-            List<SsaInsn> toSchedule;
-
-            toSchedule = insns.subList(0, movesFromPhisAtBeginning);
-
-            scheduleUseBeforeAssigned(toSchedule);
-
-            SsaInsn firstNonPhiMoveInsn = insns.get(movesFromPhisAtBeginning);
-
-            /*
-             * TODO: It's actually possible that this case never happens,
-             * because a move-exception block, having only one predecessor
-             * in SSA form, perhaps is never on a dominance frontier.
-             */
-            if (firstNonPhiMoveInsn.isMoveException()) {
-                if (true) {
-                    /*
-                     * We've yet to observe this case, and if it can
-                     * occur the code written to handle it probably
-                     * does not work.
-                     */
-                    throw new RuntimeException(
-                            "Unexpected: moves from "
-                                    +"phis before move-exception");
-                } else {
-                    /*
-                     * A move-exception insn must be placed first in this block
-                     * We need to move it there, and deal with possible
-                     * interference.
-                     */
-                    boolean moveExceptionInterferes = false;
-
-                    int moveExceptionResult
-                            = firstNonPhiMoveInsn.getResult().getReg();
-
-                    /*
-                     * Does the move-exception result reg interfere with the
-                     * phi moves?
-                     */
-                    for (SsaInsn insn : toSchedule) {
-                        if (insn.isResultReg(moveExceptionResult)
-                                || insn.isRegASource(moveExceptionResult)) {
-                            moveExceptionInterferes = true;
-                            break;
-                        }
-                    }
-
-                    if (!moveExceptionInterferes) {
-                        // This is the easy case.
-                        insns.remove(movesFromPhisAtBeginning);
-                        insns.add(0, firstNonPhiMoveInsn);
-                    } else {
-                        /*
-                         * We need to move the result to a spare reg
-                         * and move it back.
-                         */
-                        RegisterSpec originalResultSpec
-                            = firstNonPhiMoveInsn.getResult();
-                        int spareRegister = parent.borrowSpareRegister(
-                                originalResultSpec.getCategory());
-
-                        // We now move it to a spare register.
-                        firstNonPhiMoveInsn.changeResultReg(spareRegister);
-                        RegisterSpec tempSpec =
-                            firstNonPhiMoveInsn.getResult();
-
-                        insns.add(0, firstNonPhiMoveInsn);
-
-                        // And here we move it back.
-
-                        NormalSsaInsn toAdd = new NormalSsaInsn(
-                                new PlainInsn(
-                                        Rops.opMove(tempSpec.getType()),
-                                        SourcePosition.NO_INFO,
-                                        originalResultSpec,
-                                        RegisterSpecList.make(tempSpec)),
-                                this);
-
-
-                        /*
-                         * Place it immediately after the phi-moves,
-                         * overwriting the move-exception that was there.
-                         */
-                        insns.set(movesFromPhisAtBeginning + 1, toAdd);
-                    }
-                }
-            }
-        }
-
-        if (movesFromPhisAtEnd > 1) {
-            scheduleUseBeforeAssigned(
-                    insns.subList(insns.size() - movesFromPhisAtEnd - 1,
-                                insns.size() - 1));
-        }
-
-        // Return registers borrowed here and in scheduleUseBeforeAssigned().
-        parent.returnSpareRegisters();
-
-    }
-
-    /**
-     * Visits all insns in this block.
-     *
-     * @param visitor {@code non-null;} callback interface
-     */
-    public void forEachInsn(SsaInsn.Visitor visitor) {
-        // This gets called a LOT, and not using an iterator
-        // saves a lot of allocations and reduces memory usage
-        int len = insns.size();
-        for (int i = 0; i < len; i++) {
-            insns.get(i).accept(visitor);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        return "{" + index + ":" + Hex.u2(ropLabel) + '}';
-    }
-
-    /**
-     * Visitor interface for basic blocks.
-     */
-    public interface Visitor {
-        /**
-         * Indicates a block has been visited by an iterator method.
-         *
-         * @param v {@code non-null;} block visited
-         * @param parent {@code null-ok;} parent node if applicable
-         */
-        void visitBlock (SsaBasicBlock v, SsaBasicBlock parent);
-    }
-
-    /**
-     * Label comparator.
-     */
-    public static final class LabelComparator
-            implements Comparator<SsaBasicBlock> {
-        /** {@inheritDoc} */
-        public int compare(SsaBasicBlock b1, SsaBasicBlock b2) {
-            int label1 = b1.ropLabel;
-            int label2 = b2.ropLabel;
-
-            if (label1 < label2) {
-                return -1;
-            } else if (label1 > label2) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SsaConverter.java b/dx/src/main/java/com/android/dx/ssa/SsaConverter.java
deleted file mode 100644
index 5cd8b6f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SsaConverter.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.util.IntIterator;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-
-/**
- * Converts ROP methods to SSA Methods
- */
-public class SsaConverter {
-    public static final boolean DEBUG = false;
-
-    /**
-     * Returns an SSA representation, edge-split and with phi
-     * functions placed.
-     *
-     * @param rmeth input
-     * @param paramWidth the total width, in register-units, of the method's
-     * parameters
-     * @param isStatic {@code true} if this method has no {@code this}
-     * pointer argument
-     * @return output in SSA form
-     */
-    public static SsaMethod convertToSsaMethod(RopMethod rmeth,
-            int paramWidth, boolean isStatic) {
-        SsaMethod result
-            = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
-
-        edgeSplit(result);
-
-        LocalVariableInfo localInfo = LocalVariableExtractor.extract(result);
-
-        placePhiFunctions(result, localInfo, 0);
-        new SsaRenamer(result).run();
-
-        /*
-         * The exit block, added here, is not considered for edge splitting
-         * or phi placement since no actual control flows to it.
-         */
-        result.makeExitBlock();
-
-        return result;
-    }
-
-    /**
-     * Updates an SSA representation, placing phi functions and renaming all
-     * registers above a certain threshold number.
-     *
-     * @param ssaMeth input
-     * @param threshold registers below this number are unchanged
-     */
-    public static void updateSsaMethod(SsaMethod ssaMeth, int threshold) {
-        LocalVariableInfo localInfo = LocalVariableExtractor.extract(ssaMeth);
-        placePhiFunctions(ssaMeth, localInfo, threshold);
-        new SsaRenamer(ssaMeth, threshold).run();
-    }
-
-    /**
-     * Returns an SSA represention with only the edge-splitter run.
-     *
-     * @param rmeth method to process
-     * @param paramWidth width of all arguments in the method
-     * @param isStatic {@code true} if this method has no {@code this}
-     * pointer argument
-     * @return an SSA represention with only the edge-splitter run
-     */
-    public static SsaMethod testEdgeSplit (RopMethod rmeth, int paramWidth,
-            boolean isStatic) {
-        SsaMethod result;
-
-        result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
-
-        edgeSplit(result);
-        return result;
-    }
-
-    /**
-     * Returns an SSA represention with only the steps through the
-     * phi placement run.
-     *
-     * @param rmeth method to process
-     * @param paramWidth width of all arguments in the method
-     * @param isStatic {@code true} if this method has no {@code this}
-     * pointer argument
-     * @return an SSA represention with only the edge-splitter run
-     */
-    public static SsaMethod testPhiPlacement (RopMethod rmeth, int paramWidth,
-            boolean isStatic) {
-        SsaMethod result;
-
-        result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
-
-        edgeSplit(result);
-
-        LocalVariableInfo localInfo = LocalVariableExtractor.extract(result);
-
-        placePhiFunctions(result, localInfo, 0);
-        return result;
-    }
-
-    /**
-     * See Appel section 19.1:
-     *
-     * Converts CFG into "edge-split" form, such that each node either a
-     * unique successor or unique predecessor.<p>
-     *
-     * In addition, the SSA form we use enforces a further constraint,
-     * requiring each block with a final instruction that returns a
-     * value to have a primary successor that has no other
-     * predecessor. This ensures move statements can always be
-     * inserted correctly when phi statements are removed.
-     *
-     * @param result method to process
-     */
-    private static void edgeSplit(SsaMethod result) {
-        edgeSplitPredecessors(result);
-        edgeSplitMoveExceptionsAndResults(result);
-        edgeSplitSuccessors(result);
-    }
-
-    /**
-     * Inserts Z nodes as new predecessors for every node that has multiple
-     * successors and multiple predecessors.
-     *
-     * @param result {@code non-null;} method to process
-     */
-    private static void edgeSplitPredecessors(SsaMethod result) {
-        ArrayList<SsaBasicBlock> blocks = result.getBlocks();
-
-        /*
-         * New blocks are added to the end of the block list during
-         * this iteration.
-         */
-        for (int i = blocks.size() - 1; i >= 0; i-- ) {
-            SsaBasicBlock block = blocks.get(i);
-            if (nodeNeedsUniquePredecessor(block)) {
-                block.insertNewPredecessor();
-            }
-        }
-    }
-
-    /**
-     * @param block {@code non-null;} block in question
-     * @return {@code true} if this node needs to have a unique
-     * predecessor created for it
-     */
-    private static boolean nodeNeedsUniquePredecessor(SsaBasicBlock block) {
-        /*
-         * Any block with that has both multiple successors and multiple
-         * predecessors needs a new predecessor node.
-         */
-
-        int countPredecessors = block.getPredecessors().cardinality();
-        int countSuccessors = block.getSuccessors().cardinality();
-
-        return  (countPredecessors > 1 && countSuccessors > 1);
-    }
-
-    /**
-     * In ROP form, move-exception must occur as the first insn in a block
-     * immediately succeeding the insn that could thrown an exception.
-     * We may need room to insert move insns later, so make sure to split
-     * any block that starts with a move-exception such that there is a
-     * unique move-exception block for each predecessor.
-     *
-     * @param ssaMeth method to process
-     */
-    private static void edgeSplitMoveExceptionsAndResults(SsaMethod ssaMeth) {
-        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
-
-        /*
-         * New blocks are added to the end of the block list during
-         * this iteration.
-         */
-        for (int i = blocks.size() - 1; i >= 0; i-- ) {
-            SsaBasicBlock block = blocks.get(i);
-
-            /*
-             * Any block that starts with a move-exception and has more than
-             * one predecessor...
-             */
-            if (!block.isExitBlock()
-                    && block.getPredecessors().cardinality() > 1
-                    && block.getInsns().get(0).isMoveException()) {
-
-                // block.getPredecessors() is changed in the loop below.
-                BitSet preds = (BitSet)block.getPredecessors().clone();
-                for (int j = preds.nextSetBit(0); j >= 0;
-                     j = preds.nextSetBit(j + 1)) {
-                    SsaBasicBlock predecessor = blocks.get(j);
-                    SsaBasicBlock zNode
-                        = predecessor.insertNewSuccessor(block);
-
-                    /*
-                     * Make sure to place the move-exception as the
-                     * first insn.
-                     */
-                    zNode.getInsns().add(0, block.getInsns().get(0).clone());
-                }
-
-                // Remove the move-exception from the original block.
-                block.getInsns().remove(0);
-            }
-        }
-    }
-
-    /**
-     * Inserts Z nodes for every node that needs a new
-     * successor.
-     *
-     * @param result {@code non-null;} method to process
-     */
-    private static void edgeSplitSuccessors(SsaMethod result) {
-        ArrayList<SsaBasicBlock> blocks = result.getBlocks();
-
-        /*
-         * New blocks are added to the end of the block list during
-         * this iteration.
-         */
-        for (int i = blocks.size() - 1; i >= 0; i-- ) {
-            SsaBasicBlock block = blocks.get(i);
-
-            // Successors list is modified in loop below.
-            BitSet successors = (BitSet)block.getSuccessors().clone();
-            for (int j = successors.nextSetBit(0);
-                 j >= 0; j = successors.nextSetBit(j+1)) {
-
-                SsaBasicBlock succ = blocks.get(j);
-
-                if (needsNewSuccessor(block, succ)) {
-                    block.insertNewSuccessor(succ);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns {@code true} if block and successor need a Z-node
-     * between them. Presently, this is {@code true} if the final
-     * instruction has any sources or results and the current
-     * successor block has more than one predecessor.
-     *
-     * @param block predecessor node
-     * @param succ successor node
-     * @return {@code true} if a Z node is needed
-     */
-    private static boolean needsNewSuccessor(SsaBasicBlock block,
-            SsaBasicBlock succ) {
-        ArrayList<SsaInsn> insns = block.getInsns();
-        SsaInsn lastInsn = insns.get(insns.size() - 1);
-
-        return ((lastInsn.getResult() != null)
-                    || (lastInsn.getSources().size() > 0))
-                && succ.getPredecessors().cardinality() > 1;
-    }
-
-    /**
-     * See Appel algorithm 19.6:
-     *
-     * Place Phi functions in appropriate locations.
-     *
-     * @param ssaMeth {@code non-null;} method to process.
-     * Modifications are made in-place.
-     * @param localInfo {@code non-null;} local variable info, used
-     * when placing phis
-     * @param threshold registers below this number are ignored
-     */
-    private static void placePhiFunctions (SsaMethod ssaMeth,
-            LocalVariableInfo localInfo, int threshold) {
-        ArrayList<SsaBasicBlock> ssaBlocks;
-        int regCount;
-        int blockCount;
-
-        ssaBlocks = ssaMeth.getBlocks();
-        blockCount = ssaBlocks.size();
-        regCount = ssaMeth.getRegCount() - threshold;
-
-        DomFront df = new DomFront(ssaMeth);
-        DomFront.DomInfo[] domInfos = df.run();
-
-        // Bit set of registers vs block index "definition sites"
-        BitSet[] defsites = new BitSet[regCount];
-
-        // Bit set of registers vs block index "phi placement sites"
-        BitSet[] phisites = new BitSet[regCount];
-
-        for (int i = 0; i < regCount; i++) {
-            defsites[i] = new BitSet(blockCount);
-            phisites[i] = new BitSet(blockCount);
-        }
-
-        /*
-         * For each register, build a set of all basic blocks where
-         * containing an assignment to that register.
-         */
-        for (int bi = 0, s = ssaBlocks.size(); bi < s; bi++) {
-            SsaBasicBlock b = ssaBlocks.get(bi);
-
-            for (SsaInsn insn : b.getInsns()) {
-                RegisterSpec rs = insn.getResult();
-
-                if (rs != null && rs.getReg() - threshold >= 0) {
-                    defsites[rs.getReg() - threshold].set(bi);
-                }
-            }
-        }
-
-        if (DEBUG) {
-            System.out.println("defsites");
-
-            for (int i = 0; i < regCount; i++) {
-                StringBuilder sb = new StringBuilder();
-                sb.append('v').append(i).append(": ");
-                sb.append(defsites[i].toString());
-                System.out.println(sb);
-            }
-        }
-
-        BitSet worklist;
-
-        /*
-         * For each register, compute all locations for phi placement
-         * based on dominance-frontier algorithm.
-         */
-        for (int reg = 0, s = regCount; reg < s; reg++) {
-            int workBlockIndex;
-
-            /* Worklist set starts out with each node where reg is assigned. */
-
-            worklist = (BitSet) (defsites[reg].clone());
-
-            while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {
-                worklist.clear(workBlockIndex);
-                IntIterator dfIterator
-                    = domInfos[workBlockIndex].dominanceFrontiers.iterator();
-
-                while (dfIterator.hasNext()) {
-                    int dfBlockIndex = dfIterator.next();
-
-                    if (!phisites[reg].get(dfBlockIndex)) {
-                        phisites[reg].set(dfBlockIndex);
-
-                        int tReg = reg + threshold;
-                        RegisterSpec rs
-                            = localInfo.getStarts(dfBlockIndex).get(tReg);
-
-                        if (rs == null) {
-                            ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg);
-                        } else {
-                            ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);
-                        }
-
-                        if (!defsites[reg].get(dfBlockIndex)) {
-                            worklist.set(dfBlockIndex);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (DEBUG) {
-            System.out.println("phisites");
-
-            for (int i = 0; i < regCount; i++) {
-                StringBuilder sb = new StringBuilder();
-                sb.append('v').append(i).append(": ");
-                sb.append(phisites[i].toString());
-                System.out.println(sb);
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SsaInsn.java b/dx/src/main/java/com/android/dx/ssa/SsaInsn.java
deleted file mode 100644
index ca7a1a2..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SsaInsn.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.*;
-import com.android.dx.util.ToHuman;
-
-/**
- * An instruction in SSA form
- */
-public abstract class SsaInsn implements ToHuman, Cloneable {
-    /** {@code non-null;} the block that contains this instance */
-    private final SsaBasicBlock block;
-
-    /** {@code null-ok;} result register */
-    private RegisterSpec result;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param result {@code null-ok;} initial result register. May be changed.
-     * @param block {@code non-null;} block containing this insn. Can
-     * never change.
-     */
-    protected SsaInsn(RegisterSpec result, SsaBasicBlock block) {
-        if (block == null) {
-            throw new NullPointerException("block == null");
-        }
-
-        this.block = block;
-        this.result = result;
-    }
-
-    /**
-     * Makes a new SSA insn form a rop insn.
-     *
-     * @param insn {@code non-null;} rop insn
-     * @param block {@code non-null;} owning block
-     * @return {@code non-null;} an appropriately constructed instance
-     */
-    public static SsaInsn makeFromRop(Insn insn, SsaBasicBlock block) {
-        return new NormalSsaInsn(insn, block);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public SsaInsn clone() {
-        try {
-            return (SsaInsn)super.clone();
-        } catch (CloneNotSupportedException ex) {
-            throw new RuntimeException ("unexpected", ex);
-        }
-    }
-
-    /**
-     * Like {@link com.android.dx.rop.code.Insn getResult()}.
-     *
-     * @return result register
-     */
-    public RegisterSpec getResult() {
-        return result;
-    }
-
-    /**
-     * Set the result register.
-     *
-     * @param result {@code non-null;} the new result register
-     */
-    protected void setResult(RegisterSpec result) {
-        if (result == null) {
-            throw new NullPointerException("result == null");
-        }
-
-        this.result = result;
-    }
-
-    /**
-     * Like {@link com.android.dx.rop.code.Insn getSources()}.
-     *
-     * @return {@code non-null;} sources list
-     */
-    abstract public RegisterSpecList getSources();
-
-    /**
-     * Gets the block to which this insn instance belongs.
-     *
-     * @return owning block
-     */
-    public SsaBasicBlock getBlock() {
-        return block;
-    }
-
-    /**
-     * Returns whether or not the specified reg is the result reg.
-     *
-     * @param reg register to test
-     * @return true if there is a result and it is stored in the specified
-     * register
-     */
-    public boolean isResultReg(int reg) {
-        return result != null && result.getReg() == reg;
-    }
-
-
-    /**
-     * Changes the result register if this insn has a result. This is used
-     * during renaming.
-     *
-     * @param reg new result register
-     */
-    public void changeResultReg(int reg) {
-        if (result != null) {
-            result = result.withReg(reg);
-        }
-    }
-
-    /**
-     * Sets the local association for the result of this insn. This is
-     * sometimes updated during the SsaRenamer process.
-     *
-     * @param local {@code null-ok;} new debug/local variable info
-     */
-    public final void setResultLocal(LocalItem local) {
-        LocalItem oldItem = result.getLocalItem();
-
-        if (local != oldItem && (local == null
-                || !local.equals(result.getLocalItem()))) {
-            result = RegisterSpec.makeLocalOptional(
-                    result.getReg(), result.getType(), local);
-        }
-    }
-
-    /**
-     * Map registers after register allocation.
-     *
-     * @param mapper {@code non-null;} mapping from old to new registers
-     */
-    public final void mapRegisters(RegisterMapper mapper) {
-        RegisterSpec oldResult = result;
-
-        result = mapper.map(result);
-        block.getParent().updateOneDefinition(this, oldResult);
-        mapSourceRegisters(mapper);
-    }
-
-    /**
-     * Maps only source registers.
-     *
-     * @param mapper new mapping
-     */
-    abstract public void mapSourceRegisters(RegisterMapper mapper);
-
-    /**
-     * Returns the Rop opcode for this insn, or null if this is a phi insn.
-     *
-     * TODO: Move this up into NormalSsaInsn.
-     *
-     * @return {@code null-ok;} Rop opcode if there is one.
-     */
-    abstract public Rop getOpcode();
-
-    /**
-     * Returns the original Rop insn for this insn, or null if this is
-     * a phi insn.
-     *
-     * TODO: Move this up into NormalSsaInsn.
-     *
-     * @return {@code null-ok;} Rop insn if there is one.
-     */
-    abstract public Insn getOriginalRopInsn();
-
-    /**
-     * Gets the spec of a local variable assignment that occurs at this
-     * instruction, or null if no local variable assignment occurs. This
-     * may be the result register, or for {@code mark-local} insns
-     * it may be the source.
-     *
-     * @see com.android.dx.rop.code.Insn#getLocalAssignment()
-     *
-     * @return {@code null-ok;} a local-associated register spec or null
-     */
-    public RegisterSpec getLocalAssignment() {
-        if (result != null && result.getLocalItem() != null) {
-            return result;
-        }
-
-        return null;
-    }
-
-    /**
-     * Indicates whether the specified register is amongst the registers
-     * used as sources for this instruction.
-     *
-     * @param reg the register in question
-     * @return true if the reg is a source
-     */
-    public boolean isRegASource(int reg) {
-        return null != getSources().specForRegister(reg);
-    }
-
-    /**
-     * Transform back to ROP form.
-     *
-     * TODO: Move this up into NormalSsaInsn.
-     *
-     * @return {@code non-null;} a ROP representation of this instruction, with
-     * updated registers.
-     */
-    public abstract Insn toRopInsn();
-
-    /**
-     * @return true if this is a PhiInsn or a normal move insn
-     */
-    public abstract boolean isPhiOrMove();
-
-    /**
-     * Returns true if this insn is considered to have a side effect beyond
-     * that of assigning to the result reg.
-     *
-     * @return true if this insn is considered to have a side effect beyond
-     * that of assigning to the result reg.
-     */
-    public abstract boolean hasSideEffect();
-
-    /**
-     * @return true if this is a move (but not a move-operand or
-     * move-exception) instruction
-     */
-    public boolean isNormalMoveInsn() {
-        return false;
-    }
-
-    /**
-     * @return true if this is a move-exception instruction.
-     * These instructions must immediately follow a preceeding invoke*
-     */
-    public boolean isMoveException() {
-        return false;
-    }
-
-    /**
-     * @return true if this instruction can throw.
-     */
-    abstract public boolean canThrow();
-
-    /**
-     * Accepts a visitor.
-     *
-     * @param v {@code non-null} the visitor
-     */
-    public abstract void accept(Visitor v);
-
-    /**
-     * Visitor interface for this class.
-     */
-    public static interface Visitor {
-        /**
-         * Any non-phi move instruction
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitMoveInsn(NormalSsaInsn insn);
-
-        /**
-         * Any phi insn
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitPhiInsn(PhiInsn insn);
-
-        /**
-         * Any insn that isn't a move or a phi (which is also a move).
-         * @param insn {@code non-null;} the instruction to visit
-         */
-        public void visitNonMoveInsn(NormalSsaInsn insn);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SsaMethod.java b/dx/src/main/java/com/android/dx/ssa/SsaMethod.java
deleted file mode 100644
index 4c2bd85..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SsaMethod.java
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * A method in SSA form.
- */
-public final class SsaMethod {
-    /** basic blocks, indexed by block index */
-    private ArrayList<SsaBasicBlock> blocks;
-
-    /** Index of first executed block in method */
-    private int entryBlockIndex;
-
-    /**
-     * Index of exit block, which exists only in SSA form,
-     * or or {@code -1} if there is none
-     */
-    private int exitBlockIndex;
-
-    /** total number of registers required */
-    private int registerCount;
-
-    /** first register number to use for any temporary "spares" */
-    private int spareRegisterBase;
-
-    /** current count of spare registers used */
-    private int borrowedSpareRegisters;
-
-    /** really one greater than the max label */
-    private int maxLabel;
-
-    /** the total width, in register-units, of the method's parameters */
-    private final int paramWidth;
-
-    /** true if this method has no {@code this} pointer argument */
-    private final boolean isStatic;
-
-    /**
-     * indexed by register: the insn where said register is defined or null
-     * if undefined. null until (lazily) created.
-     */
-    private SsaInsn[] definitionList;
-
-    /** indexed by register: the list of all insns that use a register */
-    private ArrayList<SsaInsn>[] useList;
-
-    /** A version of useList with each List unmodifiable */
-    private List<SsaInsn>[] unmodifiableUseList;
-
-    /**
-     * "back-convert mode". Set during back-conversion when registers
-     * are about to be mapped into a non-SSA namespace. When true,
-     * use and def lists are unavailable.
-     *
-     * TODO: Remove this mode, and place the functionality elsewhere
-     */
-    private boolean backMode;
-
-    /**
-     * @param ropMethod rop-form method to convert from
-     * @param paramWidth the total width, in register-units, of the
-     * method's parameters
-     * @param isStatic {@code true} if this method has no {@code this}
-     * pointer argument
-     */
-    public static SsaMethod newFromRopMethod(RopMethod ropMethod,
-            int paramWidth, boolean isStatic) {
-        SsaMethod result = new SsaMethod(ropMethod, paramWidth, isStatic);
-
-        result.convertRopToSsaBlocks(ropMethod);
-
-        return result;
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ropMethod {@code non-null;} the original rop-form method that
-     * this instance is based on
-     * @param paramWidth the total width, in register-units, of the
-     * method's parameters
-     * @param isStatic {@code true} if this method has no {@code this}
-     * pointer argument
-     */
-    private SsaMethod(RopMethod ropMethod, int paramWidth, boolean isStatic) {
-        this.paramWidth = paramWidth;
-        this.isStatic = isStatic;
-        this.backMode = false;
-        this.maxLabel = ropMethod.getBlocks().getMaxLabel();
-        this.registerCount = ropMethod.getBlocks().getRegCount();
-        this.spareRegisterBase = registerCount;
-    }
-
-    /**
-     * Builds a BitSet of block indices from a basic block list and a list
-     * of labels taken from Rop form.
-     *
-     * @param blocks Rop blocks
-     * @param labelList list of rop block labels
-     * @return BitSet of block indices
-     */
-    static BitSet bitSetFromLabelList(BasicBlockList blocks,
-            IntList labelList) {
-        BitSet result = new BitSet(blocks.size());
-
-        for (int i = 0, sz = labelList.size(); i < sz; i++) {
-            result.set(blocks.indexOfLabel(labelList.get(i)));
-        }
-
-        return result;
-    }
-
-    /**
-     * Builds an IntList of block indices from a basic block list and a list
-     * of labels taken from Rop form.
-     *
-     * @param ropBlocks Rop blocks
-     * @param labelList list of rop block labels
-     * @return IntList of block indices
-     */
-    public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
-            IntList labelList) {
-
-        IntList result = new IntList(labelList.size());
-
-        for (int i = 0, sz = labelList.size(); i < sz; i++) {
-            result.add(ropBlocks.indexOfLabel(labelList.get(i)));
-        }
-
-        return result;
-    }
-
-    private void convertRopToSsaBlocks(RopMethod rmeth) {
-        BasicBlockList ropBlocks = rmeth.getBlocks();
-        int sz = ropBlocks.size();
-
-        blocks = new ArrayList<SsaBasicBlock>(sz + 2);
-
-        for (int i = 0; i < sz; i++) {
-            SsaBasicBlock sbb = SsaBasicBlock.newFromRop(rmeth, i, this);
-            blocks.add(sbb);
-        }
-
-        // Add an no-op entry block.
-        int origEntryBlockIndex = rmeth.getBlocks()
-                .indexOfLabel(rmeth.getFirstLabel());
-
-        SsaBasicBlock entryBlock
-                = blocks.get(origEntryBlockIndex).insertNewPredecessor();
-
-        entryBlockIndex = entryBlock.getIndex();
-        exitBlockIndex = -1; // This gets made later.
-    }
-
-    /**
-     * Creates an exit block and attaches it to the CFG if this method
-     * exits. Methods that never exit will not have an exit block. This
-     * is called after edge-splitting and phi insertion, since the edges
-     * going into the exit block should not be considered in those steps.
-     */
-    /*package*/ void makeExitBlock() {
-        if (exitBlockIndex >= 0) {
-            throw new RuntimeException("must be called at most once");
-        }
-
-        exitBlockIndex = blocks.size();
-        SsaBasicBlock exitBlock
-                = new SsaBasicBlock(exitBlockIndex, maxLabel++, this);
-
-        blocks.add(exitBlock);
-
-        for (SsaBasicBlock block : blocks) {
-            block.exitBlockFixup(exitBlock);
-        }
-
-        if (exitBlock.getPredecessors().cardinality() == 0) {
-            // In cases where there is no exit...
-            blocks.remove(exitBlockIndex);
-            exitBlockIndex = -1;
-            maxLabel--;
-        }
-    }
-
-    /**
-     * Gets a new {@code GOTO} insn.
-     *
-     * @param block block to which this GOTO will be added
-     * (not it's destination!)
-     * @return an appropriately-constructed instance.
-     */
-    private static SsaInsn getGoto(SsaBasicBlock block) {
-        return new NormalSsaInsn (
-                new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO,
-                    null, RegisterSpecList.EMPTY), block);
-    }
-
-    /**
-     * Makes a new basic block for this method, which is empty besides
-     * a single {@code GOTO}. Successors and predecessors are not yet
-     * set.
-     *
-     * @return new block
-     */
-    public SsaBasicBlock makeNewGotoBlock() {
-        int newIndex = blocks.size();
-        SsaBasicBlock newBlock = new SsaBasicBlock(newIndex, maxLabel++, this);
-
-        newBlock.getInsns().add(getGoto(newBlock));
-        blocks.add(newBlock);
-
-        return newBlock;
-    }
-
-    /**
-     * @return block index of first execution block
-     */
-    public int getEntryBlockIndex() {
-        return entryBlockIndex;
-    }
-
-    /**
-     * @return first execution block
-     */
-    public SsaBasicBlock getEntryBlock() {
-        return blocks.get(entryBlockIndex);
-    }
-
-    /**
-     * @return block index of exit block or {@code -1} if there is none
-     */
-    public int getExitBlockIndex() {
-        return exitBlockIndex;
-    }
-
-    /**
-     * @return {@code null-ok;} block of exit block or {@code null} if
-     * there is none
-     */
-    public SsaBasicBlock getExitBlock() {
-        return exitBlockIndex < 0 ? null : blocks.get(exitBlockIndex);
-    }
-
-    /**
-     * @param bi block index or {@code -1} for none
-     * @return rop label or {code -1} if {@code bi} was {@code -1}
-     */
-    public int blockIndexToRopLabel(int bi) {
-        if (bi < 0) {
-            return -1;
-        }
-        return blocks.get(bi).getRopLabel();
-    }
-
-    /**
-     * @return count of registers used in this method
-     */
-    public int getRegCount() {
-        return registerCount;
-    }
-
-    /**
-     * @return the total width, in register units, of the method's
-     * parameters
-     */
-    public int getParamWidth() {
-        return paramWidth;
-    }
-
-    /**
-     * Returns {@code true} if this is a static method.
-     *
-     * @return {@code true} if this is a static method
-     */
-    public boolean isStatic() {
-        return isStatic;
-    }
-
-    /**
-     * Borrows a register to use as a temp. Used in the phi removal process.
-     * Call returnSpareRegisters() when done.
-     *
-     * @param category width (1 or 2) of the register
-     * @return register number to use
-     */
-    public int borrowSpareRegister(int category) {
-        int result = spareRegisterBase + borrowedSpareRegisters;
-
-        borrowedSpareRegisters += category;
-        registerCount = Math.max(registerCount, result + category);
-
-        return result;
-    }
-
-    /**
-     * Returns all borrowed registers.
-     */
-    public void returnSpareRegisters() {
-        borrowedSpareRegisters = 0;
-    }
-
-    /**
-     * @return {@code non-null;} basic block list. Do not modify.
-     */
-    public ArrayList<SsaBasicBlock> getBlocks() {
-        return blocks;
-    }
-
-    /**
-     * Returns the count of reachable blocks in this method: blocks that have
-     * predecessors (or are the start block)
-     *
-     * @return {@code >= 0;} number of reachable basic blocks
-     */
-    public int getCountReachableBlocks() {
-        int ret = 0;
-
-        for (SsaBasicBlock b : blocks) {
-            // Blocks that have been disconnected don't count.
-            if (b.isReachable()) {
-                ret++;
-            }
-        }
-
-        return ret;
-    }
-
-    /**
-     * Computes reachability for all blocks in the method. First clears old
-     * values from all blocks, then starts with the entry block and walks down
-     * the control flow graph, marking all blocks it finds as reachable.
-     */
-    public void computeReachability() {
-        for (SsaBasicBlock block : blocks) {
-            block.setReachable(0);
-        }
-
-        ArrayList<SsaBasicBlock> blockList = new ArrayList<SsaBasicBlock>();
-        blockList.add(this.getEntryBlock());
-
-        while (!blockList.isEmpty()) {
-            SsaBasicBlock block = blockList.remove(0);
-            if (block.isReachable()) continue;
-
-            block.setReachable(1);
-            BitSet succs = block.getSuccessors();
-            for (int i = succs.nextSetBit(0); i >= 0;
-                     i = succs.nextSetBit(i + 1)) {
-                blockList.add(blocks.get(i));
-            }
-        }
-    }
-
-    /**
-     * Remaps unversioned registers.
-     *
-     * @param mapper maps old registers to new.
-     */
-    public void mapRegisters(RegisterMapper mapper) {
-        for (SsaBasicBlock block : getBlocks()) {
-            for (SsaInsn insn : block.getInsns()) {
-                insn.mapRegisters(mapper);
-            }
-        }
-
-        registerCount = mapper.getNewRegisterCount();
-        spareRegisterBase = registerCount;
-    }
-
-    /**
-     * Returns the insn that defines the given register
-     * @param reg register in question
-     * @return insn (actual instance from code) that defined this reg or null
-     * if reg is not defined.
-     */
-    public SsaInsn getDefinitionForRegister(int reg) {
-        if (backMode) {
-            throw new RuntimeException("No def list in back mode");
-        }
-
-        if (definitionList != null) {
-            return definitionList[reg];
-        }
-
-        definitionList = new SsaInsn[getRegCount()];
-
-        forEachInsn(new SsaInsn.Visitor() {
-            public void visitMoveInsn (NormalSsaInsn insn) {
-                definitionList[insn.getResult().getReg()] = insn;
-            }
-            public void visitPhiInsn (PhiInsn phi) {
-                definitionList[phi.getResult().getReg()] = phi;
-            }
-            public void visitNonMoveInsn (NormalSsaInsn insn) {
-                RegisterSpec result = insn.getResult();
-                if (result != null) {
-                    definitionList[insn.getResult().getReg()] = insn;
-                }
-            }
-        });
-
-        return definitionList[reg];
-    }
-
-    /**
-     * Builds useList and unmodifiableUseList.
-     */
-    private void buildUseList() {
-        if (backMode) {
-            throw new RuntimeException("No use list in back mode");
-        }
-
-        useList = new ArrayList[registerCount];
-
-        for (int i = 0; i < registerCount; i++) {
-            useList[i] = new ArrayList();
-        }
-
-        forEachInsn(new SsaInsn.Visitor() {
-            /** {@inheritDoc} */
-            public void visitMoveInsn (NormalSsaInsn insn) {
-                addToUses(insn);
-            }
-            /** {@inheritDoc} */
-            public void visitPhiInsn (PhiInsn phi) {
-                addToUses(phi);
-            }
-            /** {@inheritDoc} */
-            public void visitNonMoveInsn (NormalSsaInsn insn) {
-                addToUses(insn);
-            }
-            /**
-             * Adds specified insn to the uses list for all of its sources.
-             * @param insn {@code non-null;} insn to process
-             */
-            private void addToUses(SsaInsn insn) {
-                RegisterSpecList rl = insn.getSources();
-                int sz = rl.size();
-
-                for (int i = 0; i < sz; i++) {
-                    useList[rl.get(i).getReg()].add(insn);
-                }
-            }
-        });
-
-        unmodifiableUseList = new List[registerCount];
-
-        for (int i = 0; i < registerCount; i++) {
-            unmodifiableUseList[i] = Collections.unmodifiableList(useList[i]);
-        }
-    }
-
-    /**
-     * Updates the use list for a single change in source register.
-     *
-     * @param insn {@code non-null;} insn being changed
-     * @param oldSource {@code null-ok;} The source that was used, if
-     * applicable
-     * @param newSource {@code non-null;} the new source being used
-     */
-    /*package*/ void onSourceChanged(SsaInsn insn,
-            RegisterSpec oldSource, RegisterSpec newSource) {
-        if (useList == null) return;
-
-        if (oldSource != null) {
-            int reg = oldSource.getReg();
-            useList[reg].remove(insn);
-        }
-
-        int reg = newSource.getReg();
-        if (useList.length <= reg) {
-            useList = null;
-            return;
-        }
-        useList[reg].add(insn);
-    }
-
-    /**
-     * Updates the use list for a source list change.
-     *
-     * @param insn {@code insn non-null;} insn being changed.
-     * {@code insn.getSources()} must return the new source list.
-     * @param oldSources {@code null-ok;} list of sources that were
-     * previously used
-     */
-    /*package*/ void onSourcesChanged(SsaInsn insn,
-            RegisterSpecList oldSources) {
-        if (useList == null) return;
-
-        if (oldSources != null) {
-            removeFromUseList(insn, oldSources);
-        }
-
-        RegisterSpecList sources = insn.getSources();
-        int szNew = sources.size();
-
-        for (int i = 0; i < szNew; i++) {
-            int reg = sources.get(i).getReg();
-            useList[reg].add(insn);
-        }
-    }
-
-    /**
-     * Removes a given {@code insn} from the use lists for the given
-     * {@code oldSources} (rather than the sources currently
-     * returned by insn.getSources()).
-     *
-     * @param insn {@code non-null;} insn in question
-     * @param oldSources {@code null-ok;} registers whose use lists
-     * {@code insn} should be removed form
-     */
-    private void removeFromUseList(SsaInsn insn, RegisterSpecList oldSources) {
-        if (oldSources == null) {
-            return;
-        }
-
-        int szNew = oldSources.size();
-        for (int i = 0; i < szNew; i++) {
-            if (!useList[oldSources.get(i).getReg()].remove(insn)) {
-                throw new RuntimeException("use not found");
-            }
-        }
-    }
-
-    /**
-     * Adds an insn to both the use and def lists. For use when adding
-     * a new insn to the method.
-     *
-     * @param insn {@code non-null;} insn to add
-     */
-    /*package*/ void onInsnAdded(SsaInsn insn) {
-        onSourcesChanged(insn, null);
-        updateOneDefinition(insn, null);
-    }
-
-    /**
-     * Removes an instruction from use and def lists. For use during
-     * instruction removal.
-     *
-     * @param insn {@code non-null;} insn to remove
-     */
-    /*package*/ void onInsnRemoved(SsaInsn insn) {
-        if (useList != null) {
-            removeFromUseList(insn, insn.getSources());
-        }
-
-        RegisterSpec resultReg = insn.getResult();
-        if (definitionList != null && resultReg != null) {
-            definitionList[resultReg.getReg()] = null;
-        }
-    }
-
-    /**
-     * Indicates that the instruction list has changed or the SSA register
-     * count has increased, so that internal datastructures that rely on
-     * it should be rebuild. In general, the various other on* methods
-     * should be called in preference when changes occur if they are
-     * applicable.
-     */
-    public void onInsnsChanged() {
-        // Definition list will need to be recomputed
-        definitionList = null;
-
-        // Use list will need to be recomputed
-        useList = null;
-        unmodifiableUseList = null;
-    }
-
-    /**
-     * Updates a single definition.
-     *
-     * @param insn {@code non-null;} insn who's result should be recorded as
-     * a definition
-     * @param oldResult {@code null-ok;} a previous result that should
-     * be no longer considered a definition by this insn
-     */
-    /*package*/ void updateOneDefinition(SsaInsn insn,
-            RegisterSpec oldResult) {
-        if (definitionList == null) return;
-
-        if (oldResult != null) {
-            int reg = oldResult.getReg();
-            definitionList[reg] = null;
-        }
-
-        RegisterSpec resultReg = insn.getResult();
-
-        if (resultReg != null) {
-            int reg = resultReg.getReg();
-
-            if (definitionList[reg] != null) {
-                throw new RuntimeException("Duplicate add of insn");
-            } else {
-                definitionList[resultReg.getReg()] = insn;
-            }
-        }
-    }
-
-    /**
-     * Returns the list of all source uses (not results) for a register.
-     *
-     * @param reg register in question
-     * @return unmodifiable instruction list
-     */
-    public List<SsaInsn> getUseListForRegister(int reg) {
-
-        if (unmodifiableUseList == null) {
-            buildUseList();
-        }
-
-        return unmodifiableUseList[reg];
-    }
-
-    /**
-     * Returns a modifiable copy of the register use list.
-     *
-     * @return modifiable copy of the use-list, indexed by register
-     */
-    public ArrayList<SsaInsn>[] getUseListCopy() {
-        if (useList == null) {
-            buildUseList();
-        }
-
-        ArrayList<SsaInsn>[] useListCopy
-                = (ArrayList<SsaInsn>[])(new ArrayList[registerCount]);
-
-        for (int i = 0; i < registerCount; i++) {
-            useListCopy[i] = (ArrayList<SsaInsn>)(new ArrayList(useList[i]));
-        }
-
-        return useListCopy;
-    }
-
-    /**
-     * Checks to see if the given SSA reg is ever associated with a local
-     * local variable. Each SSA reg may be associated with at most one
-     * local var.
-     *
-     * @param spec {@code non-null;} ssa reg
-     * @return true if reg is ever associated with a local
-     */
-    public boolean isRegALocal(RegisterSpec spec) {
-        SsaInsn defn = getDefinitionForRegister(spec.getReg());
-
-        if (defn == null) {
-            // version 0 registers are never used as locals
-            return false;
-        }
-
-        // Does the definition have a local associated with it?
-        if (defn.getLocalAssignment() != null) return true;
-
-        // If not, is there a mark-local insn?
-        for (SsaInsn use : getUseListForRegister(spec.getReg())) {
-            Insn insn = use.getOriginalRopInsn();
-
-            if (insn != null
-                    && insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Sets the new register count after renaming.
-     *
-     * @param newRegCount new register count
-     */
-    /*package*/ void setNewRegCount(int newRegCount) {
-        registerCount = newRegCount;
-        spareRegisterBase = registerCount;
-        onInsnsChanged();
-    }
-
-    /**
-     * Makes a new SSA register. For use after renaming has completed.
-     *
-     * @return {@code >=0;} new SSA register.
-     */
-    public int makeNewSsaReg() {
-        int reg = registerCount++;
-        spareRegisterBase = registerCount;
-        onInsnsChanged();
-        return reg;
-    }
-
-    /**
-     * Visits all insns in this method.
-     *
-     * @param visitor {@code non-null;} callback interface
-     */
-    public void forEachInsn(SsaInsn.Visitor visitor) {
-        for (SsaBasicBlock block : blocks) {
-            block.forEachInsn(visitor);
-        }
-    }
-
-    /**
-     * Visits each phi insn in this method
-     * @param v {@code non-null;} callback.
-     *
-     */
-    public void forEachPhiInsn(PhiInsn.Visitor v) {
-        for (SsaBasicBlock block : blocks) {
-            block.forEachPhiInsn(v);
-        }
-    }
-
-
-    /**
-     * Walks the basic block tree in depth-first order, calling the visitor
-     * method once for every block. This depth-first walk may be run forward
-     * from the method entry point or backwards from the method exit points.
-     *
-     * @param reverse true if this should walk backwards from the exit points
-     * @param v {@code non-null;} callback interface. {@code parent} is set
-     * unless this is the root node
-     */
-    public void forEachBlockDepthFirst(boolean reverse,
-            SsaBasicBlock.Visitor v) {
-        BitSet visited = new BitSet(blocks.size());
-
-        // We push the parent first, then the child on the stack.
-        Stack<SsaBasicBlock> stack = new Stack<SsaBasicBlock>();
-
-        SsaBasicBlock rootBlock = reverse ? getExitBlock() : getEntryBlock();
-
-        if (rootBlock == null) {
-            // in the case there's no exit block
-            return;
-        }
-
-        stack.add(null);    // Start with null parent.
-        stack.add(rootBlock);
-
-        while (stack.size() > 0) {
-            SsaBasicBlock cur = stack.pop();
-            SsaBasicBlock parent = stack.pop();
-
-            if (!visited.get(cur.getIndex())) {
-                BitSet children
-                    = reverse ? cur.getPredecessors() : cur.getSuccessors();
-                for (int i = children.nextSetBit(0); i >= 0
-                        ; i = children.nextSetBit(i + 1)) {
-                    stack.add(cur);
-                    stack.add(blocks.get(i));
-                }
-                visited.set(cur.getIndex());
-                v.visitBlock(cur, parent);
-            }
-        }
-    }
-
-    /**
-     * Visits blocks in dom-tree order, starting at the current node.
-     * The {@code parent} parameter of the Visitor.visitBlock callback
-     * is currently always set to null.
-     *
-     * @param v {@code non-null;} callback interface
-     */
-    public void forEachBlockDepthFirstDom(SsaBasicBlock.Visitor v) {
-        BitSet visited = new BitSet(getBlocks().size());
-        Stack<SsaBasicBlock> stack = new Stack<SsaBasicBlock>();
-
-        stack.add(getEntryBlock());
-
-        while (stack.size() > 0) {
-            SsaBasicBlock cur = stack.pop();
-            ArrayList<SsaBasicBlock> curDomChildren = cur.getDomChildren();
-
-            if (!visited.get(cur.getIndex())) {
-                // We walk the tree this way for historical reasons...
-                for (int i = curDomChildren.size() - 1; i >= 0; i--) {
-                    SsaBasicBlock child = curDomChildren.get(i);
-                    stack.add(child);
-                }
-                visited.set(cur.getIndex());
-                v.visitBlock(cur, null);
-            }
-        }
-    }
-
-    /**
-     * Deletes all insns in the set from this method.
-     *
-     * @param deletedInsns {@code non-null;} insns to delete
-     */
-    public void deleteInsns(Set<SsaInsn> deletedInsns) {
-        for (SsaBasicBlock block : getBlocks()) {
-            ArrayList<SsaInsn> insns = block.getInsns();
-
-            for (int i = insns.size() - 1; i >= 0; i--) {
-                SsaInsn insn = insns.get(i);
-
-                if (deletedInsns.contains(insn)) {
-                    onInsnRemoved(insn);
-                    insns.remove(i);
-                }
-            }
-
-            // Check to see if we need to add a GOTO
-
-            int insnsSz = insns.size();
-            SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1);
-
-            if (block != getExitBlock() && (insnsSz == 0
-                    || lastInsn.getOriginalRopInsn() == null
-                    || lastInsn.getOriginalRopInsn().getOpcode()
-                        .getBranchingness() == Rop.BRANCH_NONE)) {
-                // We managed to eat a throwable insn
-
-                Insn gotoInsn = new PlainInsn(Rops.GOTO,
-                        SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY);
-                insns.add(SsaInsn.makeFromRop(gotoInsn, block));
-
-                // Remove secondary successors from this block
-                BitSet succs = block.getSuccessors();
-                for (int i = succs.nextSetBit(0); i >= 0;
-                         i = succs.nextSetBit(i + 1)) {
-                    if (i != block.getPrimarySuccessorIndex()) {
-                        block.removeSuccessor(i);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets "back-convert mode". Set during back-conversion when registers
-     * are about to be mapped into a non-SSA namespace. When true,
-     * use and def lists are unavailable.
-     */
-    public void setBackMode() {
-        backMode = true;
-        useList = null;
-        definitionList = null;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/SsaRenamer.java b/dx/src/main/java/com/android/dx/ssa/SsaRenamer.java
deleted file mode 100644
index 58e4142..0000000
--- a/dx/src/main/java/com/android/dx/ssa/SsaRenamer.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa;
-
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.type.Type;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-
-/**
- * Complete transformation to SSA form by renaming all registers accessed.<p>
- *
- * See Appel algorithm 19.7<p>
- *
- * Unlike the original algorithm presented in Appel, this renamer converts
- * to a new flat (versionless) register space. The "version 0" registers,
- * which represent the initial state of the Rop registers and should never
- * actually be meaningfully accessed in a legal program, are represented
- * as the first N registers in the SSA namespace. Subsequent assignments
- * are assigned new unique names. Note that the incoming Rop representation
- * has a concept of register widths, where 64-bit values are stored into
- * two adjoining Rop registers. This adjoining register representation is
- * ignored in SSA form conversion and while in SSA form, each register can be e
- * either 32 or 64 bits wide depending on use. The adjoining-register
- * represention is re-created later when converting back to Rop form. <p>
- *
- * But, please note, the SSA Renamer's ignoring of the adjoining-register ROP
- * representation means that unaligned accesses to 64-bit registers are not
- * supported. For example, you cannot do a 32-bit operation on a portion of
- * a 64-bit register. This will never be observed to happen when coming
- * from Java code, of course.<p>
- *
- * The implementation here, rather than keeping a single register version
- * stack for the entire method as the dom tree is walked, instead keeps
- * a mapping table for the current block being processed. Once the
- * current block has been processed, this mapping table is then copied
- * and used as the initial state for child blocks.<p>
- */
-public class SsaRenamer implements Runnable {
-    /** debug flag */
-    private static final boolean DEBUG = false;
-
-    /** method we're processing */
-    private final SsaMethod ssaMeth;
-
-    /** next available SSA register */
-    private int nextSsaReg;
-
-    /** the number of original rop registers */
-    private final int ropRegCount;
-
-    /** work only on registers above this value */
-    private int threshold;
-
-    /**
-     * indexed by block index; register version state for each block start.
-     * This list is updated by each dom parent for its children. The only
-     * sub-arrays that exist at any one time are the start states for blocks
-     * yet to be processed by a {@code BlockRenamer} instance.
-     */
-    private final RegisterSpec[][] startsForBlocks;
-
-    /** map of SSA register number to debug (local var names) or null of n/a */
-    private final ArrayList<LocalItem> ssaRegToLocalItems;
-
-    /**
-     * maps SSA registers back to the original rop number. Used for
-     * debug only.
-     */
-    private IntList ssaRegToRopReg;
-
-    /**
-     * Constructs an instance of the renamer
-     *
-     * @param ssaMeth {@code non-null;} un-renamed SSA method that will
-     * be renamed.
-     */
-    public SsaRenamer(SsaMethod ssaMeth) {
-        ropRegCount = ssaMeth.getRegCount();
-
-        this.ssaMeth = ssaMeth;
-
-        /*
-         * Reserve the first N registers in the SSA register space for
-         * "version 0" registers.
-         */
-        nextSsaReg = ropRegCount;
-        threshold = 0;
-        startsForBlocks = new RegisterSpec[ssaMeth.getBlocks().size()][];
-
-        ssaRegToLocalItems = new ArrayList<LocalItem>();
-
-        if (DEBUG) {
-            ssaRegToRopReg = new IntList(ropRegCount);
-        }
-
-        /*
-         * Appel 19.7
-         *
-         * Initialization:
-         *   for each variable a        // register i
-         *      Count[a] <- 0           // nextSsaReg, flattened
-         *      Stack[a] <- 0           // versionStack
-         *      push 0 onto Stack[a]
-         *
-         */
-
-        // top entry for the version stack is version 0
-        RegisterSpec[] initialRegMapping = new RegisterSpec[ropRegCount];
-        for (int i = 0; i < ropRegCount; i++) {
-            // everyone starts with a version 0 register
-            initialRegMapping[i] = RegisterSpec.make(i, Type.VOID);
-
-            if (DEBUG) {
-                ssaRegToRopReg.add(i);
-            }
-        }
-
-        // Initial state for entry block
-        startsForBlocks[ssaMeth.getEntryBlockIndex()] = initialRegMapping;
-    }
-
-    /**
-    * Constructs an instance of the renamer with threshold set
-    *
-    * @param ssaMeth {@code non-null;} un-renamed SSA method that will
-    * be renamed.
-    * @param thresh registers below this number are unchanged
-    */
-   public SsaRenamer(SsaMethod ssaMeth, int thresh) {
-       this(ssaMeth);
-       threshold = thresh;
-   }
-
-    /**
-     * Performs renaming transformation, modifying the method's instructions
-     * in-place.
-     */
-    public void run() {
-        // Rename each block in dom-tree DFS order.
-        ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {
-            public void visitBlock (SsaBasicBlock block,
-                    SsaBasicBlock unused) {
-                new BlockRenamer(block).process();
-            }
-        });
-
-        ssaMeth.setNewRegCount(nextSsaReg);
-        ssaMeth.onInsnsChanged();
-
-        if (DEBUG) {
-            System.out.println("SSA\tRop");
-            /*
-             * We're going to compute the version of the rop register
-             * by keeping a running total of how many times the rop
-             * register has been mapped.
-             */
-            int[] versions = new int[ropRegCount];
-
-            int sz = ssaRegToRopReg.size();
-            for (int i = 0; i < sz; i++) {
-                int ropReg = ssaRegToRopReg.get(i);
-                System.out.println(i + "\t" + ropReg + "["
-                        + versions[ropReg] + "]");
-                versions[ropReg]++;
-            }
-        }
-    }
-
-    /**
-     * Duplicates a RegisterSpec array.
-     *
-     * @param orig {@code non-null;} array to duplicate
-     * @return {@code non-null;} new instance
-     */
-    private static  RegisterSpec[] dupArray(RegisterSpec[] orig) {
-        RegisterSpec[] copy = new RegisterSpec[orig.length];
-
-        System.arraycopy(orig, 0, copy, 0, orig.length);
-
-        return copy;
-    }
-
-    /**
-     * Gets a local variable item for a specified register.
-     *
-     * @param ssaReg register in SSA name space
-     * @return {@code null-ok;} Local variable name or null if none
-     */
-    private LocalItem getLocalForNewReg(int ssaReg) {
-        if (ssaReg < ssaRegToLocalItems.size()) {
-            return ssaRegToLocalItems.get(ssaReg);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Records a debug (local variable) name for a specified register.
-     *
-     * @param ssaReg non-null named register spec in SSA name space
-     */
-    private void setNameForSsaReg(RegisterSpec ssaReg) {
-        int reg = ssaReg.getReg();
-        LocalItem local = ssaReg.getLocalItem();
-
-        ssaRegToLocalItems.ensureCapacity(reg + 1);
-        while (ssaRegToLocalItems.size() <= reg) {
-            ssaRegToLocalItems.add(null);
-        }
-
-        ssaRegToLocalItems.set(reg, local);
-    }
-
-    /**
-     * Returns true if this SSA register is below the specified threshold.
-     * Used when most code is already in SSA form, and renaming is needed only
-     * for registers above a certain threshold.
-     *
-     * @param ssaReg the SSA register in question
-     * @return {@code true} if its register number is below the threshold
-     */
-    private boolean isBelowThresholdRegister(int ssaReg) {
-        return ssaReg < threshold;
-    }
-
-    /**
-     * Returns true if this SSA register is a "version 0"
-     * register. All version 0 registers are assigned the first N register
-     * numbers, where N is the count of original rop registers.
-     *
-     * @param ssaReg the SSA register in question
-     * @return true if it is a version 0 register.
-     */
-    private boolean isVersionZeroRegister(int ssaReg) {
-        return ssaReg < ropRegCount;
-    }
-
-    /**
-     * Returns true if a and b are equal or are both null.
-     *
-     * @param a null-ok
-     * @param b null-ok
-     * @return Returns true if a and b are equal or are both null
-     */
-    private static boolean equalsHandlesNulls(Object a, Object b) {
-        return a == b ||  (a != null && a.equals(b));
-    }
-
-    /**
-     * Processes all insns in a block and renames their registers
-     * as appropriate.
-     */
-    private class BlockRenamer implements SsaInsn.Visitor{
-        /** {@code non-null;} block we're processing. */
-        private final SsaBasicBlock block;
-
-        /**
-         * {@code non-null;} indexed by old register name. The current
-         * top of the version stack as seen by this block. It's
-         * initialized from the ending state of its dom parent,
-         * updated as the block's instructions are processed, and then
-         * copied to each one of its dom children.
-         */
-        private final RegisterSpec[] currentMapping;
-
-        /**
-         * contains the set of moves we need to keep to preserve local
-         * var info. All other moves will be deleted.
-         */
-        private final HashSet<SsaInsn> movesToKeep;
-
-        /**
-         * maps the set of insns to replace after renaming is finished
-         * on the block.
-         */
-        private final HashMap<SsaInsn, SsaInsn> insnsToReplace;
-
-        private final RenamingMapper mapper;
-
-        /**
-         * Constructs a block renamer instance. Call {@code process}
-         * to process.
-         *
-         * @param block {@code non-null;} block to process
-         */
-        BlockRenamer(final SsaBasicBlock block) {
-            this.block = block;
-            currentMapping = startsForBlocks[block.getIndex()];
-            movesToKeep = new HashSet<SsaInsn>();
-            insnsToReplace = new HashMap<SsaInsn, SsaInsn>();
-            mapper =  new RenamingMapper();
-
-            // We don't need our own start state anymore
-            startsForBlocks[block.getIndex()] = null;
-        }
-
-        /**
-         * Provides a register mapping between the old register space
-         * and the current renaming mapping. The mapping is updated
-         * as the current block's instructions are processed.
-         */
-        private class RenamingMapper extends RegisterMapper {
-            public RenamingMapper() {
-                // This space intentionally left blank.
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public int getNewRegisterCount() {
-                return nextSsaReg;
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public RegisterSpec map(RegisterSpec registerSpec) {
-                if (registerSpec == null) return null;
-
-                int reg = registerSpec.getReg();
-
-                // For debugging: assert that the mapped types are compatible.
-                if (DEBUG) {
-                    RegisterSpec newVersion = currentMapping[reg];
-                    if (newVersion.getBasicType() != Type.BT_VOID
-                            && registerSpec.getBasicFrameType()
-                                != newVersion.getBasicFrameType()) {
-
-                        throw new RuntimeException(
-                                "mapping registers of incompatible types! "
-                                + registerSpec
-                                + " " + currentMapping[reg]);
-                    }
-                }
-
-                return registerSpec.withReg(currentMapping[reg].getReg());
-            }
-        }
-
-        /**
-         * Renames all the variables in this block and inserts appriopriate
-         * phis in successor blocks.
-         */
-        public void process() {
-            /*
-             * From Appel:
-             *
-             * Rename(n) =
-             *   for each statement S in block n   // 'statement' in 'block'
-             */
-
-            block.forEachInsn(this);
-
-            updateSuccessorPhis();
-
-            // Delete all move insns in this block.
-            ArrayList<SsaInsn> insns = block.getInsns();
-            int szInsns = insns.size();
-
-            for (int i = szInsns - 1; i >= 0 ; i--) {
-                SsaInsn insn = insns.get(i);
-                SsaInsn replaceInsn;
-
-                replaceInsn = insnsToReplace.get(insn);
-
-                if (replaceInsn != null) {
-                    insns.set(i, replaceInsn);
-                } else if (insn.isNormalMoveInsn()
-                        && !movesToKeep.contains(insn)) {
-                    insns.remove(i);
-                }
-            }
-
-            // Store the start states for our dom children.
-            boolean first = true;
-            for (SsaBasicBlock child : block.getDomChildren()) {
-                if (child != block) {
-                    // Don't bother duplicating the array for the first child.
-                    RegisterSpec[] childStart = first ? currentMapping
-                        : dupArray(currentMapping);
-
-                    startsForBlocks[child.getIndex()] = childStart;
-                    first = false;
-                }
-            }
-
-            // currentMapping is owned by a child now.
-        }
-
-        /**
-         * Enforces a few contraints when a register mapping is added.
-         *
-         * <ol>
-         * <li> Ensures that all new SSA registers specs in the mapping
-         * table with the same register number are identical. In effect, once
-         * an SSA register spec has received or lost a local variable name,
-         * then every old-namespace register that maps to it should gain or
-         * lose its local variable name as well.
-         * <li> Records the local name associated with the
-         * register so that a register is never associated with more than one
-         * local.
-         * <li> ensures that only one SSA register
-         * at a time is considered to be associated with a local variable. When
-         * {@code currentMapping} is updated and the newly added element
-         * is named, strip that name from any other SSA registers.
-         * </ol>
-         *
-         * @param ropReg {@code >= 0;} rop register number
-         * @param ssaReg {@code non-null;} an SSA register that has just
-         * been added to {@code currentMapping}
-         */
-        private void addMapping(int ropReg, RegisterSpec ssaReg) {
-            int ssaRegNum = ssaReg.getReg();
-            LocalItem ssaRegLocal = ssaReg.getLocalItem();
-
-            currentMapping[ropReg] = ssaReg;
-
-            /*
-             * Ensure all SSA register specs with the same reg are identical.
-             */
-            for (int i = currentMapping.length - 1; i >= 0; i--) {
-                RegisterSpec cur = currentMapping[i];
-
-                if (ssaRegNum == cur.getReg()) {
-                    currentMapping[i] = ssaReg;
-                }
-            }
-
-            // All further steps are for registers with local information.
-            if (ssaRegLocal == null) {
-                return;
-            }
-
-            // Record that this SSA reg has been associated with a local.
-            setNameForSsaReg(ssaReg);
-
-            // Ensure that no other SSA regs are associated with this local.
-            for (int i = currentMapping.length - 1; i >= 0; i--) {
-                RegisterSpec cur = currentMapping[i];
-
-                if (ssaRegNum != cur.getReg()
-                        && ssaRegLocal.equals(cur.getLocalItem())) {
-                    currentMapping[i] = cur.withLocalItem(null);
-                }
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         *
-         * Phi insns have their result registers renamed.
-         */
-        public void visitPhiInsn(PhiInsn phi) {
-            /* don't process sources for phi's */
-            processResultReg(phi);
-        }
-
-        /**
-         * {@inheritDoc}
-         *
-         * Move insns are treated as a simple mapping operation, and
-         * will later be removed unless they represent a local variable
-         * assignment. If they represent a local variable assignement, they
-         * are preserved.
-         */
-        public void visitMoveInsn(NormalSsaInsn insn) {
-            /*
-             * For moves: copy propogate the move if we can, but don't
-             * if we need to preserve local variable info and the
-             * result has a different name than the source.
-             */
-
-            RegisterSpec ropResult = insn.getResult();
-            int ropResultReg = ropResult.getReg();
-            int ropSourceReg = insn.getSources().get(0).getReg();
-
-            insn.mapSourceRegisters(mapper);
-            int ssaSourceReg = insn.getSources().get(0).getReg();
-
-            LocalItem sourceLocal
-                = currentMapping[ropSourceReg].getLocalItem();
-            LocalItem resultLocal = ropResult.getLocalItem();
-
-            /*
-             * A move from a register that's currently associated with a local
-             * to one that will not be associated with a local does not need
-             * to be preserved, but the local association should remain.
-             * Hence, we inherit the sourceLocal where the resultLocal is null.
-             */
-
-            LocalItem newLocal
-                = (resultLocal == null) ? sourceLocal : resultLocal;
-            LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);
-
-            /*
-             * If we take the new local, will only one local have ever
-             * been associated with this SSA reg?
-             */
-            boolean onlyOneAssociatedLocal
-                    = associatedLocal == null || newLocal == null
-                    || newLocal.equals(associatedLocal);
-
-            /*
-             * If we're going to copy-propogate, then the ssa register
-             * spec that's going to go into the mapping is made up of
-             * the source register number mapped from above, the type
-             * of the result, and the name either from the result (if
-             * specified) or inherited from the existing mapping.
-             *
-             * The move source has incomplete type information in null
-             * object cases, so the result type is used.
-             */
-            RegisterSpec ssaReg
-                    = RegisterSpec.makeLocalOptional(
-                        ssaSourceReg, ropResult.getType(), newLocal);
-
-            if (!Optimizer.getPreserveLocals() || (onlyOneAssociatedLocal
-                    && equalsHandlesNulls(newLocal, sourceLocal)) &&
-                    threshold == 0) {
-                /*
-                 * We don't have to keep this move to preserve local
-                 * information. Either the name is the same, or the result
-                 * register spec is unnamed.
-                 */
-
-                addMapping(ropResultReg, ssaReg);
-            } else if (onlyOneAssociatedLocal && sourceLocal == null &&
-                    threshold == 0) {
-                /*
-                 * The register was previously unnamed. This means that a
-                 * local starts after it's first assignment in SSA form
-                 */
-
-                RegisterSpecList ssaSources = RegisterSpecList.make(
-                        RegisterSpec.make(ssaReg.getReg(),
-                                ssaReg.getType(), newLocal));
-
-                SsaInsn newInsn
-                        = SsaInsn.makeFromRop(
-                            new PlainInsn(Rops.opMarkLocal(ssaReg),
-                            SourcePosition.NO_INFO, null, ssaSources),block);
-
-                insnsToReplace.put(insn, newInsn);
-
-                // Just map as above.
-                addMapping(ropResultReg, ssaReg);
-            } else {
-                /*
-                 * Do not copy-propogate, since the two registers have
-                 * two different local-variable names.
-                 */
-                processResultReg(insn);
-
-                movesToKeep.add(insn);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         *
-         * All insns that are not move or phi insns have their source registers
-         * mapped ot the current mapping. Their result registers are then
-         * renamed to a new SSA register which is then added to the current
-         * register mapping.
-         */
-        public void visitNonMoveInsn(NormalSsaInsn insn) {
-            /* for each use of some variable X in S */
-            insn.mapSourceRegisters(mapper);
-
-            processResultReg(insn);
-        }
-
-        /**
-         * Renames the result register of this insn and updates the
-         * current register mapping. Does nothing if this insn has no result.
-         * Applied to all non-move insns.
-         *
-         * @param insn insn to process.
-         */
-        void processResultReg(SsaInsn insn) {
-            RegisterSpec ropResult = insn.getResult();
-
-            if (ropResult == null) {
-                return;
-            }
-
-            int ropReg = ropResult.getReg();
-            if (isBelowThresholdRegister(ropReg)) {
-                return;
-            }
-
-            insn.changeResultReg(nextSsaReg);
-            addMapping(ropReg, insn.getResult());
-
-            if (DEBUG) {
-                ssaRegToRopReg.add(ropReg);
-            }
-
-            nextSsaReg++;
-        }
-
-        /**
-         * Updates the phi insns in successor blocks with operands based
-         * on the current mapping of the rop register the phis represent.
-         */
-        private void updateSuccessorPhis() {
-            PhiInsn.Visitor visitor = new PhiInsn.Visitor() {
-                public void visitPhiInsn (PhiInsn insn) {
-                    int ropReg;
-
-                    ropReg = insn.getRopResultReg();
-                    if (isBelowThresholdRegister(ropReg)) {
-                        return;
-                    }
-
-                    /*
-                     * Never add a version 0 register as a phi
-                     * operand. Version 0 registers represent the
-                     * initial register state, and thus are never
-                     * significant. Furthermore, the register liveness
-                     * algorithm doesn't properly count them as "live
-                     * in" at the beginning of the method.
-                     */
-
-                    RegisterSpec stackTop = currentMapping[ropReg];
-                    if (!isVersionZeroRegister(stackTop.getReg())) {
-                        insn.addPhiOperand(stackTop, block);
-                    }
-                }
-            };
-
-            BitSet successors = block.getSuccessors();
-            for (int i = successors.nextSetBit(0); i >= 0;
-                    i = successors.nextSetBit(i + 1)) {
-                SsaBasicBlock successor = ssaMeth.getBlocks().get(i);
-                successor.forEachPhiInsn(visitor);
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/FirstFitAllocator.java b/dx/src/main/java/com/android/dx/ssa/back/FirstFitAllocator.java
deleted file mode 100644
index 6416e84..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/FirstFitAllocator.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.rop.code.CstInsn;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.ssa.NormalSsaInsn;
-import com.android.dx.ssa.BasicRegisterMapper;
-import com.android.dx.ssa.RegisterMapper;
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.BitIntSet;
-
-import java.util.BitSet;
-import java.util.ArrayList;
-
-/**
- * Allocates registers via a naive n^2 register allocator.
- * This allocator does not try to co-locate local variables or deal
- * intelligently with different size register uses.
- */
-public class FirstFitAllocator extends RegisterAllocator {
-    /**
-     * If true, allocator places parameters at the top of the frame
-     * in calling-convention order.
-     */
-    private static final boolean PRESLOT_PARAMS = true;
-
-    /** indexed by old reg; the set of old regs we've mapped */
-    private final BitSet mapped;
-
-    /** {@inheritDoc} */
-    public FirstFitAllocator(
-            final SsaMethod ssaMeth, final InterferenceGraph interference) {
-        super(ssaMeth, interference);
-
-        mapped = new BitSet(ssaMeth.getRegCount());
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean wantsParamsMovedHigh() {
-        return PRESLOT_PARAMS;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public RegisterMapper allocateRegisters() {
-        int oldRegCount = ssaMeth.getRegCount();
-
-        BasicRegisterMapper mapper
-                = new BasicRegisterMapper(oldRegCount);
-
-        int nextNewRegister = 0;
-
-        if (PRESLOT_PARAMS) {
-            /*
-             * Reserve space for the params at the bottom of the register
-             * space. Later, we'll flip the params to the end of the register
-             * space.
-             */
-
-            nextNewRegister = ssaMeth.getParamWidth();
-        }
-
-        for (int i = 0; i < oldRegCount; i++) {
-            if (mapped.get(i)) {
-                // we already got this one
-                continue;
-            }
-
-            int maxCategory = getCategoryForSsaReg(i);
-            IntSet current = new BitIntSet(oldRegCount);
-
-            interference.mergeInterferenceSet(i, current);
-
-            boolean isPreslotted = false;
-            int newReg = 0;
-
-            if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {
-                // Any move-param definition must be a NormalSsaInsn
-                NormalSsaInsn defInsn = (NormalSsaInsn)
-                       ssaMeth.getDefinitionForRegister(i);
-
-                newReg = paramNumberFromMoveParam(defInsn);
-
-                mapper.addMapping(i, newReg, maxCategory);
-                isPreslotted = true;
-            } else {
-                mapper.addMapping(i, nextNewRegister, maxCategory);
-                newReg = nextNewRegister;
-            }
-
-            for (int j = i + 1; j < oldRegCount; j++) {
-                if (mapped.get(j) || isDefinitionMoveParam(j)) {
-                    continue;
-                }
-
-                /*
-                 * If reg j doesn't interfere with the current mapping.
-                 * Also, if this is a pre-slotted method parameter, we
-                 * can't use more than the original param width.
-                 */
-                if (!current.has(j)
-                        && !(isPreslotted
-                            && (maxCategory < getCategoryForSsaReg(j)))) {
-
-                    interference.mergeInterferenceSet(j, current);
-
-                    maxCategory = Math.max(maxCategory,
-                            getCategoryForSsaReg(j));
-
-                    mapper.addMapping(j, newReg, maxCategory);
-                    mapped.set(j);
-                }
-            }
-
-            mapped.set(i);
-            if (!isPreslotted) {
-                nextNewRegister += maxCategory;
-            }
-        }
-
-        return mapper;
-    }
-
-    /**
-     * Returns the parameter number that this move-param insn refers to
-     * @param ndefInsn a move-param insn (otherwise, exceptions will be thrown)
-     * @return parameter number (offset in the total parameter width)
-     */
-    private int paramNumberFromMoveParam(NormalSsaInsn ndefInsn) {
-        CstInsn origInsn = (CstInsn) ndefInsn.getOriginalRopInsn();
-
-        return ((CstInteger) origInsn.getConstant()).getValue();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java b/dx/src/main/java/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
deleted file mode 100644
index 9ef95a7..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
+++ /dev/null
@@ -1,1139 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.rop.code.*;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.ssa.InterferenceRegisterMapper;
-import com.android.dx.ssa.RegisterMapper;
-import com.android.dx.ssa.SsaInsn;
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.ssa.NormalSsaInsn;
-import com.android.dx.ssa.PhiInsn;
-import com.android.dx.ssa.Optimizer;
-import com.android.dx.ssa.SsaBasicBlock;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.IntIterator;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Allocates registers in a first-fit fashion, with the bottom reserved for
- * method parameters and all SSAregisters representing the same local variable
- * kept together if possible.
- */
-public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
-    /** local debug flag */
-    private static final boolean DEBUG = false;
-
-    /** maps local variable to a list of associated SSA registers */
-    private final Map<LocalItem, ArrayList<RegisterSpec>> localVariables;
-
-    /** list of move-result-pesudo instructions seen in this method */
-    private final ArrayList<NormalSsaInsn> moveResultPseudoInsns;
-
-    /** list of invoke-range instructions seen in this method */
-    private final ArrayList<NormalSsaInsn> invokeRangeInsns;
-
-    /** list of phi instructions seen in this method */
-    private final ArrayList<PhiInsn> phiInsns;
-
-    /** indexed by SSA reg; the set of SSA regs we've mapped */
-    private final BitSet ssaRegsMapped;
-
-    /** Register mapper which will be our result */
-    private final InterferenceRegisterMapper mapper;
-
-    /** end of rop registers range (starting at 0) reserved for parameters */
-    private final int paramRangeEnd;
-
-    /** set of rop registers reserved for parameters or local variables */
-    private final BitSet reservedRopRegs;
-
-    /** set of rop registers that have been used by anything */
-    private final BitSet usedRopRegs;
-
-    /** true if converter should take steps to minimize rop-form registers */
-    private final boolean minimizeRegisters;
-
-    /**
-     * Constructs instance.
-     *
-     * @param ssaMeth {@code non-null;} method to process
-     * @param interference non-null interference graph for SSA registers
-     * @param minimizeRegisters true if converter should take steps to
-     * minimize rop-form registers
-     */
-    public FirstFitLocalCombiningAllocator(
-            SsaMethod ssaMeth, InterferenceGraph interference,
-            boolean minimizeRegisters) {
-        super(ssaMeth, interference);
-
-        ssaRegsMapped = new BitSet(ssaMeth.getRegCount());
-
-        mapper = new InterferenceRegisterMapper(
-                interference, ssaMeth.getRegCount());
-
-        this.minimizeRegisters = minimizeRegisters;
-
-        /*
-         * Reserve space for the params at the bottom of the register
-         * space. Later, we'll flip the params to the end of the register
-         * space.
-         */
-
-        paramRangeEnd = ssaMeth.getParamWidth();
-
-        reservedRopRegs = new BitSet(paramRangeEnd * 2);
-        reservedRopRegs.set(0, paramRangeEnd);
-        usedRopRegs = new BitSet(paramRangeEnd * 2);
-        localVariables = new TreeMap<LocalItem, ArrayList<RegisterSpec>>();
-        moveResultPseudoInsns = new ArrayList<NormalSsaInsn>();
-        invokeRangeInsns = new ArrayList<NormalSsaInsn>();
-        phiInsns = new ArrayList<PhiInsn>();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean wantsParamsMovedHigh() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public RegisterMapper allocateRegisters() {
-
-        analyzeInstructions();
-
-        if (DEBUG) {
-            printLocalVars();
-        }
-
-        if (DEBUG) System.out.println("--->Mapping local-associated params");
-        handleLocalAssociatedParams();
-
-        if (DEBUG) System.out.println("--->Mapping other params");
-        handleUnassociatedParameters();
-
-        if (DEBUG) System.out.println("--->Mapping invoke-range");
-        handleInvokeRangeInsns();
-
-        if (DEBUG) {
-            System.out.println("--->Mapping local-associated non-params");
-        }
-        handleLocalAssociatedOther();
-
-        if (DEBUG) System.out.println("--->Mapping check-cast results");
-        handleCheckCastResults();
-
-        if (DEBUG) System.out.println("--->Mapping phis");
-        handlePhiInsns();
-
-        if (DEBUG) System.out.println("--->Mapping others");
-        handleNormalUnassociated();
-
-        return mapper;
-    }
-
-    /**
-     * Dumps local variable table to stdout for debugging.
-     */
-    private void printLocalVars() {
-        System.out.println("Printing local vars");
-        for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e :
-                localVariables.entrySet()) {
-            StringBuilder regs = new StringBuilder();
-
-            regs.append('{');
-            regs.append(' ');
-            for (RegisterSpec reg : e.getValue()) {
-                regs.append('v');
-                regs.append(reg.getReg());
-                regs.append(' ');
-            }
-            regs.append('}');
-            System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs);
-        }
-    }
-
-    /**
-     * Maps all local-associated parameters to rop registers.
-     */
-    private void handleLocalAssociatedParams() {
-        for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
-            int sz = ssaRegs.size();
-            int paramIndex = -1;
-            int paramCategory = 0;
-
-            // First, find out if this local variable is a parameter.
-            for (int i = 0; i < sz; i++) {
-                RegisterSpec ssaSpec = ssaRegs.get(i);
-                int ssaReg = ssaSpec.getReg();
-
-                paramIndex = getParameterIndexForReg(ssaReg);
-
-                if (paramIndex >= 0) {
-                    paramCategory = ssaSpec.getCategory();
-                    addMapping(ssaSpec, paramIndex);
-                    break;
-                }
-            }
-
-            if (paramIndex < 0) {
-                // This local wasn't a parameter.
-                continue;
-            }
-
-            // Any remaining local-associated registers will be mapped later.
-            tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
-        }
-    }
-
-    /**
-     * Gets the parameter index for SSA registers that are method parameters.
-     * {@code -1} is returned for non-parameter registers.
-     *
-     * @param ssaReg {@code >=0;} SSA register to look up
-     * @return parameter index or {@code -1} if not a parameter
-     */
-    private int getParameterIndexForReg(int ssaReg) {
-        SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);
-        if (defInsn == null) {
-            return -1;
-        }
-
-        Rop opcode = defInsn.getOpcode();
-
-        // opcode == null for phi insns.
-        if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {
-            CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();
-            return  ((CstInteger) origInsn.getConstant()).getValue();
-        }
-
-        return -1;
-    }
-
-    /**
-     * Maps all local-associated registers that are not parameters.
-     * Tries to find an unreserved range that's wide enough for all of
-     * the SSA registers, and then tries to map them all to that
-     * range. If not all fit, a new range is tried until all registers
-     * have been fit.
-     */
-    private void handleLocalAssociatedOther() {
-        for (ArrayList<RegisterSpec> specs : localVariables.values()) {
-            int ropReg = paramRangeEnd;
-
-            boolean done = false;
-            do {
-                int maxCategory = 1;
-
-                // Compute max category for remaining unmapped registers.
-                int sz = specs.size();
-                for (int i = 0; i < sz; i++) {
-                    RegisterSpec ssaSpec = specs.get(i);
-                    int category = ssaSpec.getCategory();
-                    if (!ssaRegsMapped.get(ssaSpec.getReg())
-                            && category > maxCategory) {
-                        maxCategory = category;
-                    }
-                }
-
-                ropReg = findRopRegForLocal(ropReg, maxCategory);
-                if (canMapRegs(specs, ropReg)) {
-                    done = tryMapRegs(specs, ropReg, maxCategory, true);
-                }
-
-                // Increment for next call to findRopRegForLocal.
-                ropReg++;
-            } while (!done);
-        }
-    }
-
-    /**
-     * Tries to map a list of SSA registers into the a rop reg, marking
-     * used rop space as reserved. SSA registers that don't fit are left
-     * unmapped.
-     *
-     * @param specs {@code non-null;} SSA registers to attempt to map
-     * @param ropReg {@code >=0;} rop register to map to
-     * @param maxAllowedCategory {@code 1..2;} maximum category
-     * allowed in mapping.
-     * @param markReserved do so if {@code true}
-     * @return {@code true} if all registers were mapped, {@code false}
-     * if some remain unmapped
-     */
-    private boolean tryMapRegs(
-            ArrayList<RegisterSpec> specs, int ropReg,
-            int maxAllowedCategory, boolean markReserved) {
-        boolean remaining = false;
-        for (RegisterSpec spec : specs) {
-            if (ssaRegsMapped.get(spec.getReg())) {
-                continue;
-            }
-
-            boolean succeeded;
-            succeeded = tryMapReg(spec, ropReg, maxAllowedCategory);
-            remaining = !succeeded || remaining;
-            if (succeeded && markReserved) {
-                // This only needs to be called once really with
-                // the widest category used, but <shrug>
-                markReserved(ropReg, spec.getCategory());
-            }
-        }
-        return !remaining;
-    }
-
-    /**
-     * Tries to map an SSA register to a rop register.
-     *
-     * @param ssaSpec {@code non-null;} SSA register
-     * @param ropReg {@code >=0;} rop register
-     * @param maxAllowedCategory {@code 1..2;} the maximum category
-     * that the SSA register is allowed to be
-     * @return {@code true} if map succeeded, {@code false} if not
-     */
-    private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,
-            int maxAllowedCategory) {
-        if (ssaSpec.getCategory() <= maxAllowedCategory
-                && !ssaRegsMapped.get(ssaSpec.getReg())
-                && canMapReg(ssaSpec, ropReg)) {
-            addMapping(ssaSpec, ropReg);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Marks a range of rop registers as "reserved for a local variable."
-     *
-     * @param ropReg {@code >= 0;} rop register to reserve
-     * @param category {@code > 0;} width to reserve
-     */
-    private void markReserved(int ropReg, int category) {
-        reservedRopRegs.set(ropReg, ropReg + category, true);
-    }
-
-    /**
-     * Checks to see if any rop registers in the specified range are reserved
-     * for local variables or parameters.
-     *
-     * @param ropRangeStart {@code >= 0;} lowest rop register
-     * @param width {@code > 0;} number of rop registers in range.
-     * @return {@code true} if any register in range is marked reserved
-     */
-    private boolean rangeContainsReserved(int ropRangeStart, int width) {
-        for (int i = ropRangeStart; i < (ropRangeStart + width); i++) {
-            if (reservedRopRegs.get(i)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if given rop register represents the {@code this} pointer
-     * for a non-static method.
-     *
-     * @param startReg rop register
-     * @return true if the "this" pointer is located here.
-     */
-    private boolean isThisPointerReg(int startReg) {
-        // "this" is always the first parameter.
-        return startReg == 0 && !ssaMeth.isStatic();
-    }
-
-    /**
-     * Finds a range of unreserved rop registers.
-     *
-     * @param startReg {@code >= 0;} a rop register to start the search at
-     * @param width {@code > 0;} the width, in registers, required.
-     * @return {@code >= 0;} start of available register range.
-     */
-    private int findNextUnreservedRopReg(int startReg, int width) {
-        int reg;
-
-        reg = reservedRopRegs.nextClearBit(startReg);
-
-        while (true) {
-            int i = 1;
-
-            while (i < width && !reservedRopRegs.get(reg + i)) {
-                i++;
-            }
-
-            if (i == width) {
-                return reg;
-            }
-
-            reg = reservedRopRegs.nextClearBit(reg + i);
-        }
-    }
-
-    /**
-     * Finds a range of rop regs that can be used for local variables.
-     * If {@code MIX_LOCALS_AND_OTHER} is {@code false}, this means any
-     * rop register that has not yet been used.
-     *
-     * @param startReg {@code >= 0;} a rop register to start the search at
-     * @param width {@code > 0;} the width, in registers, required.
-     * @return {@code >= 0;} start of available register range.
-     */
-    private int findRopRegForLocal(int startReg, int width) {
-        int reg;
-
-        reg = usedRopRegs.nextClearBit(startReg);
-
-        while (true) {
-            int i = 1;
-
-            while (i < width && !usedRopRegs.get(reg + i)) {
-                i++;
-            }
-
-            if (i == width) {
-                return reg;
-            }
-
-            reg = usedRopRegs.nextClearBit(reg + i);
-        }
-    }
-
-    /**
-     * Maps any parameter that isn't local-associated, which can happen
-     * in the case where there is no java debug info.
-     */
-    private void handleUnassociatedParameters() {
-        int szSsaRegs = ssaMeth.getRegCount();
-
-        for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) {
-            if (ssaRegsMapped.get(ssaReg)) {
-                // We already did this one above
-                continue;
-            }
-
-            int paramIndex = getParameterIndexForReg(ssaReg);
-
-            RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);
-            if (paramIndex >= 0) {
-                addMapping(ssaSpec, paramIndex);
-            }
-        }
-    }
-
-    /**
-     * Handles all insns that want a register range for their sources.
-     */
-    private void handleInvokeRangeInsns() {
-        for (NormalSsaInsn insn : invokeRangeInsns) {
-            adjustAndMapSourceRangeRange(insn);
-        }
-    }
-
-    /**
-     * Handles check cast results to reuse the same source register.
-     * Inserts a move if it can't map the same register to both and the
-     * check cast is not caught.
-     */
-    private void handleCheckCastResults() {
-        for (NormalSsaInsn insn : moveResultPseudoInsns) {
-            RegisterSpec moveRegSpec = insn.getResult();
-            int moveReg = moveRegSpec.getReg();
-            BitSet predBlocks = insn.getBlock().getPredecessors();
-
-            // Expect one predecessor block only
-            if (predBlocks.cardinality() != 1) {
-                continue;
-            }
-
-            SsaBasicBlock predBlock =
-                    ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));
-            ArrayList<SsaInsn> insnList = predBlock.getInsns();
-
-            /**
-             * If the predecessor block has a check-cast, it will be the last
-             * instruction
-             */
-            SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);
-            if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {
-                continue;
-            }
-
-            RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
-            int checkReg = checkRegSpec.getReg();
-
-            /**
-             * See if either register is already mapped. Most likely the move
-             * result will be mapped already since the cast result is stored
-             * in a local variable.
-             */
-            int category = checkRegSpec.getCategory();
-            boolean moveMapped = ssaRegsMapped.get(moveReg);
-            boolean checkMapped = ssaRegsMapped.get(checkReg);
-            if (moveMapped & !checkMapped) {
-                int moveRopReg = mapper.oldToNew(moveReg);
-                checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
-            }
-            if (checkMapped & !moveMapped) {
-                int checkRopReg = mapper.oldToNew(checkReg);
-                moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
-            }
-
-            // Map any unmapped registers to anything available
-            if (!moveMapped || !checkMapped) {
-                int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
-                ArrayList<RegisterSpec> ssaRegs =
-                    new ArrayList<RegisterSpec>(2);
-                ssaRegs.add(moveRegSpec);
-                ssaRegs.add(checkRegSpec);
-
-                while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
-                    ropReg = findNextUnreservedRopReg(ropReg + 1, category);
-                }
-            }
-
-            /*
-             * If source and result have a different mapping, insert a move so
-             * they can have the same mapping. Don't do this if the check cast
-             * is caught, since it will overwrite a potentially live value.
-             */
-            boolean hasExceptionHandlers =
-                checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
-            int moveRopReg = mapper.oldToNew(moveReg);
-            int checkRopReg = mapper.oldToNew(checkReg);
-            if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
-                ((NormalSsaInsn) checkCastInsn).changeOneSource(0,
-                        insertMoveBefore(checkCastInsn, checkRegSpec));
-                addMapping(checkCastInsn.getSources().get(0), moveRopReg);
-            }
-        }
-    }
-
-    /**
-    * Handles all phi instructions, trying to map them to a common register.
-    */
-    private void handlePhiInsns() {
-        for (PhiInsn insn : phiInsns) {
-            processPhiInsn(insn);
-        }
-    }
-
-    /**
-     * Maps all non-parameter, non-local variable registers.
-     */
-    private void handleNormalUnassociated() {
-        int szSsaRegs = ssaMeth.getRegCount();
-
-        for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) {
-            if (ssaRegsMapped.get(ssaReg)) {
-                // We already did this one
-                continue;
-            }
-
-            RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);
-
-            if (ssaSpec == null) continue;
-
-            int category = ssaSpec.getCategory();
-            // Find a rop reg that does not interfere
-            int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
-            while (!canMapReg(ssaSpec, ropReg)) {
-                ropReg = findNextUnreservedRopReg(ropReg + 1, category);
-            }
-
-            addMapping(ssaSpec, ropReg);
-        }
-    }
-
-    /**
-     * Checks to see if a list of SSA registers can all be mapped into
-     * the same rop reg. Ignores registers that have already been mapped,
-     * and checks the interference graph and ensures the range does not
-     * cross the parameter range.
-     *
-     * @param specs {@code non-null;} SSA registers to check
-     * @param ropReg {@code >=0;} rop register to check mapping to
-     * @return {@code true} if all unmapped registers can be mapped
-     */
-    private boolean canMapRegs(ArrayList<RegisterSpec> specs, int ropReg) {
-        for (RegisterSpec spec : specs) {
-            if (ssaRegsMapped.get(spec.getReg())) continue;
-            if (!canMapReg(spec, ropReg)) return false;
-        }
-        return true;
-    }
-
-    /**
-     * Checks to see if {@code ssaSpec} can be mapped to
-     * {@code ropReg}. Checks interference graph and ensures
-     * the range does not cross the parameter range.
-     *
-     * @param ssaSpec {@code non-null;} SSA spec
-     * @param ropReg prosepctive new-namespace reg
-     * @return {@code true} if mapping is possible
-     */
-    private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {
-        int category = ssaSpec.getCategory();
-        return !(spansParamRange(ropReg, category)
-                || mapper.interferes(ssaSpec, ropReg));
-    }
-
-    /**
-     * Returns true if the specified rop register + category
-     * will cross the boundry between the lower {@code paramWidth}
-     * registers reserved for method params and the upper registers. We cannot
-     * allocate a register that spans the param block and the normal block,
-     * because we will be moving the param block to high registers later.
-     *
-     * @param ssaReg register in new namespace
-     * @param category width that the register will have
-     * @return {@code true} in the case noted above
-     */
-    private boolean spansParamRange(int ssaReg, int category) {
-        return ((ssaReg < paramRangeEnd)
-                && ((ssaReg + category) > paramRangeEnd));
-    }
-
-    /**
-     * Analyze each instruction and find out all the local variable assignments
-     * and move-result-pseudo/invoke-range instrucitons.
-     */
-    private void analyzeInstructions() {
-        ssaMeth.forEachInsn(new SsaInsn.Visitor() {
-            /** {@inheritDoc} */
-            public void visitMoveInsn(NormalSsaInsn insn) {
-                processInsn(insn);
-            }
-
-            /** {@inheritDoc} */
-            public void visitPhiInsn(PhiInsn insn) {
-                processInsn(insn);
-            }
-
-            /** {@inheritDoc} */
-            public void visitNonMoveInsn(NormalSsaInsn insn) {
-                processInsn(insn);
-            }
-
-            /**
-             * This method collects three types of instructions:
-             *
-             * 1) Adds a local variable assignment to the
-             *    {@code localVariables} map.
-             * 2) Add move-result-pseudo to the
-             *    {@code moveResultPseudoInsns} list.
-             * 3) Add invoke-range to the
-             *    {@code invokeRangeInsns} list.
-             *
-             * @param insn {@code non-null;} insn that may represent a
-             * local variable assignment
-             */
-            private void processInsn(SsaInsn insn) {
-                RegisterSpec assignment;
-                assignment = insn.getLocalAssignment();
-
-                if (assignment != null) {
-                    LocalItem local = assignment.getLocalItem();
-
-                    ArrayList<RegisterSpec> regList
-                        = localVariables.get(local);
-
-                    if (regList == null) {
-                        regList = new ArrayList<RegisterSpec>();
-                        localVariables.put(local, regList);
-                    }
-
-                    regList.add(assignment);
-                }
-
-                if (insn instanceof NormalSsaInsn) {
-                    if (insn.getOpcode().getOpcode() ==
-                            RegOps.MOVE_RESULT_PSEUDO) {
-                        moveResultPseudoInsns.add((NormalSsaInsn) insn);
-                    } else if (Optimizer.getAdvice().requiresSourcesInOrder(
-                            insn.getOriginalRopInsn().getOpcode(),
-                            insn.getSources())) {
-                        invokeRangeInsns.add((NormalSsaInsn) insn);
-                    }
-                } else if (insn instanceof PhiInsn) {
-                    phiInsns.add((PhiInsn) insn);
-                }
-
-            }
-        });
-    }
-
-    /**
-     * Adds a mapping from an SSA register to a rop register.
-     * {@link #canMapReg} should have already been called.
-     *
-     * @param ssaSpec {@code non-null;} SSA register to map from
-     * @param ropReg {@code >=0;} rop register to map to
-     */
-    private void addMapping(RegisterSpec ssaSpec, int ropReg) {
-        int ssaReg = ssaSpec.getReg();
-
-        // An assertion.
-        if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) {
-            throw new RuntimeException(
-                    "attempt to add invalid register mapping");
-        }
-
-        if (DEBUG) {
-            System.out.printf("Add mapping s%d -> v%d c:%d\n",
-                    ssaSpec.getReg(), ropReg, ssaSpec.getCategory());
-        }
-
-        int category = ssaSpec.getCategory();
-        mapper.addMapping(ssaSpec.getReg(), ropReg, category);
-        ssaRegsMapped.set(ssaReg);
-        usedRopRegs.set(ropReg, ropReg + category);
-    }
-
-
-    /**
-     * Maps the source registers of the specified instruction such that they
-     * will fall in a contiguous range in rop form. Moves are inserted as
-     * necessary to allow the range to be allocated.
-     *
-     * @param insn {@code non-null;} insn whos sources to process
-     */
-    private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) {
-        int newRegStart = findRangeAndAdjust(insn);
-
-        RegisterSpecList sources = insn.getSources();
-        int szSources = sources.size();
-        int nextRopReg = newRegStart;
-
-        for (int i = 0; i < szSources; i++) {
-            RegisterSpec source = sources.get(i);
-            int sourceReg = source.getReg();
-            int category = source.getCategory();
-            int curRopReg = nextRopReg;
-            nextRopReg += category;
-
-            if (ssaRegsMapped.get(sourceReg)) {
-                continue;
-            }
-
-            LocalItem localItem = getLocalItemForReg(sourceReg);
-            addMapping(source, curRopReg);
-
-            if (localItem != null) {
-                markReserved(curRopReg, category);
-                ArrayList<RegisterSpec> similarRegisters
-                        = localVariables.get(localItem);
-
-                int szSimilar = similarRegisters.size();
-
-                /*
-                 * Try to map all SSA registers also associated with
-                 * this local.
-                 */
-                for (int j = 0; j < szSimilar; j++) {
-                    RegisterSpec similarSpec = similarRegisters.get(j);
-                    int similarReg = similarSpec.getReg();
-
-                    // Don't map anything that's also a source.
-                    if (-1 != sources.indexOfRegister(similarReg)) {
-                        continue;
-                    }
-
-                    // Registers left unmapped will get handled later.
-                    tryMapReg(similarSpec, curRopReg, category);
-                }
-            }
-        }
-    }
-
-    /**
-     * Find a contiguous rop register range that fits the specified
-     * instruction's sources. First, try to center the range around
-     * sources that have already been mapped to rop registers. If that fails,
-     * just find a new contiguous range that doesn't interfere.
-     *
-     * @param insn {@code non-null;} the insn whose sources need to
-     * fit. Must be last insn in basic block.
-     * @return {@code >= 0;} rop register of start of range
-     */
-    private int findRangeAndAdjust(NormalSsaInsn insn) {
-        RegisterSpecList sources = insn.getSources();
-        int szSources = sources.size();
-        // the category for each source index
-        int categoriesForIndex[] = new int[szSources];
-        int rangeLength = 0;
-
-        // Compute rangeLength and categoriesForIndex
-        for (int i = 0; i < szSources; i++) {
-            int category = sources.get(i).getCategory();
-            categoriesForIndex[i] = category;
-            rangeLength += categoriesForIndex[i];
-        }
-
-        // the highest score of fits tried so far
-        int maxScore = Integer.MIN_VALUE;
-        // the high scoring range's start
-        int resultRangeStart = -1;
-        // by source index: set of sources needing moves in high scoring plan
-        BitSet resultMovesRequired = null;
-
-        /*
-         * First, go through each source that's already been mapped. Try
-         * to center the range around the rop register this source is mapped
-         * to.
-         */
-        int rangeStartOffset = 0;
-        for (int i = 0; i < szSources; i++) {
-            int ssaCenterReg = sources.get(i).getReg();
-
-            if (i != 0) {
-                rangeStartOffset -= categoriesForIndex[i - 1];
-            }
-            if (!ssaRegsMapped.get(ssaCenterReg)) {
-                continue;
-            }
-
-            int rangeStart = mapper.oldToNew(ssaCenterReg) + rangeStartOffset;
-
-            if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) {
-                continue;
-            }
-
-            BitSet curMovesRequired = new BitSet(szSources);
-
-            int fitWidth
-                    = fitPlanForRange(rangeStart, insn, categoriesForIndex,
-                    curMovesRequired);
-
-            if (fitWidth < 0) {
-                continue;
-            }
-
-            int score = fitWidth - curMovesRequired.cardinality();
-
-            if (score > maxScore) {
-                maxScore = score;
-                resultRangeStart = rangeStart;
-                resultMovesRequired = curMovesRequired;
-            }
-
-            if (fitWidth == rangeLength) {
-                // We can't do any better than this, so stop here
-                break;
-            }
-        }
-
-        /*
-         * If we were unable to find a plan for a fit centered around
-         * an already-mapped source, just try to find a range of
-         * registers we can move the range into.
-         */
-
-        if (resultRangeStart == -1) {
-            resultMovesRequired = new BitSet(szSources);
-
-            resultRangeStart = findAnyFittingRange(insn, rangeLength,
-                    categoriesForIndex, resultMovesRequired);
-        }
-
-        /*
-         * Now, insert any moves required.
-         */
-
-        for (int i = resultMovesRequired.nextSetBit(0); i >= 0;
-             i = resultMovesRequired.nextSetBit(i+1)) {
-            insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));
-        }
-
-        return resultRangeStart;
-    }
-
-    /**
-     * Finds an unreserved range that will fit the sources of the
-     * specified instruction. Does not bother trying to center the range
-     * around an already-mapped source register;
-     *
-     * @param insn {@code non-null;} insn to build range for
-     * @param rangeLength {@code >=0;} length required in register units
-     * @param categoriesForIndex {@code non-null;} indexed by source index;
-     * the category for each source
-     * @param outMovesRequired {@code non-null;} an output parameter indexed by
-     * source index that will contain the set of sources which need
-     * moves inserted
-     * @return the rop register that starts the fitting range
-     */
-    private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength,
-            int[] categoriesForIndex, BitSet outMovesRequired) {
-        int rangeStart = paramRangeEnd;
-        while (true) {
-            rangeStart = findNextUnreservedRopReg(rangeStart, rangeLength);
-            int fitWidth
-                    = fitPlanForRange(rangeStart, insn,
-                    categoriesForIndex, outMovesRequired);
-
-            if (fitWidth >= 0) {
-                break;
-            }
-            rangeStart++;
-            outMovesRequired.clear();
-        }
-        return rangeStart;
-    }
-
-    /**
-     * Attempts to build a plan for fitting a range of sources into rop
-     * registers.
-     *
-     * @param ropReg {@code >= 0;} rop reg that begins range
-     * @param insn {@code non-null;} insn to plan range for
-     * @param categoriesForIndex {@code non-null;} indexed by source index;
-     * the category for each source
-     * @param outMovesRequired {@code non-null;} an output parameter indexed by
-     * source index that will contain the set of sources which need
-     * moves inserted
-     * @return the width of the fit that that does not involve added moves or
-     * {@code -1} if "no fit possible"
-     */
-    private int fitPlanForRange(int ropReg, NormalSsaInsn insn,
-            int[] categoriesForIndex, BitSet outMovesRequired) {
-        RegisterSpecList sources = insn.getSources();
-        int szSources = sources.size();
-        int fitWidth = 0;
-        IntSet liveOut = insn.getBlock().getLiveOutRegs();
-        RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);
-
-        // An SSA reg may only be mapped into a range once.
-        BitSet seen = new BitSet(ssaMeth.getRegCount());
-
-        for (int i = 0; i < szSources ; i++) {
-            RegisterSpec ssaSpec = sources.get(i);
-            int ssaReg = ssaSpec.getReg();
-            int category = categoriesForIndex[i];
-
-            if (i != 0) {
-                ropReg += categoriesForIndex[i-1];
-            }
-
-            if (ssaRegsMapped.get(ssaReg)
-                    && mapper.oldToNew(ssaReg) == ropReg) {
-                // This is a register that is already mapped appropriately.
-                fitWidth += category;
-            } else if (rangeContainsReserved(ropReg, category)) {
-                fitWidth = -1;
-                break;
-            } else if (!ssaRegsMapped.get(ssaReg)
-                    && canMapReg(ssaSpec, ropReg)
-                    && !seen.get(ssaReg)) {
-                // This is a register that can be mapped appropriately.
-                fitWidth += category;
-            } else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category)
-                    && !mapper.areAnyPinned(sources, ropReg, category)) {
-                /*
-                 * This is a source that can be moved. We can insert a
-                 * move as long as:
-                 *
-                 *   * no SSA register pinned to the desired rop reg
-                 *     is live out on the block
-                 *
-                 *   * no SSA register pinned to desired rop reg is
-                 *     a source of this insn (since this may require
-                 *     overlapping moves, which we can't presently handle)
-                 */
-
-                outMovesRequired.set(i);
-            } else {
-                fitWidth = -1;
-                break;
-            }
-
-            seen.set(ssaReg);
-        }
-        return fitWidth;
-    }
-
-    /**
-     * Converts a bit set of SSA registers into a RegisterSpecList containing
-     * the definition specs of all the registers.
-     *
-     * @param ssaSet {@code non-null;} set of SSA registers
-     * @return list of RegisterSpecs as noted above
-     */
-    RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
-        RegisterSpecList result = new RegisterSpecList(ssaSet.elements());
-
-        IntIterator iter = ssaSet.iterator();
-
-        int i = 0;
-        while (iter.hasNext()) {
-            result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
-        }
-
-        return result;
-    }
-
-    /**
-     * Gets a local item associated with an ssa register, if one exists.
-     *
-     * @param ssaReg {@code >= 0;} SSA register
-     * @return {@code null-ok;} associated local item or null
-     */
-    private LocalItem getLocalItemForReg(int ssaReg) {
-        for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> entry :
-                 localVariables.entrySet()) {
-            for (RegisterSpec spec : entry.getValue()) {
-                if (spec.getReg() == ssaReg) {
-                    return entry.getKey();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Attempts to map the sources and result of a phi to a common register.
-     * Will try existing mappings first, from most to least common. If none
-     * of the registers have mappings yet, a new mapping is created.
-     */
-    private void processPhiInsn(PhiInsn insn) {
-        RegisterSpec result = insn.getResult();
-        int resultReg = result.getReg();
-        int category = result.getCategory();
-
-        RegisterSpecList sources = insn.getSources();
-        int sourcesSize = sources.size();
-
-        // List of phi sources / result that need mapping
-        ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>();
-
-        // Track how many times a particular mapping is found
-        Multiset mapSet = new Multiset(sourcesSize + 1);
-
-        /*
-         * If the result of the phi has an existing mapping, get it.
-         * Otherwise, add it to the list of regs that need mapping.
-         */
-        if (ssaRegsMapped.get(resultReg)) {
-            mapSet.add(mapper.oldToNew(resultReg));
-        } else {
-            ssaRegs.add(result);
-        }
-
-        for (int i = 0; i < sourcesSize; i++) {
-            RegisterSpec source = sources.get(i);
-            SsaInsn def = ssaMeth.getDefinitionForRegister(source.getReg());
-            RegisterSpec sourceDef = def.getResult();
-            int sourceReg = sourceDef.getReg();
-
-            /*
-             * If a source of the phi has an existing mapping, get it.
-             * Otherwise, add it to the list of regs that need mapping.
-             */
-            if (ssaRegsMapped.get(sourceReg)) {
-                mapSet.add(mapper.oldToNew(sourceReg));
-            } else {
-                ssaRegs.add(sourceDef);
-            }
-        }
-
-        // Try all existing mappings, with the most common ones first
-        for (int i = 0; i < mapSet.getSize(); i++) {
-            int maxReg = mapSet.getAndRemoveHighestCount();
-            tryMapRegs(ssaRegs, maxReg, category, false);
-        }
-
-        // Map any remaining unmapped regs with whatever fits
-        int mapReg = findNextUnreservedRopReg(paramRangeEnd, category);
-        while (!tryMapRegs(ssaRegs, mapReg, category, false)) {
-            mapReg = findNextUnreservedRopReg(mapReg + 1, category);
-        }
-    }
-
-    // A set that tracks how often elements are added to it.
-    private static class Multiset {
-        private final int[] reg;
-        private final int[] count;
-        private int size;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param maxSize the maximum distinct elements the set may have
-         */
-        public Multiset(int maxSize) {
-            reg = new int[maxSize];
-            count = new int[maxSize];
-            size = 0;
-        }
-
-        /**
-         * Adds an element to the set.
-         *
-         * @param element element to add
-         */
-        public void add(int element) {
-            for (int i = 0; i < size; i++) {
-                if (reg[i] == element) {
-                    count[i]++;
-                    return;
-                }
-            }
-
-            reg[size] = element;
-            count[size] = 1;
-            size++;
-        }
-
-        /**
-         * Searches the set for the element that has been added the most.
-         * In the case of a tie, the element that was added first is returned.
-         * Then, it clears the count on that element. The size of the set
-         * remains unchanged.
-         *
-         * @return element with the highest count
-         */
-        public int getAndRemoveHighestCount() {
-            int maxIndex = -1;
-            int maxReg = -1;
-            int maxCount = 0;
-
-            for (int i = 0; i < size; i++) {
-                if (maxCount < count[i]) {
-                    maxIndex = i;
-                    maxReg = reg[i];
-                    maxCount = count[i];
-                }
-            }
-
-            count[maxIndex] = 0;
-            return maxReg;
-        }
-
-        /**
-         * Gets the number of distinct elements in the set.
-         *
-         * @return size of the set
-         */
-        public int getSize() {
-            return size;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/IdenticalBlockCombiner.java b/dx/src/main/java/com/android/dx/ssa/back/IdenticalBlockCombiner.java
deleted file mode 100644
index 515b04f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/IdenticalBlockCombiner.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.CstInsn;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.SwitchInsn;
-import com.android.dx.util.IntList;
-
-import java.util.BitSet;
-
-/**
- * Searches for basic blocks that all have the same successor and insns
- * but different predecessors. These blocks are then combined into a single
- * block and the now-unused blocks are deleted. These identical blocks
- * frequently are created when catch blocks are edge-split.
- */
-public class IdenticalBlockCombiner {
-    private final RopMethod ropMethod;
-    private final BasicBlockList blocks;
-    private final BasicBlockList newBlocks;
-
-    /**
-     * Constructs instance. Call {@code process()} to run.
-     *
-     * @param rm {@code non-null;} instance to process
-     */
-    public IdenticalBlockCombiner(RopMethod rm) {
-        ropMethod = rm;
-        blocks = ropMethod.getBlocks();
-        newBlocks = blocks.getMutableCopy();
-    }
-
-    /**
-     * Runs algorithm. TODO: This is n^2, and could be made linear-ish with
-     * a hash. In particular, hash the contents of each block and only
-     * compare blocks with the same hash.
-     *
-     * @return {@code non-null;} new method that has been processed
-     */
-    public RopMethod process() {
-        int szBlocks = blocks.size();
-        // indexed by label
-        BitSet toDelete = new BitSet(blocks.getMaxLabel());
-
-        // For each non-deleted block...
-        for (int bindex = 0; bindex < szBlocks; bindex++) {
-            BasicBlock b = blocks.get(bindex);
-
-            if (toDelete.get(b.getLabel())) {
-                // doomed block
-                continue;
-            }
-
-            IntList preds = ropMethod.labelToPredecessors(b.getLabel());
-
-            // ...look at all of it's predecessors that have only one succ...
-            int szPreds = preds.size();
-            for (int i = 0; i < szPreds; i++) {
-                int iLabel = preds.get(i);
-
-                BasicBlock iBlock = blocks.labelToBlock(iLabel);
-
-                if (toDelete.get(iLabel)
-                        || iBlock.getSuccessors().size() > 1
-                        || iBlock.getFirstInsn().getOpcode().getOpcode() ==
-                            RegOps.MOVE_RESULT) {
-                    continue;
-                }
-
-                IntList toCombine = new IntList();
-
-                // ...and see if they can be combined with any other preds...
-                for (int j = i + 1; j < szPreds; j++) {
-                    int jLabel = preds.get(j);
-                    BasicBlock jBlock = blocks.labelToBlock(jLabel);
-
-                    if (jBlock.getSuccessors().size() == 1
-                            && compareInsns(iBlock, jBlock)) {
-
-                        toCombine.add(jLabel);
-                        toDelete.set(jLabel);
-                    }
-                }
-
-                combineBlocks(iLabel, toCombine);
-            }
-        }
-
-        for (int i = szBlocks - 1; i >= 0; i--) {
-            if (toDelete.get(newBlocks.get(i).getLabel())) {
-                newBlocks.set(i, null);
-            }
-        }
-
-        newBlocks.shrinkToFit();
-        newBlocks.setImmutable();
-
-        return new RopMethod(newBlocks, ropMethod.getFirstLabel());
-    }
-
-    /**
-     * Helper method to compare the contents of two blocks.
-     *
-     * @param a {@code non-null;} a block to compare
-     * @param b {@code non-null;} another block to compare
-     * @return {@code true} iff the two blocks' instructions are the same
-     */
-    private static boolean compareInsns(BasicBlock a, BasicBlock b) {
-        return a.getInsns().contentEquals(b.getInsns());
-    }
-
-    /**
-     * Combines blocks proven identical into one alpha block, re-writing
-     * all of the successor links that point to the beta blocks to point
-     * to the alpha block instead.
-     *
-     * @param alphaLabel block that will replace all the beta block
-     * @param betaLabels label list of blocks to combine
-     */
-    private void combineBlocks(int alphaLabel, IntList betaLabels) {
-        int szBetas = betaLabels.size();
-
-        for (int i = 0; i < szBetas; i++) {
-            int betaLabel = betaLabels.get(i);
-            BasicBlock bb = blocks.labelToBlock(betaLabel);
-            IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
-            int szPreds = preds.size();
-
-            for (int j = 0; j < szPreds; j++) {
-                BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
-                replaceSucc(predBlock, betaLabel, alphaLabel);
-            }
-        }
-    }
-
-    /**
-     * Replaces one of a block's successors with a different label. Constructs
-     * an updated BasicBlock instance and places it in {@code newBlocks}.
-     *
-     * @param block block to replace
-     * @param oldLabel label of successor to replace
-     * @param newLabel label of new successor
-     */
-    private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
-        IntList newSuccessors = block.getSuccessors().mutableCopy();
-        int newPrimarySuccessor;
-
-        newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
-        newPrimarySuccessor = block.getPrimarySuccessor();
-
-        if (newPrimarySuccessor == oldLabel) {
-            newPrimarySuccessor = newLabel;
-        }
-
-        newSuccessors.setImmutable();
-
-        BasicBlock newBB = new BasicBlock(block.getLabel(),
-                block.getInsns(), newSuccessors, newPrimarySuccessor);
-
-        newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/InterferenceGraph.java b/dx/src/main/java/com/android/dx/ssa/back/InterferenceGraph.java
deleted file mode 100644
index e6cde62..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/InterferenceGraph.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.ssa.SsaBasicBlock;
-import com.android.dx.ssa.SsaInsn;
-import com.android.dx.ssa.PhiInsn;
-import com.android.dx.ssa.SetFactory;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.BitIntSet;
-import com.android.dx.util.ListIntSet;
-
-import java.util.BitSet;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * A register interference graph
- */
-public class InterferenceGraph {
-    /**
-     * {@code non-null;} interference graph, indexed by register in
-     * both dimensions
-     */
-    private final ArrayList<IntSet> interference;
-
-    /**
-     * Creates a new graph.
-     *
-     * @param countRegs {@code >= 0;} the start count of registers in
-     * the namespace. New registers can be added subsequently.
-     */
-    public InterferenceGraph(int countRegs) {
-        interference = new ArrayList<IntSet>(countRegs);
-
-        for (int i = 0; i < countRegs; i++) {
-            interference.add(SetFactory.makeInterferenceSet(countRegs));
-        }
-    }
-
-    /**
-     * Adds a register pair to the interference/liveness graph. Parameter
-     * order is insignificant.
-     *
-     * @param regV one register index
-     * @param regW another register index
-     */
-    public void add(int regV, int regW) {
-        ensureCapacity(Math.max(regV, regW) + 1);
-
-        interference.get(regV).add(regW);
-        interference.get(regW).add(regV);
-    }
-
-    /**
-     * Dumps interference graph to stdout for debugging.
-     */
-    public void dumpToStdout() {
-        int oldRegCount = interference.size();
-
-        for (int i = 0; i < oldRegCount; i++) {
-            StringBuilder sb = new StringBuilder();
-
-            sb.append("Reg " + i + ":" + interference.get(i).toString());
-
-            System.out.println(sb.toString());
-        }
-    }
-
-    /**
-     * Merges the interference set for a register into a given bit set
-     *
-     * @param reg {@code >= 0;} register
-     * @param set {@code non-null;} interference set; will be merged
-     * with set for given register
-     */
-    public void mergeInterferenceSet(int reg, IntSet set) {
-        if (reg < interference.size()) {
-            set.merge(interference.get(reg));
-        }
-    }
-
-    /**
-     * Ensures that the interference graph is appropriately sized.
-     *
-     * @param size requested minumum size
-     */
-    private void ensureCapacity(int size) {
-        int countRegs = interference.size();
-
-        interference.ensureCapacity(size);
-
-        for (int i = countRegs; i < size; i++) {
-            interference.add(SetFactory.makeInterferenceSet(size));
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/LivenessAnalyzer.java b/dx/src/main/java/com/android/dx/ssa/back/LivenessAnalyzer.java
deleted file mode 100644
index a293e6f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/LivenessAnalyzer.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.ssa.SsaBasicBlock;
-import com.android.dx.ssa.SsaInsn;
-import com.android.dx.ssa.PhiInsn;
-import com.android.dx.rop.code.RegisterSpec;
-
-import java.util.BitSet;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * From Appel "Modern Compiler Implementation in Java" algorithm 19.17
- * Calculate the live ranges for register {@code reg}.<p>
- *
- * v = regV <p>
- * s = insn <p>
- * M = visitedBlocks <p>
- */
-public class LivenessAnalyzer {
-    /**
-     * {@code non-null;} index by basic block indexed set of basic blocks
-     * that have already been visited. "M" as written in the original Appel
-     * algorithm.
-     */
-    private final BitSet visitedBlocks;
-
-    /**
-     * {@code non-null;} set of blocks remaing to visit as "live out as block"
-     */
-    private final BitSet liveOutBlocks;
-
-    /**
-     * {@code >=0;} SSA register currently being analyzed.
-     * "v" in the original Appel algorithm.
-     */
-    private final int regV;
-
-    /** method to process */
-    private final SsaMethod ssaMeth;
-
-    /** interference graph being updated */
-    private final InterferenceGraph interference;
-
-    /** block "n" in Appel 19.17 */
-    private SsaBasicBlock blockN;
-
-    /** index of statement {@code s} in {@code blockN} */
-    private int statementIndex;
-
-    /** the next function to call */
-    private NextFunction nextFunction;
-
-    /** constants for {@link #nextFunction} */
-    private static enum NextFunction {
-        LIVE_IN_AT_STATEMENT,
-            LIVE_OUT_AT_STATEMENT,
-            LIVE_OUT_AT_BLOCK,
-            DONE;
-    }
-
-    /**
-     * Runs register liveness algorithm for a method, updating the
-     * live in/out information in {@code SsaBasicBlock} instances and
-     * returning an interference graph.
-     *
-     * @param ssaMeth {@code non-null;} method to process
-     * @return {@code non-null;} interference graph indexed by SSA
-     * registers in both directions
-     */
-    public static InterferenceGraph constructInterferenceGraph(
-            SsaMethod ssaMeth) {
-        int szRegs = ssaMeth.getRegCount();
-        InterferenceGraph interference = new InterferenceGraph(szRegs);
-
-        for (int i = 0; i < szRegs; i++) {
-            new LivenessAnalyzer(ssaMeth, i, interference).run();
-        }
-
-        coInterferePhis(ssaMeth, interference);
-
-        return interference;
-    }
-
-    /**
-     * Makes liveness analyzer instance for specific register.
-     *
-     * @param ssaMeth {@code non-null;} method to process
-     * @param reg register whose liveness to analyze
-     * @param interference {@code non-null;} indexed by SSA reg in
-     * both dimensions; graph to update
-     *
-     */
-    private LivenessAnalyzer(SsaMethod ssaMeth, int reg,
-            InterferenceGraph interference) {
-        int blocksSz = ssaMeth.getBlocks().size();
-
-        this.ssaMeth = ssaMeth;
-        this.regV = reg;
-        visitedBlocks = new BitSet(blocksSz);
-        liveOutBlocks = new BitSet(blocksSz);
-        this.interference = interference;
-    }
-
-    /**
-     * The algorithm in Appel is presented in partial tail-recursion
-     * form. Obviously, that's not efficient in java, so this function
-     * serves as the dispatcher instead.
-     */
-    private void handleTailRecursion() {
-        while (nextFunction != NextFunction.DONE) {
-            switch (nextFunction) {
-                case LIVE_IN_AT_STATEMENT:
-                    nextFunction = NextFunction.DONE;
-                    liveInAtStatement();
-                    break;
-
-                case LIVE_OUT_AT_STATEMENT:
-                    nextFunction = NextFunction.DONE;
-                    liveOutAtStatement();
-                    break;
-
-                case LIVE_OUT_AT_BLOCK:
-                    nextFunction = NextFunction.DONE;
-                    liveOutAtBlock();
-                    break;
-
-                default:
-            }
-        }
-    }
-
-    /**
-     * From Appel algorithm 19.17.
-     */
-    public void run() {
-        List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);
-
-        for (SsaInsn insn : useList) {
-            nextFunction = NextFunction.DONE;
-
-            if (insn instanceof PhiInsn) {
-                // If s is a phi-function with V as it's ith argument.
-                PhiInsn phi = (PhiInsn) insn;
-
-                for (SsaBasicBlock pred :
-                         phi.predBlocksForReg(regV, ssaMeth)) {
-                    blockN = pred;
-
-                    nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
-                    handleTailRecursion();
-                }
-            } else {
-                blockN = insn.getBlock();
-                statementIndex = blockN.getInsns().indexOf(insn);
-
-                if (statementIndex < 0) {
-                    throw new RuntimeException(
-                            "insn not found in it's own block");
-                }
-
-                nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
-                handleTailRecursion();
-            }
-        }
-
-        int nextLiveOutBlock;
-        while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {
-            blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);
-            liveOutBlocks.clear(nextLiveOutBlock);
-            nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
-            handleTailRecursion();
-        }
-    }
-
-    /**
-     * "v is live-out at n."
-     */
-    private void liveOutAtBlock() {
-        if (! visitedBlocks.get(blockN.getIndex())) {
-            visitedBlocks.set(blockN.getIndex());
-
-            blockN.addLiveOut(regV);
-
-            ArrayList<SsaInsn> insns;
-
-            insns = blockN.getInsns();
-
-            // Live out at last statement in blockN
-            statementIndex = insns.size() - 1;
-            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
-        }
-    }
-
-    /**
-     * "v is live-in at s."
-     */
-    private void liveInAtStatement() {
-        // if s is the first statement in block N
-        if (statementIndex == 0) {
-            // v is live-in at n
-            blockN.addLiveIn(regV);
-
-            BitSet preds = blockN.getPredecessors();
-
-            liveOutBlocks.or(preds);
-        } else {
-            // Let s' be the statement preceeding s
-            statementIndex -= 1;
-            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
-        }
-    }
-
-    /**
-     * "v is live-out at s."
-     */
-    private void liveOutAtStatement() {
-        SsaInsn statement = blockN.getInsns().get(statementIndex);
-        RegisterSpec rs = statement.getResult();
-
-        if (!statement.isResultReg(regV)) {
-            if (rs != null) {
-                interference.add(regV, rs.getReg());
-            }
-            nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
-        }
-    }
-
-    /**
-     * Ensures that all the phi result registers for all the phis in the
-     * same basic block interfere with each other. This is needed since
-     * the dead code remover has allowed through "dead-end phis" whose
-     * results are not used except as local assignments. Without this step,
-     * a the result of a dead-end phi might be assigned the same register
-     * as the result of another phi, and the phi removal move scheduler may
-     * generate moves that over-write the live result.
-     *
-     * @param ssaMeth {@code non-null;} method to pricess
-     * @param interference {@code non-null;} interference graph
-     */
-    private static void coInterferePhis(SsaMethod ssaMeth,
-            InterferenceGraph interference) {
-        for (SsaBasicBlock b : ssaMeth.getBlocks()) {
-            List<SsaInsn> phis = b.getPhiInsns();
-
-            int szPhis = phis.size();
-
-            for (int i = 0; i < szPhis; i++) {
-                for (int j = 0; j < szPhis; j++) {
-                    if (i == j) {
-                        continue;
-                    }
-
-                    interference.add(phis.get(i).getResult().getReg(),
-                        phis.get(j).getResult().getReg());
-                }
-            }
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/NullRegisterAllocator.java b/dx/src/main/java/com/android/dx/ssa/back/NullRegisterAllocator.java
deleted file mode 100644
index 0205c11..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/NullRegisterAllocator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.ssa.BasicRegisterMapper;
-import com.android.dx.ssa.RegisterMapper;
-import com.android.dx.ssa.SsaMethod;
-
-import java.util.BitSet;
-import java.util.ArrayList;
-
-/**
- * A register allocator that maps SSA register n to Rop register 2*n,
- * essentially preserving the original mapping and remaining agnostic
- * about normal or wide categories. Used for debugging.
- */
-public class NullRegisterAllocator extends RegisterAllocator {
-    /** {@inheritDoc} */
-    public NullRegisterAllocator(SsaMethod ssaMeth,
-            InterferenceGraph interference) {
-        super(ssaMeth, interference);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean wantsParamsMovedHigh() {
-        // We're not smart enough for this.
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public RegisterMapper allocateRegisters() {
-        int oldRegCount = ssaMeth.getRegCount();
-
-        BasicRegisterMapper mapper = new BasicRegisterMapper(oldRegCount);
-
-        for (int i = 0; i < oldRegCount; i++) {
-            mapper.addMapping(i, i*2, 2);
-        }
-
-        return mapper;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/RegisterAllocator.java b/dx/src/main/java/com/android/dx/ssa/back/RegisterAllocator.java
deleted file mode 100644
index 1f9f70f..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/RegisterAllocator.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.rop.code.RegOps;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.ssa.NormalSsaInsn;
-import com.android.dx.ssa.RegisterMapper;
-import com.android.dx.ssa.SsaInsn;
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.ssa.SsaBasicBlock;
-import com.android.dx.util.IntSet;
-import com.android.dx.util.IntIterator;
-
-import java.util.BitSet;
-import java.util.ArrayList;
-
-/**
- * Base class of all register allocators.
- */
-public abstract class RegisterAllocator {
-    /** method being processed */
-    protected final SsaMethod ssaMeth;
-
-    /** interference graph, indexed by register in both dimensions */
-    protected final InterferenceGraph interference;
-
-    /**
-     * Creates an instance. Call {@code allocateRegisters} to run.
-     * @param ssaMeth method to process.
-     * @param interference Interference graph, indexed by register in both
-     * dimensions.
-     */
-    public RegisterAllocator(SsaMethod ssaMeth,
-            InterferenceGraph interference) {
-        this.ssaMeth = ssaMeth;
-        this.interference = interference;
-    }
-
-    /**
-     * Indicates whether the method params were allocated at the bottom
-     * of the namespace, and thus should be moved up to the top of the
-     * namespace after phi removal.
-     *
-     * @return {@code true} if params should be moved from low to high
-     */
-    public abstract boolean wantsParamsMovedHigh();
-
-    /**
-     * Runs the algorithm.
-     *
-     * @return a register mapper to apply to the {@code SsaMethod}
-     */
-    public abstract RegisterMapper allocateRegisters();
-
-    /**
-     * Returns the category (width) of the definition site of the register.
-     * Returns {@code 1} for undefined registers.
-     *
-     * @param reg register
-     * @return {@code 1..2}
-     */
-    protected final int getCategoryForSsaReg(int reg) {
-        SsaInsn definition = ssaMeth.getDefinitionForRegister(reg);
-
-        if (definition == null) {
-            // an undefined reg
-            return 1;
-        } else {
-            return definition.getResult().getCategory();
-        }
-    }
-
-    /**
-     * Returns the RegisterSpec of the definition of the register.
-     *
-     * @param reg {@code >= 0;} SSA register
-     * @return definition spec of the register or null if it is never defined
-     * (for the case of "version 0" SSA registers)
-     */
-    protected final RegisterSpec getDefinitionSpecForSsaReg(int reg) {
-        SsaInsn definition = ssaMeth.getDefinitionForRegister(reg);
-
-        return definition == null ? null : definition.getResult();
-    }
-
-    /**
-     * Returns true if the definition site of this register is a
-     * move-param (ie, this is a method parameter).
-     *
-     * @param reg register in question
-     * @return {@code true} if this is a method parameter
-     */
-    protected boolean isDefinitionMoveParam(int reg) {
-        SsaInsn defInsn = ssaMeth.getDefinitionForRegister(reg);
-
-        if (defInsn instanceof NormalSsaInsn) {
-            NormalSsaInsn ndefInsn = (NormalSsaInsn) defInsn;
-
-            return ndefInsn.getOpcode().getOpcode() == RegOps.MOVE_PARAM;
-        }
-
-        return false;
-    }
-
-    /**
-     * Inserts a move instruction for a specified SSA register before a
-     * specified instruction, creating a new SSA register and adjusting the
-     * interference graph in the process. The insn currently must be the
-     * last insn in a block.
-     *
-     * @param insn {@code non-null;} insn to insert move before, must
-     * be last insn in block
-     * @param reg {@code non-null;} SSA register to duplicate
-     * @return {@code non-null;} spec of new SSA register created by move
-     */
-    protected final RegisterSpec insertMoveBefore(SsaInsn insn,
-            RegisterSpec reg) {
-        SsaBasicBlock block = insn.getBlock();
-        ArrayList<SsaInsn> insns = block.getInsns();
-        int insnIndex = insns.indexOf(insn);
-
-        if (insnIndex < 0) {
-            throw new IllegalArgumentException (
-                    "specified insn is not in this block");
-        }
-
-        if (insnIndex != insns.size() - 1) {
-            /*
-             * Presently, the interference updater only works when
-             * adding before the last insn, and the last insn must have no
-             * result
-             */
-            throw new IllegalArgumentException(
-                    "Adding move here not supported:" + insn.toHuman());
-        }
-
-        /*
-         * Get new register and make new move instruction.
-         */
-
-        // The new result must not have an associated local variable.
-        RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(),
-                reg.getTypeBearer());
-
-        SsaInsn toAdd = SsaInsn.makeFromRop(
-                new PlainInsn(Rops.opMove(newRegSpec.getType()),
-                        SourcePosition.NO_INFO, newRegSpec,
-                        RegisterSpecList.make(reg)), block);
-
-        insns.add(insnIndex, toAdd);
-
-        int newReg = newRegSpec.getReg();
-
-        /*
-         * Adjust interference graph based on what's live out of the current
-         * block and what's used by the final instruction.
-         */
-
-        IntSet liveOut = block.getLiveOutRegs();
-        IntIterator liveOutIter = liveOut.iterator();
-
-        while (liveOutIter.hasNext()) {
-            interference.add(newReg, liveOutIter.next());
-        }
-
-        // Everything that's a source in the last insn interferes.
-        RegisterSpecList sources = insn.getSources();
-        int szSources = sources.size();
-
-        for (int i = 0; i < szSources; i++) {
-            interference.add(newReg, sources.get(i).getReg());
-        }
-
-        ssaMeth.onInsnsChanged();
-
-        return newRegSpec;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/ssa/back/SsaToRop.java b/dx/src/main/java/com/android/dx/ssa/back/SsaToRop.java
deleted file mode 100644
index 0e30250..0000000
--- a/dx/src/main/java/com/android/dx/ssa/back/SsaToRop.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2007 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.ssa.back;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.ssa.BasicRegisterMapper;
-import com.android.dx.ssa.PhiInsn;
-import com.android.dx.ssa.RegisterMapper;
-import com.android.dx.ssa.SsaBasicBlock;
-import com.android.dx.ssa.SsaInsn;
-import com.android.dx.ssa.SsaMethod;
-import com.android.dx.util.Hex;
-import com.android.dx.util.IntList;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Comparator;
-
-/**
- * Converts a method in SSA form to ROP form.
- */
-public class SsaToRop {
-    /** local debug flag */
-    private static final boolean DEBUG = false;
-
-    /** {@code non-null;} method to process */
-    private final SsaMethod ssaMeth;
-
-    /**
-     * {@code true} if the converter should attempt to minimize
-     * the rop-form register count
-     */
-    private final boolean minimizeRegisters;
-
-    /** {@code non-null;} interference graph */
-    private final InterferenceGraph interference;
-
-    /**
-     * Converts a method in SSA form to ROP form.
-     *
-     * @param ssaMeth {@code non-null;} method to process
-     * @param minimizeRegisters {@code true} if the converter should
-     * attempt to minimize the rop-form register count
-     * @return {@code non-null;} rop-form output
-     */
-    public static RopMethod convertToRopMethod(SsaMethod ssaMeth,
-            boolean minimizeRegisters) {
-        return new SsaToRop(ssaMeth, minimizeRegisters).convert();
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param ssaMeth {@code non-null;} method to process
-     * @param minimizeRegisters {@code true} if the converter should
-     * attempt to minimize the rop-form register count
-     */
-    private SsaToRop(SsaMethod ssaMethod, boolean minimizeRegisters) {
-        this.minimizeRegisters = minimizeRegisters;
-        this.ssaMeth = ssaMethod;
-        this.interference =
-            LivenessAnalyzer.constructInterferenceGraph(ssaMethod);
-    }
-
-    /**
-     * Performs the conversion.
-     *
-     * @return {@code non-null;} rop-form output
-     */
-    private RopMethod convert() {
-        if (DEBUG) {
-            interference.dumpToStdout();
-        }
-
-        // These are other allocators for debugging or historical comparison:
-        // allocator = new NullRegisterAllocator(ssaMeth, interference);
-        // allocator = new FirstFitAllocator(ssaMeth, interference);
-
-        RegisterAllocator allocator =
-            new FirstFitLocalCombiningAllocator(ssaMeth, interference,
-                    minimizeRegisters);
-
-        RegisterMapper mapper = allocator.allocateRegisters();
-
-        if (DEBUG) {
-            System.out.println("Printing reg map");
-            System.out.println(((BasicRegisterMapper)mapper).toHuman());
-        }
-
-        ssaMeth.setBackMode();
-
-        ssaMeth.mapRegisters(mapper);
-
-        removePhiFunctions();
-
-        if (allocator.wantsParamsMovedHigh()) {
-            moveParametersToHighRegisters();
-        }
-
-        removeEmptyGotos();
-
-        RopMethod ropMethod = new RopMethod(convertBasicBlocks(),
-                ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex()));
-        ropMethod = new IdenticalBlockCombiner(ropMethod).process();
-
-        return ropMethod;
-    }
-
-    /**
-     * Removes all blocks containing only GOTOs from the control flow.
-     * Although much of this work will be done later when converting
-     * from rop to dex, not all simplification cases can be handled
-     * there. Furthermore, any no-op block between the exit block and
-     * blocks containing the real return or throw statements must be
-     * removed.
-     */
-    private void removeEmptyGotos() {
-        final ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
-
-        ssaMeth.forEachBlockDepthFirst(false, new SsaBasicBlock.Visitor() {
-            public void visitBlock(SsaBasicBlock b, SsaBasicBlock parent) {
-                ArrayList<SsaInsn> insns = b.getInsns();
-
-                if ((insns.size() == 1)
-                        && (insns.get(0).getOpcode() == Rops.GOTO)) {
-                    BitSet preds = (BitSet) b.getPredecessors().clone();
-
-                    for (int i = preds.nextSetBit(0); i >= 0;
-                            i = preds.nextSetBit(i + 1)) {
-                        SsaBasicBlock pb = blocks.get(i);
-                        pb.replaceSuccessor(b.getIndex(),
-                                b.getPrimarySuccessorIndex());
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * See Appel 19.6. To remove the phi instructions in an edge-split
-     * SSA representation we know we can always insert a move in a
-     * predecessor block.
-     */
-    private void removePhiFunctions() {
-        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
-
-        for (SsaBasicBlock block : blocks) {
-            // Add moves in all the pred blocks for each phi insn.
-            block.forEachPhiInsn(new PhiVisitor(blocks));
-
-            // Delete the phi insns.
-            block.removeAllPhiInsns();
-        }
-
-        /*
-         * After all move insns have been added, sort them so they don't
-         * destructively interfere.
-         */
-        for (SsaBasicBlock block : blocks) {
-            block.scheduleMovesFromPhis();
-        }
-    }
-
-    /**
-     * Helper for {@link #removePhiFunctions}: PhiSuccessorUpdater for
-     * adding move instructions to predecessors based on phi insns.
-     */
-    private static class PhiVisitor implements PhiInsn.Visitor {
-        private final ArrayList<SsaBasicBlock> blocks;
-
-        public PhiVisitor(ArrayList<SsaBasicBlock> blocks) {
-            this.blocks = blocks;
-        }
-
-        public void visitPhiInsn(PhiInsn insn) {
-            RegisterSpecList sources = insn.getSources();
-            RegisterSpec result = insn.getResult();
-            int sz = sources.size();
-
-            for (int i = 0; i < sz; i++) {
-                RegisterSpec source = sources.get(i);
-                SsaBasicBlock predBlock = blocks.get(
-                        insn.predBlockIndexForSourcesIndex(i));
-
-                predBlock.addMoveToEnd(result, source);
-            }
-        }
-    }
-
-    /**
-     * Moves the parameter registers, which allocateRegisters() places
-     * at the bottom of the frame, up to the top of the frame to match
-     * Dalvik calling convention.
-     */
-    private void moveParametersToHighRegisters() {
-        int paramWidth = ssaMeth.getParamWidth();
-        BasicRegisterMapper mapper
-                = new BasicRegisterMapper(ssaMeth.getRegCount());
-        int regCount = ssaMeth.getRegCount();
-
-        for (int i = 0; i < regCount; i++) {
-            if (i < paramWidth) {
-                mapper.addMapping(i, regCount - paramWidth + i, 1);
-            } else {
-                mapper.addMapping(i, i - paramWidth, 1);
-            }
-        }
-
-        if (DEBUG) {
-            System.out.printf("Moving %d registers from 0 to %d\n",
-                    paramWidth, regCount - paramWidth);
-        }
-
-        ssaMeth.mapRegisters(mapper);
-    }
-
-    /**
-     * @return rop-form basic block list
-     */
-    private BasicBlockList convertBasicBlocks() {
-        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
-
-        // Exit block may be null.
-        SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
-
-        ssaMeth.computeReachability();
-        int ropBlockCount = ssaMeth.getCountReachableBlocks();
-
-        // Don't count the exit block, if it exists and is reachable.
-        ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;
-
-        BasicBlockList result = new BasicBlockList(ropBlockCount);
-
-        // Convert all the reachable blocks except the exit block.
-        int ropBlockIndex = 0;
-        for (SsaBasicBlock b : blocks) {
-            if (b.isReachable() && b != exitBlock) {
-                result.set(ropBlockIndex++, convertBasicBlock(b));
-            }
-        }
-
-        // The exit block, which is discarded, must do nothing.
-        if (exitBlock != null && exitBlock.getInsns().size() != 0) {
-            throw new RuntimeException(
-                    "Exit block must have no insns when leaving SSA form");
-        }
-
-        return result;
-    }
-
-    /**
-     * Validates that a basic block is a valid end predecessor. It must
-     * end in a RETURN or a THROW. Throws a runtime exception on error.
-     *
-     * @param b {@code non-null;} block to validate
-     * @throws RuntimeException on error
-     */
-    private void verifyValidExitPredecessor(SsaBasicBlock b) {
-        ArrayList<SsaInsn> insns = b.getInsns();
-        SsaInsn lastInsn = insns.get(insns.size() - 1);
-        Rop opcode = lastInsn.getOpcode();
-
-        if (opcode.getBranchingness() != Rop.BRANCH_RETURN
-                && opcode != Rops.THROW) {
-            throw new RuntimeException("Exit predecessor must end"
-                    + " in valid exit statement.");
-        }
-    }
-
-    /**
-     * Converts a single basic block to rop form.
-     *
-     * @param block SSA block to process
-     * @return {@code non-null;} ROP block
-     */
-    private BasicBlock convertBasicBlock(SsaBasicBlock block) {
-        IntList successorList = block.getRopLabelSuccessorList();
-        int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();
-
-        // Filter out any reference to the SSA form's exit block.
-
-        // Exit block may be null.
-        SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
-        int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();
-
-        if (successorList.contains(exitRopLabel)) {
-            if (successorList.size() > 1) {
-                throw new RuntimeException(
-                        "Exit predecessor must have no other successors"
-                                + Hex.u2(block.getRopLabel()));
-            } else {
-                successorList = IntList.EMPTY;
-                primarySuccessorLabel = -1;
-
-                verifyValidExitPredecessor(block);
-            }
-        }
-
-        successorList.setImmutable();
-
-        BasicBlock result = new BasicBlock(
-                block.getRopLabel(), convertInsns(block.getInsns()),
-                successorList,
-                primarySuccessorLabel);
-
-        return result;
-    }
-
-    /**
-     * Converts an insn list to rop form.
-     *
-     * @param ssaInsns {@code non-null;} old instructions
-     * @return {@code non-null;} immutable instruction list
-     */
-    private InsnList convertInsns(ArrayList<SsaInsn> ssaInsns) {
-        int insnCount = ssaInsns.size();
-        InsnList result = new InsnList(insnCount);
-
-        for (int i = 0; i < insnCount; i++) {
-            result.set(i, ssaInsns.get(i).toRopInsn());
-        }
-
-        result.setImmutable();
-
-        return result;
-    }
-
-    /**
-     * <b>Note:</b> This method is not presently used.
-     *
-     * @return a list of registers ordered by most-frequently-used to
-     * least-frequently-used. Each register is listed once and only
-     * once.
-     */
-    public int[] getRegistersByFrequency() {
-        int regCount = ssaMeth.getRegCount();
-        Integer[] ret = new Integer[regCount];
-
-        for (int i = 0; i < regCount; i++) {
-            ret[i] = i;
-        }
-
-        Arrays.sort(ret, new Comparator<Integer>() {
-            public int compare(Integer o1, Integer o2) {
-                return ssaMeth.getUseListForRegister(o2).size()
-                        - ssaMeth.getUseListForRegister(o1).size();
-            }
-        });
-
-        int result[] = new int[regCount];
-
-        for (int i = 0; i < regCount; i++) {
-            result[i] = ret[i];
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/AnnotatedOutput.java b/dx/src/main/java/com/android/dx/util/AnnotatedOutput.java
deleted file mode 100644
index 7a9ea29..0000000
--- a/dx/src/main/java/com/android/dx/util/AnnotatedOutput.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Interface for a binary output destination that may be augmented
- * with textual annotations.
- */
-public interface AnnotatedOutput
-        extends Output {
-    /**
-     * Get whether this instance will actually keep annotations.
-     *
-     * @return {@code true} iff annotations are being kept
-     */
-    public boolean annotates();
-
-    /**
-     * Get whether this instance is intended to keep verbose annotations.
-     * Annotators may use the result of calling this method to inform their
-     * annotation activity.
-     *
-     * @return {@code true} iff annotations are to be verbose
-     */
-    public boolean isVerbose();
-
-    /**
-     * Add an annotation for the subsequent output. Any previously
-     * open annotation will be closed by this call, and the new
-     * annotation marks all subsequent output until another annotation
-     * call.
-     *
-     * @param msg {@code non-null;} the annotation message
-     */
-    public void annotate(String msg);
-
-    /**
-     * Add an annotation for a specified amount of subsequent
-     * output. Any previously open annotation will be closed by this
-     * call. If there is already pending annotation from one or more
-     * previous calls to this method, the new call "consumes" output
-     * after all the output covered by the previous calls.
-     *
-     * @param amt {@code >= 0;} the amount of output for this annotation to
-     * cover
-     * @param msg {@code non-null;} the annotation message
-     */
-    public void annotate(int amt, String msg);
-
-    /**
-     * End the most recent annotation. Subsequent output will be unannotated,
-     * until the next call to {@link #annotate}.
-     */
-    public void endAnnotation();
-
-    /**
-     * Get the maximum width of the annotated output. This is advisory:
-     * Implementations of this interface are encouraged to deal with too-wide
-     * output, but annotaters are encouraged to attempt to avoid exceeding
-     * the indicated width.
-     *
-     * @return {@code >= 1;} the maximum width
-     */
-    public int getAnnotationWidth();
-}
diff --git a/dx/src/main/java/com/android/dx/util/BitIntSet.java b/dx/src/main/java/com/android/dx/util/BitIntSet.java
deleted file mode 100644
index b364f0c..0000000
--- a/dx/src/main/java/com/android/dx/util/BitIntSet.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-import java.util.NoSuchElementException;
-
-/**
- * A set of integers, represented by a bit set
- */
-public class BitIntSet implements IntSet {
-
-    /** also accessed in ListIntSet */
-    int[] bits;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param max the maximum value of ints in this set.
-     */
-    public BitIntSet(int max) {
-        bits = Bits.makeBitSet(max);
-    }
-
-    /** @inheritDoc */
-    public void add(int value) {
-        ensureCapacity(value);
-        Bits.set(bits, value, true);
-    }
-
-    /**
-     * Ensures that the bit set has the capacity to represent the given value.
-     *
-     * @param value {@code >= 0;} value to represent
-     */
-    private void ensureCapacity(int value) {
-        if (value >= Bits.getMax(bits)) {
-            int[] newBits = Bits.makeBitSet(
-                    Math.max(value + 1, 2 * Bits.getMax(bits)));
-            System.arraycopy(bits, 0, newBits, 0, bits.length);
-            bits = newBits;
-        }
-    }
-
-    /** @inheritDoc */
-    public void remove(int value) {
-        if (value < Bits.getMax(bits)) {
-            Bits.set(bits, value, false);
-        }
-    }
-
-    /** @inheritDoc */
-    public boolean has(int value) {
-        return (value < Bits.getMax(bits)) && Bits.get(bits, value);
-    }
-
-    /** @inheritDoc */
-    public void merge(IntSet other) {
-        if (other instanceof BitIntSet) {
-            BitIntSet o = (BitIntSet) other;
-            ensureCapacity(Bits.getMax(o.bits) + 1);
-            Bits.or(bits, o.bits);
-        } else if (other instanceof ListIntSet) {
-            ListIntSet o = (ListIntSet) other;
-            int sz = o.ints.size();
-
-            if (sz > 0) {
-                ensureCapacity(o.ints.get(sz - 1));
-            }
-            for (int i = 0; i < o.ints.size(); i++) {
-                Bits.set(bits, o.ints.get(i), true);
-            }
-        } else {
-            IntIterator iter = other.iterator();
-            while (iter.hasNext()) {
-                add(iter.next());
-            }
-        }
-    }
-
-    /** @inheritDoc */
-    public int elements() {
-        return Bits.bitCount(bits);
-    }
-
-    /** @inheritDoc */
-    public IntIterator iterator() {
-        return new IntIterator() {
-            private int idx = Bits.findFirst(bits, 0);
-
-            /** @inheritDoc */
-            public boolean hasNext() {
-                return idx >= 0;
-            }
-
-            /** @inheritDoc */
-            public int next() {
-                if (!hasNext()) {
-                    throw new NoSuchElementException();
-                }
-
-                int ret = idx;
-
-                idx = Bits.findFirst(bits, idx+1);
-
-                return ret;
-            }
-        };
-    }
-
-    /** @inheritDoc */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append('{');
-
-        boolean first = true;
-        for (int i = Bits.findFirst(bits, 0)
-                ; i >= 0
-                ; i = Bits.findFirst(bits, i + 1)) {
-            if (!first) {
-                sb.append(", ");
-            }
-            first = false;
-            sb.append(i);
-        }
-
-        sb.append('}');
-
-        return sb.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Bits.java b/dx/src/main/java/com/android/dx/util/Bits.java
deleted file mode 100644
index cbc0a5b..0000000
--- a/dx/src/main/java/com/android/dx/util/Bits.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Utilities for treating {@code int[]}s as bit sets.
- */
-public final class Bits {
-    /**
-     * This class is uninstantiable.
-     */
-    private Bits() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Constructs a bit set to contain bits up to the given index (exclusive).
-     *
-     * @param max {@code >= 0;} the maximum bit index (exclusive)
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public static int[] makeBitSet(int max) {
-        int size = (max + 0x1f) >> 5;
-        return new int[size];
-    }
-
-    /**
-     * Gets the maximum index (exclusive) for the given bit set.
-     *
-     * @param bits {@code non-null;} bit set in question
-     * @return {@code >= 0;} the maximum index (exclusive) that may be set
-     */
-    public static int getMax(int[] bits) {
-        return bits.length * 0x20;
-    }
-
-    /**
-     * Gets the value of the bit at the given index.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param idx {@code >= 0, < getMax(set);} which bit
-     * @return the value of the indicated bit
-     */
-    public static boolean get(int[] bits, int idx) {
-        int arrayIdx = idx >> 5;
-        int bit = 1 << (idx & 0x1f);
-        return (bits[arrayIdx] & bit) != 0;
-    }
-
-    /**
-     * Sets the given bit to the given value.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param idx {@code >= 0, < getMax(set);} which bit
-     * @param value the new value for the bit
-     */
-    public static void set(int[] bits, int idx, boolean value) {
-        int arrayIdx = idx >> 5;
-        int bit = 1 << (idx & 0x1f);
-
-        if (value) {
-            bits[arrayIdx] |= bit;
-        } else {
-            bits[arrayIdx] &= ~bit;
-        }
-    }
-
-    /**
-     * Sets the given bit to {@code true}.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param idx {@code >= 0, < getMax(set);} which bit
-     */
-    public static void set(int[] bits, int idx) {
-        int arrayIdx = idx >> 5;
-        int bit = 1 << (idx & 0x1f);
-        bits[arrayIdx] |= bit;
-    }
-
-    /**
-     * Sets the given bit to {@code false}.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param idx {@code >= 0, < getMax(set);} which bit
-     */
-    public static void clear(int[] bits, int idx) {
-        int arrayIdx = idx >> 5;
-        int bit = 1 << (idx & 0x1f);
-        bits[arrayIdx] &= ~bit;
-    }
-
-    /**
-     * Returns whether or not the given bit set is empty, that is, whether
-     * no bit is set to {@code true}.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @return {@code true} iff all bits are {@code false}
-     */
-    public static boolean isEmpty(int[] bits) {
-        int len = bits.length;
-
-        for (int i = 0; i < len; i++) {
-            if (bits[i] != 0) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Gets the number of bits set to {@code true} in the given bit set.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @return {@code >= 0;} the bit count (aka population count) of the set
-     */
-    public static int bitCount(int[] bits) {
-        int len = bits.length;
-        int count = 0;
-
-        for (int i = 0; i < len; i++) {
-            count += Integer.bitCount(bits[i]);
-        }
-
-        return count;
-    }
-
-    /**
-     * Returns whether any bits are set to {@code true} in the
-     * specified range.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param start {@code >= 0;} index of the first bit in the range (inclusive)
-     * @param end {@code >= 0;} index of the last bit in the range (exclusive)
-     * @return {@code true} if any bit is set to {@code true} in
-     * the indicated range
-     */
-    public static boolean anyInRange(int[] bits, int start, int end) {
-        int idx = findFirst(bits, start);
-        return (idx >= 0) && (idx < end);
-    }
-
-    /**
-     * Finds the lowest-order bit set at or after the given index in the
-     * given bit set.
-     *
-     * @param bits {@code non-null;} bit set to operate on
-     * @param idx {@code >= 0;} minimum index to return
-     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
-     * or {@code -1} if there is no appropriate bit index to return
-     */
-    public static int findFirst(int[] bits, int idx) {
-        int len = bits.length;
-        int minBit = idx & 0x1f;
-
-        for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) {
-            int word = bits[arrayIdx];
-            if (word != 0) {
-                int bitIdx = findFirst(word, minBit);
-                if (bitIdx >= 0) {
-                    return (arrayIdx << 5) + bitIdx;
-                }
-            }
-            minBit = 0;
-        }
-
-        return -1;
-    }
-
-    /**
-     * Finds the lowest-order bit set at or after the given index in the
-     * given {@code int}.
-     *
-     * @param value the value in question
-     * @param idx 0..31 the minimum bit index to return
-     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
-     * or {@code -1} if there is no appropriate bit index to return
-     */
-    public static int findFirst(int value, int idx) {
-        value &= ~((1 << idx) - 1); // Mask off too-low bits.
-        int result = Integer.numberOfTrailingZeros(value);
-        return (result == 32) ? -1 : result;
-    }
-
-    /**
-     * Ors bit array {@code b} into bit array {@code a}.
-     * {@code a.length} must be greater than or equal to
-     * {@code b.length}.
-     *
-     * @param a {@code non-null;} int array to be ored with other argument. This
-     * argument is modified.
-     * @param b {@code non-null;} int array to be ored into {@code a}. This
-     * argument is not modified.
-     */
-    public static void or(int[] a, int[] b) {
-        for (int i = 0; i < b.length; i++) {
-            a[i] |= b[i];
-        }
-    }
-
-    public static String toHuman(int[] bits) {
-        StringBuilder sb = new StringBuilder();
-
-        boolean needsComma = false;
-
-        sb.append('{');
-
-        int bitsLength = 32 * bits.length;
-        for (int i = 0; i < bitsLength; i++) {
-            if (Bits.get(bits, i)) {
-                if (needsComma) {
-                    sb.append(',');
-                }
-                needsComma = true;
-                sb.append(i);
-            }
-        }
-        sb.append('}');
-
-        return sb.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ByteArray.java b/dx/src/main/java/com/android/dx/util/ByteArray.java
deleted file mode 100644
index 21d0457..0000000
--- a/dx/src/main/java/com/android/dx/util/ByteArray.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Wrapper for a {@code byte[]}, which provides read-only access and
- * can "reveal" a partial slice of the underlying array.
- *
- * <b>Note:</b> Multibyte accessors all use big-endian order.
- */
-public final class ByteArray {
-    /** {@code non-null;} underlying array */
-    private final byte[] bytes;
-
-    /** {@code >= 0}; start index of the slice (inclusive) */
-    private final int start;
-
-    /** {@code >= 0, <= bytes.length}; size computed as
-     * {@code end - start} (in the constructor) */
-    private final int size;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param bytes {@code non-null;} the underlying array
-     * @param start {@code >= 0;} start index of the slice (inclusive)
-     * @param end {@code >= start, <= bytes.length;} end index of
-     * the slice (exclusive)
-     */
-    public ByteArray(byte[] bytes, int start, int end) {
-        if (bytes == null) {
-            throw new NullPointerException("bytes == null");
-        }
-
-        if (start < 0) {
-            throw new IllegalArgumentException("start < 0");
-        }
-
-        if (end < start) {
-            throw new IllegalArgumentException("end < start");
-        }
-
-        if (end > bytes.length) {
-            throw new IllegalArgumentException("end > bytes.length");
-        }
-
-        this.bytes = bytes;
-        this.start = start;
-        this.size = end - start;
-    }
-
-    /**
-     * Constructs an instance from an entire {@code byte[]}.
-     *
-     * @param bytes {@code non-null;} the underlying array
-     */
-    public ByteArray(byte[] bytes) {
-        this(bytes, 0, bytes.length);
-    }
-
-    /**
-     * Gets the size of the array, in bytes.
-     *
-     * @return {@code >= 0;} the size
-     */
-    public int size() {
-        return size;
-    }
-
-    /**
-     * Returns a slice (that is, a sub-array) of this instance.
-     *
-     * @param start {@code >= 0;} start index of the slice (inclusive)
-     * @param end {@code >= start, <= size();} end index of
-     * the slice (exclusive)
-     * @return {@code non-null;} the slice
-     */
-    public ByteArray slice(int start, int end) {
-        checkOffsets(start, end);
-        return new ByteArray(bytes, start + this.start, end + this.start);
-    }
-
-    /**
-     * Returns the offset into the given array represented by the given
-     * offset into this instance.
-     *
-     * @param offset offset into this instance
-     * @param bytes {@code non-null;} (alleged) underlying array
-     * @return corresponding offset into {@code bytes}
-     * @throws IllegalArgumentException thrown if {@code bytes} is
-     * not the underlying array of this instance
-     */
-    public int underlyingOffset(int offset, byte[] bytes) {
-        if (bytes != this.bytes) {
-            throw new IllegalArgumentException("wrong bytes");
-        }
-
-        return start + offset;
-    }
-
-    /**
-     * Gets the {@code signed byte} value at a particular offset.
-     *
-     * @param off {@code >= 0, < size();} offset to fetch
-     * @return {@code signed byte} at that offset
-     */
-    public int getByte(int off) {
-        checkOffsets(off, off + 1);
-        return getByte0(off);
-    }
-
-    /**
-     * Gets the {@code signed short} value at a particular offset.
-     *
-     * @param off {@code >= 0, < (size() - 1);} offset to fetch
-     * @return {@code signed short} at that offset
-     */
-    public int getShort(int off) {
-        checkOffsets(off, off + 2);
-        return (getByte0(off) << 8) | getUnsignedByte0(off + 1);
-    }
-
-    /**
-     * Gets the {@code signed int} value at a particular offset.
-     *
-     * @param off {@code >= 0, < (size() - 3);} offset to fetch
-     * @return {@code signed int} at that offset
-     */
-    public int getInt(int off) {
-        checkOffsets(off, off + 4);
-        return (getByte0(off) << 24) |
-            (getUnsignedByte0(off + 1) << 16) |
-            (getUnsignedByte0(off + 2) << 8) |
-            getUnsignedByte0(off + 3);
-    }
-
-    /**
-     * Gets the {@code signed long} value at a particular offset.
-     *
-     * @param off {@code >= 0, < (size() - 7);} offset to fetch
-     * @return {@code signed int} at that offset
-     */
-    public long getLong(int off) {
-        checkOffsets(off, off + 8);
-        int part1 = (getByte0(off) << 24) |
-            (getUnsignedByte0(off + 1) << 16) |
-            (getUnsignedByte0(off + 2) << 8) |
-            getUnsignedByte0(off + 3);
-        int part2 = (getByte0(off + 4) << 24) |
-            (getUnsignedByte0(off + 5) << 16) |
-            (getUnsignedByte0(off + 6) << 8) |
-            getUnsignedByte0(off + 7);
-
-        return (part2 & 0xffffffffL) | ((long) part1) << 32;
-    }
-
-    /**
-     * Gets the {@code unsigned byte} value at a particular offset.
-     *
-     * @param off {@code >= 0, < size();} offset to fetch
-     * @return {@code unsigned byte} at that offset
-     */
-    public int getUnsignedByte(int off) {
-        checkOffsets(off, off + 1);
-        return getUnsignedByte0(off);
-    }
-
-    /**
-     * Gets the {@code unsigned short} value at a particular offset.
-     *
-     * @param off {@code >= 0, < (size() - 1);} offset to fetch
-     * @return {@code unsigned short} at that offset
-     */
-    public int getUnsignedShort(int off) {
-        checkOffsets(off, off + 2);
-        return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1);
-    }
-
-    /**
-     * Copies the contents of this instance into the given raw
-     * {@code byte[]} at the given offset. The given array must be
-     * large enough.
-     *
-     * @param out {@code non-null;} array to hold the output
-     * @param offset {@code non-null;} index into {@code out} for the first
-     * byte of output
-     */
-    public void getBytes(byte[] out, int offset) {
-        if ((out.length - offset) < size) {
-            throw new IndexOutOfBoundsException("(out.length - offset) < " +
-                                                "size()");
-        }
-
-        System.arraycopy(bytes, start, out, offset, size);
-    }
-
-    /**
-     * Checks a range of offsets for validity, throwing if invalid.
-     *
-     * @param s start offset (inclusive)
-     * @param e end offset (exclusive)
-     */
-    private void checkOffsets(int s, int e) {
-        if ((s < 0) || (e < s) || (e > size)) {
-            throw new IllegalArgumentException("bad range: " + s + ".." + e +
-                                               "; actual size " + size);
-        }
-    }
-
-    /**
-     * Gets the {@code signed byte} value at the given offset,
-     * without doing any argument checking.
-     *
-     * @param off offset to fetch
-     * @return byte at that offset
-     */
-    private int getByte0(int off) {
-        return bytes[start + off];
-    }
-
-    /**
-     * Gets the {@code unsigned byte} value at the given offset,
-     * without doing any argument checking.
-     *
-     * @param off offset to fetch
-     * @return byte at that offset
-     */
-    private int getUnsignedByte0(int off) {
-        return bytes[start + off] & 0xff;
-    }
-
-    /**
-     * Gets a {@code DataInputStream} that reads from this instance,
-     * with the cursor starting at the beginning of this instance's data.
-     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}
-     * if needed.
-     *
-     * @return {@code non-null;} an appropriately-constructed
-     * {@code DataInputStream} instance
-     */
-    public MyDataInputStream makeDataInputStream() {
-        return new MyDataInputStream(makeInputStream());
-    }
-
-    /**
-     * Gets a {@code InputStream} that reads from this instance,
-     * with the cursor starting at the beginning of this instance's data.
-     * <b>Note:</b> The returned instance may be cast to {@link #GetCursor}
-     * if needed.
-     *
-     * @return {@code non-null;} an appropriately-constructed
-     * {@code InputStream} instancex
-     */
-    public MyInputStream makeInputStream() {
-        return new MyInputStream();
-    }
-
-    /**
-     * Helper interface that allows one to get the cursor (of a stream).
-     */
-    public interface GetCursor {
-        /**
-         * Gets the current cursor.
-         *
-         * @return {@code 0..size();} the cursor
-         */
-        public int getCursor();
-    }
-
-    /**
-     * Helper class for {@link #makeInputStream}, which implements the
-     * stream functionality.
-     */
-    public class MyInputStream extends InputStream {
-        /** 0..size; the cursor */
-        private int cursor;
-
-        /** 0..size; the mark */
-        private int mark;
-
-        public MyInputStream() {
-            cursor = 0;
-            mark = 0;
-        }
-
-        public int read() throws IOException {
-            if (cursor >= size) {
-                return -1;
-            }
-
-            int result = getUnsignedByte0(cursor);
-            cursor++;
-            return result;
-        }
-
-        public int read(byte[] arr, int offset, int length) {
-            if ((offset + length) > arr.length) {
-                length = arr.length - offset;
-            }
-
-            int maxLength = size - cursor;
-            if (length > maxLength) {
-                length = maxLength;
-            }
-
-            System.arraycopy(bytes, cursor + start, arr, offset, length);
-            cursor += length;
-            return length;
-        }
-
-        public int available() {
-            return size - cursor;
-        }
-
-        public void mark(int reserve) {
-            mark = cursor;
-        }
-
-        public void reset() {
-            cursor = mark;
-        }
-
-        public boolean markSupported() {
-            return true;
-        }
-    }
-
-    /**
-     * Helper class for {@link #makeDataInputStream}. This is used
-     * simply so that the cursor of a wrapped {@link #MyInputStream}
-     * instance may be easily determined.
-     */
-    public static class MyDataInputStream extends DataInputStream {
-        /** {@code non-null;} the underlying {@link #MyInputStream} */
-        private final MyInputStream wrapped;
-
-        public MyDataInputStream(MyInputStream wrapped) {
-            super(wrapped);
-
-            this.wrapped = wrapped;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ByteArrayAnnotatedOutput.java b/dx/src/main/java/com/android/dx/util/ByteArrayAnnotatedOutput.java
deleted file mode 100644
index 05ec733..0000000
--- a/dx/src/main/java/com/android/dx/util/ByteArrayAnnotatedOutput.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-
-/**
- * Implementation of {@link AnnotatedOutput} which stores the written data
- * into a {@code byte[]}.
- *
- * <p><b>Note:</b> As per the {@link Output} interface, multi-byte
- * writes all use little-endian order.</p>
- */
-public final class ByteArrayAnnotatedOutput
-        implements AnnotatedOutput, ByteOutput {
-    /** default size for stretchy instances */
-    private static final int DEFAULT_SIZE = 1000;
-
-    /**
-     * whether the instance is stretchy, that is, whether its array
-     * may be resized to increase capacity
-     */
-    private final boolean stretchy;
-
-    /** {@code non-null;} the data itself */
-    private byte[] data;
-
-    /** {@code >= 0;} current output cursor */
-    private int cursor;
-
-    /** whether annotations are to be verbose */
-    private boolean verbose;
-
-    /**
-     * {@code null-ok;} list of annotations, or {@code null} if this instance
-     * isn't keeping them
-     */
-    private ArrayList<Annotation> annotations;
-
-    /** {@code >= 40 (if used);} the desired maximum annotation width */
-    private int annotationWidth;
-
-    /**
-     * {@code >= 8 (if used);} the number of bytes of hex output to use
-     * in annotations
-     */
-    private int hexCols;
-
-    /**
-     * Constructs an instance with a fixed maximum size. Note that the
-     * given array is the only one that will be used to store data. In
-     * particular, no reallocation will occur in order to expand the
-     * capacity of the resulting instance. Also, the constructed
-     * instance does not keep annotations by default.
-     *
-     * @param data {@code non-null;} data array to use for output
-     */
-    public ByteArrayAnnotatedOutput(byte[] data) {
-        this(data, false);
-    }
-
-    /**
-     * Constructs a "stretchy" instance. The underlying array may be
-     * reallocated. The constructed instance does not keep annotations
-     * by default.
-     */
-    public ByteArrayAnnotatedOutput() {
-        this(DEFAULT_SIZE);
-    }
-
-    /**
-     * Constructs a "stretchy" instance with initial size {@code size}. The
-     * underlying array may be reallocated. The constructed instance does not
-     * keep annotations by default.
-     */
-    public ByteArrayAnnotatedOutput(int size) {
-        this(new byte[size], true);
-    }
-
-    /**
-     * Internal constructor.
-     *
-     * @param data {@code non-null;} data array to use for output
-     * @param stretchy whether the instance is to be stretchy
-     */
-    private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) {
-        if (data == null) {
-            throw new NullPointerException("data == null");
-        }
-
-        this.stretchy = stretchy;
-        this.data = data;
-        this.cursor = 0;
-        this.verbose = false;
-        this.annotations = null;
-        this.annotationWidth = 0;
-        this.hexCols = 0;
-    }
-
-    /**
-     * Gets the underlying {@code byte[]} of this instance, which
-     * may be larger than the number of bytes written
-     *
-     * @see #toByteArray
-     *
-     * @return {@code non-null;} the {@code byte[]}
-     */
-    public byte[] getArray() {
-        return data;
-    }
-
-    /**
-     * Constructs and returns a new {@code byte[]} that contains
-     * the written contents exactly (that is, with no extra unwritten
-     * bytes at the end).
-     *
-     * @see #getArray
-     *
-     * @return {@code non-null;} an appropriately-constructed array
-     */
-    public byte[] toByteArray() {
-        byte[] result = new byte[cursor];
-        System.arraycopy(data, 0, result, 0, cursor);
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    public int getCursor() {
-        return cursor;
-    }
-
-    /** {@inheritDoc} */
-    public void assertCursor(int expectedCursor) {
-        if (cursor != expectedCursor) {
-            throw new ExceptionWithContext("expected cursor " +
-                    expectedCursor + "; actual value: " + cursor);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void writeByte(int value) {
-        int writeAt = cursor;
-        int end = writeAt + 1;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        data[writeAt] = (byte) value;
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void writeShort(int value) {
-        int writeAt = cursor;
-        int end = writeAt + 2;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        data[writeAt] = (byte) value;
-        data[writeAt + 1] = (byte) (value >> 8);
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void writeInt(int value) {
-        int writeAt = cursor;
-        int end = writeAt + 4;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        data[writeAt] = (byte) value;
-        data[writeAt + 1] = (byte) (value >> 8);
-        data[writeAt + 2] = (byte) (value >> 16);
-        data[writeAt + 3] = (byte) (value >> 24);
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void writeLong(long value) {
-        int writeAt = cursor;
-        int end = writeAt + 8;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        int half = (int) value;
-        data[writeAt] = (byte) half;
-        data[writeAt + 1] = (byte) (half >> 8);
-        data[writeAt + 2] = (byte) (half >> 16);
-        data[writeAt + 3] = (byte) (half >> 24);
-
-        half = (int) (value >> 32);
-        data[writeAt + 4] = (byte) half;
-        data[writeAt + 5] = (byte) (half >> 8);
-        data[writeAt + 6] = (byte) (half >> 16);
-        data[writeAt + 7] = (byte) (half >> 24);
-
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public int writeUleb128(int value) {
-        if (stretchy) {
-            ensureCapacity(cursor + 5); // pessimistic
-        }
-        int cursorBefore = cursor;
-        Leb128Utils.writeUnsignedLeb128(this, value);
-        return (cursor - cursorBefore);
-    }
-
-    /** {@inheritDoc} */
-    public int writeSleb128(int value) {
-        if (stretchy) {
-            ensureCapacity(cursor + 5); // pessimistic
-        }
-        int cursorBefore = cursor;
-        Leb128Utils.writeSignedLeb128(this, value);
-        return (cursor - cursorBefore);
-    }
-
-    /** {@inheritDoc} */
-    public void write(ByteArray bytes) {
-        int blen = bytes.size();
-        int writeAt = cursor;
-        int end = writeAt + blen;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        bytes.getBytes(data, writeAt);
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void write(byte[] bytes, int offset, int length) {
-        int writeAt = cursor;
-        int end = writeAt + length;
-        int bytesEnd = offset + length;
-
-        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
-        if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {
-            throw new IndexOutOfBoundsException("bytes.length " +
-                                                bytes.length + "; " +
-                                                offset + "..!" + end);
-        }
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        System.arraycopy(bytes, offset, data, writeAt, length);
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void write(byte[] bytes) {
-        write(bytes, 0, bytes.length);
-    }
-
-    /** {@inheritDoc} */
-    public void writeZeroes(int count) {
-        if (count < 0) {
-            throw new IllegalArgumentException("count < 0");
-        }
-
-        int end = cursor + count;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        /*
-         * There is no need to actually write zeroes, since the array is
-         * already preinitialized with zeroes.
-         */
-
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public void alignTo(int alignment) {
-        int mask = alignment - 1;
-
-        if ((alignment < 0) || ((mask & alignment) != 0)) {
-            throw new IllegalArgumentException("bogus alignment");
-        }
-
-        int end = (cursor + mask) & ~mask;
-
-        if (stretchy) {
-            ensureCapacity(end);
-        } else if (end > data.length) {
-            throwBounds();
-            return;
-        }
-
-        /*
-         * There is no need to actually write zeroes, since the array is
-         * already preinitialized with zeroes.
-         */
-
-        cursor = end;
-    }
-
-    /** {@inheritDoc} */
-    public boolean annotates() {
-        return (annotations != null);
-    }
-
-    /** {@inheritDoc} */
-    public boolean isVerbose() {
-        return verbose;
-    }
-
-    /** {@inheritDoc} */
-    public void annotate(String msg) {
-        if (annotations == null) {
-            return;
-        }
-
-        endAnnotation();
-        annotations.add(new Annotation(cursor, msg));
-    }
-
-    /** {@inheritDoc} */
-    public void annotate(int amt, String msg) {
-        if (annotations == null) {
-            return;
-        }
-
-        endAnnotation();
-
-        int asz = annotations.size();
-        int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();
-        int startAt;
-
-        if (lastEnd <= cursor) {
-            startAt = cursor;
-        } else {
-            startAt = lastEnd;
-        }
-
-        annotations.add(new Annotation(startAt, startAt + amt, msg));
-    }
-
-    /** {@inheritDoc} */
-    public void endAnnotation() {
-        if (annotations == null) {
-            return;
-        }
-
-        int sz = annotations.size();
-
-        if (sz != 0) {
-            annotations.get(sz - 1).setEndIfUnset(cursor);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public int getAnnotationWidth() {
-        int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);
-
-        return annotationWidth - leftWidth;
-    }
-
-    /**
-     * Indicates that this instance should keep annotations. This method may
-     * be called only once per instance, and only before any data has been
-     * written to the it.
-     *
-     * @param annotationWidth {@code >= 40;} the desired maximum annotation width
-     * @param verbose whether or not to indicate verbose annotations
-     */
-    public void enableAnnotations(int annotationWidth, boolean verbose) {
-        if ((annotations != null) || (cursor != 0)) {
-            throw new RuntimeException("cannot enable annotations");
-        }
-
-        if (annotationWidth < 40) {
-            throw new IllegalArgumentException("annotationWidth < 40");
-        }
-
-        int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;
-        if (hexCols < 6) {
-            hexCols = 6;
-        } else if (hexCols > 10) {
-            hexCols = 10;
-        }
-
-        this.annotations = new ArrayList<Annotation>(1000);
-        this.annotationWidth = annotationWidth;
-        this.hexCols = hexCols;
-        this.verbose = verbose;
-    }
-
-    /**
-     * Finishes up annotation processing. This closes off any open
-     * annotations and removes annotations that don't refer to written
-     * data.
-     */
-    public void finishAnnotating() {
-        // Close off the final annotation, if any.
-        endAnnotation();
-
-        // Remove annotations that refer to unwritten data.
-        if (annotations != null) {
-            int asz = annotations.size();
-            while (asz > 0) {
-                Annotation last = annotations.get(asz - 1);
-                if (last.getStart() > cursor) {
-                    annotations.remove(asz - 1);
-                    asz--;
-                } else if (last.getEnd() > cursor) {
-                    last.setEnd(cursor);
-                    break;
-                } else {
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Writes the annotated content of this instance to the given writer.
-     *
-     * @param out {@code non-null;} where to write to
-     */
-    public void writeAnnotationsTo(Writer out) throws IOException {
-        int width2 = getAnnotationWidth();
-        int width1 = annotationWidth - width2 - 1;
-
-        TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, "|");
-        Writer left = twoc.getLeft();
-        Writer right = twoc.getRight();
-        int leftAt = 0; // left-hand byte output cursor
-        int rightAt = 0; // right-hand annotation index
-        int rightSz = annotations.size();
-
-        while ((leftAt < cursor) && (rightAt < rightSz)) {
-            Annotation a = annotations.get(rightAt);
-            int start = a.getStart();
-            int end;
-            String text;
-
-            if (leftAt < start) {
-                // This is an area with no annotation.
-                end = start;
-                start = leftAt;
-                text = "";
-            } else {
-                // This is an area with an annotation.
-                end = a.getEnd();
-                text = a.getText();
-                rightAt++;
-            }
-
-            left.write(Hex.dump(data, start, end - start, start, hexCols, 6));
-            right.write(text);
-            twoc.flush();
-            leftAt = end;
-        }
-
-        if (leftAt < cursor) {
-            // There is unannotated output at the end.
-            left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt,
-                                hexCols, 6));
-        }
-
-        while (rightAt < rightSz) {
-            // There are zero-byte annotations at the end.
-            right.write(annotations.get(rightAt).getText());
-            rightAt++;
-        }
-
-        twoc.flush();
-    }
-
-    /**
-     * Throws the excpetion for when an attempt is made to write past the
-     * end of the instance.
-     */
-    private static void throwBounds() {
-        throw new IndexOutOfBoundsException("attempt to write past the end");
-    }
-
-    /**
-     * Reallocates the underlying array if necessary. Calls to this method
-     * should be guarded by a test of {@link #stretchy}.
-     *
-     * @param desiredSize {@code >= 0;} the desired minimum total size of the array
-     */
-    private void ensureCapacity(int desiredSize) {
-        if (data.length < desiredSize) {
-            byte[] newData = new byte[desiredSize * 2 + 1000];
-            System.arraycopy(data, 0, newData, 0, cursor);
-            data = newData;
-        }
-    }
-
-    /**
-     * Annotation on output.
-     */
-    private static class Annotation {
-        /** {@code >= 0;} start of annotated range (inclusive) */
-        private final int start;
-
-        /**
-         * {@code >= 0;} end of annotated range (exclusive);
-         * {@code Integer.MAX_VALUE} if unclosed
-         */
-        private int end;
-
-        /** {@code non-null;} annotation text */
-        private final String text;
-
-        /**
-         * Constructs an instance.
-         *
-         * @param start {@code >= 0;} start of annotated range
-         * @param end {@code >= start;} end of annotated range (exclusive) or
-         * {@code Integer.MAX_VALUE} if unclosed
-         * @param text {@code non-null;} annotation text
-         */
-        public Annotation(int start, int end, String text) {
-            this.start = start;
-            this.end = end;
-            this.text = text;
-        }
-
-        /**
-         * Constructs an instance. It is initally unclosed.
-         *
-         * @param start {@code >= 0;} start of annotated range
-         * @param text {@code non-null;} annotation text
-         */
-        public Annotation(int start, String text) {
-            this(start, Integer.MAX_VALUE, text);
-        }
-
-        /**
-         * Sets the end as given, but only if the instance is unclosed;
-         * otherwise, do nothing.
-         *
-         * @param end {@code >= start;} the end
-         */
-        public void setEndIfUnset(int end) {
-            if (this.end == Integer.MAX_VALUE) {
-                this.end = end;
-            }
-        }
-
-        /**
-         * Sets the end as given.
-         *
-         * @param end {@code >= start;} the end
-         */
-        public void setEnd(int end) {
-            this.end = end;
-        }
-
-        /**
-         * Gets the start.
-         *
-         * @return the start
-         */
-        public int getStart() {
-            return start;
-        }
-
-        /**
-         * Gets the end.
-         *
-         * @return the end
-         */
-        public int getEnd() {
-            return end;
-        }
-
-        /**
-         * Gets the text.
-         *
-         * @return {@code non-null;} the text
-         */
-        public String getText() {
-            return text;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ByteArrayByteInput.java b/dx/src/main/java/com/android/dx/util/ByteArrayByteInput.java
deleted file mode 100644
index 07c543f..0000000
--- a/dx/src/main/java/com/android/dx/util/ByteArrayByteInput.java
+++ /dev/null
@@ -1,31 +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.util;
-
-public final class ByteArrayByteInput implements ByteInput {
-
-    private final byte[] bytes;
-    private int position;
-
-    public ByteArrayByteInput(byte... bytes) {
-        this.bytes = bytes;
-    }
-
-    @Override public byte readByte() {
-        return bytes[position++];
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ByteInput.java b/dx/src/main/java/com/android/dx/util/ByteInput.java
deleted file mode 100644
index 8181e3e..0000000
--- a/dx/src/main/java/com/android/dx/util/ByteInput.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.util;
-
-/**
- * A byte source.
- */
-public interface ByteInput {
-
-    /**
-     * Returns a byte.
-     *
-     * @throws IndexOutOfBoundsException if all bytes have been read.
-     */
-    byte readByte();
-}
diff --git a/dx/src/main/java/com/android/dx/util/ByteOutput.java b/dx/src/main/java/com/android/dx/util/ByteOutput.java
deleted file mode 100644
index 512dcf8..0000000
--- a/dx/src/main/java/com/android/dx/util/ByteOutput.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.util;
-
-/**
- * A byte sink.
- */
-public interface ByteOutput {
-
-    /**
-     * Writes a byte.
-     *
-     * @throws IndexOutOfBoundsException if all bytes have been written.
-     */
-    void writeByte(int i);
-}
diff --git a/dx/src/main/java/com/android/dx/util/DexException.java b/dx/src/main/java/com/android/dx/util/DexException.java
deleted file mode 100644
index 527b0b9..0000000
--- a/dx/src/main/java/com/android/dx/util/DexException.java
+++ /dev/null
@@ -1,31 +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.util;
-
-/**
- * Thrown when there's a format problem reading, writing, or generally
- * processing a dex file.
- */
-public final class DexException extends ExceptionWithContext {
-    public DexException(String message) {
-        super(message);
-    }
-
-    public DexException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ExceptionWithContext.java b/dx/src/main/java/com/android/dx/util/ExceptionWithContext.java
deleted file mode 100644
index 7f8523c..0000000
--- a/dx/src/main/java/com/android/dx/util/ExceptionWithContext.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Exception which carries around structured context.
- */
-public class ExceptionWithContext
-        extends RuntimeException {
-    /** {@code non-null;} human-oriented context of the exception */
-    private StringBuffer context;
-
-    /**
-     * Augments the given exception with the given context, and return the
-     * result. The result is either the given exception if it was an
-     * {@link ExceptionWithContext}, or a newly-constructed exception if it
-     * was not.
-     *
-     * @param ex {@code non-null;} the exception to augment
-     * @param str {@code non-null;} context to add
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static ExceptionWithContext withContext(Throwable ex, String str) {
-        ExceptionWithContext ewc;
-
-        if (ex instanceof ExceptionWithContext) {
-            ewc = (ExceptionWithContext) ex;
-        } else {
-            ewc = new ExceptionWithContext(ex);
-        }
-
-        ewc.addContext(str);
-        return ewc;
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param message human-oriented message
-     */
-    public ExceptionWithContext(String message) {
-        this(message, null);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param cause {@code null-ok;} exception that caused this one
-     */
-    public ExceptionWithContext(Throwable cause) {
-        this(null, cause);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param message human-oriented message
-     * @param cause {@code null-ok;} exception that caused this one
-     */
-    public ExceptionWithContext(String message, Throwable cause) {
-        super((message != null) ? message :
-              (cause != null) ? cause.getMessage() : null,
-              cause);
-
-        if (cause instanceof ExceptionWithContext) {
-            String ctx = ((ExceptionWithContext) cause).context.toString();
-            context = new StringBuffer(ctx.length() + 200);
-            context.append(ctx);
-        } else {
-            context = new StringBuffer(200);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void printStackTrace(PrintStream out) {
-        super.printStackTrace(out);
-        out.println(context);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void printStackTrace(PrintWriter out) {
-        super.printStackTrace(out);
-        out.println(context);
-    }
-
-    /**
-     * Adds a line of context to this instance.
-     *
-     * @param str {@code non-null;} new context
-     */
-    public void addContext(String str) {
-        if (str == null) {
-            throw new NullPointerException("str == null");
-        }
-
-        context.append(str);
-        if (!str.endsWith("\n")) {
-            context.append('\n');
-        }
-    }
-
-    /**
-     * Gets the context.
-     *
-     * @return {@code non-null;} the context
-     */
-    public String getContext() {
-        return context.toString();
-    }
-
-    /**
-     * Prints the message and context.
-     *
-     * @param out {@code non-null;} where to print to
-     */
-    public void printContext(PrintStream out) {
-        out.println(getMessage());
-        out.print(context);
-    }
-
-    /**
-     * Prints the message and context.
-     *
-     * @param out {@code non-null;} where to print to
-     */
-    public void printContext(PrintWriter out) {
-        out.println(getMessage());
-        out.print(context);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/FileUtils.java b/dx/src/main/java/com/android/dx/util/FileUtils.java
deleted file mode 100644
index bcf6729..0000000
--- a/dx/src/main/java/com/android/dx/util/FileUtils.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * File I/O utilities.
- */
-public final class FileUtils {
-    /**
-     * This class is uninstantiable.
-     */
-    private FileUtils() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Reads the named file, translating {@link IOException} to a
-     * {@link RuntimeException} of some sort.
-     *
-     * @param fileName {@code non-null;} name of the file to read
-     * @return {@code non-null;} contents of the file
-     */
-    public static byte[] readFile(String fileName) {
-        File file = new File(fileName);
-        return readFile(file);
-    }
-
-    /**
-     * Reads the given file, translating {@link IOException} to a
-     * {@link RuntimeException} of some sort.
-     *
-     * @param file {@code non-null;} the file to read
-     * @return {@code non-null;} contents of the file
-     */
-    public static byte[] readFile(File file) {
-        if (!file.exists()) {
-            throw new RuntimeException(file + ": file not found");
-        }
-
-        if (!file.isFile()) {
-            throw new RuntimeException(file + ": not a file");
-        }
-
-        if (!file.canRead()) {
-            throw new RuntimeException(file + ": file not readable");
-        }
-
-        long longLength = file.length();
-        int length = (int) longLength;
-        if (length != longLength) {
-            throw new RuntimeException(file + ": file too long");
-        }
-
-        byte[] result = new byte[length];
-
-        try {
-            FileInputStream in = new FileInputStream(file);
-            int at = 0;
-            while (length > 0) {
-                int amt = in.read(result, at, length);
-                if (amt == -1) {
-                    throw new RuntimeException(file + ": unexpected EOF");
-                }
-                at += amt;
-                length -= amt;
-            }
-            in.close();
-        } catch (IOException ex) {
-            throw new RuntimeException(file + ": trouble reading", ex);
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns true if {@code fileName} names a .zip, .jar, or .apk.
-     */
-    public static boolean hasArchiveSuffix(String fileName) {
-        return fileName.endsWith(".zip")
-                || fileName.endsWith(".jar")
-                || fileName.endsWith(".apk");
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/FixedSizeList.java b/dx/src/main/java/com/android/dx/util/FixedSizeList.java
deleted file mode 100644
index fb3af04..0000000
--- a/dx/src/main/java/com/android/dx/util/FixedSizeList.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.util.Arrays;
-
-/**
- * Simple (mostly) fixed-size list of objects, which may be made immutable.
- */
-public class FixedSizeList
-        extends MutabilityControl implements ToHuman {
-    /** {@code non-null;} array of elements */
-    private Object[] arr;
-
-    /**
-     * Constructs an instance. All indices initially contain {@code null}.
-     *
-     * @param size the size of the list
-     */
-    public FixedSizeList(int size) {
-        super(size != 0);
-
-        try {
-            arr = new Object[size];
-        } catch (NegativeArraySizeException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("size < 0");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            // Easy out.
-            return true;
-        }
-
-        if ((other == null) || (getClass() != other.getClass())) {
-            // Another easy out.
-            return false;
-        }
-
-        FixedSizeList list = (FixedSizeList) other;
-        return Arrays.equals(arr, list.arr);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(arr);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        String name = getClass().getName();
-
-        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
-                         ", ",
-                         "}",
-                         false);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * This method will only work if every element of the list
-     * implements {@link ToHuman}.
-     */
-    public String toHuman() {
-        String name = getClass().getName();
-
-        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
-                         ", ",
-                         "}",
-                         true);
-    }
-
-    /**
-     * Gets a customized string form for this instance.
-     *
-     * @param prefix {@code null-ok;} prefix for the start of the result
-     * @param separator {@code null-ok;} separator to insert between each item
-     * @param suffix {@code null-ok;} suffix for the end of the result
-     * @return {@code non-null;} the custom string
-     */
-    public String toString(String prefix, String separator, String suffix) {
-        return toString0(prefix, separator, suffix, false);
-    }
-
-    /**
-     * Gets a customized human string for this instance. This method will
-     * only work if every element of the list implements {@link
-     * ToHuman}.
-     *
-     * @param prefix {@code null-ok;} prefix for the start of the result
-     * @param separator {@code null-ok;} separator to insert between each item
-     * @param suffix {@code null-ok;} suffix for the end of the result
-     * @return {@code non-null;} the custom string
-     */
-    public String toHuman(String prefix, String separator, String suffix) {
-        return toString0(prefix, separator, suffix, true);
-    }
-
-    /**
-     * Gets the number of elements in this list.
-     */
-    public final int size() {
-        return arr.length;
-    }
-
-    /**
-     * Shrinks this instance to fit, by removing any unset
-     * ({@code null}) elements, leaving the remaining elements in
-     * their original order.
-     */
-    public void shrinkToFit() {
-        int sz = arr.length;
-        int newSz = 0;
-
-        for (int i = 0; i < sz; i++) {
-            if (arr[i] != null) {
-                newSz++;
-            }
-        }
-
-        if (sz == newSz) {
-            return;
-        }
-
-        throwIfImmutable();
-
-        Object[] newa = new Object[newSz];
-        int at = 0;
-
-        for (int i = 0; i < sz; i++) {
-            Object one = arr[i];
-            if (one != null) {
-                newa[at] = one;
-                at++;
-            }
-        }
-
-        arr = newa;
-        if (newSz == 0) {
-            setImmutable();
-        }
-    }
-
-    /**
-     * Gets the indicated element. It is an error to call this with the
-     * index for an element which was never set; if you do that, this
-     * will throw {@code NullPointerException}. This method is
-     * protected so that subclasses may offer a safe type-checked
-     * public interface to their clients.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return {@code non-null;} the indicated element
-     */
-    protected final Object get0(int n) {
-        try {
-            Object result = arr[n];
-
-            if (result == null) {
-                throw new NullPointerException("unset: " + n);
-            }
-
-            return result;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            return throwIndex(n);
-        }
-    }
-
-    /**
-     * Gets the indicated element, allowing {@code null}s to be
-     * returned. This method is protected so that subclasses may
-     * (optionally) offer a safe type-checked public interface to
-     * their clients.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return {@code null-ok;} the indicated element
-     */
-    protected final Object getOrNull0(int n) {
-        return arr[n];
-    }
-
-    /**
-     * Sets the element at the given index, but without doing any type
-     * checks on the element. This method is protected so that
-     * subclasses may offer a safe type-checked public interface to
-     * their clients.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @param obj {@code null-ok;} the value to store
-     */
-    protected final void set0(int n, Object obj) {
-        throwIfImmutable();
-
-        try {
-            arr[n] = obj;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            throwIndex(n);
-        }
-    }
-
-    /**
-     * Throws the appropriate exception for the given index value.
-     *
-     * @param n the index value
-     * @return never
-     * @throws IndexOutOfBoundsException always thrown
-     */
-    private Object throwIndex(int n) {
-        if (n < 0) {
-            throw new IndexOutOfBoundsException("n < 0");
-        }
-
-        throw new IndexOutOfBoundsException("n >= size()");
-    }
-
-    /**
-     * Helper for {@link #toString} and {@link #toHuman}, which both of
-     * those call to pretty much do everything.
-     *
-     * @param prefix {@code null-ok;} prefix for the start of the result
-     * @param separator {@code null-ok;} separator to insert between each item
-     * @param suffix {@code null-ok;} suffix for the end of the result
-     * @param human whether the output is to be human
-     * @return {@code non-null;} the custom string
-     */
-    private String toString0(String prefix, String separator, String suffix,
-                             boolean human) {
-        int len = arr.length;
-        StringBuffer sb = new StringBuffer(len * 10 + 10);
-
-        if (prefix != null) {
-            sb.append(prefix);
-        }
-
-        for (int i = 0; i < len; i++) {
-            if ((i != 0) && (separator != null)) {
-                sb.append(separator);
-            }
-
-            if (human) {
-                sb.append(((ToHuman) arr[i]).toHuman());
-            } else {
-                sb.append(arr[i]);
-            }
-        }
-
-        if (suffix != null) {
-            sb.append(suffix);
-        }
-
-        return sb.toString();
-    }
-
-}
diff --git a/dx/src/main/java/com/android/dx/util/Hex.java b/dx/src/main/java/com/android/dx/util/Hex.java
deleted file mode 100644
index e95669c..0000000
--- a/dx/src/main/java/com/android/dx/util/Hex.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Utilities for formatting numbers as hexadecimal.
- */
-public final class Hex {
-    /**
-     * This class is uninstantiable.
-     */
-    private Hex() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Formats a {@code long} as an 8-byte unsigned hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u8(long v) {
-        char[] result = new char[16];
-        for (int i = 0; i < 16; i++) {
-            result[15 - i] = Character.forDigit((int) v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 4-byte unsigned hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u4(int v) {
-        char[] result = new char[8];
-        for (int i = 0; i < 8; i++) {
-            result[7 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 3-byte unsigned hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u3(int v) {
-        char[] result = new char[6];
-        for (int i = 0; i < 6; i++) {
-            result[5 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 2-byte unsigned hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u2(int v) {
-        char[] result = new char[4];
-        for (int i = 0; i < 4; i++) {
-            result[3 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as either a 2-byte unsigned hex value
-     * (if the value is small enough) or a 4-byte unsigned hex value (if
-     * not).
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u2or4(int v) {
-        if (v == (char) v) {
-            return u2(v);
-        } else {
-            return u4(v);
-        }
-    }
-
-    /**
-     * Formats an {@code int} as a 1-byte unsigned hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String u1(int v) {
-        char[] result = new char[2];
-        for (int i = 0; i < 2; i++) {
-            result[1 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 4-bit unsigned hex nibble.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String uNibble(int v) {
-        char[] result = new char[1];
-
-        result[0] = Character.forDigit(v & 0x0f, 16);
-        return new String(result);
-    }
-
-    /**
-     * Formats a {@code long} as an 8-byte signed hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String s8(long v) {
-        char[] result = new char[17];
-
-        if (v < 0) {
-            result[0] = '-';
-            v = -v;
-        } else {
-            result[0] = '+';
-        }
-
-        for (int i = 0; i < 16; i++) {
-            result[16 - i] = Character.forDigit((int) v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 4-byte signed hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String s4(int v) {
-        char[] result = new char[9];
-
-        if (v < 0) {
-            result[0] = '-';
-            v = -v;
-        } else {
-            result[0] = '+';
-        }
-
-        for (int i = 0; i < 8; i++) {
-            result[8 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 2-byte signed hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String s2(int v) {
-        char[] result = new char[5];
-
-        if (v < 0) {
-            result[0] = '-';
-            v = -v;
-        } else {
-            result[0] = '+';
-        }
-
-        for (int i = 0; i < 4; i++) {
-            result[4 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats an {@code int} as a 1-byte signed hex value.
-     *
-     * @param v value to format
-     * @return {@code non-null;} formatted form
-     */
-    public static String s1(int v) {
-        char[] result = new char[3];
-
-        if (v < 0) {
-            result[0] = '-';
-            v = -v;
-        } else {
-            result[0] = '+';
-        }
-
-        for (int i = 0; i < 2; i++) {
-            result[2 - i] = Character.forDigit(v & 0x0f, 16);
-            v >>= 4;
-        }
-
-        return new String(result);
-    }
-
-    /**
-     * Formats a hex dump of a portion of a {@code byte[]}. The result
-     * is always newline-terminated, unless the passed-in length was zero,
-     * in which case the result is always the empty string ({@code ""}).
-     *
-     * @param arr {@code non-null;} array to format
-     * @param offset {@code >= 0;} offset to the part to dump
-     * @param length {@code >= 0;} number of bytes to dump
-     * @param outOffset {@code >= 0;} first output offset to print
-     * @param bpl {@code >= 0;} number of bytes of output per line
-     * @param addressLength {@code {2,4,6,8};} number of characters for each address
-     * header
-     * @return {@code non-null;} a string of the dump
-     */
-    public static String dump(byte[] arr, int offset, int length,
-                              int outOffset, int bpl, int addressLength) {
-        int end = offset + length;
-
-        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
-        if (((offset | length | end) < 0) || (end > arr.length)) {
-            throw new IndexOutOfBoundsException("arr.length " +
-                                                arr.length + "; " +
-                                                offset + "..!" + end);
-        }
-
-        if (outOffset < 0) {
-            throw new IllegalArgumentException("outOffset < 0");
-        }
-
-        if (length == 0) {
-            return "";
-        }
-
-        StringBuffer sb = new StringBuffer(length * 4 + 6);
-        boolean bol = true;
-        int col = 0;
-
-        while (length > 0) {
-            if (col == 0) {
-                String astr;
-                switch (addressLength) {
-                    case 2:  astr = Hex.u1(outOffset); break;
-                    case 4:  astr = Hex.u2(outOffset); break;
-                    case 6:  astr = Hex.u3(outOffset); break;
-                    default: astr = Hex.u4(outOffset); break;
-                }
-                sb.append(astr);
-                sb.append(": ");
-            } else if ((col & 1) == 0) {
-                sb.append(' ');
-            }
-            sb.append(Hex.u1(arr[offset]));
-            outOffset++;
-            offset++;
-            col++;
-            if (col == bpl) {
-                sb.append('\n');
-                col = 0;
-            }
-            length--;
-        }
-
-        if (col != 0) {
-            sb.append('\n');
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/HexParser.java b/dx/src/main/java/com/android/dx/util/HexParser.java
deleted file mode 100644
index 1b34345..0000000
--- a/dx/src/main/java/com/android/dx/util/HexParser.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Utilities for parsing hexadecimal text.
- */
-public final class HexParser {
-    /**
-     * This class is uninstantiable.
-     */
-    private HexParser() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Parses the given text as hex, returning a {@code byte[]}
-     * corresponding to the text. The format is simple: Each line may
-     * start with a hex offset followed by a colon (which is verified
-     * and presumably used just as a comment), and then consists of
-     * hex digits freely interspersed with whitespace. If a pound sign
-     * is encountered, it and the rest of the line are ignored as a
-     * comment. If a double quote is encountered, then the ASCII value
-     * of the subsequent characters is used, until the next double
-     * quote. Quoted strings may not span multiple lines.
-     *
-     * @param src {@code non-null;} the source string
-     * @return {@code non-null;} the parsed form
-     */
-    public static byte[] parse(String src) {
-        int len = src.length();
-        byte[] result = new byte[len / 2];
-        int at = 0;
-        int outAt = 0;
-
-        while (at < len) {
-            int nlAt = src.indexOf('\n', at);
-            if (nlAt < 0) {
-                nlAt = len;
-            }
-            int poundAt = src.indexOf('#', at);
-
-            String line;
-            if ((poundAt >= 0) && (poundAt < nlAt)) {
-                line = src.substring(at, poundAt);
-            } else {
-                line = src.substring(at, nlAt);
-            }
-            at = nlAt + 1;
-
-            int colonAt = line.indexOf(':');
-
-            atCheck:
-            if (colonAt != -1) {
-                int quoteAt = line.indexOf('\"');
-                if ((quoteAt != -1) && (quoteAt < colonAt)) {
-                    break atCheck;
-                }
-
-                String atStr = line.substring(0, colonAt).trim();
-                line = line.substring(colonAt + 1);
-                int alleged = Integer.parseInt(atStr, 16);
-                if (alleged != outAt) {
-                    throw new RuntimeException("bogus offset marker: " +
-                                               atStr);
-                }
-            }
-
-            int lineLen = line.length();
-            int value = -1;
-            boolean quoteMode = false;
-
-            for (int i = 0; i < lineLen; i++) {
-                char c = line.charAt(i);
-
-                if (quoteMode) {
-                    if (c == '\"') {
-                        quoteMode = false;
-                    } else {
-                        result[outAt] = (byte) c;
-                        outAt++;
-                    }
-                    continue;
-                }
-
-                if (c <= ' ') {
-                    continue;
-                }
-                if (c == '\"') {
-                    if (value != -1) {
-                        throw new RuntimeException("spare digit around " +
-                                                   "offset " + Hex.u4(outAt));
-                    }
-                    quoteMode = true;
-                    continue;
-                }
-
-                int digVal = Character.digit(c, 16);
-                if (digVal == -1) {
-                    throw new RuntimeException("bogus digit character: \"" +
-                                               c + "\"");
-                }
-                if (value == -1) {
-                    value = digVal;
-                } else {
-                    result[outAt] = (byte) ((value << 4) | digVal);
-                    outAt++;
-                    value = -1;
-                }
-            }
-
-            if (value != -1) {
-                throw new RuntimeException("spare digit around offset " +
-                                           Hex.u4(outAt));
-            }
-
-            if (quoteMode) {
-                throw new RuntimeException("unterminated quote around " +
-                                           "offset " + Hex.u4(outAt));
-            }
-        }
-
-        if (outAt < result.length) {
-            byte[] newr = new byte[outAt];
-            System.arraycopy(result, 0, newr, 0, outAt);
-            result = newr;
-        }
-
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/IndentingWriter.java b/dx/src/main/java/com/android/dx/util/IndentingWriter.java
deleted file mode 100644
index 3424e37..0000000
--- a/dx/src/main/java/com/android/dx/util/IndentingWriter.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Writer that wraps another writer and passes width-limited and
- * optionally-prefixed output to its subordinate. When lines are
- * wrapped they are automatically indented based on the start of the
- * line.
- */
-public final class IndentingWriter extends FilterWriter {
-    /** {@code null-ok;} optional prefix for every line */
-    private final String prefix;
-
-    /** {@code > 0;} the maximum output width */
-    private final int width;
-
-    /** {@code > 0;} the maximum indent */
-    private final int maxIndent;
-
-    /** {@code >= 0;} current output column (zero-based) */
-    private int column;
-
-    /** whether indent spaces are currently being collected */
-    private boolean collectingIndent;
-
-    /** {@code >= 0;} current indent amount */
-    private int indent;
-
-    /**
-     * Constructs an instance.
-     *
-     * @param out {@code non-null;} writer to send final output to
-     * @param width {@code >= 0;} the maximum output width (not including
-     * {@code prefix}), or {@code 0} for no maximum
-     * @param prefix {@code non-null;} the prefix for each line
-     */
-    public IndentingWriter(Writer out, int width, String prefix) {
-        super(out);
-
-        if (out == null) {
-            throw new NullPointerException("out == null");
-        }
-
-        if (width < 0) {
-            throw new IllegalArgumentException("width < 0");
-        }
-
-        if (prefix == null) {
-            throw new NullPointerException("prefix == null");
-        }
-
-        this.width = (width != 0) ? width : Integer.MAX_VALUE;
-        this.maxIndent = width >> 1;
-        this.prefix = (prefix.length() == 0) ? null : prefix;
-
-        bol();
-    }
-
-    /**
-     * Constructs a no-prefix instance.
-     *
-     * @param out {@code non-null;} writer to send final output to
-     * @param width {@code >= 0;} the maximum output width (not including
-     * {@code prefix}), or {@code 0} for no maximum
-     */
-    public IndentingWriter(Writer out, int width) {
-        this(out, width, "");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void write(int c) throws IOException {
-        synchronized (lock) {
-            if (collectingIndent) {
-                if (c == ' ') {
-                    indent++;
-                    if (indent >= maxIndent) {
-                        indent = maxIndent;
-                        collectingIndent = false;
-                    }
-                } else {
-                    collectingIndent = false;
-                }
-            }
-
-            if ((column == width) && (c != '\n')) {
-                out.write('\n');
-                column = 0;
-                /*
-                 * Note: No else, so this should fall through to the next
-                 * if statement.
-                 */
-            }
-
-            if (column == 0) {
-                if (prefix != null) {
-                    out.write(prefix);
-                }
-
-                if (!collectingIndent) {
-                    for (int i = 0; i < indent; i++) {
-                        out.write(' ');
-                    }
-                    column = indent;
-                }
-            }
-
-            out.write(c);
-
-            if (c == '\n') {
-                bol();
-            } else {
-                column++;
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void write(char[] cbuf, int off, int len) throws IOException {
-        synchronized (lock) {
-            while (len > 0) {
-                write(cbuf[off]);
-                off++;
-                len--;
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void write(String str, int off, int len) throws IOException {
-        synchronized (lock) {
-            while (len > 0) {
-                write(str.charAt(off));
-                off++;
-                len--;
-            }
-        }
-    }
-
-    /**
-     * Indicates that output is at the beginning of a line.
-     */
-    private void bol() {
-        column = 0;
-        collectingIndent = (maxIndent != 0);
-        indent = 0;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/IntIterator.java b/dx/src/main/java/com/android/dx/util/IntIterator.java
deleted file mode 100644
index 4caa439..0000000
--- a/dx/src/main/java/com/android/dx/util/IntIterator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-/**
- * An iterator for a list of ints.
- */
-public interface IntIterator {
-
-    /**
-     * Checks to see if the iterator has a next value.
-     *
-     * @return true if next() will succeed
-     */
-    boolean hasNext();
-
-    /**
-     * Returns the next value in the iterator.
-     *
-     * @return next value
-     * @throws java.util.NoSuchElementException if no next element exists
-     */
-    int next();
-}
diff --git a/dx/src/main/java/com/android/dx/util/IntList.java b/dx/src/main/java/com/android/dx/util/IntList.java
deleted file mode 100644
index be400aa..0000000
--- a/dx/src/main/java/com/android/dx/util/IntList.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.util.Arrays;
-
-/**
- * Simple list of {@code int}s.
- */
-public final class IntList extends MutabilityControl {
-    /** {@code non-null;} immutable, no-element instance */
-    public static final IntList EMPTY = new IntList(0);
-
-    /** {@code non-null;} array of elements */
-    private int[] values;
-
-    /** {@code >= 0;} current size of the list */
-    private int size;
-
-    /** whether the values are currently sorted */
-    private boolean sorted;
-
-    static {
-        EMPTY.setImmutable();
-    }
-
-    /**
-     * Constructs a new immutable instance with the given element.
-     *
-     * @param value the sole value in the list
-     */
-    public static IntList makeImmutable(int value) {
-        IntList result = new IntList(1);
-
-        result.add(value);
-        result.setImmutable();
-
-        return result;
-    }
-
-    /**
-     * Constructs a new immutable instance with the given elements.
-     *
-     * @param value0 the first value in the list
-     * @param value1 the second value in the list
-     */
-    public static IntList makeImmutable(int value0, int value1) {
-        IntList result = new IntList(2);
-
-        result.add(value0);
-        result.add(value1);
-        result.setImmutable();
-
-        return result;
-    }
-
-    /**
-     * Constructs an empty instance with a default initial capacity.
-     */
-    public IntList() {
-        this(4);
-    }
-
-    /**
-     * Constructs an empty instance.
-     *
-     * @param initialCapacity {@code >= 0;} initial capacity of the list
-     */
-    public IntList(int initialCapacity) {
-        super(true);
-
-        try {
-            values = new int[initialCapacity];
-        } catch (NegativeArraySizeException ex) {
-            // Translate the exception.
-            throw new IllegalArgumentException("size < 0");
-        }
-
-        size = 0;
-        sorted = true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        int result = 0;
-
-        for (int i = 0; i < size; i++) {
-            result = (result * 31) + values[i];
-        }
-
-        return result;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean equals(Object other) {
-        if (other == this) {
-            return true;
-        }
-
-        if (! (other instanceof IntList)) {
-            return false;
-        }
-
-        IntList otherList = (IntList) other;
-
-        if (sorted != otherList.sorted) {
-            return false;
-        }
-
-        if (size != otherList.size) {
-            return false;
-        }
-
-        for (int i = 0; i < size; i++) {
-            if (values[i] != otherList.values[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer(size * 5 + 10);
-
-        sb.append('{');
-
-        for (int i = 0; i < size; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(values[i]);
-        }
-
-        sb.append('}');
-
-        return sb.toString();
-    }
-
-    /**
-     * Gets the number of elements in this list.
-     */
-    public int size() {
-        return size;
-    }
-
-    /**
-     * Gets the indicated value.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @return the indicated element's value
-     */
-    public int get(int n) {
-        if (n >= size) {
-            throw new IndexOutOfBoundsException("n >= size()");
-        }
-
-        try {
-            return values[n];
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate exception.
-            throw new IndexOutOfBoundsException("n < 0");
-        }
-    }
-
-    /**
-     * Sets the value at the given index.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @param value value to store
-     */
-    public void set(int n, int value) {
-        throwIfImmutable();
-
-        if (n >= size) {
-            throw new IndexOutOfBoundsException("n >= size()");
-        }
-
-        try {
-            values[n] = value;
-            sorted = false;
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            // Translate the exception.
-            if (n < 0) {
-                throw new IllegalArgumentException("n < 0");
-            }
-        }
-    }
-
-    /**
-     * Adds an element to the end of the list. This will increase the
-     * list's capacity if necessary.
-     *
-     * @param value the value to add
-     */
-    public void add(int value) {
-        throwIfImmutable();
-
-        growIfNeeded();
-
-        values[size++] = value;
-
-        if (sorted && (size > 1)) {
-            sorted = (value >= values[size - 2]);
-        }
-    }
-
-    /**
-     * Inserts element into specified index, moving elements at and above
-     * that index up one. May not be used to insert at an index beyond the
-     * current size (that is, insertion as a last element is legal but
-     * no further).
-     *
-     * @param n {@code >= 0, <=size();} index of where to insert
-     * @param value value to insert
-     */
-    public void insert(int n, int value) {
-        if (n > size) {
-            throw new IndexOutOfBoundsException("n > size()");
-        }
-
-        growIfNeeded();
-
-        System.arraycopy (values, n, values, n+1, size - n);
-        values[n] = value;
-        size++;
-
-        sorted = sorted
-                && (n == 0 || value > values[n-1])
-                && (n == (size - 1) || value < values[n+1]);
-    }
-
-    /**
-     * Removes an element at a given index, shifting elements at greater
-     * indicies down one.
-     *
-     * @param n  {@code >=0, < size();} index of element to remove
-     */
-    public void removeIndex(int n) {
-        if (n >= size) {
-            throw new IndexOutOfBoundsException("n >= size()");
-        }
-
-        System.arraycopy (values, n + 1, values, n, size - n - 1);
-        size--;
-
-        // sort status is unchanged
-    }
-
-    /**
-     * Increases size of array if needed
-     */
-    private void growIfNeeded() {
-        if (size == values.length) {
-            // Resize.
-            int[] newv = new int[size * 3 / 2 + 10];
-            System.arraycopy(values, 0, newv, 0, size);
-            values = newv;
-        }
-    }
-
-    /**
-     * Returns the last element in the array without modifying the array
-     *
-     * @return last value in the array
-     * @throws IndexOutOfBoundsException if stack is empty
-     */
-    public int top() {
-        return get(size - 1);
-    }
-
-    /**
-     * Pops an element off the end of the list and decreasing the size by one.
-     *
-     * @return value from what was the last element
-     * @throws IndexOutOfBoundsException if stack is empty
-     */
-    public int pop() {
-        throwIfImmutable();
-
-        int result;
-
-        result = get(size-1);
-        size--;
-
-        return result;
-    }
-
-    /**
-     * Pops N elements off the end of the list and decreasing the size by N.
-     *
-     * @param n {@code >= 0;} number of elements to remove from end
-     * @throws IndexOutOfBoundsException if stack is smaller than N
-     */
-    public void pop(int n) {
-        throwIfImmutable();
-
-        size -= n;
-    }
-
-    /**
-     * Shrinks the size of the list.
-     *
-     * @param newSize {@code >= 0;} the new size
-     */
-    public void shrink(int newSize) {
-        if (newSize < 0) {
-            throw new IllegalArgumentException("newSize < 0");
-        }
-
-        if (newSize > size) {
-            throw new IllegalArgumentException("newSize > size");
-        }
-
-        throwIfImmutable();
-
-        size = newSize;
-    }
-
-    /**
-     * Makes and returns a mutable copy of the list.
-     *
-     * @return {@code non-null;} an appropriately-constructed instance
-     */
-    public IntList mutableCopy() {
-        int sz = size;
-        IntList result = new IntList(sz);
-
-        for (int i = 0; i < sz; i++) {
-            result.add(values[i]);
-        }
-
-        return result;
-    }
-
-    /**
-     * Sorts the elements in the list in-place.
-     */
-    public void sort() {
-        throwIfImmutable();
-
-        if (!sorted) {
-            Arrays.sort(values, 0, size);
-            sorted = true;
-        }
-    }
-
-    /**
-     * Returns the index of the given value, or -1 if the value does not
-     * appear in the list.  This will do a binary search if the list is
-     * sorted or a linear search if not.
-     *
-     * @param value value to find
-     * @return index of value or -1
-     */
-    public int indexOf(int value) {
-        int ret = binarysearch(value);
-
-        return ret >= 0 ? ret : -1;
-
-    }
-
-    /**
-     * Performs a binary search on a sorted list, returning the index of
-     * the given value if it is present or
-     * {@code (-(insertion point) - 1)} if the value is not present.
-     * If the list is not sorted, then reverts to linear search and returns
-     * {@code -size()} if the element is not found.
-     *
-     * @param value value to find
-     * @return index of value or {@code (-(insertion point) - 1)} if the
-     * value is not present
-     */
-    public int binarysearch(int value) {
-        int sz = size;
-
-        if (!sorted) {
-            // Linear search.
-            for (int i = 0; i < sz; i++) {
-                if (values[i] == value) {
-                    return i;
-                }
-            }
-
-            return -sz;
-        }
-
-        /*
-         * Binary search. This variant does only one value comparison
-         * per iteration but does one more iteration on average than
-         * the variant that includes a value equality check per
-         * iteration.
-         */
-
-        int min = -1;
-        int max = sz;
-
-        while (max > (min + 1)) {
-            /*
-             * The guessIdx calculation is equivalent to ((min + max)
-             * / 2) but won't go wonky when min and max are close to
-             * Integer.MAX_VALUE.
-             */
-            int guessIdx = min + ((max - min) >> 1);
-            int guess = values[guessIdx];
-
-            if (value <= guess) {
-                max = guessIdx;
-            } else {
-                min = guessIdx;
-            }
-        }
-
-        if ((max != sz)) {
-            return (value == values[max]) ? max : (-max - 1);
-        } else {
-            return -sz - 1;
-        }
-    }
-
-
-    /**
-     * Returns whether or not the given value appears in the list.
-     * This will do a binary search if the list is sorted or a linear
-     * search if not.
-     *
-     * @see #sort
-     *
-     * @param value value to look for
-     * @return whether the list contains the given value
-     */
-    public boolean contains(int value) {
-        return indexOf(value) >= 0;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/IntSet.java b/dx/src/main/java/com/android/dx/util/IntSet.java
deleted file mode 100644
index 33b6bdd..0000000
--- a/dx/src/main/java/com/android/dx/util/IntSet.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-/**
- * A set of integers
- */
-public interface IntSet {
-
-    /**
-     * Adds an int to a set
-     *
-     * @param value int to add
-     */
-    void add(int value);
-
-    /**
-     * Removes an int from a set.
-     *
-     * @param value int to remove
-     */
-    void remove(int value);
-
-    /**
-     * Checks to see if a value is in the set
-     *
-     * @param value int to check
-     * @return true if in set
-     */
-    boolean has(int value);
-
-    /**
-     * Merges {@code other} into this set, so this set becomes the
-     * union of the two.
-     *
-     * @param other {@code non-null;} other set to merge with.
-     */
-    void merge(IntSet other);
-
-    /**
-     * Returns the count of unique elements in this set.
-     *
-     * @return {@code > = 0;} count of unique elements
-     */
-    int elements();
-
-    /**
-     * Iterates the set
-     *
-     * @return {@code non-null;} a set iterator
-     */
-    IntIterator iterator();
-}
diff --git a/dx/src/main/java/com/android/dx/util/LabeledItem.java b/dx/src/main/java/com/android/dx/util/LabeledItem.java
deleted file mode 100644
index b4856cf..0000000
--- a/dx/src/main/java/com/android/dx/util/LabeledItem.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * An item that has an integer label.
- */
-public interface LabeledItem {
-
-    /*
-     * Gets the label of this block.
-     *
-     * @return {@code >= 0;} the label
-     */
-    public int getLabel();
-}
diff --git a/dx/src/main/java/com/android/dx/util/LabeledList.java b/dx/src/main/java/com/android/dx/util/LabeledList.java
deleted file mode 100644
index 963b5aa..0000000
--- a/dx/src/main/java/com/android/dx/util/LabeledList.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.util.Arrays;
-
-/**
- * A list of labeled items, allowing easy lookup by label.
- */
-public class LabeledList extends FixedSizeList {
-    /**
-     * Sparse array indexed by label to FixedSizeList index;
-     * {@code -1} for an invalid label.
-     */
-    private final IntList labelToIndex;
-
-    /** @inheritDoc */
-    public LabeledList(int size) {
-        super(size);
-
-        labelToIndex = new IntList(size);
-    }
-
-    /**
-     * Constructs a new instance that is a copy of the old instance.
-     *
-     * @param old instance to copy
-     */
-    public LabeledList(LabeledList old) {
-        super(old.size());
-        labelToIndex = old.labelToIndex.mutableCopy();
-
-        int sz = old.size();
-
-        for (int i = 0; i < sz; i++) {
-            Object one = old.get0(i);
-            if (one != null) {
-                set0(i, one);
-            }
-        }
-    }
-
-    /**
-     * Gets the maximum label (exclusive) of any block added to this instance.
-     *
-     * @return {@code >= 0;} the maximum label
-     */
-    public final int getMaxLabel() {
-        int sz = labelToIndex.size();
-
-        // Gobble any deleted labels that may be at the end.
-        int i;
-        for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--)
-            /*empty*/ ;
-
-        int newSize = i + 1;
-
-        labelToIndex.shrink(newSize);
-
-        return newSize;
-    }
-
-    /**
-     * Removes a label from the label-to-index mapping.
-     *
-     * @param oldLabel label to remove
-     */
-    private void removeLabel(int oldLabel) {
-        labelToIndex.set(oldLabel, -1);
-    }
-
-    /**
-     * Adds a label and index to the label-to-index mapping.
-     *
-     * @param label new label
-     * @param index index of block.
-     */
-    private void addLabelIndex(int label, int index) {
-        int origSz = labelToIndex.size();
-
-        for (int i = 0; i <= (label - origSz); i++) {
-            labelToIndex.add(-1);
-        }
-
-        labelToIndex.set(label, index);
-    }
-
-    /**
-     * Gets the index of the first item in the list with the given
-     * label, if any.
-     *
-     * @param label {@code >= 0;} the label to look for
-     * @return {@code >= -1;} the index of the so-labelled item, or {@code -1}
-     * if none is found
-     */
-    public final int indexOfLabel(int label) {
-        if (label >= labelToIndex.size()) {
-            return -1;
-        } else {
-            return labelToIndex.get(label);
-        }
-    }
-
-    /**
-     * Gets an array containing all of the labels used in this instance,
-     * in order. The returned array is freshly-allocated and so may be
-     * modified safely by the caller without impacting this instance.
-     *
-     * @return {@code non-null;} ordered array of labels
-     * @throws NullPointerException thrown if there are any {@code null}
-     * items in this instance
-     */
-    public final int[] getLabelsInOrder() {
-        int sz = size();
-        int[] result = new int[sz];
-
-        for (int i = 0; i < sz; i++) {
-            LabeledItem li = (LabeledItem) get0(i);
-            if (li == null) {
-                throw new NullPointerException("null at index " + i);
-            }
-            result[i] = li.getLabel();
-        }
-
-        Arrays.sort(result);
-        return result;
-    }
-
-    /** @inheritDoc */
-    @Override
-    public void shrinkToFit() {
-        super.shrinkToFit();
-
-        rebuildLabelToIndex();
-    }
-
-    /**
-     * Rebuilds the label-to-index mapping after a {@code shrinkToFit()}.
-     * Note: This assumes that the labels that are in the list are the
-     * same, although the indicies may have changed.
-     */
-    private void rebuildLabelToIndex() {
-        int szItems = size();
-
-        for (int i = 0; i < szItems; i++) {
-            LabeledItem li = (LabeledItem) get0(i);
-
-            if (li != null) {
-                labelToIndex.set(li.getLabel(), i);
-            }
-        }
-    }
-
-    /**
-     * Sets the element at the given index.
-     *
-     * @param n {@code >= 0, < size();} which element
-     * @param item {@code null-ok;} the value to store
-     */
-    protected void set(int n, LabeledItem item) {
-        LabeledItem old = (LabeledItem) getOrNull0(n);
-
-        set0(n, item);
-
-        if (old != null) {
-            removeLabel(old.getLabel());
-        }
-
-        if (item != null) {
-            addLabelIndex(item.getLabel(), n);
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Leb128Utils.java b/dx/src/main/java/com/android/dx/util/Leb128Utils.java
deleted file mode 100644
index 1037463..0000000
--- a/dx/src/main/java/com/android/dx/util/Leb128Utils.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-/**
- * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3
- * section 7.6.
- */
-public final class Leb128Utils {
-    /**
-     * This class is uninstantiable.
-     */
-    private Leb128Utils() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Gets the number of bytes in the unsigned LEB128 encoding of the
-     * given value.
-     *
-     * @param value the value in question
-     * @return its write size, in bytes
-     */
-    public static int unsignedLeb128Size(int value) {
-        // TODO: This could be much cleverer.
-
-        int remaining = value >> 7;
-        int count = 0;
-
-        while (remaining != 0) {
-            remaining >>= 7;
-            count++;
-        }
-
-        return count + 1;
-    }
-
-    /**
-     * Gets the number of bytes in the signed LEB128 encoding of the
-     * given value.
-     *
-     * @param value the value in question
-     * @return its write size, in bytes
-     */
-    public static int signedLeb128Size(int value) {
-        // TODO: This could be much cleverer.
-
-        int remaining = value >> 7;
-        int count = 0;
-        boolean hasMore = true;
-        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
-
-        while (hasMore) {
-            hasMore = (remaining != end)
-                || ((remaining & 1) != ((value >> 6) & 1));
-
-            value = remaining;
-            remaining >>= 7;
-            count++;
-        }
-
-        return count;
-    }
-
-    /**
-     * Reads an signed integer from {@code in}.
-     */
-    public static int readSignedLeb128(ByteInput in) {
-        int result = 0;
-        int cur;
-        int count = 0;
-        int signBits = -1;
-
-        do {
-            cur = in.readByte() & 0xff;
-            result |= (cur & 0x7f) << (count * 7);
-            signBits <<= 7;
-            count++;
-        } while (((cur & 0x80) == 0x80) && count < 5);
-
-        if ((cur & 0x80) == 0x80) {
-            throw new DexException("invalid LEB128 sequence");
-        }
-
-        // Sign extend if appropriate
-        if (((signBits >> 1) & result) != 0 ) {
-            result |= signBits;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads an unsigned integer from {@code in}.
-     */
-    public static int readUnsignedLeb128(ByteInput in) {
-        int result = 0;
-        int cur;
-        int count = 0;
-
-        do {
-            cur = in.readByte() & 0xff;
-            result |= (cur & 0x7f) << (count * 7);
-            count++;
-        } while (((cur & 0x80) == 0x80) && count < 5);
-
-        if ((cur & 0x80) == 0x80) {
-            throw new DexException("invalid LEB128 sequence");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes {@code value} as an unsigned integer to {@code out}, starting at
-     * {@code offset}. Returns the number of bytes written.
-     */
-    public static void writeUnsignedLeb128(ByteOutput out, int value) {
-        int remaining = value >>> 7;
-
-        while (remaining != 0) {
-            out.writeByte((byte) ((value & 0x7f) | 0x80));
-            value = remaining;
-            remaining >>>= 7;
-        }
-
-        out.writeByte((byte) (value & 0x7f));
-    }
-
-    /**
-     * Writes {@code value} as a signed integer to {@code out}, starting at
-     * {@code offset}. Returns the number of bytes written.
-     */
-    public static void writeSignedLeb128(ByteOutput out, int value) {
-        int remaining = value >> 7;
-        boolean hasMore = true;
-        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
-
-        while (hasMore) {
-            hasMore = (remaining != end)
-                    || ((remaining & 1) != ((value >> 6) & 1));
-
-            out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));
-            value = remaining;
-            remaining >>= 7;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/ListIntSet.java b/dx/src/main/java/com/android/dx/util/ListIntSet.java
deleted file mode 100644
index 2b4fc21..0000000
--- a/dx/src/main/java/com/android/dx/util/ListIntSet.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-import java.util.NoSuchElementException;
-
-/**
- * A set of integers, represented by a list
- */
-public class ListIntSet implements IntSet {
-
-    /** also accessed in BitIntSet */
-    final IntList ints;
-
-    /**
-     * Constructs an instance
-     */
-    public ListIntSet() {
-        ints = new IntList();
-        ints.sort();
-    }
-
-    /** @inheritDoc */
-    public void add(int value) {
-        int index = ints.binarysearch(value);
-
-        if (index < 0) {
-            ints.insert(-(index + 1), value);
-        }
-    }
-
-    /** @inheritDoc */
-    public void remove(int value) {
-        int index = ints.indexOf(value);
-
-        if (index >= 0) {
-            ints.removeIndex(index);
-        }
-    }
-
-    /** @inheritDoc */
-    public boolean has(int value) {
-        return ints.indexOf(value) >= 0;
-    }
-
-    /** @inheritDoc */
-    public void merge(IntSet other) {
-        if (other instanceof ListIntSet) {
-            ListIntSet o = (ListIntSet) other;
-            int szThis = ints.size();
-            int szOther = o.ints.size();
-
-            int i = 0;
-            int j = 0;
-
-            while (j < szOther && i < szThis) {
-                while (j < szOther && o.ints.get(j) < ints.get(i)) {
-                    add(o.ints.get(j++));
-                }
-                if (j == szOther) {
-                    break;
-                }
-                while (i < szThis && o.ints.get(j) >= ints.get(i)) {
-                    i++;
-                }
-            }
-
-            while (j < szOther) {
-                add(o.ints.get(j++));
-            }
-
-            ints.sort();
-        } else if (other instanceof BitIntSet) {
-            BitIntSet o = (BitIntSet) other;
-
-            for (int i = 0; i >= 0; i = Bits.findFirst(o.bits, i + 1)) {
-                ints.add(i);
-            }
-            ints.sort();
-        } else {
-            IntIterator iter = other.iterator();
-            while (iter.hasNext()) {
-                add(iter.next());
-            }
-        }
-    }
-
-    /** @inheritDoc */
-    public int elements() {
-        return ints.size();
-    }
-
-    /** @inheritDoc */
-    public IntIterator iterator() {
-        return new IntIterator() {
-            private int idx = 0;
-
-            /** @inheritDoc */
-            public boolean hasNext() {
-                return idx < ints.size();
-            }
-
-            /** @inheritDoc */
-            public int next() {
-                if (!hasNext()) {
-                    throw new NoSuchElementException();
-                }
-
-                return ints.get(idx++);
-            }
-        };
-    }
-
-    /** @inheritDoc */
-    public String toString() {
-        return ints.toString();
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/MutabilityControl.java b/dx/src/main/java/com/android/dx/util/MutabilityControl.java
deleted file mode 100644
index 14e0f2e..0000000
--- a/dx/src/main/java/com/android/dx/util/MutabilityControl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Very simple base class that implements a flag to control the mutability
- * of instances. This class just provides the flag and a utility to check
- * and throw the right exception, but it is up to subclasses to place calls
- * to the checker in all the right places.
- */
-public class MutabilityControl {
-    /** whether this instance is mutable */
-    private boolean mutable;
-
-    /**
-     * Constructs an instance. It is initially mutable.
-     */
-    public MutabilityControl() {
-        mutable = true;
-    }
-
-    /**
-     * Constructs an instance, explicitly indicating the mutability.
-     *
-     * @param mutable {@code true} iff this instance is mutable
-     */
-    public MutabilityControl(boolean mutable) {
-        this.mutable = mutable;
-    }
-
-    /**
-     * Makes this instance immutable.
-     */
-    public void setImmutable() {
-        mutable = false;
-    }
-
-    /**
-     * Checks to see whether or not this instance is immutable. This is the
-     * same as calling {@code !isMutable()}.
-     *
-     * @return {@code true} iff this instance is immutable
-     */
-    public final boolean isImmutable() {
-        return !mutable;
-    }
-
-    /**
-     * Checks to see whether or not this instance is mutable.
-     *
-     * @return {@code true} iff this instance is mutable
-     */
-    public final boolean isMutable() {
-        return mutable;
-    }
-
-    /**
-     * Throws {@link MutabilityException} if this instance is
-     * immutable.
-     */
-    public final void throwIfImmutable() {
-        if (!mutable) {
-            throw new MutabilityException("immutable instance");
-        }
-    }
-
-    /**
-     * Throws {@link MutabilityException} if this instance is mutable.
-     */
-    public final void throwIfMutable() {
-        if (mutable) {
-            throw new MutabilityException("mutable instance");
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/MutabilityException.java b/dx/src/main/java/com/android/dx/util/MutabilityException.java
deleted file mode 100644
index bd21651..0000000
--- a/dx/src/main/java/com/android/dx/util/MutabilityException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Exception due to a mutability problem.
- */
-public class MutabilityException
-        extends ExceptionWithContext {
-    public MutabilityException(String message) {
-        super(message);
-    }
-
-    public MutabilityException(Throwable cause) {
-        super(cause);
-    }
-
-    public MutabilityException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Mutf8.java b/dx/src/main/java/com/android/dx/util/Mutf8.java
deleted file mode 100644
index fe55724..0000000
--- a/dx/src/main/java/com/android/dx/util/Mutf8.java
+++ /dev/null
@@ -1,114 +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.util;
-
-import java.io.UTFDataFormatException;
-
-/**
- * Modified UTF-8 as described in the dex file format spec.
- *
- * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.
- */
-public final class Mutf8 {
-    private Mutf8() {}
-
-    /**
-     * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is
-     * encountered. Returns a new string containing the decoded characters.
-     */
-    public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {
-        int s = 0;
-        while (true) {
-            char a = (char) (in.readByte() & 0xff);
-            if (a == 0) {
-                return new String(out, 0, s);
-            }
-            out[s] = a;
-            if (a < '\u0080') {
-                s++;
-            } else if ((a & 0xe0) == 0xc0) {
-                int b = in.readByte() & 0xff;
-                if ((b & 0xC0) != 0x80) {
-                    throw new UTFDataFormatException("bad second byte");
-                }
-                out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
-            } else if ((a & 0xf0) == 0xe0) {
-                int b = in.readByte() & 0xff;
-                int c = in.readByte() & 0xff;
-                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
-                    throw new UTFDataFormatException("bad second or third byte");
-                }
-                out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
-            } else {
-                throw new UTFDataFormatException("bad byte");
-            }
-        }
-    }
-
-    /**
-     * Returns the number of bytes the modified UTF8 representation of 's' would take.
-     */
-    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
-        long result = 0;
-        final int length = s.length();
-        for (int i = 0; i < length; ++i) {
-            char ch = s.charAt(i);
-            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
-                ++result;
-            } else if (ch <= 2047) {
-                result += 2;
-            } else {
-                result += 3;
-            }
-            if (shortLength && result > 65535) {
-                throw new UTFDataFormatException("String more than 65535 UTF bytes long");
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Encodes the modified UTF-8 bytes corresponding to {@code s} into  {@code
-     * dst}, starting at {@code offset}.
-     */
-    public static void encode(byte[] dst, int offset, String s) {
-        final int length = s.length();
-        for (int i = 0; i < length; i++) {
-            char ch = s.charAt(i);
-            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
-                dst[offset++] = (byte) ch;
-            } else if (ch <= 2047) {
-                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
-                dst[offset++] = (byte) (0x80 | (0x3f & ch));
-            } else {
-                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
-                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
-                dst[offset++] = (byte) (0x80 | (0x3f & ch));
-            }
-        }
-    }
-
-    /**
-     * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.
-     */
-    public static byte[] encode(String s) throws UTFDataFormatException {
-        int utfCount = (int) countBytes(s, true);
-        byte[] result = new byte[utfCount];
-        encode(result, 0, s);
-        return result;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Output.java b/dx/src/main/java/com/android/dx/util/Output.java
deleted file mode 100644
index e5956a2..0000000
--- a/dx/src/main/java/com/android/dx/util/Output.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Interface for a sink for binary output. This is similar to
- * {@code java.util.DataOutput}, but no {@code IOExceptions}
- * are declared, and multibyte output is defined to be little-endian.
- */
-public interface Output extends ByteOutput {
-    /**
-     * Gets the current cursor position. This is the same as the number of
-     * bytes written to this instance.
-     *
-     * @return {@code >= 0;} the cursor position
-     */
-    public int getCursor();
-
-    /**
-     * Asserts that the cursor is the given value.
-     *
-     * @param expectedCursor the expected cursor value
-     * @throws RuntimeException thrown if {@code getCursor() !=
-     * expectedCursor}
-     */
-    public void assertCursor(int expectedCursor);
-
-    /**
-     * Writes a {@code byte} to this instance.
-     *
-     * @param value the value to write; all but the low 8 bits are ignored
-     */
-    public void writeByte(int value);
-
-    /**
-     * Writes a {@code short} to this instance.
-     *
-     * @param value the value to write; all but the low 16 bits are ignored
-     */
-    public void writeShort(int value);
-
-    /**
-     * Writes an {@code int} to this instance.
-     *
-     * @param value the value to write
-     */
-    public void writeInt(int value);
-
-    /**
-     * Writes a {@code long} to this instance.
-     *
-     * @param value the value to write
-     */
-    public void writeLong(long value);
-
-    /**
-     * Writes a DWARFv3-style unsigned LEB128 integer. For details,
-     * see the "Dalvik Executable Format" document or DWARF v3 section
-     * 7.6.
-     *
-     * @param value value to write, treated as an unsigned value
-     * @return {@code 1..5;} the number of bytes actually written
-     */
-    public int writeUleb128(int value);
-
-    /**
-     * Writes a DWARFv3-style unsigned LEB128 integer. For details,
-     * see the "Dalvik Executable Format" document or DWARF v3 section
-     * 7.6.
-     *
-     * @param value value to write
-     * @return {@code 1..5;} the number of bytes actually written
-     */
-    public int writeSleb128(int value);
-
-    /**
-     * Writes a {@link ByteArray} to this instance.
-     *
-     * @param bytes {@code non-null;} the array to write
-     */
-    public void write(ByteArray bytes);
-
-    /**
-     * Writes a portion of a {@code byte[]} to this instance.
-     *
-     * @param bytes {@code non-null;} the array to write
-     * @param offset {@code >= 0;} offset into {@code bytes} for the first
-     * byte to write
-     * @param length {@code >= 0;} number of bytes to write
-     */
-    public void write(byte[] bytes, int offset, int length);
-
-    /**
-     * Writes a {@code byte[]} to this instance. This is just
-     * a convenient shorthand for {@code write(bytes, 0, bytes.length)}.
-     *
-     * @param bytes {@code non-null;} the array to write
-     */
-    public void write(byte[] bytes);
-
-    /**
-     * Writes the given number of {@code 0} bytes.
-     *
-     * @param count {@code >= 0;} the number of zeroes to write
-     */
-    public void writeZeroes(int count);
-
-    /**
-     * Adds extra bytes if necessary (with value {@code 0}) to
-     * force alignment of the output cursor as given.
-     *
-     * @param alignment {@code > 0;} the alignment; must be a power of two
-     */
-    public void alignTo(int alignment);
-}
diff --git a/dx/src/main/java/com/android/dx/util/ToHuman.java b/dx/src/main/java/com/android/dx/util/ToHuman.java
deleted file mode 100644
index b3a31a5..0000000
--- a/dx/src/main/java/com/android/dx/util/ToHuman.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-/**
- * Simple interface for objects that can return a "human" (as opposed to
- * a complete but often hard to read) string form.
- */
-public interface ToHuman {
-    /**
-     * Return the "human" string form of this instance.  This is
-     * generally less "debuggy" than {@code toString()}.
-     *
-     * @return {@code non-null;} the human string form
-     */
-    public String toHuman();
-}
diff --git a/dx/src/main/java/com/android/dx/util/TwoColumnOutput.java b/dx/src/main/java/com/android/dx/util/TwoColumnOutput.java
deleted file mode 100644
index ed2ab9f..0000000
--- a/dx/src/main/java/com/android/dx/util/TwoColumnOutput.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-
-/**
- * Class that takes a combined output destination and provides two
- * output writers, one of which ends up writing to the left column and
- * one which goes on the right.
- */
-public final class TwoColumnOutput {
-    /** {@code non-null;} underlying writer for final output */
-    private final Writer out;
-
-    /** {@code > 0;} the left column width */
-    private final int leftWidth;
-
-    /** {@code non-null;} pending left column output */
-    private final StringBuffer leftBuf;
-
-    /** {@code non-null;} pending right column output */
-    private final StringBuffer rightBuf;
-
-    /** {@code non-null;} left column writer */
-    private final IndentingWriter leftColumn;
-
-    /** {@code non-null;} right column writer */
-    private final IndentingWriter rightColumn;
-
-    /**
-     * Turns the given two strings (with widths) and spacer into a formatted
-     * two-column string.
-     *
-     * @param s1 {@code non-null;} first string
-     * @param width1 {@code > 0;} width of the first column
-     * @param spacer {@code non-null;} spacer string
-     * @param s2 {@code non-null;} second string
-     * @param width2 {@code > 0;} width of the second column
-     * @return {@code non-null;} an appropriately-formatted string
-     */
-    public static String toString(String s1, int width1, String spacer,
-                                  String s2, int width2) {
-        int len1 = s1.length();
-        int len2 = s2.length();
-
-        StringWriter sw = new StringWriter((len1 + len2) * 3);
-        TwoColumnOutput twoOut =
-            new TwoColumnOutput(sw, width1, width2, spacer);
-
-        try {
-            twoOut.getLeft().write(s1);
-            twoOut.getRight().write(s2);
-        } catch (IOException ex) {
-            throw new RuntimeException("shouldn't happen", ex);
-        }
-
-        twoOut.flush();
-        return sw.toString();
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param out {@code non-null;} writer to send final output to
-     * @param leftWidth {@code > 0;} width of the left column, in characters
-     * @param rightWidth {@code > 0;} width of the right column, in characters
-     * @param spacer {@code non-null;} spacer string to sit between the two columns
-     */
-    public TwoColumnOutput(Writer out, int leftWidth, int rightWidth,
-                           String spacer) {
-        if (out == null) {
-            throw new NullPointerException("out == null");
-        }
-
-        if (leftWidth < 1) {
-            throw new IllegalArgumentException("leftWidth < 1");
-        }
-
-        if (rightWidth < 1) {
-            throw new IllegalArgumentException("rightWidth < 1");
-        }
-
-        if (spacer == null) {
-            throw new NullPointerException("spacer == null");
-        }
-
-        StringWriter leftWriter = new StringWriter(1000);
-        StringWriter rightWriter = new StringWriter(1000);
-
-        this.out = out;
-        this.leftWidth = leftWidth;
-        this.leftBuf = leftWriter.getBuffer();
-        this.rightBuf = rightWriter.getBuffer();
-        this.leftColumn = new IndentingWriter(leftWriter, leftWidth);
-        this.rightColumn =
-            new IndentingWriter(rightWriter, rightWidth, spacer);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param out {@code non-null;} stream to send final output to
-     * @param leftWidth {@code >= 1;} width of the left column, in characters
-     * @param rightWidth {@code >= 1;} width of the right column, in characters
-     * @param spacer {@code non-null;} spacer string to sit between the two columns
-     */
-    public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth,
-                           String spacer) {
-        this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer);
-    }
-
-    /**
-     * Gets the writer to use to write to the left column.
-     *
-     * @return {@code non-null;} the left column writer
-     */
-    public Writer getLeft() {
-        return leftColumn;
-    }
-
-    /**
-     * Gets the writer to use to write to the right column.
-     *
-     * @return {@code non-null;} the right column writer
-     */
-    public Writer getRight() {
-        return rightColumn;
-    }
-
-    /**
-     * Flushes the output. If there are more lines of pending output in one
-     * column, then the other column will get filled with blank lines.
-     */
-    public void flush() {
-        try {
-            appendNewlineIfNecessary(leftBuf, leftColumn);
-            appendNewlineIfNecessary(rightBuf, rightColumn);
-            outputFullLines();
-            flushLeft();
-            flushRight();
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Outputs to the final destination as many full line pairs as
-     * there are in the pending output, removing those lines from
-     * their respective buffers. This method terminates when at
-     * least one of the two column buffers is empty.
-     */
-    private void outputFullLines() throws IOException {
-        for (;;) {
-            int leftLen = leftBuf.indexOf("\n");
-            if (leftLen < 0) {
-                return;
-            }
-
-            int rightLen = rightBuf.indexOf("\n");
-            if (rightLen < 0) {
-                return;
-            }
-
-            if (leftLen != 0) {
-                out.write(leftBuf.substring(0, leftLen));
-            }
-
-            if (rightLen != 0) {
-                writeSpaces(out, leftWidth - leftLen);
-                out.write(rightBuf.substring(0, rightLen));
-            }
-
-            out.write('\n');
-
-            leftBuf.delete(0, leftLen + 1);
-            rightBuf.delete(0, rightLen + 1);
-        }
-    }
-
-    /**
-     * Flushes the left column buffer, printing it and clearing the buffer.
-     * If the buffer is already empty, this does nothing.
-     */
-    private void flushLeft() throws IOException {
-        appendNewlineIfNecessary(leftBuf, leftColumn);
-
-        while (leftBuf.length() != 0) {
-            rightColumn.write('\n');
-            outputFullLines();
-        }
-    }
-
-    /**
-     * Flushes the right column buffer, printing it and clearing the buffer.
-     * If the buffer is already empty, this does nothing.
-     */
-    private void flushRight() throws IOException {
-        appendNewlineIfNecessary(rightBuf, rightColumn);
-
-        while (rightBuf.length() != 0) {
-            leftColumn.write('\n');
-            outputFullLines();
-        }
-    }
-
-    /**
-     * Appends a newline to the given buffer via the given writer, but
-     * only if it isn't empty and doesn't already end with one.
-     *
-     * @param buf {@code non-null;} the buffer in question
-     * @param out {@code non-null;} the writer to use
-     */
-    private static void appendNewlineIfNecessary(StringBuffer buf,
-                                                 Writer out)
-            throws IOException {
-        int len = buf.length();
-
-        if ((len != 0) && (buf.charAt(len - 1) != '\n')) {
-            out.write('\n');
-        }
-    }
-
-    /**
-     * Writes the given number of spaces to the given writer.
-     *
-     * @param out {@code non-null;} where to write
-     * @param amt {@code >= 0;} the number of spaces to write
-     */
-    private static void writeSpaces(Writer out, int amt) throws IOException {
-        while (amt > 0) {
-            out.write(' ');
-            amt--;
-        }
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Uint.java b/dx/src/main/java/com/android/dx/util/Uint.java
deleted file mode 100644
index 039756a..0000000
--- a/dx/src/main/java/com/android/dx/util/Uint.java
+++ /dev/null
@@ -1,32 +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.util;
-
-/**
- * An unsigned integer.
- */
-public final class Uint implements Comparable<Uint> {
-    public final int intValue;
-
-    public Uint(int value) {
-        this.intValue = value;
-    }
-
-    public int compareTo(Uint uint) {
-        return Unsigned.compare(intValue, uint.intValue);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Unsigned.java b/dx/src/main/java/com/android/dx/util/Unsigned.java
deleted file mode 100644
index f15bd86..0000000
--- a/dx/src/main/java/com/android/dx/util/Unsigned.java
+++ /dev/null
@@ -1,42 +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.util;
-
-/**
- * Unsigned arithmetic over Java's signed types.
- */
-public final class Unsigned {
-    private Unsigned() {}
-
-    public static int compare(short ushortA, short ushortB) {
-        if (ushortA == ushortB) {
-            return 0;
-        }
-        int a = ushortA & 0xFFFF;
-        int b = ushortB & 0xFFFF;
-        return a < b ? -1 : 1;
-    }
-
-    public static int compare(int uintA, int uintB) {
-        if (uintA == uintB) {
-            return 0;
-        }
-        long a = uintA & 0xFFFFFFFFL;
-        long b = uintB & 0xFFFFFFFFL;
-        return a < b ? -1 : 1;
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Warning.java b/dx/src/main/java/com/android/dx/util/Warning.java
deleted file mode 100644
index 3c23c7c..0000000
--- a/dx/src/main/java/com/android/dx/util/Warning.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-/**
- * Exception which is meant to indicate a non-fatal warning.
- */
-public class Warning extends RuntimeException {
-    /**
-     * Constructs an instance.
-     *
-     * @param message human-oriented message
-     */
-    public Warning(String message) {
-        super(message);
-    }
-}
diff --git a/dx/src/main/java/com/android/dx/util/Writers.java b/dx/src/main/java/com/android/dx/util/Writers.java
deleted file mode 100644
index eba845c..0000000
--- a/dx/src/main/java/com/android/dx/util/Writers.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 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.util;
-
-import java.io.PrintWriter;
-import java.io.Writer;
-
-/**
- * Utilities for dealing with {@code Writer}s.
- */
-public final class Writers {
-    /**
-     * This class is uninstantiable.
-     */
-    private Writers() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Makes a {@code PrintWriter} for the given {@code Writer},
-     * returning the given writer if it already happens to be the right
-     * class.
-     *
-     * @param writer {@code non-null;} writer to (possibly) wrap
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static PrintWriter printWriterFor(Writer writer) {
-        if (writer instanceof PrintWriter) {
-            return (PrintWriter) writer;
-        }
-
-        return new PrintWriter(writer);
-    }
-}
diff --git a/lib/dalvik-dx-1-sources.jar b/lib/dalvik-dx-1-sources.jar
new file mode 100644
index 0000000..45cc845
--- /dev/null
+++ b/lib/dalvik-dx-1-sources.jar
Binary files differ
diff --git a/lib/dalvik-dx-1.jar b/lib/dalvik-dx-1.jar
new file mode 100644
index 0000000..c559399
--- /dev/null
+++ b/lib/dalvik-dx-1.jar
Binary files differ
diff --git a/lib/dalvik-dx-1.jar.txt b/lib/dalvik-dx-1.jar.txt
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/lib/dalvik-dx-1.jar.txt
@@ -0,0 +1,202 @@
+Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
+
diff --git a/lib/libcore-dex-2-sources.jar b/lib/libcore-dex-2-sources.jar
new file mode 100644
index 0000000..3391687
--- /dev/null
+++ b/lib/libcore-dex-2-sources.jar
Binary files differ
diff --git a/lib/libcore-dex-2.jar b/lib/libcore-dex-2.jar
new file mode 100644
index 0000000..4d368d5
--- /dev/null
+++ b/lib/libcore-dex-2.jar
Binary files differ
diff --git a/lib/libcore-dex-2.jar.txt b/lib/libcore-dex-2.jar.txt
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/lib/libcore-dex-2.jar.txt
@@ -0,0 +1,202 @@
+Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
+
