diff --git a/Android.mk b/Android.mk
index 0a9a0b8..fd9bcd1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -50,28 +50,4 @@
 $(info ********************************************************************************)
 endif
 
-
-#
-# "m dalvik-host" for quick minimal host build
-#
-
-ifeq ($(WITH_HOST_DALVIK),true)
-    .PHONY: dalvik-host
-    dalvik-host: \
-        dalvik \
-        $(HOST_OUT)/bin/dalvikvm \
-        $(HOST_OUT)/bin/dexopt \
-        $(HOST_OUT)/lib/libjavacore.so \
-        $(HOST_OUT)/lib/libjavacrypto.so \
-        $(HOST_OUT)/lib/libjavacoretests.so \
-        cacerts-host \
-        core-hostdex \
-        conscrypt-hostdex \
-        okhttp-hostdex \
-        bouncycastle-hostdex \
-        apache-xml-hostdex \
-        apache-harmony-tests-hostdex \
-        $(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)/classes.jar
-endif
-
 include $(subdir_makefiles)
diff --git a/CaCerts.mk b/CaCerts.mk
index 980d0fb..f85f524 100644
--- a/CaCerts.mk
+++ b/CaCerts.mk
@@ -50,10 +50,9 @@
 # This is so that build/target/product/core.mk can use cacerts in PRODUCT_PACKAGES
 ALL_MODULES.cacerts.INSTALLED := $(cacerts_target)
 
-ifeq ($(WITH_HOST_DALVIK),true)
 cacerts_host_directory := $(HOST_OUT)/etc/security/cacerts
 $(foreach cacert, $(cacerts), $(eval $(call include-prebuilt-with-destination-directory,host-cacert-$(notdir $(cacert)),$(cacert),$(cacerts_host_directory))))
-endif
+
 cacerts_host := $(addprefix $(cacerts_host_directory)/,$(foreach cacert,$(cacerts),$(notdir $(cacert))))
 .PHONY: cacerts-host
 cacerts-host: $(cacerts_host)
diff --git a/Docs.mk b/Docs.mk
index 612b3d9..a163d1f 100644
--- a/Docs.mk
+++ b/Docs.mk
@@ -17,8 +17,8 @@
    dalvik/src/main/java/dalvik/annotation \
    dalvik/src/main/java/dalvik/bytecode \
    json/src/main/java \
-   libdvm/src/main/java/dalvik \
-   libdvm/src/main/java/java \
+   libart/src/main/java/dalvik \
+   libart/src/main/java/java \
    luni/src/main/java/android \
    luni/src/main/java/java \
    luni/src/main/java/javax \
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index d97f453..c857390 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -62,7 +62,6 @@
 endif
 endif
 
-libdvm_core_src_files += $(common_core_src_files) $(call all-main-java-files-under,libdvm)
 libart_core_src_files += $(common_core_src_files) $(call all-main-java-files-under,libart)
 
 local_javac_flags=-encoding UTF-8
@@ -76,18 +75,6 @@
 # Definitions to make the core library.
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(libdvm_core_src_files)
-LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVACFLAGS := $(local_javac_flags)
-LOCAL_DX_FLAGS := --core-library
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := core
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-LOCAL_REQUIRED_MODULES := tzdata
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(libart_core_src_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
@@ -108,7 +95,7 @@
 LOCAL_SRC_FILES := $(test_src_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit okhttp
+LOCAL_JAVA_LIBRARIES := core-libart okhttp core-junit bouncycastle
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests
@@ -122,7 +109,7 @@
 LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit
+LOCAL_JAVA_LIBRARIES := core-libart core-junit bouncycastle
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests-support
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -135,7 +122,7 @@
 LOCAL_SRC_FILES :=  $(call all-test-java-files-under, jsr166-tests)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core core-junit
+LOCAL_JAVA_LIBRARIES := core-libart core-junit
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := jsr166-tests
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -167,62 +154,49 @@
 LOCAL_MODULE := dex-host
 include $(BUILD_HOST_JAVA_LIBRARY)
 
-ifeq ($(WITH_HOST_DALVIK),true)
+# Definitions to make the core library.
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(libart_core_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVACFLAGS := $(local_javac_flags)
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := core-libart-hostdex
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
+LOCAL_REQUIRED_MODULES := tzdata-host
+# Should not be dex-preopted as it isn't really a Dalvik boot jar or a
+# regular java library, but part of the image for ART.
+LOCAL_DEX_PREOPT := false
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 
-    # Definitions to make the core library.
-    include $(CLEAR_VARS)
-    LOCAL_SRC_FILES := $(libdvm_core_src_files)
-    LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_DX_FLAGS := --core-library
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-hostdex
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-    LOCAL_REQUIRED_MODULES := tzdata-host
-    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-
-    include $(CLEAR_VARS)
-    LOCAL_SRC_FILES := $(libart_core_src_files)
-    LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVACFLAGS := $(local_javac_flags)
-    LOCAL_DX_FLAGS := --core-library
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := core-libart-hostdex
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-    LOCAL_REQUIRED_MODULES := tzdata-host
-    # Should not be dex-preopted as it isn't really a Dalvik boot jar or a
-    # regular java library, but part of the image for ART.
-    LOCAL_DEX_PREOPT := false
-    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-
-    # Make the core-tests library.
-    ifeq ($(LIBCORE_SKIP_TESTS),)
+# Make the core-tests library.
+ifeq ($(LIBCORE_SKIP_TESTS),)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(test_src_files)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex okhttp-hostdex
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_JAVA_LIBRARIES := core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex
     LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-hostdex
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-    endif
+endif
 
-    # Make the core-tests-support library.
-    ifeq ($(LIBCORE_SKIP_TESTS),)
+# Make the core-tests-support library.
+ifeq ($(LIBCORE_SKIP_TESTS),)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex
+    LOCAL_NO_STANDARD_LIBRARIES := true
+    LOCAL_JAVA_LIBRARIES := core-libart-hostdex core-junit-hostdex bouncycastle-hostdex
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-support-hostdex
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
-    endif
 endif
 
 #
diff --git a/NativeCode.mk b/NativeCode.mk
index 2a16598..98e87b0 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -112,22 +112,24 @@
 # Build for the host.
 #
 
-ifeq ($(WITH_HOST_DALVIK),true)
-    include $(CLEAR_VARS)
-    LOCAL_CLANG := true
-    LOCAL_SRC_FILES += $(core_src_files)
-    LOCAL_CFLAGS += $(core_cflags)
-    LOCAL_C_INCLUDES += $(core_c_includes)
-    LOCAL_CPPFLAGS += $(core_cppflags)
-    LOCAL_LDLIBS += -ldl -lpthread -lrt
-    LOCAL_MODULE_TAGS := optional
-    LOCAL_MODULE := libjavacore
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
-    LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host
-    LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive-host libutils
-    include $(BUILD_HOST_SHARED_LIBRARY)
+include $(CLEAR_VARS)
+LOCAL_CLANG := true
+LOCAL_SRC_FILES += $(core_src_files)
+LOCAL_CFLAGS += $(core_cflags)
+LOCAL_C_INCLUDES += $(core_c_includes)
+LOCAL_CPPFLAGS += $(core_cppflags)
+LOCAL_LDLIBS += -ldl -lpthread
+ifeq ($(HOST_OS),linux)
+LOCAL_LDLIBS += -lrt
+endif
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libjavacore
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
+LOCAL_SHARED_LIBRARIES += $(core_shared_libraries) libexpat-host libicuuc-host libicui18n-host libcrypto-host libz-host
+LOCAL_STATIC_LIBRARIES += $(core_static_libraries) libziparchive-host libutils
+include $(BUILD_HOST_SHARED_LIBRARY)
 
-    ifeq ($(LIBCORE_SKIP_TESTS),)
+ifeq ($(LIBCORE_SKIP_TESTS),)
     include $(CLEAR_VARS)
     LOCAL_CLANG := true
     LOCAL_SRC_FILES += $(core_test_files)
@@ -140,5 +142,4 @@
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
     LOCAL_SHARED_LIBRARIES := libcrypto-host
     include $(BUILD_HOST_SHARED_LIBRARY)
-    endif # LIBCORE_SKIP_TESTS
-endif
+endif # LIBCORE_SKIP_TESTS
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index b91894f..c0a38a0 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -1,34 +1,39 @@
+# -*- mode: makefile -*-
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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)
-##################################################
-include $(CLEAR_VARS)
 
 ifeq ($(LIBCORE_SKIP_TESTS),)
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+##################################################
+include $(CLEAR_VARS)
 LOCAL_MODULE := benchmarks
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	caliper-prebuilt \
-	core-tests
-
-LOCAL_JAVA_LIBRARIES := \
-	bouncycastle \
-	conscrypt \
-	core
-
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := caliper-prebuilt core-tests
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-libart conscrypt core-junit bouncycastle framework
 LOCAL_MODULE_TAGS := tests
-
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/data/caliperperf
-
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_JAVA_LIBRARY)
 
 ##################################################
 # Prebuilt Java libraries
 include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
-	caliper-prebuilt:libs/caliper.jar
-
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := caliper-prebuilt:libs/caliper.jar
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_MULTI_PREBUILT)
+
 endif
diff --git a/benchmarks/src/benchmarks/regression/IcuBenchmark.java b/benchmarks/src/benchmarks/regression/IcuBenchmark.java
index ee8270a..2aed36b 100644
--- a/benchmarks/src/benchmarks/regression/IcuBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/IcuBenchmark.java
@@ -26,7 +26,7 @@
 public class IcuBenchmark extends SimpleBenchmark {
   public void time_getBestDateTimePattern(int reps) throws Exception {
     for (int rep = 0; rep < reps; ++rep) {
-      ICU.getBestDateTimePattern("dEEEMMM", "US");
+      ICU.getBestDateTimePattern("dEEEMMM", new Locale("en", "US"));
     }
   }
 }
diff --git a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
index cde257b..ae6b6b6 100644
--- a/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/StringCaseMappingBenchmark.java
@@ -106,13 +106,13 @@
 
     public void timeToUpperCase_ICU(int reps) {
         for (int i = 0; i < reps; ++i) {
-            libcore.icu.ICU.toUpperCase(s.value, Locale.US.toString());
+            libcore.icu.ICU.toUpperCase(s.value, Locale.US);
         }
     }
 
     public void timeToLowerCase_ICU(int reps) {
         for (int i = 0; i < reps; ++i) {
-            libcore.icu.ICU.toLowerCase(s.value, Locale.US.toString());
+            libcore.icu.ICU.toLowerCase(s.value, Locale.US);
         }
     }
 
diff --git a/expectations/icebox.txt b/expectations/icebox.txt
index 07449c6..8764185 100644
--- a/expectations/icebox.txt
+++ b/expectations/icebox.txt
@@ -3,16 +3,6 @@
  */
 [
 {
- description: "javasqlite doesn't honor query timeouts",
- bug: 5213614,
- names: [
-   "libcore.sqlite.QueryTimeoutTest#testExecuteUpdate",
-   "libcore.sqlite.QueryTimeoutTest#testPreparedStatementFetch",
-   "libcore.sqlite.QueryTimeoutTest#testPreparedStatementUpdate",
-   "libcore.sqlite.QueryTimeoutTest#testTimeoutAndStatementReuse"
-  ]
-},
-{
   description: "Dalvik doesn't support XML Schemas, DTDs or validation",
   bug: 3268630,
   name: "libcore.xml.DomTest#testEntityDeclarations",
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 108fa6e..698ebc5 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -755,70 +755,6 @@
   name: "tests.api.javax.net.ssl.TrustManagerFactory1Test#test_initLjavax_net_ssl_ManagerFactoryParameters"
 },
 {
-  description: "method test fails once in a while. Cannot be sure that exception is thrown in every test execution.",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testBusy_handler"
-},
-{
-  description: "Database does not lock values",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testBusy_timeout"
-},
-{
-  description: "Returns wrong number for updates: returns value > 1 for select.",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testChanges"
-},
-{
-  description: "Aggregation function not called",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testCreate_aggregate"
-},
-{
-  description: "Reason for failure unknown: Database should be locked. Specification of interrupt is scarce.",
-  result: EXEC_FAILED,
-  name: "libcore.sqlite.OldDatabaseTest#testInterrupt"
-},
-{
-  description: "not supported",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testOpen_blob"
-},
-{
-  description: "Callback never made for authorization. Results of private table are returned without further checks.",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testSet_authorizer"
-},
-{
-  description: "ASCII encoding does not work: a UTF encoded val is returned. Spec is not sufficient. Might be that test impl is wrong or String constructor for the ASCII encoding.",
-  bug: 3403706,
-  name: "libcore.sqlite.OldDatabaseTest#testSet_encoding"
-},
-{
-  description: "db.open_blob is not supported.",
-  bug: 3403706,
-  name: "libcore.sqlite.OldBlobTest#testBlob"
-},
-{
-  description: "Wrong value is returned in case of a prepared statement to which a '*' bound",
-  bug: 3403706,
-  name: "libcore.sqlite.OldStmtTest#testColumn_count"
-},
-{
-  description: "ZeroBlob not supported",
-  bug: 3403706,
-  name: "libcore.sqlite.OldFunctionContextTest#testSet_result_zeroblob"
-},
-{
-  description: "SQLite test fail",
-  bug: 3403706,
-  names: [
-    "libcore.sqlite.OldDatabaseTest#testGet_tableString",
-    "libcore.sqlite.OldDatabaseTest#testGet_tableStringStringArrayTableResult",
-    "libcore.sqlite.OldStmtTest#testColumn_type"
-  ]
-},
-{
   modes: [ "jvm" ],
   description: "The RI's formatter doesn't localize arabic properly",
   names: [
@@ -1441,10 +1377,5 @@
   description: "Known failure in GregorianCalendarTest",
   bug: 12778197,
   name: "org.apache.harmony.tests.java.util.GregorianCalendarTest#test_computeTime"
-},
-{
-  description: "Large test that ends in a timeout during CTS runs",
-  bug: 5513723,
-  name: "libcore.java.security.KeyPairGeneratorTest#test_getInstance"
 }
 ]
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java
index 08a4fa9..17f822d 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/RuntimeTest.java
@@ -19,6 +19,8 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Vector;
 
 public class RuntimeTest extends junit.framework.TestCase {
@@ -82,14 +84,6 @@
     }
 
     /**
-     * java.lang.Runtime#freeMemory()
-     */
-    public void test_freeMemory() {
-        // Test for method long java.lang.Runtime.freeMemory()
-        assertTrue("freeMemory returned nonsense value", r.freeMemory() > 0);
-    }
-
-    /**
      * java.lang.Runtime#gc()
      */
     public void test_gc() {
@@ -142,12 +136,28 @@
     }
 
     /**
-     * java.lang.Runtime#totalMemory()
+     * java.lang.Runtime#freeMemory() / java.lang.Runtime#totalMemory() /
+     * java.lang.Runtime#maxMemory()
      */
-    public void test_totalMemory() {
-        // Test for method long java.lang.Runtime.totalMemory()
-        assertTrue("totalMemory returned nonsense value", r.totalMemory() >= r
-                .freeMemory());
+    public void test_memory() {
+        assertTrue("freeMemory <= 0", r.freeMemory() > 0);
+        assertTrue("totalMemory() < freeMemory()", r.totalMemory() >= r.freeMemory());
+        assertTrue("maxMemory() < totalMemory()", r.maxMemory() >= r.totalMemory());
+    }
+
+    public void test_freeMemory() {
+        // Heap might grow or do GC at any time, so we can't really test a lot. Hence we are just
+        // doing some basic sanity checks here.
+        long freeBefore = r.freeMemory();
+        List<byte[]> arrays = new ArrayList<byte[]>();
+        for (int i = 1; i < 10; i++) {
+            arrays.add(new byte[10000]);
+        }
+        long freeAfter =  r.freeMemory();
+
+        // If totalMemory() has grown/shrunk freeMemory() might have gone down or up, but the
+        // freeMemory is unlikely to stay the same.
+        assertTrue("free memory must change with allocations", freeAfter != freeBefore);
     }
 
     public RuntimeTest() {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
index 6a75746..e3e1207 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
@@ -18,7 +18,6 @@
 package org.apache.harmony.tests.java.net;
 
 import java.io.IOException;
-import java.io.InterruptedIOException;
 import java.net.BindException;
 import java.net.DatagramPacket;
 import java.net.Inet4Address;
@@ -29,8 +28,10 @@
 import java.net.NetworkInterface;
 import java.net.SocketAddress;
 import java.net.SocketException;
+import java.net.SocketTimeoutException;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.List;
 
 public class MulticastSocketTest extends junit.framework.TestCase {
 
@@ -52,158 +53,124 @@
     private static InetAddress GOOD_IPv6 = lookup("ff05::7:7");
     private static InetAddress BAD_IPv6 = lookup("ff05::7:8");
 
-    static class MulticastServer extends Thread {
+    private NetworkInterface loopbackInterface;
+    private NetworkInterface ipv4NetworkInterface;
+    private NetworkInterface ipv6NetworkInterface;
 
-        public final MulticastSocket ms;
-        public final byte[] rbuf = new byte[512];
-        public final DatagramPacket rdp;
-        private final InetAddress groupAddr;
-        private final NetworkInterface groupNI;
+    @Override
+    protected void setUp() throws Exception {
+        // The loopback interface isn't actually useful for sending/receiving multicast messages
+        // but it can be used as a dummy for tests where that does not matter.
+        loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
+        assertNotNull(loopbackInterface);
+        assertTrue(loopbackInterface.isLoopback());
+        assertFalse(loopbackInterface.supportsMulticast());
 
-        private volatile boolean running = true;
+        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+        assertNotNull(interfaces);
 
-        public MulticastServer(InetAddress anAddress, int aPort) throws java.io.IOException {
-            rbuf[0] = -1;
-            rdp = new DatagramPacket(rbuf, rbuf.length);
-            ms = new MulticastSocket(aPort);
-            ms.setSoTimeout(2000);
-
-            groupAddr = anAddress;
-            groupNI = null;
-
-            ms.joinGroup(groupAddr);
-        }
-
-        public MulticastServer(InetAddress anAddress, int aPort,
-                NetworkInterface netInterface) throws java.io.IOException {
-            rbuf[0] = -1;
-            rdp = new DatagramPacket(rbuf, rbuf.length);
-            ms = new MulticastSocket(aPort);
-            ms.setSoTimeout(2000);
-
-            groupAddr = anAddress;
-            groupNI = netInterface;
-
-            ms.joinGroup(new InetSocketAddress(groupAddr, ms.getLocalPort()), groupNI);
-        }
-
-        public void run() {
-            try {
-                byte[] tmpbuf = new byte[512];
-                DatagramPacket tmpPack = new DatagramPacket(tmpbuf, tmpbuf.length);
-
-                while (running) {
-                    try {
-                        ms.receive(tmpPack);
-                        System.arraycopy(tmpPack.getData(), 0, rdp.getData(), rdp.getOffset(),
-                                tmpPack.getLength());
-                        rdp.setLength(tmpPack.getLength());
-                        rdp.setAddress(tmpPack.getAddress());
-                        rdp.setPort(tmpPack.getPort());
-                    } catch (InterruptedIOException e) {
+        while (interfaces.hasMoreElements()
+                && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) {
+            NetworkInterface nextInterface = interfaces.nextElement();
+            if (willWorkForMulticast(nextInterface)) {
+                Enumeration<InetAddress> addresses = nextInterface.getInetAddresses();
+                while (addresses.hasMoreElements()) {
+                    final InetAddress nextAddress = addresses.nextElement();
+                    if (nextAddress instanceof Inet6Address && ipv6NetworkInterface == null) {
+                        ipv6NetworkInterface = nextInterface;
+                    } else if (nextAddress instanceof Inet4Address && ipv4NetworkInterface == null) {
+                        ipv4NetworkInterface = nextInterface;
                     }
                 }
-            } catch (java.io.IOException e) {
-                fail();
-            } finally {
-                ms.close();
             }
         }
-
-        public void stopServer() {
-            running = false;
-            try {
-                ms.leaveGroup(groupAddr);
-            } catch (IOException e) {
-            }
-        }
+        assertTrue("Test environment must have at least one interface capable of multicast for IPv4"
+                + " and IPv6",
+                ipv4NetworkInterface != null && ipv6NetworkInterface != null);
     }
 
-    private NetworkInterface loopbackInterface;
-    private NetworkInterface networkInterface1;
-    private NetworkInterface IPV6networkInterface1;
-
     public void test_Constructor() throws IOException {
-        // regression test for 497
+        // Regression test for 497.
         MulticastSocket s = new MulticastSocket();
-        // regression test for Harmony-1162
+        // Regression test for Harmony-1162.
         assertTrue(s.getReuseAddress());
+
+        s.close();
     }
 
     public void test_ConstructorI() throws IOException {
         MulticastSocket orig = new MulticastSocket();
         int port = orig.getLocalPort();
         orig.close();
-        MulticastSocket dup = null;
-        try {
-            dup = new MulticastSocket(port);
-            // regression test for Harmony-1162
-            assertTrue(dup.getReuseAddress());
-        } catch (IOException e) {
-            fail("duplicate binding not allowed: " + e);
-        }
-        if (dup != null) {
-            dup.close();
-        }
+
+        MulticastSocket dup = new MulticastSocket(port);
+        // Regression test for Harmony-1162.
+        assertTrue(dup.getReuseAddress());
+        dup.close();
     }
 
     public void test_getInterface() throws Exception {
-        // validate that we get the expected response when one was not set
+        // Validate that we get the expected response when one was not set.
         MulticastSocket mss = new MulticastSocket(0);
-        // we expect an ANY address in this case
+        // We expect an ANY address in this case.
         assertTrue(mss.getInterface().isAnyLocalAddress());
 
-        // validate that we get the expected response when we set via
-        // setInterface
-        Enumeration addresses = networkInterface1.getInetAddresses();
+        // Validate that we get the expected response when we set via setInterface.
+        Enumeration addresses = ipv4NetworkInterface.getInetAddresses();
         if (addresses.hasMoreElements()) {
             InetAddress firstAddress = (InetAddress) addresses.nextElement();
             mss.setInterface(firstAddress);
-            assertEquals("getNetworkInterface did not return interface set by setInterface", firstAddress, mss.getInterface());
+            assertEquals("getNetworkInterface did not return interface set by setInterface",
+                    firstAddress, mss.getInterface());
 
             mss.close();
             mss = new MulticastSocket(0);
-            mss.setNetworkInterface(networkInterface1);
-            assertEquals("getInterface did not return interface set by setNetworkInterface", networkInterface1, NetworkInterface.getByInetAddress(mss.getInterface()));
+            mss.setNetworkInterface(ipv4NetworkInterface);
+            assertEquals("getInterface did not return interface set by setNetworkInterface",
+                    ipv4NetworkInterface, NetworkInterface.getByInetAddress(mss.getInterface()));
         }
 
         mss.close();
     }
 
     public void test_getNetworkInterface() throws IOException {
-        // validate that we get the expected response when one was not set
+        // Validate that we get the expected response when one was not set.
         MulticastSocket mss = new MulticastSocket(0);
         NetworkInterface theInterface = mss.getNetworkInterface();
-        assertTrue("network interface returned wrong network interface when not set:" + theInterface,
+        assertTrue(
+                "network interface returned wrong network interface when not set:" + theInterface,
                 theInterface.getInetAddresses().hasMoreElements());
-        InetAddress firstAddress = (InetAddress) theInterface.getInetAddresses().nextElement();
-        // validate we the first address in the network interface is the ANY address
+        InetAddress firstAddress = theInterface.getInetAddresses().nextElement();
+        // Validate we the first address in the network interface is the ANY address.
         assertTrue(firstAddress.isAnyLocalAddress());
 
-        mss.setNetworkInterface(networkInterface1);
+        mss.setNetworkInterface(ipv4NetworkInterface);
         assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
-                networkInterface1, mss.getNetworkInterface());
+                ipv4NetworkInterface, mss.getNetworkInterface());
 
         mss.setNetworkInterface(loopbackInterface);
-        assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
+        assertEquals(
+                "getNetworkInterface did not return network interface set by second"
+                        + " setNetworkInterface call",
                 loopbackInterface, mss.getNetworkInterface());
         mss.close();
 
-        mss = new MulticastSocket(0);
-        if (IPV6networkInterface1 != null) {
-            mss.setNetworkInterface(IPV6networkInterface1);
+        if (ipv6NetworkInterface != null) {
+            mss = new MulticastSocket(0);
+            mss.setNetworkInterface(ipv6NetworkInterface);
             assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
-                    IPV6networkInterface1, mss.getNetworkInterface());
+                    ipv6NetworkInterface, mss.getNetworkInterface());
+            mss.close();
         }
 
-        // validate that we get the expected response when we set via setInterface
+        // Validate that we get the expected response when we set via setInterface.
         mss = new MulticastSocket(0);
-        Enumeration addresses = networkInterface1.getInetAddresses();
+        Enumeration addresses = ipv4NetworkInterface.getInetAddresses();
         if (addresses.hasMoreElements()) {
             firstAddress = (InetAddress) addresses.nextElement();
             mss.setInterface(firstAddress);
             assertEquals("getNetworkInterface did not return interface set by setInterface",
-                    networkInterface1, mss.getNetworkInterface());
+                    ipv4NetworkInterface, mss.getNetworkInterface());
         }
         mss.close();
     }
@@ -214,12 +181,14 @@
         assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
         mss.setTimeToLive(220);
         assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive());
+        mss.close();
     }
 
     public void test_getTTL() throws Exception {
         MulticastSocket mss = new MulticastSocket();
         mss.setTTL((byte) 120);
         assertEquals("Returned incorrect TTL", 120, mss.getTTL());
+        mss.close();
     }
 
     public void test_joinGroupLjava_net_InetAddress_IPv4() throws Exception {
@@ -231,19 +200,23 @@
     }
 
     private void test_joinGroupLjava_net_InetAddress(InetAddress group) throws Exception {
-        MulticastServer server = new MulticastServer(group, 0);
-        server.start();
-        Thread.sleep(1000);
+        MulticastSocket receivingSocket = createReceivingSocket(0);
+        receivingSocket.joinGroup(group);
+
         String msg = "Hello World";
-        MulticastSocket mss = new MulticastSocket(server.ms.getLocalPort());
-        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group,
-                server.ms.getLocalPort());
-        mss.send(sdp, (byte) 10);
-        Thread.sleep(1000);
-        String receivedMessage = new String(server.rdp.getData(), 0, server.rdp.getLength());
+        MulticastSocket sendingSocket = new MulticastSocket(receivingSocket.getLocalPort());
+        InetSocketAddress groupAddress =
+                new InetSocketAddress(group, receivingSocket.getLocalPort());
+        DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+        sendingSocket.send(sdp, (byte) 10 /* ttl */);
+
+        DatagramPacket rdp = createReceiveDatagramPacket();
+        receivingSocket.receive(rdp);
+        String receivedMessage = extractMessage(rdp);
         assertEquals("Group member did not recv data", msg, receivedMessage);
-        mss.close();
-        server.stopServer();
+
+        sendingSocket.close();
+        receivingSocket.close();
     }
 
     public void test_joinGroup_null_null() throws Exception {
@@ -276,52 +249,64 @@
         mss.close();
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv4, BAD_IPv4);
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+            throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+                ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv6, BAD_IPv6);
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+            throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+                ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
     }
 
-    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(InetAddress group, InetAddress group2) throws Exception {
+    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+            NetworkInterface networkInterface, InetAddress group, InetAddress group2)
+            throws Exception {
         // Check that we can join a group using a null network interface.
-        MulticastSocket mss = new MulticastSocket(0);
-        SocketAddress groupSockAddr = new InetSocketAddress(group, mss.getLocalPort());
+        MulticastSocket sendingSocket = new MulticastSocket(0);
+        SocketAddress groupSockAddr = new InetSocketAddress(group, sendingSocket.getLocalPort());
+        sendingSocket.joinGroup(groupSockAddr, null);
+        sendingSocket.setTimeToLive(2);
 
-        mss.joinGroup(groupSockAddr, null);
-        mss.setTimeToLive(2);
-        Thread.sleep(1000);
+        MulticastSocket receivingSocket = createReceivingSocket(0);
+        InetSocketAddress groupAddress =
+                new InetSocketAddress(group, receivingSocket.getLocalPort());
+        receivingSocket.joinGroup(groupAddress, networkInterface);
 
-        // set up the server and join the group on networkInterface1
-        MulticastServer server = new MulticastServer(group, 0, networkInterface1);
-        server.start();
-        Thread.sleep(1000);
         String msg = "Hello World";
-        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group,
-                server.ms.getLocalPort());
-        mss.setTimeToLive(2);
-        mss.send(sdp);
-        Thread.sleep(1000);
-        // now validate that we received the data as expected
-        assertEquals("Group member did not recv data", msg, new String(server.rdp.getData(), 0, server.rdp.getLength()));
-        server.stopServer();
-        mss.close();
+        DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+        sendingSocket.send(sdp);
 
-        server = new MulticastServer(group, 0, networkInterface1);
-        server.start();
-        Thread.sleep(1000);
+        DatagramPacket rdp = createReceiveDatagramPacket();
+        receivingSocket.receive(rdp);
+        // Now validate that we received the data as expected.
+        assertEquals("Group member did not recv data", msg, extractMessage(rdp));
+        receivingSocket.close();
+        sendingSocket.close();
 
-        mss = new MulticastSocket(0);
-        mss.setTimeToLive(10);
+        receivingSocket = createReceivingSocket(0);
+        groupAddress = new InetSocketAddress(group, receivingSocket.getLocalPort());
+        receivingSocket.joinGroup(groupAddress, networkInterface);
+
+        sendingSocket = new MulticastSocket(0);
+        sendingSocket.setTimeToLive(10);
         msg = "Hello World - Different Group";
-        sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2, server.ms.getLocalPort());
-        mss.send(sdp);
-        Thread.sleep(1000);
-        assertFalse("Group member received data when sent on different group: ",
-                new String(server.rdp.getData(), 0, server.rdp.getLength()).equals(msg));
-        server.stopServer();
-        mss.close();
+        InetSocketAddress group2Address =
+                new InetSocketAddress(group2, receivingSocket.getLocalPort());
+        sdp = createSendDatagramPacket(group2Address, msg);
+        sendingSocket.send(sdp);
+
+        rdp = createReceiveDatagramPacket();
+        try {
+            receivingSocket.receive(rdp);
+            fail("Expected timeout");
+        } catch (SocketTimeoutException expected) {
+        }
+
+        receivingSocket.close();
+        sendingSocket.close();
     }
 
     public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
@@ -329,27 +314,19 @@
         // received on that interface. This test is only really useful on devices with multiple
         // non-loopback interfaces.
 
-        ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
+        List<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
         Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
         while (theInterfaces.hasMoreElements()) {
             NetworkInterface thisInterface = theInterfaces.nextElement();
-            if (thisInterface.getInetAddresses().hasMoreElements()) {
+            // Skip interfaces that do not support multicast - there's no point in proving
+            // they cannot send / receive multicast messages.
+            if (willWorkForMulticast(thisInterface)) {
                 realInterfaces.add(thisInterface);
             }
         }
 
-        for (int i = 0; i < realInterfaces.size(); i++) {
-            NetworkInterface thisInterface = realInterfaces.get(i);
-            if (!thisInterface.supportsMulticast()) {
-                // Skip interfaces that do not support multicast - there's no point in proving
-                // they cannot send / receive multicast messages.
-                continue;
-            }
-
-            // get the first address on the interface
-
-            // start server which is joined to the group and has
-            // only asked for packets on this interface
+        for (NetworkInterface thisInterface : realInterfaces) {
+            // Find a suitable group IP and interface to use to sent packets to thisInterface.
             Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
 
             NetworkInterface sendingInterface = null;
@@ -358,57 +335,69 @@
                 InetAddress firstAddress = addresses.nextElement();
                 if (firstAddress instanceof Inet4Address) {
                     group = GOOD_IPv4;
-                    sendingInterface = networkInterface1;
+                    sendingInterface = ipv4NetworkInterface;
                 } else {
                     // if this interface only seems to support IPV6 addresses
                     group = GOOD_IPv6;
-                    sendingInterface = IPV6networkInterface1;
+                    sendingInterface = ipv6NetworkInterface;
                 }
             }
 
-            MulticastServer server = new MulticastServer(group, 0, thisInterface);
-            server.start();
-            Thread.sleep(1000);
+            // Create a receivingSocket which is joined to the group and has only asked for packets
+            // on thisInterface.
+            MulticastSocket receivingSocket = createReceivingSocket(0);
+            InetSocketAddress groupAddress =
+                    new InetSocketAddress(group, receivingSocket.getLocalPort());
+            receivingSocket.joinGroup(groupAddress, thisInterface);
 
-            // Now send out a package on interface networkInterface 1. We should
-            // only see the packet if we send it on interface 1
-            MulticastSocket mss = new MulticastSocket(0);
-            mss.setNetworkInterface(sendingInterface);
-            String msg = "Hello World - Again" + thisInterface.getName();
-            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group,
-                    server.ms.getLocalPort());
-            mss.send(sdp);
-            Thread.sleep(1000);
-            if (thisInterface.equals(sendingInterface)) {
+            // Now send out a packet on sendingInterface. We should only see the packet if we send
+            // it on thisInterface.
+            MulticastSocket sendingSocket = new MulticastSocket(0);
+            sendingSocket.setNetworkInterface(sendingInterface);
+            String msg = "Hello World - Again " + thisInterface.getName();
+            DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+            sendingSocket.send(sdp);
+
+            DatagramPacket rdp = createReceiveDatagramPacket();
+            try {
+                receivingSocket.receive(rdp);
+
+                // If the packet is received....
+                assertEquals(thisInterface, sendingInterface);
                 assertEquals("Group member did not recv data when bound on specific interface",
-                        msg, new String(server.rdp.getData(), 0, server.rdp.getLength()));
-            } else {
-                assertFalse("Group member received data on other interface when only asked for it on one interface: ",
-                        new String(server.rdp.getData(), 0, server.rdp.getLength()).equals(msg));
+                        msg, extractMessage(rdp));
+            } catch (SocketTimeoutException e) {
+                // If the packet was not received...
+                assertTrue(!thisInterface.equals(sendingInterface));
             }
 
-            server.stopServer();
-            mss.close();
+            receivingSocket.close();
+            sendingSocket.close();
         }
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4() throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(GOOD_IPv4);
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4()
+            throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+                ipv4NetworkInterface, GOOD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6() throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(GOOD_IPv6);
+    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6()
+            throws Exception {
+        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+                ipv6NetworkInterface, GOOD_IPv6);
     }
 
-    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(InetAddress group) throws Exception {
-        // validate that we can join the same address on two
-        // different interfaces but not on the same interface
+    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+            NetworkInterface networkInterface, InetAddress group) throws Exception {
+        // Validate that we can join the same address on two different interfaces but not on the
+        // same interface.
         MulticastSocket mss = new MulticastSocket(0);
         SocketAddress groupSockAddr = new InetSocketAddress(group, mss.getLocalPort());
-        mss.joinGroup(groupSockAddr, networkInterface1);
+        mss.joinGroup(groupSockAddr, networkInterface);
         mss.joinGroup(groupSockAddr, loopbackInterface);
         try {
-            mss.joinGroup(groupSockAddr, networkInterface1);
+            mss.joinGroup(groupSockAddr, networkInterface);
             fail("Did not get expected exception when joining for second time on same interface");
         } catch (IOException e) {
         }
@@ -426,9 +415,9 @@
     private void test_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception {
         String msg = "Hello World";
         MulticastSocket mss = new MulticastSocket(0);
-        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group,
-                mss.getLocalPort());
-        mss.send(sdp, (byte) 10);
+        InetSocketAddress groupAddress = new InetSocketAddress(group, mss.getLocalPort());
+        DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+        mss.send(sdp, (byte) 10 /* ttl */);
         try {
             // Try to leave a group we didn't join.
             mss.leaveGroup(group);
@@ -468,15 +457,21 @@
         mss.close();
     }
 
-    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() throws Exception {
-        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv4, BAD_IPv4);
+    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+            throws Exception {
+        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+                ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
     }
 
-    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() throws Exception {
-        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(GOOD_IPv6, BAD_IPv6);
+    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+            throws Exception {
+        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+                ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
     }
 
-    private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(InetAddress group, InetAddress group2) throws Exception {
+    private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+            NetworkInterface networkInterface, InetAddress group, InetAddress group2)
+            throws Exception {
         SocketAddress groupSockAddr = null;
         SocketAddress groupSockAddr2 = null;
 
@@ -491,20 +486,20 @@
         }
 
         groupSockAddr2 = new InetSocketAddress(group2, mss.getLocalPort());
-        mss.joinGroup(groupSockAddr, networkInterface1);
+        mss.joinGroup(groupSockAddr, networkInterface);
         try {
-            mss.leaveGroup(groupSockAddr2, networkInterface1);
+            mss.leaveGroup(groupSockAddr2, networkInterface);
             fail("Did not get exception when trying to leave group that was never joined");
         } catch (IOException expected) {
         }
 
-        mss.leaveGroup(groupSockAddr, networkInterface1);
+        mss.leaveGroup(groupSockAddr, networkInterface);
 
-        mss.joinGroup(groupSockAddr, networkInterface1);
+        mss.joinGroup(groupSockAddr, networkInterface);
         try {
             mss.leaveGroup(groupSockAddr, loopbackInterface);
             fail("Did not get exception when trying to leave group on wrong interface " +
-                    "joined on [" + networkInterface1 + "] left on [" + loopbackInterface + "]");
+                    "joined on [" + networkInterface + "] left on [" + loopbackInterface + "]");
         } catch (IOException expected) {
         }
     }
@@ -519,31 +514,36 @@
 
     private void test_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception {
         String msg = "Hello World";
-        MulticastSocket mss = new MulticastSocket(0);
-        MulticastServer server = new MulticastServer(group, mss.getLocalPort());
-        server.start();
-        Thread.sleep(200);
-        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg.length(), group, mss.getLocalPort());
-        mss.send(sdp, (byte) 10);
-        Thread.sleep(1000);
-        mss.close();
-        byte[] data = server.rdp.getData();
-        int length = server.rdp.getLength();
-        assertEquals("Failed to send data. Received " + length, msg, new String(data, 0, length));
-        server.stopServer();
+        MulticastSocket sendingSocket = new MulticastSocket(0);
+        MulticastSocket receivingSocket = createReceivingSocket(sendingSocket.getLocalPort());
+        receivingSocket.joinGroup(group);
+
+        InetSocketAddress groupAddress = new InetSocketAddress(group, sendingSocket.getLocalPort());
+        DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+        sendingSocket.send(sdp, (byte) 10 /* ttl */);
+        sendingSocket.close();
+
+        DatagramPacket rdp = createReceiveDatagramPacket();
+        receivingSocket.receive(rdp);
+        String receivedMessage = extractMessage(rdp);
+        assertEquals("Failed to send data. Received " + rdp.getLength(), msg, receivedMessage);
+        receivingSocket.close();
     }
 
     public void test_setInterfaceLjava_net_InetAddress() throws Exception {
         MulticastSocket mss = new MulticastSocket();
         mss.setInterface(InetAddress.getLocalHost());
         InetAddress theInterface = mss.getInterface();
-        // under IPV6 we are not guarrenteed to get the same address back as
-        // the address, all we should be guaranteed is that we get an
-        // address on the same interface
+        // Under IPV6 we are not guaranteed to get the same address back as the address that was
+        // set, all we should be guaranteed is that we get an address on the same interface.
         if (theInterface instanceof Inet6Address) {
-            assertTrue("Failed to return correct interface IPV6", NetworkInterface.getByInetAddress(mss.getInterface()).equals(NetworkInterface.getByInetAddress(theInterface)));
+            assertEquals("Failed to return correct interface IPV6",
+                    NetworkInterface.getByInetAddress(mss.getInterface()),
+                    NetworkInterface.getByInetAddress(theInterface));
         } else {
-            assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() + " excpeted: " + InetAddress.getLocalHost(), mss.getInterface().equals(InetAddress.getLocalHost()));
+            assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() +
+                    " expected: " + InetAddress.getLocalHost(),
+                    mss.getInterface().equals(InetAddress.getLocalHost()));
         }
         mss.close();
     }
@@ -556,7 +556,7 @@
         test_setInterface_unbound_address(GOOD_IPv6);
     }
 
-    // Regression test for Harmony-2410
+    // Regression test for Harmony-2410.
     private void test_setInterface_unbound_address(InetAddress address) throws Exception {
         MulticastSocket mss = new MulticastSocket();
         try {
@@ -568,7 +568,7 @@
     }
 
     public void test_setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception {
-        // validate that null interface is handled ok
+        // Validate that null interface is handled ok.
         MulticastSocket mss = new MulticastSocket();
         try {
             mss.setNetworkInterface(null);
@@ -579,10 +579,11 @@
     }
 
     public void test_setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception {
-        // validate that we can get and set the interface
+        // Validate that we can get and set the interface.
         MulticastSocket mss = new MulticastSocket();
-        mss.setNetworkInterface(networkInterface1);
-        assertEquals("Interface did not seem to be set by setNeworkInterface", networkInterface1, mss.getNetworkInterface());
+        mss.setNetworkInterface(ipv4NetworkInterface);
+        assertEquals("Interface did not seem to be set by setNeworkInterface",
+                ipv4NetworkInterface, mss.getNetworkInterface());
         mss.close();
     }
 
@@ -594,35 +595,35 @@
         test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6);
     }
 
-    private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group) throws IOException, InterruptedException {
-        // set up the server and join the group
+    private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group)
+            throws IOException, InterruptedException {
+        // Set up the receiving socket and join the group.
         Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
         while (theInterfaces.hasMoreElements()) {
             NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
             if (thisInterface.getInetAddresses().hasMoreElements() && thisInterface.isUp()) {
                 if ((!(thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) {
-                    MulticastServer server = new MulticastServer(group, 0);
-                    server.start();
-                    // give the server some time to start up
-                    Thread.sleep(1000);
+                    MulticastSocket receivingSocket = createReceivingSocket(0);
+                    InetSocketAddress groupAddress =
+                            new InetSocketAddress(group, receivingSocket.getLocalPort());
+                    receivingSocket.joinGroup(groupAddress, thisInterface);
 
-                    // Send the packets on a particular interface. The
-                    // source address in the received packet
-                    // should be one of the addresses for the interface
-                    // set
-                    MulticastSocket mss = new MulticastSocket(0);
-                    mss.setNetworkInterface(thisInterface);
+                    // Send the packets on a particular interface. The source address in the
+                    // received packet should be one of the addresses for the interface set.
+                    MulticastSocket sendingSocket = new MulticastSocket(0);
+                    sendingSocket.setNetworkInterface(thisInterface);
                     String msg = thisInterface.getName();
-                    byte theBytes[] = msg.getBytes();
-                    DatagramPacket sdp = new DatagramPacket(theBytes, theBytes.length, group,
-                            server.ms.getLocalPort());
-                    mss.send(sdp);
-                    Thread.sleep(1000);
-                    String receivedMessage = new String(server.rdp.getData(), 0, server.rdp.getLength());
-                    assertEquals("Group member did not recv data sent on a specific interface", msg, receivedMessage);
-                    // stop the server
-                    server.stopServer();
-                    mss.close();
+                    DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg);
+                    sendingSocket.send(sdp);
+
+                    DatagramPacket rdp = createReceiveDatagramPacket();
+                    receivingSocket.receive(rdp);
+                    String receivedMessage = extractMessage(rdp);
+                    assertEquals("Group member did not recv data sent on a specific interface",
+                            msg, receivedMessage);
+                    // Stop the server.
+                    receivingSocket.close();
+                    sendingSocket.close();
                 }
             }
         }
@@ -651,24 +652,28 @@
         assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
         ms.close();
         assertTrue("should be closed", ms.isClosed());
+
         ms = new MulticastSocket(0);
         assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
         ms.close();
         assertTrue("should be closed", ms.isClosed());
+
         ms = new MulticastSocket(0);
         assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected());
         ms.close();
         assertTrue("should be closed", ms.isClosed());
+
         try {
-            ms = new MulticastSocket(new InetSocketAddress("unresolvedname", 31415));
+            new MulticastSocket(new InetSocketAddress("unresolvedname", 31415));
             fail();
         } catch (IOException expected) {
         }
 
-        // regression test for Harmony-1162
+        // Regression test for Harmony-1162.
         InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
         MulticastSocket s = new MulticastSocket(addr);
         assertTrue(s.getReuseAddress());
+        s.close();
     }
 
     public void test_getLoopbackMode() throws Exception {
@@ -699,129 +704,69 @@
     }
 
     private void test_setLoopbackModeSendReceive(InetAddress group) throws IOException {
+        // Test send receive.
         final String message = "Hello, world!";
 
-        // test send receive
         MulticastSocket socket = new MulticastSocket(0);
         socket.setLoopbackMode(false); // false indicates doing loop back
         socket.joinGroup(group);
 
-        // send the datagram
-        byte[] sendData = message.getBytes();
-        DatagramPacket sendDatagram = new DatagramPacket(sendData, 0, sendData.length,
-                new InetSocketAddress(group, socket.getLocalPort()));
+        // Send the datagram.
+        InetSocketAddress groupAddress = new InetSocketAddress(group, socket.getLocalPort());
+        DatagramPacket sendDatagram = createSendDatagramPacket(groupAddress, message);
         socket.send(sendDatagram);
 
-        // receive the datagram
-        byte[] recvData = new byte[100];
-        DatagramPacket recvDatagram = new DatagramPacket(recvData, recvData.length);
-        socket.setSoTimeout(5000); // prevent eternal block in
+        // Receive the datagram.
+        DatagramPacket recvDatagram = createReceiveDatagramPacket();
+        socket.setSoTimeout(5000); // Prevent eternal block in.
         socket.receive(recvDatagram);
-        String recvMessage = new String(recvData, 0, recvDatagram.getLength());
+        String recvMessage = extractMessage(recvDatagram);
         assertEquals(message, recvMessage);
         socket.close();
     }
 
     public void test_setReuseAddressZ() throws Exception {
-        // test case were we set it to false
-        MulticastSocket theSocket1 = null;
-        MulticastSocket theSocket2 = null;
+        // Test case were we to set ReuseAddress to false.
+        MulticastSocket theSocket1 = new MulticastSocket(null);
+        theSocket1.setReuseAddress(false);
+
+        MulticastSocket theSocket2 = new MulticastSocket(null);
+        theSocket2.setReuseAddress(false);
+
+        InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
+        theSocket1.bind(addr);
+        addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
         try {
-            theSocket1 = new MulticastSocket(null);
-            theSocket2 = new MulticastSocket(null);
-            theSocket1.setReuseAddress(false);
-            theSocket2.setReuseAddress(false);
-            InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
-            theSocket1.bind(addr);
-            addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
             theSocket2.bind(addr);
-            fail("No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
+            fail("No exception when trying to connect to do duplicate socket bind with re-useaddr"
+                    + " set to false");
         } catch (BindException expected) {
         }
-        if (theSocket1 != null) {
-            theSocket1.close();
-        }
-        if (theSocket2 != null) {
-            theSocket2.close();
-        }
+        theSocket1.close();
+        theSocket2.close();
 
-        // test case were we set it to true
+        // Test case were we set it to true.
         theSocket1 = new MulticastSocket(null);
         theSocket2 = new MulticastSocket(null);
         theSocket1.setReuseAddress(true);
         theSocket2.setReuseAddress(true);
-        InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
+        addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
         theSocket1.bind(addr);
         addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
         theSocket2.bind(addr);
 
-        if (theSocket1 != null) {
-            theSocket1.close();
-        }
-        if (theSocket2 != null) {
-            theSocket2.close();
-        }
+        theSocket1.close();
+        theSocket2.close();
 
-        // test the default case which we expect to be
-        // the same on all platforms
+        // Test the default case which we expect to be the same on all platforms.
         theSocket1 = new MulticastSocket(null);
         theSocket2 = new MulticastSocket(null);
         addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0);
         theSocket1.bind(addr);
         addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort());
         theSocket2.bind(addr);
-        if (theSocket1 != null) {
-            theSocket1.close();
-        }
-        if (theSocket2 != null) {
-            theSocket2.close();
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // The loopback interface isn't actually useful for sending/receiving multicast messages
-        // but it can be used as a dummy for tests where that does not matter.
-        loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
-        assertNotNull(loopbackInterface);
-        assertTrue(loopbackInterface.isLoopback());
-        assertFalse(loopbackInterface.supportsMulticast());
-
-        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
-
-        // only consider interfaces that have addresses associated with them.
-        // Otherwise tests don't work so well
-        if (interfaces != null) {
-            boolean atLeastOneInterface = false;
-            while (interfaces.hasMoreElements() && (atLeastOneInterface == false)) {
-                networkInterface1 = interfaces.nextElement();
-                if (willWorkForMulticast(networkInterface1)) {
-                    atLeastOneInterface = true;
-                }
-            }
-
-            assertTrue("Test environment must have at least one environment capable of multicast",
-                    atLeastOneInterface);
-
-            // Find the first multicast-compatible interface that supports IPV6 if one exists
-            interfaces = NetworkInterface.getNetworkInterfaces();
-
-            boolean found = false;
-            while (interfaces.hasMoreElements() && !found) {
-                NetworkInterface nextInterface = interfaces.nextElement();
-                if (willWorkForMulticast(nextInterface)) {
-                    Enumeration<InetAddress> addresses = nextInterface.getInetAddresses();
-                    while (addresses.hasMoreElements()) {
-                        final InetAddress nextAddress = addresses.nextElement();
-                        if (nextAddress instanceof Inet6Address) {
-                            IPV6networkInterface1 = nextInterface;
-                            found = true;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
+        theSocket1.close();
+        theSocket2.close();
     }
 
     private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
@@ -831,4 +776,26 @@
                 && !iface.isLoopback() && iface.supportsMulticast()
                 && iface.getInetAddresses().hasMoreElements();
     }
+
+    private static MulticastSocket createReceivingSocket(int aPort) throws IOException {
+        MulticastSocket ms = new MulticastSocket(aPort);
+        ms.setSoTimeout(2000);
+        return ms;
+    }
+
+    private static DatagramPacket createReceiveDatagramPacket() {
+        byte[] rbuf = new byte[512];
+        return new DatagramPacket(rbuf, rbuf.length);
+    }
+
+    private static DatagramPacket createSendDatagramPacket(
+            InetSocketAddress groupAndPort, String msg) {
+        return new DatagramPacket(
+                msg.getBytes(), msg.length(), groupAndPort.getAddress(), groupAndPort.getPort());
+    }
+
+    private static String extractMessage(DatagramPacket rdp) {
+        return new String(rdp.getData(), 0, rdp.getLength());
+    }
+
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
index 092cc54..07256e4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
@@ -28,7 +28,18 @@
 
 public class CurrencyTest extends junit.framework.TestCase {
 
-    private static Locale defaultLocale = Locale.getDefault();
+    private Locale originalLocale;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        originalLocale = Locale.getDefault();
+    }
+
+    @Override
+    protected void tearDown() {
+        Locale.setDefault(originalLocale);
+    }
 
     /**
      * java.util.Currency#getInstance(java.lang.String)
@@ -146,14 +157,16 @@
         assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
         // END android-changed
 
-        // test what happens if this is an invalid locale,
-        // one with Korean country but an India language
+        // Test what happens if the default is an invalid locale, one with the country Korea (KR)
+        // but a currently unsupported language. "kr" == Kanuri (Korean is actually "ko").
+        // All these values are those defined in the "root" locale or the currency code if one isn't
+        // defined.
         Locale.setDefault(new Locale("kr", "KR"));
         // BEGIN android-changed
         assertEquals("currK.getSymbol()", "\u20a9", currK.getSymbol());
         assertEquals("currI.getSymbol()", "IEP", currI.getSymbol());
+        assertEquals("currUS.getSymbol()", "US$", currUS.getSymbol());
         // END android-changed
-        assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
     }
 
     /**
@@ -161,7 +174,7 @@
      */
     public void test_getSymbolLjava_util_Locale() {
         //Tests was simplified because java specification not
-        // includes strong requirements for returnig symbol.
+        // includes strong requirements for returning symbol.
         // on android platform used wrong character for yen
         // sign: \u00a5 instead of \uffe5
         Locale[] desiredLocales = new Locale[]{
@@ -243,8 +256,6 @@
             for (i = 0; i < loc1.length; i++) {
                 flag = false;
                 for  (j = 0; j < yen.length; j++) {
-                    byte[] b1 = null;
-                    byte[] b2 = null;
                     if (currJ.getSymbol(loc1[i]).equals(yen[j])) {
                         flag = true;
                         break;
@@ -391,38 +402,4 @@
                     Currency.getInstance(l).toString(), d);
         }
     }
-
-    protected void setUp() {
-        Locale.setDefault(defaultLocale);
-    }
-
-    protected void tearDown() {
-    }
-
-    /**
-     * Helper method to display Currency info
-     *
-     * @param c
-     */
-    private void printCurrency(Currency c) {
-        System.out.println();
-        System.out.println(c.getCurrencyCode());
-        System.out.println(c.getSymbol());
-        System.out.println(c.getDefaultFractionDigits());
-    }
-
-    /**
-     * helper method to display Locale info
-     */
-    private static void printLocale(Locale loc) {
-        System.out.println();
-        System.out.println(loc.getDisplayName());
-        System.out.println(loc.getCountry());
-        System.out.println(loc.getLanguage());
-        System.out.println(loc.getDisplayCountry());
-        System.out.println(loc.getDisplayLanguage());
-        System.out.println(loc.getDisplayName());
-        System.out.println(loc.getISO3Country());
-        System.out.println(loc.getISO3Language());
-    }
 }
diff --git a/include/ScopedIcuLocale.h b/include/ScopedIcuLocale.h
new file mode 100644
index 0000000..2109e03
--- /dev/null
+++ b/include/ScopedIcuLocale.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_ICU_LOCALE_H_included
+#define SCOPED_ICU_LOCALE_H_included
+
+#include "JNIHelp.h"
+#include "ScopedUtfChars.h"
+#include "unicode/locid.h"
+
+class ScopedIcuLocale {
+ public:
+  ScopedIcuLocale(JNIEnv* env, jstring javaLocaleName) : mEnv(env) {
+    mLocale.setToBogus();
+
+    if (javaLocaleName == NULL) {
+      jniThrowNullPointerException(mEnv, "javaLocaleName == null");
+      return;
+    }
+
+    const ScopedUtfChars localeName(env, javaLocaleName);
+    if (localeName.c_str() == NULL) {
+      return;
+    }
+
+    mLocale = Locale::createFromName(localeName.c_str());
+  }
+
+  ~ScopedIcuLocale() {
+  }
+
+  bool valid() const {
+    return !mLocale.isBogus();
+  }
+
+  Locale& locale() {
+    return mLocale;
+  }
+
+ private:
+  JNIEnv* const mEnv;
+  Locale mLocale;
+
+  // Disallow copy and assignment.
+  ScopedIcuLocale(const ScopedIcuLocale&);
+  void operator=(const ScopedIcuLocale&);
+};
+
+#endif  // SCOPED_ICU_LOCALE_H_included
diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
index ff52b41..df6b2ce 100644
--- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java
+++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
@@ -135,7 +135,7 @@
      *
      * @return the parameter types
      */
-    public Class<?>[] getParameterTypes() {
+    Class<?>[] getParameterTypes() {
         return artMethod.getParameterTypes();
     }
 
diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java
index b1efe06..2eb12b0 100644
--- a/libart/src/main/java/java/lang/reflect/Constructor.java
+++ b/libart/src/main/java/java/lang/reflect/Constructor.java
@@ -111,7 +111,7 @@
      * parameter types of this constructor. If the constructor was declared with
      * no parameters, an empty array will be returned.
      */
-    public Class<?>[] getParameterTypes() {
+    @Override public Class<?>[] getParameterTypes() {
         return super.getParameterTypes();
     }
 
diff --git a/libdvm/src/main/java/dalvik/system/VMRuntime.java b/libdvm/src/main/java/dalvik/system/VMRuntime.java
deleted file mode 100644
index 1d58d8d..0000000
--- a/libdvm/src/main/java/dalvik/system/VMRuntime.java
+++ /dev/null
@@ -1,373 +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 dalvik.system;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Provides an interface to VM-global, Dalvik-specific features.
- * An application cannot create its own Runtime instance, and must obtain
- * one from the getRuntime method.
- *
- * @hide
- */
-public final class VMRuntime {
-
-    /**
-     * Holds the VMRuntime singleton.
-     */
-    private static final VMRuntime THE_ONE = new VMRuntime();
-
-    private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
-            = new HashMap<String, String>();
-    static {
-        ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
-        ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
-        ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
-        ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
-    }
-
-    private int targetSdkVersion;
-
-    /**
-     * Prevents this class from being instantiated.
-     */
-    private VMRuntime() {
-    }
-
-    /**
-     * Returns the object that represents the VM instance's Dalvik-specific
-     * runtime environment.
-     *
-     * @return the runtime object
-     */
-    public static VMRuntime getRuntime() {
-        return THE_ONE;
-    }
-
-    /**
-     * Returns a copy of the VM's command-line property settings.
-     * These are in the form "name=value" rather than "-Dname=value".
-     */
-    public native String[] properties();
-
-    /**
-     * Returns the VM's boot class path.
-     */
-    public native String bootClassPath();
-
-    /**
-     * Returns the VM's class path.
-     */
-    public native String classPath();
-
-    /**
-     * Returns the VM's version.
-     */
-    public native String vmVersion();
-
-    /**
-     * Returns the name of the shared library providing the VM implementation.
-     */
-    public native String vmLibrary();
-
-    /**
-     * Returns the VM's instruction set.
-     */
-    public String vmInstructionSet() {
-        return "";
-    }
-
-    /**
-     * Returns whether the VM is running in 64-bit mode.
-     */
-    public boolean is64Bit() {
-        return false;
-    }
-
-    /**
-     * Returns whether the VM is running with JNI checking enabled.
-     */
-    public native boolean isCheckJniEnabled();
-
-    /**
-     * Gets the current ideal heap utilization, represented as a number
-     * between zero and one.  After a GC happens, the Dalvik heap may
-     * be resized so that (size of live objects) / (size of heap) is
-     * equal to this number.
-     *
-     * @return the current ideal heap utilization
-     */
-    public native float getTargetHeapUtilization();
-
-    /**
-     * Sets the current ideal heap utilization, represented as a number
-     * between zero and one.  After a GC happens, the Dalvik heap may
-     * be resized so that (size of live objects) / (size of heap) is
-     * equal to this number.
-     *
-     * <p>This is only a hint to the garbage collector and may be ignored.
-     *
-     * @param newTarget the new suggested ideal heap utilization.
-     *                  This value may be adjusted internally.
-     * @return the previous ideal heap utilization
-     * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
-     */
-    public float setTargetHeapUtilization(float newTarget) {
-        if (newTarget <= 0.0f || newTarget >= 1.0f) {
-            throw new IllegalArgumentException(newTarget +
-                    " out of range (0,1)");
-        }
-        /* Synchronize to make sure that only one thread gets
-         * a given "old" value if both update at the same time.
-         * Allows for reliable save-and-restore semantics.
-         */
-        synchronized (this) {
-            float oldTarget = getTargetHeapUtilization();
-            nativeSetTargetHeapUtilization(newTarget);
-            return oldTarget;
-        }
-    }
-
-    /**
-     * Sets the target SDK version. Should only be called before the
-     * app starts to run, because it may change the VM's behavior in
-     * dangerous ways. Use 0 to mean "current" (since callers won't
-     * necessarily know the actual current SDK version, and the
-     * allocated version numbers start at 1), and 10000 to mean
-     * CUR_DEVELOPMENT.
-     */
-    public synchronized void setTargetSdkVersion(int targetSdkVersion) {
-        this.targetSdkVersion = targetSdkVersion;
-        setTargetSdkVersionNative(this.targetSdkVersion);
-    }
-
-    /**
-     * Gets the target SDK version. See {@link #setTargetSdkVersion} for
-     * special values.
-     */
-    public synchronized int getTargetSdkVersion() {
-        return targetSdkVersion;
-    }
-
-    private native void setTargetSdkVersionNative(int targetSdkVersion);
-
-    /**
-     * This method exists for binary compatibility.  It was part of a
-     * heap sizing API which was removed in Android 3.0 (Honeycomb).
-     */
-    @Deprecated
-    public long getMinimumHeapSize() {
-        return 0;
-    }
-
-    /**
-     * This method exists for binary compatibility.  It was part of a
-     * heap sizing API which was removed in Android 3.0 (Honeycomb).
-     */
-    @Deprecated
-    public long setMinimumHeapSize(long size) {
-        return 0;
-    }
-
-    /**
-     * This method exists for binary compatibility.  It used to
-     * perform a garbage collection that cleared SoftReferences.
-     */
-    @Deprecated
-    public void gcSoftReferences() {}
-
-    /**
-     * This method exists for binary compatibility.  It is equivalent
-     * to {@link System#runFinalization}.
-     */
-    @Deprecated
-    public void runFinalizationSync() {
-        System.runFinalization();
-    }
-
-    /**
-     * Implements setTargetHeapUtilization().
-     *
-     * @param newTarget the new suggested ideal heap utilization.
-     *                  This value may be adjusted internally.
-     */
-    private native void nativeSetTargetHeapUtilization(float newTarget);
-
-    /**
-     * This method exists for binary compatibility.  It was part of
-     * the external allocation API which was removed in Android 3.0 (Honeycomb).
-     */
-    @Deprecated
-    public boolean trackExternalAllocation(long size) {
-        return true;
-    }
-
-    /**
-     * This method exists for binary compatibility.  It was part of
-     * the external allocation API which was removed in Android 3.0 (Honeycomb).
-     */
-    @Deprecated
-    public void trackExternalFree(long size) {}
-
-    /**
-     * This method exists for binary compatibility.  It was part of
-     * the external allocation API which was removed in Android 3.0 (Honeycomb).
-     */
-    @Deprecated
-    public long getExternalBytesAllocated() {
-        return 0;
-    }
-
-    /**
-     * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
-     * implementation, calling this method should have no effect.
-     */
-    public native void startJitCompilation();
-
-    /**
-     * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
-     * implementation, calling this method should have no effect.
-     */
-    public native void disableJitCompilation();
-
-    /**
-     * Returns an array allocated in an area of the Java heap where it will never be moved.
-     * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
-     * and Bitmaps.
-     */
-    public native Object newNonMovableArray(Class<?> componentType, int length);
-
-    /**
-     * Returns an array of at least minLength, but potentially larger. The increased size comes from
-     * avoiding any padding after the array. The amount of padding varies depending on the
-     * componentType and the memory allocator implementation.
-     */
-    public Object newUnpaddedArray(Class<?> componentType, int minLength) {
-        // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc,
-        // allocations are 8byte aligned so having 4bytes of array data avoids padding.
-        if (!componentType.isPrimitive()) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return java.lang.reflect.Array.newInstance(componentType, size);
-        } else if (componentType == char.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new char[size];
-        } else if (componentType == int.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new int[size];
-        } else if (componentType == byte.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new byte[size];
-        } else if (componentType == boolean.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new boolean[size];
-        } else if (componentType == short.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new short[size];
-        } else if (componentType == float.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new float[size];
-        } else if (componentType == long.class) {
-            return new long[minLength];
-        } else if (componentType == double.class) {
-            return new double[minLength];
-        } else {
-            assert componentType == void.class;
-            throw new IllegalArgumentException("Can't allocate an array of void");
-        }
-    }
-
-    /**
-     * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
-     * give you the address of a copy of the array when in forcecopy mode.
-     */
-    public native long addressOf(Object array);
-
-    /**
-     * Removes any growth limits, allowing the application to allocate
-     * up to the maximum heap size.
-     */
-    public native void clearGrowthLimit();
-
-    /**
-     * Returns true if either a Java debugger or native debugger is active.
-     */
-    public native boolean isDebuggerActive();
-
-    /**
-     * Registers a native allocation so that the heap knows about it and performs GC as required.
-     * If the number of native allocated bytes exceeds the native allocation watermark, the
-     * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
-     * watermark, it is determined that the application is registering native allocations at an
-     * unusually high rate and a GC is performed inside of the function to prevent memory usage
-     * from excessively increasing.
-     */
-    public native void registerNativeAllocation(int bytes);
-
-    /**
-     * Registers a native free by reducing the number of native bytes accounted for.
-     */
-    public native void registerNativeFree(int bytes);
-
-    /**
-     * Let the heap know of the new process state. This can change allocation and garbage collection
-     * behavior regarding trimming and compaction.
-     */
-    public native void updateProcessState(int state);
-
-    /**
-     * Fill in dex caches with classes, fields, and methods that are
-     * already loaded. Typically used after Zygote preloading.
-     */
-    public native void preloadDexCaches();
-
-    /**
-     * Register application info
-     */
-    public static void registerAppInfo(String appDir, String processName, String pkgname) {
-        // Nothing to do in dalvik.
-    }
-
-    /**
-     * Returns the runtime instruction set corresponding to a given ABI. Multiple
-     * compatible ABIs might map to the same instruction set. For example
-     * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
-     *
-     * This influences the compilation of the applications classes.
-     */
-    public static String getInstructionSet(String abi) {
-        final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
-        if (instructionSet == null) {
-            throw new IllegalArgumentException("Unsupported ABI: " + abi);
-        }
-
-        return instructionSet;
-    }
-}
diff --git a/libdvm/src/main/java/dalvik/system/VMStack.java b/libdvm/src/main/java/dalvik/system/VMStack.java
deleted file mode 100644
index bae1829..0000000
--- a/libdvm/src/main/java/dalvik/system/VMStack.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 dalvik.system;
-
-/**
- * Provides a limited interface to the Dalvik VM stack. This class is mostly
- * used for implementing security checks.
- *
- * @hide
- */
-public final class VMStack {
-    /**
-     * Returns the defining class loader of the caller's caller.
-     *
-     * @return the requested class loader, or {@code null} if this is the
-     *         bootstrap class loader.
-     */
-    native public static ClassLoader getCallingClassLoader();
-
-    /**
-     * Returns the class of the caller's caller's caller.
-     *
-     * @return the requested class, or {@code null}.
-     */
-    native public static Class<?> getStackClass2();
-
-    /**
-     * Creates an array of classes from the methods at the top of the stack.
-     * We continue until we reach the bottom of the stack or exceed the
-     * specified maximum depth.
-     * <p>
-     * The topmost stack frame (this method) and the one above that (the
-     * caller) are excluded from the array.  Frames with java.lang.reflect
-     * classes are skipped over.
-     * <p>
-     * The classes in the array are the defining classes of the methods.
-     * <p>
-     * This is similar to Harmony's VMStack.getClasses, except that this
-     * implementation doesn't have a concept of "privileged" frames.
-     *
-     * @param maxDepth
-     *      maximum number of classes to return, or -1 for all
-     * @return an array with classes for the most-recent methods on the stack
-     */
-    native public static Class<?>[] getClasses(int maxDepth);
-
-    /**
-     * Returns the first ClassLoader on the call stack that isn't either of
-     * the passed-in ClassLoaders.
-     */
-    public static ClassLoader getClosestUserClassLoader(ClassLoader bootstrap,
-                                                        ClassLoader system) {
-        Class<?>[] stackClasses = VMStack.getClasses(-1);
-        for (Class<?> stackClass : stackClasses) {
-            ClassLoader loader = stackClass.getClassLoader();
-            if (loader != null && loader != bootstrap && loader != system) {
-                return loader;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Retrieves the stack trace from the specified thread.
-     *
-     * @param t
-     *      thread of interest
-     * @return an array of stack trace elements, or null if the thread
-     *      doesn't have a stack trace (e.g. because it exited)
-     */
-    native public static StackTraceElement[] getThreadStackTrace(Thread t);
-
-    /**
-     * Retrieves a partial stack trace from the specified thread into
-     * the provided array.
-     *
-     * @param t
-     *      thread of interest
-     * @param stackTraceElements
-     *      preallocated array for use when only the top of stack is
-     *      desired. Unused elements will be filled with null values.
-     * @return the number of elements filled
-     */
-    native public static int fillStackTraceElements(Thread t,
-        StackTraceElement[] stackTraceElements);
-}
diff --git a/libdvm/src/main/java/java/lang/Class.java b/libdvm/src/main/java/java/lang/Class.java
deleted file mode 100644
index af6278d..0000000
--- a/libdvm/src/main/java/java/lang/Class.java
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2006-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 java.lang;
-
-import com.android.dex.Dex;
-import dalvik.system.VMStack;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Inherited;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.AnnotationAccess;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.InternalNames;
-import libcore.reflect.Types;
-import libcore.util.BasicLruCache;
-import libcore.util.CollectionUtils;
-import libcore.util.EmptyArray;
-
-/**
- * The in-memory representation of a Java class. This representation serves as
- * the starting point for querying class-related information, a process usually
- * called "reflection". There are basically three types of {@code Class}
- * instances: those representing real classes and interfaces, those representing
- * primitive types, and those representing array classes.
- *
- * <h4>Class instances representing object types (classes or interfaces)</h4>
- * <p>
- * These represent an ordinary class or interface as found in the class
- * hierarchy. The name associated with these {@code Class} instances is simply
- * the fully qualified class name of the class or interface that it represents.
- * In addition to this human-readable name, each class is also associated by a
- * so-called <em>signature</em>, which is the letter "L", followed by the
- * class name and a semicolon (";"). The signature is what the runtime system
- * uses internally for identifying the class (for example in a DEX file).
- * </p>
- * <h4>Classes representing primitive types</h4>
- * <p>
- * These represent the standard Java primitive types and hence share their
- * names (for example "int" for the {@code int} primitive type). Although it is
- * not possible to create new instances based on these {@code Class} instances,
- * they are still useful for providing reflection information, and as the
- * component type of array classes. There is one {@code Class} instance for each
- * primitive type, and their signatures are:
- * </p>
- * <ul>
- * <li>{@code B} representing the {@code byte} primitive type</li>
- * <li>{@code S} representing the {@code short} primitive type</li>
- * <li>{@code I} representing the {@code int} primitive type</li>
- * <li>{@code J} representing the {@code long} primitive type</li>
- * <li>{@code F} representing the {@code float} primitive type</li>
- * <li>{@code D} representing the {@code double} primitive type</li>
- * <li>{@code C} representing the {@code char} primitive type</li>
- * <li>{@code Z} representing the {@code boolean} primitive type</li>
- * <li>{@code V} representing void function return values</li>
- * </ul>
- * <p>
- * <h4>Classes representing array classes</h4>
- * <p>
- * These represent the classes of Java arrays. There is one such {@code Class}
- * instance per combination of array leaf component type and arity (number of
- * dimensions). In this case, the name associated with the {@code Class}
- * consists of one or more left square brackets (one per dimension in the array)
- * followed by the signature of the class representing the leaf component type,
- * which can be either an object type or a primitive type. The signature of a
- * {@code Class} representing an array type is the same as its name. Examples
- * of array class signatures are:
- * </p>
- * <ul>
- * <li>{@code [I} representing the {@code int[]} type</li>
- * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li>
- * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li>
- * </ul>
- */
-public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type {
-
-    private static final long serialVersionUID = 3206093459760846163L;
-
-    /**
-     * Class def index from dex file. An index of -1 indicates that there is no class definition,
-     * for example for an array type.
-     */
-    private transient int dexClassDefIndex;
-
-    /** The type index of this class within the dex file that defines it. */
-    private transient int dexTypeIndex;
-
-    /**
-     * Have we computed the type and class def indices? Volatile to avoid double check locking bugs.
-     */
-    private transient volatile boolean dexIndicesInitialized;
-
-    /**
-     * Lazily computed name of this class; always prefer calling getName().
-     */
-    private transient String name;
-
-    private Class() {
-        // Prevent this class to be instantiated, instance
-        // should be created by JVM only
-    }
-
-    /**
-     * Returns the dex file from which this class was loaded.
-     * @hide
-     */
-    public native Dex getDex();
-
-    /** Lazily compute indices in to Dex */
-    private synchronized void computeDexIndices() {
-        if (!dexIndicesInitialized) {
-            Dex dex = getDex();
-            dexTypeIndex = dex.findTypeIndex(InternalNames.getInternalName(this));
-            if (dexTypeIndex < 0) {
-                dexTypeIndex = -1;
-                dexClassDefIndex = -1;
-            } else {
-                dexClassDefIndex = dex.findClassDefIndexFromTypeIndex(dexTypeIndex);
-            }
-            dexIndicesInitialized = true;
-        }
-    }
-
-    /**
-     * The class def of this class in its own Dex, or -1 if there is no class def.
-     *
-     * @hide
-     */
-    public int getDexClassDefIndex() {
-        if (!dexIndicesInitialized) {
-            computeDexIndices();
-        }
-        return dexClassDefIndex;
-    }
-
-    /**
-     * The type index of this class in its own Dex, or -1 if it is unknown. If a class is referenced
-     * by multiple Dex files, it will have a different type index in each. Dex files support 65534
-     * type indices, with 65535 representing no index.
-     *
-     * @hide
-     */
-    public int getDexTypeIndex() {
-        if (!dexIndicesInitialized) {
-            computeDexIndices();
-        }
-        return dexTypeIndex;
-    }
-
-    /**
-     * Returns a {@code Class} object which represents the class with the
-     * given name. The name should be the name of a non-primitive class, as described in
-     * the {@link Class class definition}.
-     * Primitive types can not be found using this method; use {@code int.class} or {@code Integer.TYPE} instead.
-     *
-     * <p>If the class has not yet been loaded, it is loaded and initialized
-     * first. This is done through either the class loader of the calling class
-     * or one of its parent class loaders. It is possible that a static initializer is run as
-     * a result of this call.
-     *
-     * @throws ClassNotFoundException
-     *             if the requested class can not be found.
-     * @throws LinkageError
-     *             if an error occurs during linkage
-     * @throws ExceptionInInitializerError
-     *             if an exception occurs during static initialization of a
-     *             class.
-     */
-    public static Class<?> forName(String className) throws ClassNotFoundException {
-        return forName(className, true, VMStack.getCallingClassLoader());
-    }
-
-    /**
-     * Returns a {@code Class} object which represents the class with the
-     * given name. The name should be the name of a non-primitive class, as described in
-     * the {@link Class class definition}.
-     * Primitive types can not be found using this method; use {@code int.class} or {@code Integer.TYPE} instead.
-     *
-     * <p>If the class has not yet been loaded, it is loaded first, using the given class loader.
-     * If the class has not yet been initialized and {@code shouldInitialize} is true,
-     * the class will be initialized.
-     *
-     * @throws ClassNotFoundException
-     *             if the requested class can not be found.
-     * @throws LinkageError
-     *             if an error occurs during linkage
-     * @throws ExceptionInInitializerError
-     *             if an exception occurs during static initialization of a
-     *             class.
-     */
-    public static Class<?> forName(String className, boolean shouldInitialize,
-            ClassLoader classLoader) throws ClassNotFoundException {
-
-        if (classLoader == null) {
-            classLoader = ClassLoader.getSystemClassLoader();
-        }
-        // Catch an Exception thrown by the underlying native code. It wraps
-        // up everything inside a ClassNotFoundException, even if e.g. an
-        // Error occurred during initialization. This as a workaround for
-        // an ExceptionInInitializerError that's also wrapped. It is actually
-        // expected to be thrown. Maybe the same goes for other errors.
-        // Not wrapping up all the errors will break android though.
-        Class<?> result;
-        try {
-            result = classForName(className, shouldInitialize,
-                    classLoader);
-        } catch (ClassNotFoundException e) {
-            Throwable cause = e.getCause();
-            if (cause instanceof ExceptionInInitializerError) {
-                throw (ExceptionInInitializerError) cause;
-            }
-            throw e;
-        }
-        return result;
-    }
-
-    private static native Class<?> classForName(String className, boolean shouldInitialize,
-            ClassLoader classLoader) throws ClassNotFoundException;
-
-    /**
-     * Returns an array containing {@code Class} objects for all public classes
-     * and interfaces that are members of this class. This includes public
-     * members inherited from super classes and interfaces. If there are no such
-     * class members or if this object represents a primitive type then an array
-     * of length 0 is returned.
-     */
-    public Class<?>[] getClasses() {
-        Class<?>[] result = getDeclaredClasses(this, true);
-        // Traverse all superclasses.
-        for (Class<?> c = this.getSuperclass(); c != null; c = c.getSuperclass()) {
-            Class<?>[] temp = getDeclaredClasses(c, true);
-            if (temp.length != 0) {
-                result = arraycopy(new Class[result.length + temp.length], result, temp);
-            }
-        }
-        return result;
-    }
-
-    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-
-        A annotation = getDeclaredAnnotation(annotationType);
-        if (annotation != null) {
-            return annotation;
-        }
-
-        if (annotationType.isAnnotationPresent(Inherited.class)) {
-            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
-                annotation = sup.getDeclaredAnnotation(annotationType);
-                if (annotation != null) {
-                    return annotation;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an array containing all the annotations of this class. If there are no annotations
-     * then an empty array is returned.
-     *
-     * @see #getDeclaredAnnotations()
-     */
-    public Annotation[] getAnnotations() {
-        /*
-         * We need to get the annotations declared on this class, plus the
-         * annotations from superclasses that have the "@Inherited" annotation
-         * set.  We create a temporary map to use while we accumulate the
-         * annotations and convert it to an array at the end.
-         *
-         * It's possible to have duplicates when annotations are inherited.
-         * We use a Map to filter those out.
-         *
-         * HashMap might be overkill here.
-         */
-        HashMap<Class, Annotation> map = new HashMap<Class, Annotation>();
-        Annotation[] declaredAnnotations = getDeclaredAnnotations();
-
-        for (int i = declaredAnnotations.length-1; i >= 0; --i) {
-            map.put(declaredAnnotations[i].annotationType(), declaredAnnotations[i]);
-        }
-        for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
-            declaredAnnotations = sup.getDeclaredAnnotations();
-            for (int i = declaredAnnotations.length-1; i >= 0; --i) {
-                Class<?> clazz = declaredAnnotations[i].annotationType();
-                if (!map.containsKey(clazz) && clazz.isAnnotationPresent(Inherited.class)) {
-                    map.put(clazz, declaredAnnotations[i]);
-                }
-            }
-        }
-
-        /* convert annotation values from HashMap to array */
-        Collection<Annotation> coll = map.values();
-        return coll.toArray(new Annotation[coll.size()]);
-    }
-
-    /**
-     * Returns the canonical name of this class. If this class does not have a
-     * canonical name as defined in the Java Language Specification, then the
-     * method returns {@code null}.
-     */
-    public String getCanonicalName() {
-        if (isLocalClass() || isAnonymousClass())
-            return null;
-
-        if (isArray()) {
-            /*
-             * The canonical name of an array type depends on the (existence of)
-             * the component type's canonical name.
-             */
-            String name = getComponentType().getCanonicalName();
-            if (name != null) {
-                return name + "[]";
-            }
-        } else if (isMemberClass()) {
-            /*
-             * The canonical name of an inner class depends on the (existence
-             * of) the declaring class' canonical name.
-             */
-            String name = getDeclaringClass().getCanonicalName();
-            if (name != null) {
-                return name + "." + getSimpleName();
-            }
-        } else {
-            /*
-             * The canonical name of a top-level class or primitive type is
-             * equal to the fully qualified name.
-             */
-            return getName();
-        }
-
-        /*
-         * Other classes don't have a canonical name.
-         */
-        return null;
-    }
-
-    /**
-     * Returns the class loader which was used to load the class represented by
-     * this {@code Class}. Implementations are free to return {@code null} for
-     * classes that were loaded by the bootstrap class loader. The Android
-     * reference implementation, though, always returns a reference to an actual
-     * class loader.
-     */
-    public ClassLoader getClassLoader() {
-        if (this.isPrimitive()) {
-            return null;
-        }
-
-        ClassLoader loader = getClassLoaderImpl();
-        if (loader == null) {
-            loader = BootClassLoader.getInstance();
-        }
-        return loader;
-    }
-
-    /**
-     * This must be provided by the VM vendor, as it is used by other provided
-     * class implementations in this package. Outside of this class, it is used
-     * by SecurityManager.classLoaderDepth(),
-     * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
-     * this Class without doing any security checks. The bootstrap ClassLoader
-     * is returned, unlike getClassLoader() which returns null in place of the
-     * bootstrap ClassLoader.
-     */
-    ClassLoader getClassLoaderImpl() {
-        ClassLoader loader = getClassLoader(this);
-        return loader == null ? BootClassLoader.getInstance() : loader;
-    }
-
-    /*
-     * Returns the defining class loader for the given class.
-     */
-    private static native ClassLoader getClassLoader(Class<?> c);
-
-    /**
-     * Returns a {@code Class} object which represents the component type if
-     * this class represents an array type. Returns {@code null} if this class
-     * does not represent an array type. The component type of an array type is
-     * the type of the elements of the array.
-     */
-    public native Class<?> getComponentType();
-
-    /**
-     * Returns a {@code Constructor} object which represents the public
-     * constructor matching the given parameter types.
-     * {@code (Class[]) null} is equivalent to the empty array.
-     *
-     * <p>See {@link #getMethod} for details of the search order.
-     * Use {@link #getDeclaredConstructor} if you don't want to search superclasses.
-     *
-     * @throws NoSuchMethodException
-     *             if the constructor can not be found.
-     */
-    @SuppressWarnings("unchecked")
-    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException {
-        return (Constructor) getConstructorOrMethod("<init>", false, true, parameterTypes);
-    }
-
-    /**
-     * Returns a constructor or method with the given name. Use "<init>" to return a constructor.
-     */
-    private Member getConstructorOrMethod(String name, boolean searchSuperTypes,
-            boolean publicOnly, Class<?>[] parameterTypes) throws NoSuchMethodException {
-        if (searchSuperTypes && !publicOnly) {
-            throw new AssertionError(); // can't lookup non-public members recursively
-        }
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-        if (parameterTypes == null) {
-            parameterTypes = EmptyArray.CLASS;
-        }
-        for (Class<?> c : parameterTypes) {
-            if (c == null) {
-                throw new NoSuchMethodException("parameter type is null");
-            }
-        }
-        Member result = searchSuperTypes
-                ? getPublicConstructorOrMethodRecursive(name, parameterTypes)
-                : Class.getDeclaredConstructorOrMethod(this, name, parameterTypes);
-        if (result == null || publicOnly && (result.getModifiers() & Modifier.PUBLIC) == 0) {
-            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
-        }
-        return result;
-    }
-
-    private Member getPublicConstructorOrMethodRecursive(String name, Class<?>[] parameterTypes) {
-        // search superclasses
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            Member result = Class.getDeclaredConstructorOrMethod(c, name, parameterTypes);
-            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
-                return result;
-            }
-        }
-
-        // search implemented interfaces
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Class<?> ifc : c.getInterfaces()) {
-                Member result = ifc.getPublicConstructorOrMethodRecursive(name, parameterTypes);
-                if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
-                    return result;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an array containing {@code Constructor} objects for all public
-     * constructors for this {@code Class}. If there
-     * are no public constructors or if this {@code Class} represents an array
-     * class, a primitive type or void then an empty array is returned.
-     *
-     * @see #getDeclaredConstructors()
-     */
-    public Constructor<?>[] getConstructors() {
-        return getDeclaredConstructors(this, true);
-    }
-
-    /**
-     * Returns the annotations that are directly defined on the class
-     * represented by this {@code Class}. Annotations that are inherited are not
-     * included in the result. If there are no annotations at all, an empty
-     * array is returned.
-     *
-     * @see #getAnnotations()
-     */
-    public native Annotation[] getDeclaredAnnotations();
-
-    /**
-     * Returns the annotation if it exists.
-     */
-    native private <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass);
-
-    /**
-     * Returns true if the annotation exists.
-     */
-    native private boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass);
-
-    /**
-     * Returns an array containing {@code Class} objects for all classes and
-     * interfaces that are declared as members of the class which this {@code
-     * Class} represents. If there are no classes or interfaces declared or if
-     * this class represents an array class, a primitive type or void, then an
-     * empty array is returned.
-     */
-    public Class<?>[] getDeclaredClasses() {
-        return getDeclaredClasses(this, false);
-    }
-
-    /*
-     * Returns the list of member classes of the given class.
-     * If no members exist, an empty array is returned.
-     */
-    private static native Class<?>[] getDeclaredClasses(Class<?> c, boolean publicOnly);
-
-    /**
-     * Returns a {@code Constructor} object which represents the constructor
-     * matching the given parameter types that is declared by the class
-     * represented by this {@code Class}.
-     * {@code (Class[]) null} is equivalent to the empty array.
-     *
-     * <p>Use {@link #getConstructor} if you want to search superclasses.
-     *
-     * @throws NoSuchMethodException
-     *             if the requested constructor can not be found.
-     */
-    @SuppressWarnings("unchecked")
-    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
-            throws NoSuchMethodException {
-        return (Constructor) getConstructorOrMethod("<init>", false, false, parameterTypes);
-    }
-
-    /**
-     * Returns an array containing {@code Constructor} objects for all
-     * constructors declared in the class represented by this {@code Class}. If
-     * there are no constructors or if this {@code Class} represents an array
-     * class, a primitive type, or void then an empty array is returned.
-     *
-     * @see #getConstructors()
-     */
-    public Constructor<?>[] getDeclaredConstructors() {
-        return getDeclaredConstructors(this, false);
-    }
-
-    /*
-     * Returns the list of constructors. If no constructors exist, an empty array is returned.
-     */
-    private static native <T> Constructor<T>[] getDeclaredConstructors(Class<T> c,
-                                                                       boolean publicOnly);
-
-    /**
-     * Returns a {@code Field} object for the field with the given name
-     * which is declared in the class represented by this {@code Class}.
-     *
-     * @throws NoSuchFieldException if the requested field can not be found.
-     * @see #getField(String)
-     */
-    public Field getDeclaredField(String name) throws NoSuchFieldException {
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-        Field result = getDeclaredField(this, name);
-        if (result == null) {
-            throw new NoSuchFieldException(name);
-        }
-        return result;
-    }
-
-    /**
-     * Returns an array containing {@code Field} objects for all fields declared
-     * in the class represented by this {@code Class}. If there are no fields or
-     * if this {@code Class} represents an array class, a primitive type or void
-     * then an empty array is returned.
-     *
-     * @see #getFields()
-     */
-    public Field[] getDeclaredFields() {
-        return getDeclaredFields(this, false);
-    }
-
-    /*
-     * Returns the list of fields without performing any security checks
-     * first. If no fields exist at all, an empty array is returned.
-     */
-    static native Field[] getDeclaredFields(Class<?> c, boolean publicOnly);
-
-    /**
-     * Returns the field if it is defined by {@code c}; null otherwise. This
-     * may return a non-public member.
-     */
-    static native Field getDeclaredField(Class<?> c, String name);
-
-    /**
-     * Returns a {@code Method} object which represents the method matching the
-     * given name and parameter types that is declared by the class
-     * represented by this {@code Class}.
-     * {@code (Class[]) null} is equivalent to the empty array.
-     *
-     * <p>See {@link #getMethod} if you want to search superclasses.
-     *
-     * @throws NoSuchMethodException
-     *             if the requested method can not be found.
-     * @throws NullPointerException
-     *             if {@code name} is {@code null}.
-     */
-    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
-            throws NoSuchMethodException {
-        Member member = getConstructorOrMethod(name, false, false, parameterTypes);
-        if (member instanceof Constructor) {
-            throw new NoSuchMethodException(name);
-        }
-        return (Method) member;
-    }
-
-    /**
-     * Returns an array containing {@code Method} objects for all methods
-     * declared in the class represented by this {@code Class}. If there are no
-     * methods or if this {@code Class} represents an array class, a primitive
-     * type or void then an empty array is returned.
-     *
-     * @see #getMethods()
-     */
-    public Method[] getDeclaredMethods() {
-        return getDeclaredMethods(this, false);
-    }
-
-    /**
-     * Returns the list of methods. If no methods exist, an empty array is returned.
-     */
-    static native Method[] getDeclaredMethods(Class<?> c, boolean publicOnly);
-
-    /**
-     * Returns the constructor or method if it is defined by {@code c}; null
-     * otherwise. This may return a non-public member. Use "<init>" to get a constructor.
-     */
-    static native Member getDeclaredConstructorOrMethod(Class c, String name, Class[] args);
-
-    /**
-     * Returns the declaring {@code Class} of this {@code Class}. Returns
-     * {@code null} if the class is not a member of another class or if this
-     * {@code Class} represents an array class, a primitive type, or void.
-     */
-    public native Class<?> getDeclaringClass();
-
-    /**
-     * Returns the enclosing {@code Class} of this {@code Class}. If there is no
-     * enclosing class the method returns {@code null}.
-     */
-    public native Class<?> getEnclosingClass();
-
-    /**
-     * Returns the enclosing {@code Constructor} of this {@code Class}, if it is an
-     * anonymous or local/automatic class; otherwise {@code null}.
-     */
-    public native Constructor<?> getEnclosingConstructor();
-
-    /**
-     * Returns the enclosing {@code Method} of this {@code Class}, if it is an
-     * anonymous or local/automatic class; otherwise {@code null}.
-     */
-    public native Method getEnclosingMethod();
-
-    /**
-     * Returns the {@code enum} constants associated with this {@code Class}.
-     * Returns {@code null} if this {@code Class} does not represent an {@code
-     * enum} type.
-     */
-    @SuppressWarnings("unchecked") // we only cast after confirming that this class is an enum
-    public T[] getEnumConstants() {
-        if (!isEnum()) {
-            return null;
-        }
-        return (T[]) Enum.getSharedConstants((Class) this).clone();
-    }
-
-    /**
-     * Returns a {@code Field} object which represents the public field with the
-     * given name. This method first searches the class C represented by
-     * this {@code Class}, then the interfaces implemented by C and finally the
-     * superclasses of C.
-     *
-     * @throws NoSuchFieldException
-     *             if the field can not be found.
-     * @see #getDeclaredField(String)
-     */
-    public Field getField(String name) throws NoSuchFieldException {
-        if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-        Field result = getPublicFieldRecursive(name);
-        if (result == null) {
-            throw new NoSuchFieldException(name);
-        }
-        return result;
-    }
-
-    private Field getPublicFieldRecursive(String name) {
-        // search superclasses
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            Field result = Class.getDeclaredField(c, name);
-            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
-                return result;
-            }
-        }
-
-        // search implemented interfaces
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Class<?> ifc : c.getInterfaces()) {
-                Field result = ifc.getPublicFieldRecursive(name);
-                if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
-                    return result;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns an array containing {@code Field} objects for all public fields
-     * for the class C represented by this {@code Class}. Fields may be declared
-     * in C, the interfaces it implements or in the superclasses of C. The
-     * elements in the returned array are in no particular order.
-     *
-     * <p>If there are no public fields or if this class represents an array class,
-     * a primitive type or {@code void} then an empty array is returned.
-     *
-     * @see #getDeclaredFields()
-     */
-    public Field[] getFields() {
-        List<Field> fields = new ArrayList<Field>();
-        getPublicFieldsRecursive(fields);
-
-        /*
-         * The result may include duplicates when this class implements an interface
-         * through multiple paths. Remove those duplicates.
-         */
-        CollectionUtils.removeDuplicates(fields, Field.ORDER_BY_NAME_AND_DECLARING_CLASS);
-        return fields.toArray(new Field[fields.size()]);
-    }
-
-    /**
-     * Populates {@code result} with public fields defined by this class, its
-     * superclasses, and all implemented interfaces.
-     */
-    private void getPublicFieldsRecursive(List<Field> result) {
-        // search superclasses
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Field field : Class.getDeclaredFields(c, true)) {
-                result.add(field);
-            }
-        }
-
-        // search implemented interfaces
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Class<?> ifc : c.getInterfaces()) {
-                ifc.getPublicFieldsRecursive(result);
-            }
-        }
-    }
-
-    /**
-     * Returns the {@link Type}s of the interfaces that this {@code Class} directly
-     * implements. If the {@code Class} represents a primitive type or {@code
-     * void} then an empty array is returned.
-     */
-    public Type[] getGenericInterfaces() {
-        Type[] result;
-        synchronized (Caches.genericInterfaces) {
-            result = Caches.genericInterfaces.get(this);
-            if (result == null) {
-                String annotationSignature = AnnotationAccess.getSignature(this);
-                if (annotationSignature == null) {
-                    result = getInterfaces();
-                } else {
-                    GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
-                    parser.parseForClass(this, annotationSignature);
-                    result = Types.getTypeArray(parser.interfaceTypes, false);
-                }
-                Caches.genericInterfaces.put(this, result);
-            }
-        }
-        return (result.length == 0) ? result : result.clone();
-    }
-
-    /**
-     * Returns the {@code Type} that represents the superclass of this {@code
-     * class}.
-     */
-    public Type getGenericSuperclass() {
-        Type genericSuperclass = getSuperclass();
-        // This method is specified to return null for all cases where getSuperclass
-        // returns null, i.e, for primitives, interfaces, void and java.lang.Object.
-
-        if (genericSuperclass == null) {
-            return null;
-        }
-        String annotationSignature = AnnotationAccess.getSignature(this);
-        if (annotationSignature != null) {
-            GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
-            parser.parseForClass(this, annotationSignature);
-            genericSuperclass = parser.superclassType;
-        }
-        return Types.getType(genericSuperclass);
-    }
-
-    /**
-     * Returns an array of {@code Class} objects that match the interfaces
-     * in the {@code implements} declaration of the class represented
-     * by this {@code Class}. The order of the elements in the array is
-     * identical to the order in the original class declaration. If the class
-     * does not implement any interfaces, an empty array is returned.
-     */
-    public native Class<?>[] getInterfaces();
-
-    /**
-     * Returns a {@code Method} object which represents the public method with
-     * the given name and parameter types.
-     * {@code (Class[]) null} is equivalent to the empty array.
-     *
-     * <p>This method first searches the class C represented by this {@code Class},
-     * then the superclasses of C,
-     * and finally the interfaces implemented by C and its superclasses.
-     *
-     * <p>Use {@link #getDeclaredMethod} if you don't want to search superclasses.
-     *
-     * @throws NoSuchMethodException
-     *             if the method can not be found.
-     */
-    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException {
-        Member member = getConstructorOrMethod(name, true, true, parameterTypes);
-        if (member instanceof Constructor) {
-            throw new NoSuchMethodException(name);
-        }
-        return (Method) member;
-    }
-
-    /**
-     * Returns an array containing {@code Method} objects for all public methods
-     * for the class C represented by this {@code Class}. Methods may be
-     * declared in C, the interfaces it implements or in the superclasses of C.
-     * The elements in the returned array are in no particular order.
-     *
-     * <p>If there are no public methods or if this {@code Class} represents a
-     * primitive type or {@code void} then an empty array is returned.
-     *
-     * @see #getDeclaredMethods()
-     */
-    public Method[] getMethods() {
-        List<Method> methods = new ArrayList<Method>();
-        getPublicMethodsRecursive(methods);
-
-        /*
-         * Remove methods defined by multiple types, preferring to keep methods
-         * declared by derived types.
-         */
-        CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
-        return methods.toArray(new Method[methods.size()]);
-    }
-
-    /**
-     * Populates {@code result} with public methods defined by this class, its
-     * superclasses, and all implemented interfaces, including overridden methods.
-     */
-    private void getPublicMethodsRecursive(List<Method> result) {
-        // search superclasses
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Method method : Class.getDeclaredMethods(c, true)) {
-                result.add(method);
-            }
-        }
-
-        // search implemented interfaces
-        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
-            for (Class<?> ifc : c.getInterfaces()) {
-                ifc.getPublicMethodsRecursive(result);
-            }
-        }
-    }
-
-    /**
-     * Returns an integer that represents the modifiers of the class represented
-     * by this {@code Class}. The returned value is a combination of bits
-     * defined by constants in the {@link Modifier} class.
-     */
-    public int getModifiers() {
-        return getModifiers(this, false);
-    }
-
-    /*
-     * Returns the modifiers for the given class.
-     *
-     * {@code ignoreInnerClassesAttrib} determines whether we look for and use the
-     *     flags from an "inner class" attribute
-     */
-    private static native int getModifiers(Class<?> clazz, boolean ignoreInnerClassesAttrib);
-
-    /**
-     * Returns the name of the class represented by this {@code Class}. For a
-     * description of the format which is used, see the class definition of
-     * {@link Class}.
-     */
-    public String getName() {
-        String result = name;
-        return (result == null) ? (name = getNameNative()) : result;
-    }
-
-    private native String getNameNative();
-
-    /**
-     * Returns the simple name of the class represented by this {@code Class} as
-     * defined in the source code. If there is no name (that is, the class is
-     * anonymous) then an empty string is returned. If the receiver is an array
-     * then the name of the underlying type with square braces appended (for
-     * example {@code "Integer[]"}) is returned.
-     *
-     * @return the simple name of the class represented by this {@code Class}.
-     */
-    public String getSimpleName() {
-        if (isArray()) {
-            return getComponentType().getSimpleName() + "[]";
-        }
-
-        String name = getName();
-
-        if (isAnonymousClass()) {
-            return "";
-        }
-
-        if (isMemberClass() || isLocalClass()) {
-            return getInnerClassName();
-        }
-
-        int dot = name.lastIndexOf('.');
-        if (dot != -1) {
-            return name.substring(dot + 1);
-        }
-
-        return name;
-    }
-
-    /*
-     * Returns the simple name of a member or local class, or null otherwise.
-     */
-    private native String getInnerClassName();
-
-    /**
-     * Returns null.
-     */
-    public ProtectionDomain getProtectionDomain() {
-        return null;
-    }
-
-    /**
-     * Returns the URL of the given resource, or null if the resource is not found.
-     * The mapping between the resource name and the URL is managed by the class' class loader.
-     *
-     * @see ClassLoader
-     */
-    public URL getResource(String resourceName) {
-        // Get absolute resource name, but without the leading slash
-        if (resourceName.startsWith("/")) {
-            resourceName = resourceName.substring(1);
-        } else {
-            String pkg = getName();
-            int dot = pkg.lastIndexOf('.');
-            if (dot != -1) {
-                pkg = pkg.substring(0, dot).replace('.', '/');
-            } else {
-                pkg = "";
-            }
-
-            resourceName = pkg + "/" + resourceName;
-        }
-
-        // Delegate to proper class loader
-        ClassLoader loader = getClassLoader();
-        if (loader != null) {
-            return loader.getResource(resourceName);
-        } else {
-            return ClassLoader.getSystemResource(resourceName);
-        }
-    }
-
-    /**
-     * Returns a read-only stream for the contents of the given resource, or null if the resource
-     * is not found.
-     * The mapping between the resource name and the stream is managed by the class' class loader.
-     *
-     * @see ClassLoader
-     */
-    public InputStream getResourceAsStream(String resourceName) {
-        // Get absolute resource name, but without the leading slash
-        if (resourceName.startsWith("/")) {
-            resourceName = resourceName.substring(1);
-        } else {
-            String pkg = getName();
-            int dot = pkg.lastIndexOf('.');
-            if (dot != -1) {
-                pkg = pkg.substring(0, dot).replace('.', '/');
-            } else {
-                pkg = "";
-            }
-
-            resourceName = pkg + "/" + resourceName;
-        }
-
-        // Delegate to proper class loader
-        ClassLoader loader = getClassLoader();
-        if (loader != null) {
-            return loader.getResourceAsStream(resourceName);
-        } else {
-            return ClassLoader.getSystemResourceAsStream(resourceName);
-        }
-    }
-
-    /**
-     * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
-     * All classes from any given dex file will have the same signers, but different dex
-     * files may have different signers. This does not fit well with the original
-     * {@code ClassLoader}-based model of {@code getSigners}.)
-     */
-    public Object[] getSigners() {
-        // See http://code.google.com/p/android/issues/detail?id=1766.
-        return null;
-    }
-
-    /**
-     * Returns the {@code Class} object which represents the superclass of the
-     * class represented by this {@code Class}. If this {@code Class} represents
-     * the {@code Object} class, a primitive type, an interface or void then the
-     * method returns {@code null}. If this {@code Class} represents an array
-     * class then the {@code Object} class is returned.
-     */
-    public native Class<? super T> getSuperclass();
-
-    /**
-     * Returns an array containing {@code TypeVariable} objects for type
-     * variables declared by the generic class represented by this {@code
-     * Class}. Returns an empty array if the class is not generic.
-     */
-    @SuppressWarnings("unchecked")
-    public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
-        String annotationSignature = AnnotationAccess.getSignature(this);
-        if (annotationSignature == null) {
-            return EmptyArray.TYPE_VARIABLE;
-        }
-        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
-        parser.parseForClass(this, annotationSignature);
-        return parser.formalTypeParameters;
-    }
-
-    /**
-     * Tests whether this {@code Class} represents an annotation class.
-     */
-    public boolean isAnnotation() {
-        final int ACC_ANNOTATION = 0x2000;  // not public in reflect.Modifiers
-        int mod = getModifiers(this, true);
-        return (mod & ACC_ANNOTATION) != 0;
-    }
-
-    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-
-        if (isDeclaredAnnotationPresent(annotationType)) {
-            return true;
-        }
-
-        if (annotationType.isDeclaredAnnotationPresent(Inherited.class)) {
-            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
-                if (sup.isDeclaredAnnotationPresent(annotationType)) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Tests whether the class represented by this {@code Class} is
-     * anonymous.
-     */
-    native public boolean isAnonymousClass();
-
-    /**
-     * Tests whether the class represented by this {@code Class} is an array class.
-     */
-    public boolean isArray() {
-        return getComponentType() != null;
-    }
-
-    /**
-     * Tests whether the given class type can be converted to the class
-     * represented by this {@code Class}. Conversion may be done via an identity
-     * conversion or a widening reference conversion (if either the receiver or
-     * the argument represent primitive types, only the identity conversion
-     * applies).
-     *
-     * @throws NullPointerException
-     *             if {@code c} is {@code null}.
-     */
-    public native boolean isAssignableFrom(Class<?> c);
-
-    /**
-     * Tests whether the class represented by this {@code Class} is an
-     * {@code enum}.
-     */
-    public boolean isEnum() {
-        if (getSuperclass() != Enum.class) {
-            return false;
-        }
-        int mod = getModifiers(this, true);
-        return (mod & 0x4000) != 0;
-    }
-
-    /**
-     * Tests whether the given object can be cast to the class
-     * represented by this {@code Class}. This is the runtime version of the
-     * {@code instanceof} operator.
-     *
-     * @return {@code true} if {@code object} can be cast to the type
-     *         represented by this {@code Class}; {@code false} if {@code
-     *         object} is {@code null} or cannot be cast.
-     */
-    public native boolean isInstance(Object object);
-
-    /**
-     * Tests whether this {@code Class} represents an interface.
-     */
-    public native boolean isInterface();
-
-    /**
-     * Tests whether the class represented by this {@code Class} is defined
-     * locally.
-     */
-    public boolean isLocalClass() {
-        boolean enclosed = (getEnclosingMethod() != null ||
-                         getEnclosingConstructor() != null);
-        return enclosed && !isAnonymousClass();
-    }
-
-    /**
-     * Tests whether the class represented by this {@code Class} is a member
-     * class.
-     */
-    public boolean isMemberClass() {
-        return getDeclaringClass() != null;
-    }
-
-    /**
-     * Tests whether this {@code Class} represents a primitive type.
-     */
-    public native boolean isPrimitive();
-
-    /**
-     * Tests whether this {@code Class} represents a synthetic type.
-     */
-    public boolean isSynthetic() {
-        final int ACC_SYNTHETIC = 0x1000;   // not public in reflect.Modifiers
-        int mod = getModifiers(this, true);
-        return (mod & ACC_SYNTHETIC) != 0;
-    }
-
-    /**
-     * Returns a new instance of the class represented by this {@code Class},
-     * created by invoking the default (that is, zero-argument) constructor. If
-     * there is no such constructor, or if the creation fails (either because of
-     * a lack of available memory or because an exception is thrown by the
-     * constructor), an {@code InstantiationException} is thrown. If the default
-     * constructor exists but is not accessible from the context where this
-     * method is invoked, an {@code IllegalAccessException} is thrown.
-     *
-     * @throws IllegalAccessException
-     *             if the default constructor is not visible.
-     * @throws InstantiationException
-     *             if the instance can not be created.
-     */
-    public T newInstance() throws InstantiationException, IllegalAccessException {
-        return newInstanceImpl();
-    }
-
-    private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;
-
-    @Override
-    public String toString() {
-        if (isPrimitive()) {
-            return getSimpleName();
-        }
-        return (isInterface() ? "interface " : "class ") + getName();
-    }
-
-    /**
-     * Returns the {@code Package} of which the class represented by this
-     * {@code Class} is a member. Returns {@code null} if no {@code Package}
-     * object was created by the class loader of the class.
-     */
-    public Package getPackage() {
-        // TODO This might be a hack, but the VM doesn't have the necessary info.
-        ClassLoader loader = getClassLoader();
-        if (loader != null) {
-            String name = getName();
-            int dot = name.lastIndexOf('.');
-            return (dot != -1 ? loader.getPackage(name.substring(0, dot)) : null);
-        }
-        return null;
-    }
-
-    /**
-     * Returns the assertion status for the class represented by this {@code
-     * Class}. Assertion is enabled / disabled based on the class loader,
-     * package or class default at runtime.
-     */
-    public native boolean desiredAssertionStatus();
-
-    /**
-     * Casts this {@code Class} to represent a subclass of the given class.
-     * If successful, this {@code Class} is returned; otherwise a {@code
-     * ClassCastException} is thrown.
-     *
-     * @throws ClassCastException
-     *             if this {@code Class} cannot be cast to the given type.
-     */
-    @SuppressWarnings("unchecked")
-    public <U> Class<? extends U> asSubclass(Class<U> c) {
-        if (c.isAssignableFrom(this)) {
-            return (Class<? extends U>)this;
-        }
-        String actualClassName = this.getName();
-        String desiredClassName = c.getName();
-        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
-    }
-
-    /**
-     * Casts the given object to the type represented by this {@code Class}.
-     * If the object is {@code null} then the result is also {@code null}.
-     *
-     * @throws ClassCastException
-     *             if the object cannot be cast to the given type.
-     */
-    @SuppressWarnings("unchecked")
-    public T cast(Object obj) {
-        if (obj == null) {
-            return null;
-        } else if (this.isInstance(obj)) {
-            return (T)obj;
-        }
-        String actualClassName = obj.getClass().getName();
-        String desiredClassName = this.getName();
-        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
-    }
-
-    /**
-     * Copies two arrays into one. Assumes that the destination array is large
-     * enough.
-     *
-     * @param result the destination array
-     * @param head the first source array
-     * @param tail the second source array
-     * @return the destination array, that is, result
-     */
-    private static <T extends Object> T[] arraycopy(T[] result, T[] head, T[] tail) {
-        System.arraycopy(head, 0, result, 0, head.length);
-        System.arraycopy(tail, 0, result, head.length, tail.length);
-        return result;
-    }
-
-    /**
-     * The annotation directory offset of this class in its own Dex, or 0 if it
-     * is unknown.
-     *
-     * TODO: 0 is a sentinel that means 'no annotations directory'; this should be -1 if unknown
-     *
-     * @hide
-     */
-    public int getDexAnnotationDirectoryOffset() {
-        Dex dex = getDex();
-        if (dex == null) {
-            return 0;
-        }
-        int classDefIndex = getDexClassDefIndex();
-        if (classDefIndex < 0) {
-            return 0;
-        }
-        return dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex);
-    }
-
-
-    /**
-     * Returns a resolved type from the dex cache, computing the type from the dex file if
-     * necessary.
-     * TODO: use Dalvik's dex cache.
-     * @hide
-     */
-    public Class<?> getDexCacheType(Dex dex, int typeIndex) {
-        String internalName = dex.typeNames().get(typeIndex);
-        return InternalNames.getClass(getClassLoader(), internalName);
-    }
-
-    /**
-     * Returns a string from the dex cache, computing the string from the dex file if necessary.
-     *
-     * @hide
-     */
-    public String getDexCacheString(Dex dex, int dexStringIndex) {
-        return dex.strings().get(dexStringIndex);
-    }
-
-
-    private static class Caches {
-        /**
-         * Cache to avoid frequent recalculation of generic interfaces, which is generally uncommon.
-         * Sized sufficient to allow ConcurrentHashMapTest to run without recalculating its generic
-         * interfaces (required to avoid time outs). Validated by running reflection heavy code
-         * such as applications using Guice-like frameworks.
-         */
-        private static final BasicLruCache<Class, Type[]> genericInterfaces
-            = new BasicLruCache<Class, Type[]>(8);
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/ClassLoader.java b/libdvm/src/main/java/java/lang/ClassLoader.java
deleted file mode 100644
index c6a80913..0000000
--- a/libdvm/src/main/java/java/lang/ClassLoader.java
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang;
-
-import dalvik.system.PathClassLoader;
-import dalvik.system.VMStack;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.security.ProtectionDomain;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Loads classes and resources from a repository. One or more class loaders are
- * installed at runtime. These are consulted whenever the runtime system needs a
- * specific class that is not yet available in-memory. Typically, class loaders
- * are grouped into a tree where child class loaders delegate all requests to
- * parent class loaders. Only if the parent class loader cannot satisfy the
- * request, the child class loader itself tries to handle it.
- * <p>
- * {@code ClassLoader} is an abstract class that implements the common
- * infrastructure required by all class loaders. Android provides several
- * concrete implementations of the class, with
- * {@link dalvik.system.PathClassLoader} being the one typically used. Other
- * applications may implement subclasses of {@code ClassLoader} to provide
- * special ways for loading classes.
- * </p>
- * @see Class
- */
-public abstract class ClassLoader {
-
-    /**
-     * The 'System' ClassLoader - the one that is responsible for loading
-     * classes from the classpath. It is not equal to the bootstrap class loader -
-     * that one handles the built-in classes.
-     *
-     * Because of a potential class initialization race between ClassLoader and
-     * java.lang.System, reproducible when using JDWP with "suspend=y", we defer
-     * creation of the system class loader until first use. We use a static
-     * inner class to get synchronization at init time without having to sync on
-     * every access.
-     *
-     * @see #getSystemClassLoader()
-     */
-    static private class SystemClassLoader {
-        public static ClassLoader loader = ClassLoader.createSystemClassLoader();
-    }
-
-    /**
-     * The parent ClassLoader.
-     */
-    private ClassLoader parent;
-
-    /**
-     * The packages known to the class loader.
-     */
-    private Map<String, Package> packages = new HashMap<String, Package>();
-
-    /**
-     * Create the system class loader. Note this is NOT the bootstrap class
-     * loader (which is managed by the VM). We use a null value for the parent
-     * to indicate that the bootstrap loader is our parent.
-     */
-    private static ClassLoader createSystemClassLoader() {
-        String classPath = System.getProperty("java.class.path", ".");
-
-        // String[] paths = classPath.split(":");
-        // URL[] urls = new URL[paths.length];
-        // for (int i = 0; i < paths.length; i++) {
-        // try {
-        // urls[i] = new URL("file://" + paths[i]);
-        // }
-        // catch (Exception ex) {
-        // ex.printStackTrace();
-        // }
-        // }
-        //
-        // return new java.net.URLClassLoader(urls, null);
-
-        // TODO Make this a java.net.URLClassLoader once we have those?
-        return new PathClassLoader(classPath, BootClassLoader.getInstance());
-    }
-
-    /**
-     * Returns the system class loader. This is the parent for new
-     * {@code ClassLoader} instances and is typically the class loader used to
-     * start the application.
-     */
-    public static ClassLoader getSystemClassLoader() {
-        return SystemClassLoader.loader;
-    }
-
-    /**
-     * Finds the URL of the resource with the specified name. The system class
-     * loader's resource lookup algorithm is used to find the resource.
-     *
-     * @return the {@code URL} object for the requested resource or {@code null}
-     *         if the resource can not be found.
-     * @param resName
-     *            the name of the resource to find.
-     * @see Class#getResource
-     */
-    public static URL getSystemResource(String resName) {
-        return SystemClassLoader.loader.getResource(resName);
-    }
-
-    /**
-     * Returns an enumeration of URLs for the resource with the specified name.
-     * The system class loader's resource lookup algorithm is used to find the
-     * resource.
-     *
-     * @return an enumeration of {@code URL} objects containing the requested
-     *         resources.
-     * @param resName
-     *            the name of the resource to find.
-     * @throws IOException
-     *             if an I/O error occurs.
-     */
-    public static Enumeration<URL> getSystemResources(String resName) throws IOException {
-        return SystemClassLoader.loader.getResources(resName);
-    }
-
-    /**
-     * Returns a stream for the resource with the specified name. The system
-     * class loader's resource lookup algorithm is used to find the resource.
-     * Basically, the contents of the java.class.path are searched in order,
-     * looking for a path which matches the specified resource.
-     *
-     * @return a stream for the resource or {@code null}.
-     * @param resName
-     *            the name of the resource to find.
-     * @see Class#getResourceAsStream
-     */
-    public static InputStream getSystemResourceAsStream(String resName) {
-        return SystemClassLoader.loader.getResourceAsStream(resName);
-    }
-
-    /**
-     * Constructs a new instance of this class with the system class loader as
-     * its parent.
-     */
-    protected ClassLoader() {
-        this(getSystemClassLoader(), false);
-    }
-
-    /**
-     * Constructs a new instance of this class with the specified class loader
-     * as its parent.
-     *
-     * @param parentLoader
-     *            The {@code ClassLoader} to use as the new class loader's
-     *            parent.
-     */
-    protected ClassLoader(ClassLoader parentLoader) {
-        this(parentLoader, false);
-    }
-
-    /*
-     * constructor for the BootClassLoader which needs parent to be null.
-     */
-    ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
-        if (parentLoader == null && !nullAllowed) {
-            throw new NullPointerException("parentLoader == null && !nullAllowed");
-        }
-        parent = parentLoader;
-    }
-
-    /**
-     * Constructs a new class from an array of bytes containing a class
-     * definition in class file format.
-     *
-     * @param classRep
-     *            the memory image of a class file.
-     * @param offset
-     *            the offset into {@code classRep}.
-     * @param length
-     *            the length of the class file.
-     * @return the {@code Class} object created from the specified subset of
-     *         data in {@code classRep}.
-     * @throws ClassFormatError
-     *             if {@code classRep} does not contain a valid class.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0}, {@code length < 0} or if
-     *             {@code offset + length} is greater than the length of
-     *             {@code classRep}.
-     * @deprecated Use {@link #defineClass(String, byte[], int, int)} instead.
-     */
-    @Deprecated
-    protected final Class<?> defineClass(byte[] classRep, int offset, int length)
-            throws ClassFormatError {
-        throw new UnsupportedOperationException("can't load this type of class file");
-    }
-
-    /**
-     * Constructs a new class from an array of bytes containing a class
-     * definition in class file format.
-     *
-     * @param className
-     *            the expected name of the new class, may be {@code null} if not
-     *            known.
-     * @param classRep
-     *            the memory image of a class file.
-     * @param offset
-     *            the offset into {@code classRep}.
-     * @param length
-     *            the length of the class file.
-     * @return the {@code Class} object created from the specified subset of
-     *         data in {@code classRep}.
-     * @throws ClassFormatError
-     *             if {@code classRep} does not contain a valid class.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0}, {@code length < 0} or if
-     *             {@code offset + length} is greater than the length of
-     *             {@code classRep}.
-     */
-    protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length)
-            throws ClassFormatError {
-        throw new UnsupportedOperationException("can't load this type of class file");
-    }
-
-    /**
-     * Constructs a new class from an array of bytes containing a class
-     * definition in class file format and assigns the specified protection
-     * domain to the new class. If the provided protection domain is
-     * {@code null} then a default protection domain is assigned to the class.
-     *
-     * @param className
-     *            the expected name of the new class, may be {@code null} if not
-     *            known.
-     * @param classRep
-     *            the memory image of a class file.
-     * @param offset
-     *            the offset into {@code classRep}.
-     * @param length
-     *            the length of the class file.
-     * @param protectionDomain
-     *            the protection domain to assign to the loaded class, may be
-     *            {@code null}.
-     * @return the {@code Class} object created from the specified subset of
-     *         data in {@code classRep}.
-     * @throws ClassFormatError
-     *             if {@code classRep} does not contain a valid class.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0}, {@code length < 0} or if
-     *             {@code offset + length} is greater than the length of
-     *             {@code classRep}.
-     * @throws NoClassDefFoundError
-     *             if {@code className} is not equal to the name of the class
-     *             contained in {@code classRep}.
-     */
-    protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length,
-            ProtectionDomain protectionDomain) throws java.lang.ClassFormatError {
-        throw new UnsupportedOperationException("can't load this type of class file");
-    }
-
-    /**
-     * Defines a new class with the specified name, byte code from the byte
-     * buffer and the optional protection domain. If the provided protection
-     * domain is {@code null} then a default protection domain is assigned to
-     * the class.
-     *
-     * @param name
-     *            the expected name of the new class, may be {@code null} if not
-     *            known.
-     * @param b
-     *            the byte buffer containing the byte code of the new class.
-     * @param protectionDomain
-     *            the protection domain to assign to the loaded class, may be
-     *            {@code null}.
-     * @return the {@code Class} object created from the data in {@code b}.
-     * @throws ClassFormatError
-     *             if {@code b} does not contain a valid class.
-     * @throws NoClassDefFoundError
-     *             if {@code className} is not equal to the name of the class
-     *             contained in {@code b}.
-     */
-    protected final Class<?> defineClass(String name, ByteBuffer b,
-            ProtectionDomain protectionDomain) throws ClassFormatError {
-
-        byte[] temp = new byte[b.remaining()];
-        b.get(temp);
-        return defineClass(name, temp, 0, temp.length, protectionDomain);
-    }
-
-    /**
-     * Overridden by subclasses, throws a {@code ClassNotFoundException} by
-     * default. This method is called by {@code loadClass} after the parent
-     * {@code ClassLoader} has failed to find a loaded class of the same name.
-     *
-     * @param className
-     *            the name of the class to look for.
-     * @return the {@code Class} object that is found.
-     * @throws ClassNotFoundException
-     *             if the class cannot be found.
-     */
-    protected Class<?> findClass(String className) throws ClassNotFoundException {
-        throw new ClassNotFoundException(className);
-    }
-
-    /**
-     * Returns the class with the specified name if it has already been loaded
-     * by the VM or {@code null} if it has not yet been loaded.
-     *
-     * @param className
-     *            the name of the class to look for.
-     * @return the {@code Class} object or {@code null} if the requested class
-     *         has not been loaded.
-     */
-    protected final Class<?> findLoadedClass(String className) {
-        ClassLoader loader;
-        if (this == BootClassLoader.getInstance())
-            loader = null;
-        else
-            loader = this;
-        return VMClassLoader.findLoadedClass(loader, className);
-    }
-
-    /**
-     * Finds the class with the specified name, loading it using the system
-     * class loader if necessary.
-     *
-     * @param className
-     *            the name of the class to look for.
-     * @return the {@code Class} object with the requested {@code className}.
-     * @throws ClassNotFoundException
-     *             if the class can not be found.
-     */
-    protected final Class<?> findSystemClass(String className) throws ClassNotFoundException {
-        return Class.forName(className, false, getSystemClassLoader());
-    }
-
-    /**
-     * Returns this class loader's parent.
-     *
-     * @return this class loader's parent or {@code null}.
-     */
-    public final ClassLoader getParent() {
-        return parent;
-    }
-
-    /**
-     * Returns the URL of the resource with the specified name. This
-     * implementation first tries to use the parent class loader to find the
-     * resource; if this fails then {@link #findResource(String)} is called to
-     * find the requested resource.
-     *
-     * @param resName
-     *            the name of the resource to find.
-     * @return the {@code URL} object for the requested resource or {@code null}
-     *         if the resource can not be found
-     * @see Class#getResource
-     */
-    public URL getResource(String resName) {
-        URL resource = parent.getResource(resName);
-        if (resource == null) {
-            resource = findResource(resName);
-        }
-        return resource;
-    }
-
-    /**
-     * Returns an enumeration of URLs for the resource with the specified name.
-     * This implementation first uses this class loader's parent to find the
-     * resource, then it calls {@link #findResources(String)} to get additional
-     * URLs. The returned enumeration contains the {@code URL} objects of both
-     * find operations.
-     *
-     * @return an enumeration of {@code URL} objects for the requested resource.
-     * @param resName
-     *            the name of the resource to find.
-     * @throws IOException
-     *             if an I/O error occurs.
-     */
-    @SuppressWarnings("unchecked")
-    public Enumeration<URL> getResources(String resName) throws IOException {
-
-        Enumeration first = parent.getResources(resName);
-        Enumeration second = findResources(resName);
-
-        return new TwoEnumerationsInOne(first, second);
-    }
-
-    /**
-     * Returns a stream for the resource with the specified name. See
-     * {@link #getResource(String)} for a description of the lookup algorithm
-     * used to find the resource.
-     *
-     * @return a stream for the resource or {@code null} if the resource can not be found
-     * @param resName
-     *            the name of the resource to find.
-     * @see Class#getResourceAsStream
-     */
-    public InputStream getResourceAsStream(String resName) {
-        try {
-            URL url = getResource(resName);
-            if (url != null) {
-                return url.openStream();
-            }
-        } catch (IOException ex) {
-            // Don't want to see the exception.
-        }
-
-        return null;
-    }
-
-    /**
-     * Loads the class with the specified name. Invoking this method is
-     * equivalent to calling {@code loadClass(className, false)}.
-     * <p>
-     * <strong>Note:</strong> In the Android reference implementation, the
-     * second parameter of {@link #loadClass(String, boolean)} is ignored
-     * anyway.
-     * </p>
-     *
-     * @return the {@code Class} object.
-     * @param className
-     *            the name of the class to look for.
-     * @throws ClassNotFoundException
-     *             if the class can not be found.
-     */
-    public Class<?> loadClass(String className) throws ClassNotFoundException {
-        return loadClass(className, false);
-    }
-
-    /**
-     * Loads the class with the specified name, optionally linking it after
-     * loading. The following steps are performed:
-     * <ol>
-     * <li> Call {@link #findLoadedClass(String)} to determine if the requested
-     * class has already been loaded.</li>
-     * <li>If the class has not yet been loaded: Invoke this method on the
-     * parent class loader.</li>
-     * <li>If the class has still not been loaded: Call
-     * {@link #findClass(String)} to find the class.</li>
-     * </ol>
-     * <p>
-     * <strong>Note:</strong> In the Android reference implementation, the
-     * {@code resolve} parameter is ignored; classes are never linked.
-     * </p>
-     *
-     * @return the {@code Class} object.
-     * @param className
-     *            the name of the class to look for.
-     * @param resolve
-     *            Indicates if the class should be resolved after loading. This
-     *            parameter is ignored on the Android reference implementation;
-     *            classes are not resolved.
-     * @throws ClassNotFoundException
-     *             if the class can not be found.
-     */
-    protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
-        Class<?> clazz = findLoadedClass(className);
-
-        if (clazz == null) {
-            try {
-                clazz = parent.loadClass(className, false);
-            } catch (ClassNotFoundException e) {
-                // Don't want to see this.
-            }
-
-            if (clazz == null) {
-                clazz = findClass(className);
-            }
-        }
-
-        return clazz;
-    }
-
-    /**
-     * Forces a class to be linked (initialized). If the class has already been
-     * linked this operation has no effect.
-     * <p>
-     * <strong>Note:</strong> In the Android reference implementation, this
-     * method has no effect.
-     * </p>
-     *
-     * @param clazz
-     *            the class to link.
-     */
-    protected final void resolveClass(Class<?> clazz) {
-        // no-op, doesn't make sense on android.
-    }
-
-    /**
-     * Finds the URL of the resource with the specified name. This
-     * implementation just returns {@code null}; it should be overridden in
-     * subclasses.
-     *
-     * @param resName
-     *            the name of the resource to find.
-     * @return the {@code URL} object for the requested resource.
-     */
-    protected URL findResource(String resName) {
-        return null;
-    }
-
-    /**
-     * Finds an enumeration of URLs for the resource with the specified name.
-     * This implementation just returns an empty {@code Enumeration}; it should
-     * be overridden in subclasses.
-     *
-     * @param resName
-     *            the name of the resource to find.
-     * @return an enumeration of {@code URL} objects for the requested resource.
-     * @throws IOException
-     *             if an I/O error occurs.
-     */
-    @SuppressWarnings( {
-            "unchecked", "unused"
-    })
-    protected Enumeration<URL> findResources(String resName) throws IOException {
-        return Collections.emptyEnumeration();
-    }
-
-    /**
-     * Returns the absolute path of the native library with the specified name,
-     * or {@code null}. If this method returns {@code null} then the virtual
-     * machine searches the directories specified by the system property
-     * "java.library.path".
-     * <p>
-     * This implementation always returns {@code null}.
-     * </p>
-     *
-     * @param libName
-     *            the name of the library to find.
-     * @return the absolute path of the library.
-     */
-    protected String findLibrary(String libName) {
-        return null;
-    }
-
-    /**
-     * Returns the package with the specified name. Package information is
-     * searched in this class loader.
-     *
-     * @param name
-     *            the name of the package to find.
-     * @return the package with the requested name; {@code null} if the package
-     *         can not be found.
-     */
-    protected Package getPackage(String name) {
-        synchronized (packages) {
-            return packages.get(name);
-        }
-    }
-
-    /**
-     * Returns all the packages known to this class loader.
-     *
-     * @return an array with all packages known to this class loader.
-     */
-    protected Package[] getPackages() {
-        synchronized (packages) {
-            Collection<Package> col = packages.values();
-            Package[] result = new Package[col.size()];
-            col.toArray(result);
-            return result;
-        }
-    }
-
-    /**
-     * Defines and returns a new {@code Package} using the specified
-     * information. If {@code sealBase} is {@code null}, the package is left
-     * unsealed. Otherwise, the package is sealed using this URL.
-     *
-     * @param name
-     *            the name of the package.
-     * @param specTitle
-     *            the title of the specification.
-     * @param specVersion
-     *            the version of the specification.
-     * @param specVendor
-     *            the vendor of the specification.
-     * @param implTitle
-     *            the implementation title.
-     * @param implVersion
-     *            the implementation version.
-     * @param implVendor
-     *            the specification vendor.
-     * @param sealBase
-     *            the URL used to seal this package or {@code null} to leave the
-     *            package unsealed.
-     * @return the {@code Package} object that has been created.
-     * @throws IllegalArgumentException
-     *             if a package with the specified name already exists.
-     */
-    protected Package definePackage(String name, String specTitle, String specVersion,
-            String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)
-            throws IllegalArgumentException {
-
-        synchronized (packages) {
-            if (packages.containsKey(name)) {
-                throw new IllegalArgumentException("Package " + name + " already defined");
-            }
-
-            Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle,
-                    implVersion, implVendor, sealBase);
-
-            packages.put(name, newPackage);
-
-            return newPackage;
-        }
-    }
-
-    /**
-     * Sets the signers of the specified class. This implementation does
-     * nothing.
-     *
-     * @param c
-     *            the {@code Class} object for which to set the signers.
-     * @param signers
-     *            the signers for {@code c}.
-     */
-    protected final void setSigners(Class<?> c, Object[] signers) {
-    }
-
-    /**
-     * Sets the assertion status of the class with the specified name.
-     * <p>
-     * <strong>Note: </strong>This method does nothing in the Android reference
-     * implementation.
-     * </p>
-     *
-     * @param cname
-     *            the name of the class for which to set the assertion status.
-     * @param enable
-     *            the new assertion status.
-     */
-    public void setClassAssertionStatus(String cname, boolean enable) {
-    }
-
-    /**
-     * Sets the assertion status of the package with the specified name.
-     * <p>
-     * <strong>Note: </strong>This method does nothing in the Android reference
-     * implementation.
-     * </p>
-     *
-     * @param pname
-     *            the name of the package for which to set the assertion status.
-     * @param enable
-     *            the new assertion status.
-     */
-    public void setPackageAssertionStatus(String pname, boolean enable) {
-    }
-
-    /**
-     * Sets the default assertion status for this class loader.
-     * <p>
-     * <strong>Note: </strong>This method does nothing in the Android reference
-     * implementation.
-     * </p>
-     *
-     * @param enable
-     *            the new assertion status.
-     */
-    public void setDefaultAssertionStatus(boolean enable) {
-    }
-
-    /**
-     * Sets the default assertion status for this class loader to {@code false}
-     * and removes any package default and class assertion status settings.
-     * <p>
-     * <strong>Note:</strong> This method does nothing in the Android reference
-     * implementation.
-     * </p>
-     */
-    public void clearAssertionStatus() {
-    }
-}
-
-/*
- * Provides a helper class that combines two existing URL enumerations into one.
- * It is required for the getResources() methods. Items are fetched from the
- * first enumeration until it's empty, then from the second one.
- */
-class TwoEnumerationsInOne implements Enumeration<URL> {
-
-    private Enumeration<URL> first;
-
-    private Enumeration<URL> second;
-
-    public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) {
-        this.first = first;
-        this.second = second;
-    }
-
-    public boolean hasMoreElements() {
-        return first.hasMoreElements() || second.hasMoreElements();
-    }
-
-    public URL nextElement() {
-        if (first.hasMoreElements()) {
-            return first.nextElement();
-        } else {
-            return second.nextElement();
-        }
-    }
-
-}
-
-/**
- * Provides an explicit representation of the boot class loader. It sits at the
- * head of the class loader chain and delegates requests to the VM's internal
- * class loading mechanism.
- */
-class BootClassLoader extends ClassLoader {
-
-    private static BootClassLoader instance;
-
-    @FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
-    public static synchronized BootClassLoader getInstance() {
-        if (instance == null) {
-            instance = new BootClassLoader();
-        }
-
-        return instance;
-    }
-
-    public BootClassLoader() {
-        super(null, true);
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        return VMClassLoader.loadClass(name, false);
-    }
-
-    @Override
-    protected URL findResource(String name) {
-        return VMClassLoader.getResource(name);
-    }
-
-    @SuppressWarnings("unused")
-    @Override
-    protected Enumeration<URL> findResources(String resName) throws IOException {
-        return Collections.enumeration(VMClassLoader.getResources(resName));
-    }
-
-    /**
-     * Returns package information for the given package. Unfortunately, the
-     * Android BootClassLoader doesn't really have this information, and as a
-     * non-secure ClassLoader, it isn't even required to, according to the spec.
-     * Yet, we want to provide it, in order to make all those hopeful callers of
-     * {@code myClass.getPackage().getName()} happy. Thus we construct a Package
-     * object the first time it is being requested and fill most of the fields
-     * with dummy values. The Package object is then put into the ClassLoader's
-     * Package cache, so we see the same one next time. We don't create Package
-     * objects for null arguments or for the default package.
-     * <p>
-     * There a limited chance that we end up with multiple Package objects
-     * representing the same package: It can happen when when a package is
-     * scattered across different JAR files being loaded by different
-     * ClassLoaders. Rather unlikely, and given that this whole thing is more or
-     * less a workaround, probably not worth the effort.
-     */
-    @Override
-    protected Package getPackage(String name) {
-        if (name != null && !name.isEmpty()) {
-            synchronized (this) {
-                Package pack = super.getPackage(name);
-
-                if (pack == null) {
-                    pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0",
-                            "Unknown", null);
-                }
-
-                return pack;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public URL getResource(String resName) {
-        return findResource(resName);
-    }
-
-    @Override
-    protected Class<?> loadClass(String className, boolean resolve)
-           throws ClassNotFoundException {
-        Class<?> clazz = findLoadedClass(className);
-
-        if (clazz == null) {
-            clazz = findClass(className);
-        }
-
-        return clazz;
-    }
-
-    @Override
-    public Enumeration<URL> getResources(String resName) throws IOException {
-        return findResources(resName);
-    }
-}
-
-/**
- * TODO Open issues - Missing / empty methods - Signer stuff - Protection
- * domains - Assertions
- */
diff --git a/libdvm/src/main/java/java/lang/Daemons.java b/libdvm/src/main/java/java/lang/Daemons.java
deleted file mode 100644
index 78a4152..0000000
--- a/libdvm/src/main/java/java/lang/Daemons.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import dalvik.system.VMRuntime;
-import java.lang.ref.FinalizerReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.util.concurrent.TimeoutException;
-import libcore.util.EmptyArray;
-
-/**
- * Calls Object.finalize() on objects in the finalizer reference queue. The VM
- * will abort if any finalize() call takes more than the maximum finalize time
- * to complete.
- *
- * @hide
- */
-public final class Daemons {
-    private static final int NANOS_PER_MILLI = 1000 * 1000;
-    private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
-    private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;
-
-    public static void start() {
-        ReferenceQueueDaemon.INSTANCE.start();
-        FinalizerDaemon.INSTANCE.start();
-        FinalizerWatchdogDaemon.INSTANCE.start();
-    }
-
-    public static void stop() {
-        ReferenceQueueDaemon.INSTANCE.stop();
-        FinalizerDaemon.INSTANCE.stop();
-        FinalizerWatchdogDaemon.INSTANCE.stop();
-    }
-
-    /**
-     * A background task that provides runtime support to the application.
-     * Daemons can be stopped and started, but only so that the zygote can be a
-     * single-threaded process when it forks.
-     */
-    private static abstract class Daemon implements Runnable {
-        private Thread thread;
-
-        public synchronized void start() {
-            if (thread != null) {
-                throw new IllegalStateException("already running");
-            }
-            thread = new Thread(ThreadGroup.mSystem, this,
-                getClass().getSimpleName());
-            thread.setDaemon(true);
-            thread.start();
-        }
-
-        public abstract void run();
-
-        /**
-         * Returns true while the current thread should continue to run; false
-         * when it should return.
-         */
-        protected synchronized boolean isRunning() {
-            return thread != null;
-        }
-
-        public synchronized void interrupt() {
-            if (thread == null) {
-                throw new IllegalStateException("not running");
-            }
-            thread.interrupt();
-        }
-
-        /**
-         * Waits for the runtime thread to stop. This interrupts the thread
-         * currently running the runnable and then waits for it to exit.
-         */
-        public void stop() {
-            Thread threadToStop;
-            synchronized (this) {
-                threadToStop = thread;
-                thread = null;
-            }
-            if (threadToStop == null) {
-                throw new IllegalStateException("not running");
-            }
-            threadToStop.interrupt();
-            while (true) {
-                try {
-                    threadToStop.join();
-                    return;
-                } catch (InterruptedException ignored) {
-                }
-            }
-        }
-
-        /**
-         * Returns the current stack trace of the thread, or an empty stack trace
-         * if the thread is not currently running.
-         */
-        public synchronized StackTraceElement[] getStackTrace() {
-            return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
-        }
-    }
-
-    /**
-     * This heap management thread moves elements from the garbage collector's
-     * pending list to the managed reference queue.
-     */
-    private static class ReferenceQueueDaemon extends Daemon {
-        private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
-
-        @Override public void run() {
-            while (isRunning()) {
-                Reference<?> list;
-                try {
-                    synchronized (ReferenceQueue.class) {
-                        while (ReferenceQueue.unenqueued == null) {
-                            ReferenceQueue.class.wait();
-                        }
-                        list = ReferenceQueue.unenqueued;
-                        ReferenceQueue.unenqueued = null;
-                    }
-                } catch (InterruptedException e) {
-                    continue;
-                }
-                enqueue(list);
-            }
-        }
-
-        private void enqueue(Reference<?> list) {
-            while (list != null) {
-                Reference<?> reference;
-                // pendingNext is owned by the GC so no synchronization is required
-                if (list == list.pendingNext) {
-                    reference = list;
-                    reference.pendingNext = null;
-                    list = null;
-                } else {
-                    reference = list.pendingNext;
-                    list.pendingNext = reference.pendingNext;
-                    reference.pendingNext = null;
-                }
-                reference.enqueueInternal();
-            }
-        }
-    }
-
-    private static class FinalizerDaemon extends Daemon {
-        private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
-        private final ReferenceQueue<Object> queue = FinalizerReference.queue;
-        private volatile Object finalizingObject;
-        private volatile long finalizingStartedNanos;
-
-        @Override public void run() {
-            while (isRunning()) {
-                // Take a reference, blocking until one is ready or the thread should stop
-                try {
-                    doFinalize((FinalizerReference<?>) queue.remove());
-                } catch (InterruptedException ignored) {
-                }
-            }
-        }
-
-        @FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")
-        private void doFinalize(FinalizerReference<?> reference) {
-            FinalizerReference.remove(reference);
-            Object object = reference.get();
-            reference.clear();
-            try {
-                finalizingStartedNanos = System.nanoTime();
-                finalizingObject = object;
-                synchronized (FinalizerWatchdogDaemon.INSTANCE) {
-                    FinalizerWatchdogDaemon.INSTANCE.notify();
-                }
-                object.finalize();
-            } catch (Throwable ex) {
-                // The RI silently swallows these, but Android has always logged.
-                System.logE("Uncaught exception thrown by finalizer", ex);
-            } finally {
-                finalizingObject = null;
-            }
-        }
-    }
-
-    /**
-     * The watchdog exits the VM if the finalizer ever gets stuck. We consider
-     * the finalizer to be stuck if it spends more than MAX_FINALIZATION_MILLIS
-     * on one instance.
-     */
-    private static class FinalizerWatchdogDaemon extends Daemon {
-        private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
-
-        @Override public void run() {
-            while (isRunning()) {
-                Object object = waitForObject();
-                if (object == null) {
-                    // We have been interrupted, need to see if this daemon has been stopped.
-                    continue;
-                }
-                boolean finalized = waitForFinalization(object);
-                if (!finalized && !VMRuntime.getRuntime().isDebuggerActive()) {
-                    finalizerTimedOut(object);
-                    break;
-                }
-            }
-        }
-
-        private Object waitForObject() {
-            while (true) {
-                Object object = FinalizerDaemon.INSTANCE.finalizingObject;
-                if (object != null) {
-                    return object;
-                }
-                synchronized (this) {
-                    // wait until something is ready to be finalized
-                    // http://code.google.com/p/android/issues/detail?id=22778
-                    try {
-                        wait();
-                    } catch (InterruptedException e) {
-                        // Daemon.stop may have interrupted us.
-                        return null;
-                    }
-                }
-            }
-        }
-
-        private void sleepFor(long startNanos, long durationNanos) {
-            while (true) {
-                long elapsedNanos = System.nanoTime() - startNanos;
-                long sleepNanos = durationNanos - elapsedNanos;
-                long sleepMills = sleepNanos / NANOS_PER_MILLI;
-                if (sleepMills <= 0) {
-                    return;
-                }
-                try {
-                    Thread.sleep(sleepMills);
-                } catch (InterruptedException e) {
-                    if (!isRunning()) {
-                        return;
-                    }
-                }
-            }
-        }
-
-        private boolean waitForFinalization(Object object) {
-            sleepFor(FinalizerDaemon.INSTANCE.finalizingStartedNanos, MAX_FINALIZE_NANOS);
-            return object != FinalizerDaemon.INSTANCE.finalizingObject;
-        }
-
-        private static void finalizerTimedOut(Object object) {
-            // The current object has exceeded the finalization deadline; abort!
-            String message = object.getClass().getName() + ".finalize() timed out after "
-                    + (MAX_FINALIZE_NANOS / NANOS_PER_SECOND) + " seconds";
-            Exception syntheticException = new TimeoutException(message);
-            // We use the stack from where finalize() was running to show where it was stuck.
-            syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
-            Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();
-            if (h == null) {
-                // If we have no handler, log and exit.
-                System.logE(message, syntheticException);
-                System.exit(2);
-            }
-            // Otherwise call the handler to do crash reporting.
-            // We don't just throw because we're not the thread that
-            // timed out; we're the thread that detected it.
-            h.uncaughtException(Thread.currentThread(), syntheticException);
-        }
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/Enum.java b/libdvm/src/main/java/java/lang/Enum.java
deleted file mode 100644
index 4b897aa..0000000
--- a/libdvm/src/main/java/java/lang/Enum.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import libcore.util.BasicLruCache;
-import libcore.util.EmptyArray;
-
-/**
- * The superclass of all enumerated types. Actual enumeration types inherit from
- * this class, but extending this class does not make a class an enumeration
- * type, since the compiler needs to generate special information for it.
- */
-public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {
-
-    private static final long serialVersionUID = -4300926546619394005L;
-
-    private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
-            = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
-        @Override protected Object[] create(Class<? extends Enum> enumType) {
-            if (!enumType.isEnum()) {
-                return null;
-            }
-            Method method = (Method) Class.getDeclaredConstructorOrMethod(
-                    enumType, "values", EmptyArray.CLASS);
-            try {
-                return (Object[]) method.invoke((Object[]) null);
-            } catch (IllegalAccessException impossible) {
-                throw new AssertionError();
-            } catch (InvocationTargetException impossible) {
-                throw new AssertionError();
-            }
-        }
-    };
-
-    private final String name;
-
-    private final int ordinal;
-
-    /**
-     * Constructor for constants of enum subtypes.
-     *
-     * @param name
-     *            the enum constant's declared name.
-     * @param ordinal
-     *            the enum constant's ordinal, which corresponds to its position
-     *            in the enum declaration, starting at zero.
-     */
-    protected Enum(String name, int ordinal) {
-        this.name = name;
-        this.ordinal = ordinal;
-    }
-
-    /**
-     * Returns the name of this enum constant. The name is the field as it
-     * appears in the {@code enum} declaration.
-     *
-     * @return the name of this enum constant.
-     * @see #toString()
-     */
-    public final String name() {
-        return name;
-    }
-
-    /**
-     * Returns the position of the enum constant in the declaration. The first
-     * constant has an ordinal value of zero.
-     *
-     * @return the ordinal value of this enum constant.
-     */
-    public final int ordinal() {
-        return ordinal;
-    }
-
-    /**
-     * Returns a string containing a concise, human-readable description of this
-     * object. In this case, the enum constant's name is returned.
-     *
-     * @return a printable representation of this object.
-     */
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    /**
-     * Compares this object with the specified object and indicates if they are
-     * equal. In order to be equal, {@code object} must be identical to this
-     * enum constant.
-     *
-     * @param other
-     *            the object to compare this enum constant with.
-     * @return {@code true} if the specified object is equal to this
-     *         {@code Enum}; {@code false} otherwise.
-     */
-    @Override
-    public final boolean equals(Object other) {
-        return this == other;
-    }
-
-    @Override
-    public final int hashCode() {
-        return ordinal + (name == null ? 0 : name.hashCode());
-    }
-
-    /**
-     * {@code Enum} objects are singletons, they may not be cloned. This method
-     * always throws a {@code CloneNotSupportedException}.
-     *
-     * @return does not return.
-     * @throws CloneNotSupportedException
-     *             is always thrown.
-     */
-    @Override
-    protected final Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException("Enums may not be cloned");
-    }
-
-    /**
-     * Compares this object to the specified enum object to determine their
-     * relative order. This method compares the object's ordinal values, that
-     * is, their position in the enum declaration.
-     *
-     * @param o
-     *            the enum object to compare this object to.
-     * @return a negative value if the ordinal value of this enum constant is
-     *         less than the ordinal value of {@code o}; 0 if the ordinal
-     *         values of this enum constant and {@code o} are equal; a positive
-     *         value if the ordinal value of this enum constant is greater than
-     *         the ordinal value of {@code o}.
-     * @see java.lang.Comparable
-     */
-    public final int compareTo(E o) {
-        return ordinal - o.ordinal();
-    }
-
-    /**
-     * Returns the enum constant's declaring class.
-     *
-     * @return the class object representing the constant's enum type.
-     */
-    @SuppressWarnings("unchecked")
-    public final Class<E> getDeclaringClass() {
-        Class<?> myClass = getClass();
-        Class<?> mySuperClass = myClass.getSuperclass();
-        if (Enum.class == mySuperClass) {
-            return (Class<E>)myClass;
-        }
-        return (Class<E>)mySuperClass;
-    }
-
-    /**
-     * Returns the constant with the specified name of the specified enum type.
-     *
-     * @param enumType
-     *            the class of the enumerated type to search for the constant
-     *            value.
-     * @param name
-     *            the name of the constant value to find.
-     * @return the enum constant.
-     * @throws NullPointerException
-     *             if either {@code enumType} or {@code name} are {@code null}.
-     * @throws IllegalArgumentException
-     *             if {@code enumType} is not an enumerated type or does not
-     *             have a constant value called {@code name}.
-     */
-    public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
-        if (enumType == null) {
-            throw new NullPointerException("enumType == null");
-        } else if (name == null) {
-            throw new NullPointerException("name == null");
-        }
-        T[] values = getSharedConstants(enumType);
-        if (values == null) {
-            throw new IllegalArgumentException(enumType + " is not an enum type");
-        }
-        for (T value : values) {
-            if (name.equals(value.name())) {
-                return value;
-            }
-        }
-        throw new IllegalArgumentException(name + " is not a constant in " + enumType.getName());
-    }
-
-    /**
-     * Returns a shared, mutable array containing the constants of this enum. It
-     * is an error to modify the returned array.
-     *
-     * @hide
-     */
-    @SuppressWarnings("unchecked") // the cache always returns the type matching enumType
-    public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
-        return (T[]) sharedConstantsCache.get(enumType);
-    }
-
-    /**
-     * Enum types may not have finalizers.
-     *
-     * @since 1.6
-     */
-    @Override
-    @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
-    protected final void finalize() {
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/Object.java b/libdvm/src/main/java/java/lang/Object.java
deleted file mode 100644
index d2cd2f1..0000000
--- a/libdvm/src/main/java/java/lang/Object.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang;
-
-/**
- * The root class of the Java class hierarchy. All non-primitive types
- * (including arrays) inherit either directly or indirectly from this class.
- *
- * <a name="writing_equals"><h4>Writing a correct {@code equals} method</h4></a>
- * <p>Follow this style to write a canonical {@code equals} method:
- * <pre>
- *   // Use @Override to avoid accidental overloading.
- *   &#x0040;Override public boolean equals(Object o) {
- *     // Return true if the objects are identical.
- *     // (This is just an optimization, not required for correctness.)
- *     if (this == o) {
- *       return true;
- *     }
- *
- *     // Return false if the other object has the wrong type.
- *     // This type may be an interface depending on the interface's specification.
- *     if (!(o instanceof MyType)) {
- *       return false;
- *     }
- *
- *     // Cast to the appropriate type.
- *     // This will succeed because of the instanceof, and lets us access private fields.
- *     MyType lhs = (MyType) o;
- *
- *     // Check each field. Primitive fields, reference fields, and nullable reference
- *     // fields are all treated differently.
- *     return primitiveField == lhs.primitiveField &amp;&amp;
- *             referenceField.equals(lhs.referenceField) &amp;&amp;
- *             (nullableField == null ? lhs.nullableField == null
- *                                    : nullableField.equals(lhs.nullableField));
- *   }
- * </pre>
- * <p>If you override {@code equals}, you should also override {@code hashCode}: equal
- * instances must have equal hash codes.
- *
- * <p>See <i>Effective Java</i> item 8 for much more detail and clarification.
- *
- * <a name="writing_hashCode"><h4>Writing a correct {@code hashCode} method</h4></a>
- * <p>Follow this style to write a canonical {@code hashCode} method:
- * <pre>
- *   &#x0040;Override public int hashCode() {
- *     // Start with a non-zero constant.
- *     int result = 17;
- *
- *     // Include a hash for each field.
- *     result = 31 * result + (booleanField ? 1 : 0);
- *
- *     result = 31 * result + byteField;
- *     result = 31 * result + charField;
- *     result = 31 * result + shortField;
- *     result = 31 * result + intField;
- *
- *     result = 31 * result + (int) (longField ^ (longField >>> 32));
- *
- *     result = 31 * result + Float.floatToIntBits(floatField);
- *
- *     long doubleFieldBits = Double.doubleToLongBits(doubleField);
- *     result = 31 * result + (int) (doubleFieldBits ^ (doubleFieldBits >>> 32));
- *
- *     result = 31 * result + Arrays.hashCode(arrayField);
- *
- *     result = 31 * result + referenceField.hashCode();
- *     result = 31 * result +
- *         (nullableReferenceField == null ? 0
- *                                         : nullableReferenceField.hashCode());
- *
- *     return result;
- *   }
- * </pre>
- *
- * <p>If you don't intend your type to be used as a hash key, don't simply rely on the default
- * {@code hashCode} implementation, because that silently and non-obviously breaks any future
- * code that does use your type as a hash key. You should throw instead:
- * <pre>
- *   &#x0040;Override public int hashCode() {
- *     throw new UnsupportedOperationException();
- *   }
- * </pre>
- *
- * <p>See <i>Effective Java</i> item 9 for much more detail and clarification.
- *
- * <a name="writing_toString"><h4>Writing a useful {@code toString} method</h4></a>
- * <p>For debugging convenience, it's common to override {@code toString} in this style:
- * <pre>
- *   &#x0040;Override public String toString() {
- *     return getClass().getName() + "[" +
- *         "primitiveField=" + primitiveField + ", " +
- *         "referenceField=" + referenceField + ", " +
- *         "arrayField=" + Arrays.toString(arrayField) + "]";
- *   }
- * </pre>
- * <p>The set of fields to include is generally the same as those that would be tested
- * in your {@code equals} implementation.
- * <p>See <i>Effective Java</i> item 10 for much more detail and clarification.
- */
-public class Object {
-    /**
-     * Constructs a new instance of {@code Object}.
-     */
-    public Object() {
-    }
-
-    /**
-     * Creates and returns a copy of this {@code Object}. The default
-     * implementation returns a so-called "shallow" copy: It creates a new
-     * instance of the same class and then copies the field values (including
-     * object references) from this instance to the new instance. A "deep" copy,
-     * in contrast, would also recursively clone nested objects. A subclass that
-     * needs to implement this kind of cloning should call {@code super.clone()}
-     * to create the new instance and then create deep copies of the nested,
-     * mutable objects.
-     *
-     * @return a copy of this object.
-     * @throws CloneNotSupportedException
-     *             if this object's class does not implement the {@code
-     *             Cloneable} interface.
-     */
-    protected Object clone() throws CloneNotSupportedException {
-        if (!(this instanceof Cloneable)) {
-            throw new CloneNotSupportedException("Class doesn't implement Cloneable");
-        }
-
-        return internalClone((Cloneable) this);
-    }
-
-    /*
-     * Native helper method for cloning.
-     */
-    private native Object internalClone(Cloneable o);
-
-    /**
-     * Compares this instance with the specified object and indicates if they
-     * are equal. In order to be equal, {@code o} must represent the same object
-     * as this instance using a class-specific comparison. The general contract
-     * is that this comparison should be reflexive, symmetric, and transitive.
-     * Also, no object reference other than null is equal to null.
-     *
-     * <p>The default implementation returns {@code true} only if {@code this ==
-     * o}. See <a href="{@docRoot}reference/java/lang/Object.html#writing_equals">Writing a correct
-     * {@code equals} method</a>
-     * if you intend implementing your own {@code equals} method.
-     *
-     * <p>The general contract for the {@code equals} and {@link
-     * #hashCode()} methods is that if {@code equals} returns {@code true} for
-     * any two objects, then {@code hashCode()} must return the same value for
-     * these objects. This means that subclasses of {@code Object} usually
-     * override either both methods or neither of them.
-     *
-     * @param o
-     *            the object to compare this instance with.
-     * @return {@code true} if the specified object is equal to this {@code
-     *         Object}; {@code false} otherwise.
-     * @see #hashCode
-     */
-    public boolean equals(Object o) {
-        return this == o;
-    }
-
-    /**
-     * Invoked when the garbage collector has detected that this instance is no longer reachable.
-     * The default implementation does nothing, but this method can be overridden to free resources.
-     *
-     * <p>Note that objects that override {@code finalize} are significantly more expensive than
-     * objects that don't. Finalizers may be run a long time after the object is no longer
-     * reachable, depending on memory pressure, so it's a bad idea to rely on them for cleanup.
-     * Note also that finalizers are run on a single VM-wide finalizer thread,
-     * so doing blocking work in a finalizer is a bad idea. A finalizer is usually only necessary
-     * for a class that has a native peer and needs to call a native method to destroy that peer.
-     * Even then, it's better to provide an explicit {@code close} method (and implement
-     * {@link java.io.Closeable}), and insist that callers manually dispose of instances. This
-     * works well for something like files, but less well for something like a {@code BigInteger}
-     * where typical calling code would have to deal with lots of temporaries. Unfortunately,
-     * code that creates lots of temporaries is the worst kind of code from the point of view of
-     * the single finalizer thread.
-     *
-     * <p>If you <i>must</i> use finalizers, consider at least providing your own
-     * {@link java.lang.ref.ReferenceQueue} and having your own thread process that queue.
-     *
-     * <p>Unlike constructors, finalizers are not automatically chained. You are responsible for
-     * calling {@code super.finalize()} yourself.
-     *
-     * <p>Uncaught exceptions thrown by finalizers are ignored and do not terminate the finalizer
-     * thread.
-     *
-     * See <i>Effective Java</i> Item 7, "Avoid finalizers" for more.
-     */
-    @FindBugsSuppressWarnings("FI_EMPTY")
-    protected void finalize() throws Throwable {
-    }
-
-    /**
-     * Returns the unique instance of {@link Class} that represents this
-     * object's class. Note that {@code getClass()} is a special case in that it
-     * actually returns {@code Class<? extends Foo>} where {@code Foo} is the
-     * erasure of the type of the expression {@code getClass()} was called upon.
-     * <p>
-     * As an example, the following code actually compiles, although one might
-     * think it shouldn't:
-     * <p>
-     * <pre>{@code
-     *   List<Integer> l = new ArrayList<Integer>();
-     *   Class<? extends List> c = l.getClass();}</pre>
-     *
-     * @return this object's {@code Class} instance.
-     */
-    public final native Class<?> getClass();
-
-    /**
-     * Returns an integer hash code for this object. By contract, any two
-     * objects for which {@link #equals} returns {@code true} must return
-     * the same hash code value. This means that subclasses of {@code Object}
-     * usually override both methods or neither method.
-     *
-     * <p>Note that hash values must not change over time unless information used in equals
-     * comparisons also changes.
-     *
-     * <p>See <a href="{@docRoot}reference/java/lang/Object.html#writing_hashCode">Writing a correct
-     * {@code hashCode} method</a>
-     * if you intend implementing your own {@code hashCode} method.
-     *
-     * @return this object's hash code.
-     * @see #equals
-     */
-    public native int hashCode();
-
-    /**
-     * Causes a thread which is waiting on this object's monitor (by means of
-     * calling one of the {@code wait()} methods) to be woken up. If more than
-     * one thread is waiting, one of them is chosen at the discretion of the
-     * VM. The chosen thread will not run immediately. The thread
-     * that called {@code notify()} has to release the object's monitor first.
-     * Also, the chosen thread still has to compete against other threads that
-     * try to synchronize on the same object.
-     *
-     * <p>This method can only be invoked by a thread which owns this object's
-     * monitor. A thread becomes owner of an object's monitor
-     * <ul>
-     * <li>by executing a synchronized method of that object;</li>
-     * <li>by executing the body of a {@code synchronized} statement that
-     * synchronizes on the object;</li>
-     * <li>by executing a synchronized static method if the object is of type
-     * {@code Class}.</li>
-     * </ul>
-     *
-     * @see #notifyAll
-     * @see #wait()
-     * @see #wait(long)
-     * @see #wait(long,int)
-     * @see java.lang.Thread
-     */
-    public final native void notify();
-
-    /**
-     * Causes all threads which are waiting on this object's monitor (by means
-     * of calling one of the {@code wait()} methods) to be woken up. The threads
-     * will not run immediately. The thread that called {@code notify()} has to
-     * release the object's monitor first. Also, the threads still have to
-     * compete against other threads that try to synchronize on the same object.
-     *
-     * <p>This method can only be invoked by a thread which owns this object's
-     * monitor. A thread becomes owner of an object's monitor
-     * <ul>
-     * <li>by executing a synchronized method of that object;</li>
-     * <li>by executing the body of a {@code synchronized} statement that
-     * synchronizes on the object;</li>
-     * <li>by executing a synchronized static method if the object is of type
-     * {@code Class}.</li>
-     * </ul>
-     *
-     * @throws IllegalMonitorStateException
-     *             if the thread calling this method is not the owner of this
-     *             object's monitor.
-     * @see #notify
-     * @see #wait()
-     * @see #wait(long)
-     * @see #wait(long,int)
-     * @see java.lang.Thread
-     */
-    public final native void notifyAll();
-
-    /**
-     * Returns a string containing a concise, human-readable description of this
-     * object. Subclasses are encouraged to override this method and provide an
-     * implementation that takes into account the object's type and data. The
-     * default implementation is equivalent to the following expression:
-     * <pre>
-     *   getClass().getName() + '@' + Integer.toHexString(hashCode())</pre>
-     * <p>See <a href="{@docRoot}reference/java/lang/Object.html#writing_toString">Writing a useful
-     * {@code toString} method</a>
-     * if you intend implementing your own {@code toString} method.
-     *
-     * @return a printable representation of this object.
-     */
-    public String toString() {
-        return getClass().getName() + '@' + Integer.toHexString(hashCode());
-    }
-
-    /**
-     * Causes the calling thread to wait until another thread calls the {@code
-     * notify()} or {@code notifyAll()} method of this object. This method can
-     * only be invoked by a thread which owns this object's monitor; see
-     * {@link #notify()} on how a thread can become the owner of a monitor.
-     *
-     * <p>A waiting thread can be sent {@code interrupt()} to cause it to
-     * prematurely stop waiting, so {@code wait} should be called in a loop to
-     * check that the condition that has been waited for has been met before
-     * continuing.
-     *
-     * <p>While the thread waits, it gives up ownership of this object's
-     * monitor. When it is notified (or interrupted), it re-acquires the monitor
-     * before it starts running.
-     *
-     * @throws IllegalMonitorStateException
-     *             if the thread calling this method is not the owner of this
-     *             object's monitor.
-     * @throws InterruptedException if the current thread has been interrupted.
-     *             The interrupted status of the current thread will be cleared before the exception
-     *             is thrown.
-     * @see #notify
-     * @see #notifyAll
-     * @see #wait(long)
-     * @see #wait(long,int)
-     * @see java.lang.Thread
-     */
-    public final void wait() throws InterruptedException {
-        wait(0, 0);
-    }
-
-    /**
-     * Causes the calling thread to wait until another thread calls the {@code
-     * notify()} or {@code notifyAll()} method of this object or until the
-     * specified timeout expires. This method can only be invoked by a thread
-     * which owns this object's monitor; see {@link #notify()} on how a thread
-     * can become the owner of a monitor.
-     *
-     * <p>A waiting thread can be sent {@code interrupt()} to cause it to
-     * prematurely stop waiting, so {@code wait} should be called in a loop to
-     * check that the condition that has been waited for has been met before
-     * continuing.
-     *
-     * <p>While the thread waits, it gives up ownership of this object's
-     * monitor. When it is notified (or interrupted), it re-acquires the monitor
-     * before it starts running.
-     *
-     * <p>A timeout of zero means the calling thread should wait forever unless interrupted or
-     * notified.
-     *
-     * @param millis
-     *            the maximum time to wait in milliseconds.
-     * @throws IllegalArgumentException
-     *             if {@code millis < 0}.
-     * @throws IllegalMonitorStateException
-     *             if the thread calling this method is not the owner of this
-     *             object's monitor.
-     * @throws InterruptedException if the current thread has been interrupted.
-     *             The interrupted status of the current thread will be cleared before the exception
-     *             is thrown.
-     * @see #notify
-     * @see #notifyAll
-     * @see #wait()
-     * @see #wait(long,int)
-     * @see java.lang.Thread
-     */
-    public final void wait(long millis) throws InterruptedException {
-        wait(millis, 0);
-    }
-
-    /**
-     * Causes the calling thread to wait until another thread calls the {@code
-     * notify()} or {@code notifyAll()} method of this object or until the
-     * specified timeout expires. This method can only be invoked by a thread
-     * that owns this object's monitor; see {@link #notify()} on how a thread
-     * can become the owner of a monitor.
-     *
-     * <p>A waiting thread can be sent {@code interrupt()} to cause it to
-     * prematurely stop waiting, so {@code wait} should be called in a loop to
-     * check that the condition that has been waited for has been met before
-     * continuing.
-     *
-     * <p>While the thread waits, it gives up ownership of this object's
-     * monitor. When it is notified (or interrupted), it re-acquires the monitor
-     * before it starts running.
-     *
-     * <p>A timeout of zero means the calling thread should wait forever unless interrupted or
-     * notified.
-     *
-     * @param millis
-     *            the maximum time to wait in milliseconds.
-     * @param nanos
-     *            the fraction of a millisecond to wait, specified in
-     *            nanoseconds.
-     * @throws IllegalArgumentException
-     *             if {@code millis < 0}, {@code nanos < 0} or {@code nanos >
-     *             999999}.
-     * @throws IllegalMonitorStateException
-     *             if the thread calling this method is not the owner of this
-     *             object's monitor.
-     * @throws InterruptedException if the current thread has been interrupted.
-     *             The interrupted status of the current thread will be cleared before the exception
-     *             is thrown.
-     * @see #notify
-     * @see #notifyAll
-     * @see #wait()
-     * @see #wait(long,int)
-     * @see java.lang.Thread
-     */
-    public final native void wait(long millis, int nanos) throws InterruptedException;
-}
diff --git a/libdvm/src/main/java/java/lang/String.java b/libdvm/src/main/java/java/lang/String.java
deleted file mode 100644
index 10a6301..0000000
--- a/libdvm/src/main/java/java/lang/String.java
+++ /dev/null
@@ -1,2075 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package java.lang;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.Charsets;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Formatter;
-import java.util.Locale;
-import java.util.regex.Pattern;
-import libcore.util.EmptyArray;
-
-/**
- * An immutable sequence of characters/code units ({@code char}s). A
- * {@code String} is represented by array of UTF-16 values, such that
- * Unicode supplementary characters (code points) are stored/encoded as
- * surrogate pairs via Unicode code units ({@code char}).
- *
- * <a name="backing_array"><h3>Backing Arrays</h3></a>
- * This class is implemented using a char[]. The length of the array may exceed
- * the length of the string. For example, the string "Hello" may be backed by
- * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with
- * offset 0 and length 5.
- *
- * <p>Multiple strings can share the same char[] because strings are immutable.
- * The {@link #substring} method <strong>always</strong> returns a string that
- * shares the backing array of its source string. Generally this is an
- * optimization: fewer character arrays need to be allocated, and less copying
- * is necessary. But this can also lead to unwanted heap retention. Taking a
- * short substring of long string means that the long shared char[] won't be
- * garbage until both strings are garbage. This typically happens when parsing
- * small substrings out of a large input. To avoid this where necessary, call
- * {@code new String(longString.subString(...))}. The string copy constructor
- * always ensures that the backing array is no larger than necessary.
- *
- * @see StringBuffer
- * @see StringBuilder
- * @see Charset
- * @since 1.0
- */
-public final class String implements Serializable, Comparable<String>, CharSequence {
-
-    private static final long serialVersionUID = -6849794470754667710L;
-
-    private static final char REPLACEMENT_CHAR = (char) 0xfffd;
-
-    /**
-     * CaseInsensitiveComparator compares Strings ignoring the case of the
-     * characters.
-     */
-    private static final class CaseInsensitiveComparator implements
-            Comparator<String>, Serializable {
-        private static final long serialVersionUID = 8575799808933029326L;
-
-        /**
-         * Compare the two objects to determine the relative ordering.
-         *
-         * @param o1
-         *            an Object to compare
-         * @param o2
-         *            an Object to compare
-         * @return an int < 0 if object1 is less than object2, 0 if they are
-         *         equal, and > 0 if object1 is greater
-         *
-         * @throws ClassCastException
-         *                if objects are not the correct type
-         */
-        public int compare(String o1, String o2) {
-            return o1.compareToIgnoreCase(o2);
-        }
-    }
-
-    /**
-     * A comparator ignoring the case of the characters.
-     */
-    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
-
-    private static final char[] ASCII;
-    static {
-        ASCII = new char[128];
-        for (int i = 0; i < ASCII.length; ++i) {
-            ASCII[i] = (char) i;
-        }
-    }
-
-    private final char[] value;
-
-    private final int offset;
-
-    private final int count;
-
-    private int hashCode;
-
-    /**
-     * Creates an empty string.
-     */
-    public String() {
-        value = EmptyArray.CHAR;
-        offset = 0;
-        count = 0;
-    }
-
-    /*
-     * Private constructor used for JIT optimization.
-     */
-    @SuppressWarnings("unused")
-    private String(String s, char c) {
-        offset = 0;
-        value = new char[s.count + 1];
-        count = s.count + 1;
-        System.arraycopy(s.value, s.offset, value, 0, s.count);
-        value[s.count] = c;
-    }
-
-    /**
-     * Converts the byte array to a string using the system's
-     * {@link java.nio.charset.Charset#defaultCharset default charset}.
-     */
-    @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING")
-    public String(byte[] data) {
-        this(data, 0, data.length);
-    }
-
-    /**
-     * Converts the byte array to a string, setting the high byte of every
-     * character to the specified value.
-     *
-     * @param data
-     *            the byte array to convert to a string.
-     * @param high
-     *            the high byte to use.
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead.
-     */
-    @Deprecated
-    public String(byte[] data, int high) {
-        this(data, high, 0, data.length);
-    }
-
-    /**
-     * Converts a subsequence of the byte array to a string using the system's
-     * {@link java.nio.charset.Charset#defaultCharset default charset}.
-     *
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
-     */
-    public String(byte[] data, int offset, int byteCount) {
-        this(data, offset, byteCount, Charset.defaultCharset());
-    }
-
-    /**
-     * Converts the byte array to a string, setting the high byte of every
-     * character to {@code high}.
-     *
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
-     *
-     * @deprecated Use {@link #String(byte[], int, int)} instead.
-     */
-    @Deprecated
-    public String(byte[] data, int high, int offset, int byteCount) {
-        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
-            throw failedBoundsCheck(data.length, offset, byteCount);
-        }
-        this.offset = 0;
-        this.value = new char[byteCount];
-        this.count = byteCount;
-        high <<= 8;
-        for (int i = 0; i < count; i++) {
-            value[i] = (char) (high + (data[offset++] & 0xff));
-        }
-    }
-
-    /**
-     * Converts the byte array to a string using the named charset.
-     *
-     * <p>The behavior when the bytes cannot be decoded by the named charset
-     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
-     *
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}.
-     * @throws UnsupportedEncodingException
-     *             if the named charset is not supported.
-     */
-    public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
-        this(data, offset, byteCount, Charset.forNameUEE(charsetName));
-    }
-
-    /**
-     * Converts the byte array to a string using the named charset.
-     *
-     * <p>The behavior when the bytes cannot be decoded by the named charset
-     * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control.
-     *
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @throws UnsupportedEncodingException
-     *             if {@code charsetName} is not supported.
-     */
-    public String(byte[] data, String charsetName) throws UnsupportedEncodingException {
-        this(data, 0, data.length, Charset.forNameUEE(charsetName));
-    }
-
-    /**
-     * Converts the byte array to a string using the given charset.
-     *
-     * <p>The behavior when the bytes cannot be decoded by the given charset
-     * is to replace malformed input and unmappable characters with the charset's default
-     * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control.
-     *
-     * @throws IndexOutOfBoundsException
-     *             if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}
-     * @throws NullPointerException
-     *             if {@code data == null}
-     *
-     * @since 1.6
-     */
-    public String(byte[] data, int offset, int byteCount, Charset charset) {
-        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
-            throw failedBoundsCheck(data.length, offset, byteCount);
-        }
-
-        // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and
-        // 'value' are final.
-        String canonicalCharsetName = charset.name();
-        if (canonicalCharsetName.equals("UTF-8")) {
-            byte[] d = data;
-            char[] v = new char[byteCount];
-
-            int idx = offset;
-            int last = offset + byteCount;
-            int s = 0;
-outer:
-            while (idx < last) {
-                byte b0 = d[idx++];
-                if ((b0 & 0x80) == 0) {
-                    // 0xxxxxxx
-                    // Range:  U-00000000 - U-0000007F
-                    int val = b0 & 0xff;
-                    v[s++] = (char) val;
-                } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) ||
-                        ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) {
-                    int utfCount = 1;
-                    if ((b0 & 0xf0) == 0xe0) utfCount = 2;
-                    else if ((b0 & 0xf8) == 0xf0) utfCount = 3;
-                    else if ((b0 & 0xfc) == 0xf8) utfCount = 4;
-                    else if ((b0 & 0xfe) == 0xfc) utfCount = 5;
-
-                    // 110xxxxx (10xxxxxx)+
-                    // Range:  U-00000080 - U-000007FF (count == 1)
-                    // Range:  U-00000800 - U-0000FFFF (count == 2)
-                    // Range:  U-00010000 - U-001FFFFF (count == 3)
-                    // Range:  U-00200000 - U-03FFFFFF (count == 4)
-                    // Range:  U-04000000 - U-7FFFFFFF (count == 5)
-
-                    if (idx + utfCount > last) {
-                        v[s++] = REPLACEMENT_CHAR;
-                        continue;
-                    }
-
-                    // Extract usable bits from b0
-                    int val = b0 & (0x1f >> (utfCount - 1));
-                    for (int i = 0; i < utfCount; ++i) {
-                        byte b = d[idx++];
-                        if ((b & 0xc0) != 0x80) {
-                            v[s++] = REPLACEMENT_CHAR;
-                            idx--; // Put the input char back
-                            continue outer;
-                        }
-                        // Push new bits in from the right side
-                        val <<= 6;
-                        val |= b & 0x3f;
-                    }
-
-                    // Note: Java allows overlong char
-                    // specifications To disallow, check that val
-                    // is greater than or equal to the minimum
-                    // value for each count:
-                    //
-                    // count    min value
-                    // -----   ----------
-                    //   1           0x80
-                    //   2          0x800
-                    //   3        0x10000
-                    //   4       0x200000
-                    //   5      0x4000000
-
-                    // Allow surrogate values (0xD800 - 0xDFFF) to
-                    // be specified using 3-byte UTF values only
-                    if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) {
-                        v[s++] = REPLACEMENT_CHAR;
-                        continue;
-                    }
-
-                    // Reject chars greater than the Unicode maximum of U+10FFFF.
-                    if (val > 0x10FFFF) {
-                        v[s++] = REPLACEMENT_CHAR;
-                        continue;
-                    }
-
-                    // Encode chars from U+10000 up as surrogate pairs
-                    if (val < 0x10000) {
-                        v[s++] = (char) val;
-                    } else {
-                        int x = val & 0xffff;
-                        int u = (val >> 16) & 0x1f;
-                        int w = (u - 1) & 0xffff;
-                        int hi = 0xd800 | (w << 6) | (x >> 10);
-                        int lo = 0xdc00 | (x & 0x3ff);
-                        v[s++] = (char) hi;
-                        v[s++] = (char) lo;
-                    }
-                } else {
-                    // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff
-                    v[s++] = REPLACEMENT_CHAR;
-                }
-            }
-
-            if (s == byteCount) {
-                // We guessed right, so we can use our temporary array as-is.
-                this.offset = 0;
-                this.value = v;
-                this.count = s;
-            } else {
-                // Our temporary array was too big, so reallocate and copy.
-                this.offset = 0;
-                this.value = new char[s];
-                this.count = s;
-                System.arraycopy(v, 0, value, 0, s);
-            }
-        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
-            this.offset = 0;
-            this.value = new char[byteCount];
-            this.count = byteCount;
-            Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
-        } else if (canonicalCharsetName.equals("US-ASCII")) {
-            this.offset = 0;
-            this.value = new char[byteCount];
-            this.count = byteCount;
-            Charsets.asciiBytesToChars(data, offset, byteCount, value);
-        } else {
-            CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
-            this.offset = 0;
-            this.count = cb.length();
-            if (count > 0) {
-                // We could use cb.array() directly, but that would mean we'd have to trust
-                // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later,
-                // which would break String's immutability guarantee. It would also tend to
-                // mean that we'd be wasting memory because CharsetDecoder doesn't trim the
-                // array. So we copy.
-                this.value = new char[count];
-                System.arraycopy(cb.array(), 0, value, 0, count);
-            } else {
-                this.value = EmptyArray.CHAR;
-            }
-        }
-    }
-
-    /**
-     * Converts the byte array to a String using the given charset.
-     *
-     * @throws NullPointerException if {@code data == null}
-     * @since 1.6
-     */
-    public String(byte[] data, Charset charset) {
-        this(data, 0, data.length, charset);
-    }
-
-    /**
-     * Initializes this string to contain the characters in the specified
-     * character array. Modifying the character array after creating the string
-     * has no effect on the string.
-     *
-     * @throws NullPointerException if {@code data == null}
-     */
-    public String(char[] data) {
-        this(data, 0, data.length);
-    }
-
-    /**
-     * Initializes this string to contain the specified characters in the
-     * character array. Modifying the character array after creating the string
-     * has no effect on the string.
-     *
-     * @throws NullPointerException
-     *             if {@code data == null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code charCount < 0 || offset < 0 || offset + charCount > data.length}
-     */
-    public String(char[] data, int offset, int charCount) {
-        if ((offset | charCount) < 0 || charCount > data.length - offset) {
-            throw failedBoundsCheck(data.length, offset, charCount);
-        }
-        this.offset = 0;
-        this.value = new char[charCount];
-        this.count = charCount;
-        System.arraycopy(data, offset, value, 0, count);
-    }
-
-    /*
-     * Internal version of the String(char[], int, int) constructor.
-     * Does not range check, null check, or copy the character array.
-     */
-    String(int offset, int charCount, char[] chars) {
-        this.value = chars;
-        this.offset = offset;
-        this.count = charCount;
-    }
-
-    /**
-     * Constructs a new string with the same sequence of characters as {@code
-     * toCopy}. The returned string's <a href="#backing_array">backing array</a>
-     * is no larger than necessary.
-     */
-    public String(String toCopy) {
-        value = (toCopy.value.length == toCopy.count)
-                ? toCopy.value
-                : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length());
-        offset = 0;
-        count = value.length;
-    }
-
-    /*
-     * Private constructor useful for JIT optimization.
-     */
-    @SuppressWarnings( { "unused", "nls" })
-    private String(String s1, String s2) {
-        if (s1 == null) {
-            s1 = "null";
-        }
-        if (s2 == null) {
-            s2 = "null";
-        }
-        count = s1.count + s2.count;
-        value = new char[count];
-        offset = 0;
-        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
-        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
-    }
-
-    /*
-     * Private constructor useful for JIT optimization.
-     */
-    @SuppressWarnings( { "unused", "nls" })
-    private String(String s1, String s2, String s3) {
-        if (s1 == null) {
-            s1 = "null";
-        }
-        if (s2 == null) {
-            s2 = "null";
-        }
-        if (s3 == null) {
-            s3 = "null";
-        }
-        count = s1.count + s2.count + s3.count;
-        value = new char[count];
-        offset = 0;
-        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
-        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
-        System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count, s3.count);
-    }
-
-    /**
-     * Creates a {@code String} from the contents of the specified
-     * {@code StringBuffer}.
-     */
-    public String(StringBuffer stringBuffer) {
-        offset = 0;
-        synchronized (stringBuffer) {
-            value = stringBuffer.shareValue();
-            count = stringBuffer.length();
-        }
-    }
-
-    /**
-     * Creates a {@code String} from the sub-array of Unicode code points.
-     *
-     * @throws NullPointerException
-     *             if {@code codePoints == null}.
-     * @throws IllegalArgumentException
-     *             if any of the elements of {@code codePoints} are not valid
-     *             Unicode code points.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset} or {@code count} are not within the bounds
-     *             of {@code codePoints}.
-     * @since 1.5
-     */
-    public String(int[] codePoints, int offset, int count) {
-        if (codePoints == null) {
-            throw new NullPointerException("codePoints == null");
-        }
-        if ((offset | count) < 0 || count > codePoints.length - offset) {
-            throw failedBoundsCheck(codePoints.length, offset, count);
-        }
-        this.offset = 0;
-        this.value = new char[count * 2];
-        int end = offset + count;
-        int c = 0;
-        for (int i = offset; i < end; i++) {
-            c += Character.toChars(codePoints[i], this.value, c);
-        }
-        this.count = c;
-    }
-
-    /**
-     * Creates a {@code String} from the contents of the specified {@code
-     * StringBuilder}.
-     *
-     * @throws NullPointerException
-     *             if {@code stringBuilder == null}.
-     * @since 1.5
-     */
-    public String(StringBuilder stringBuilder) {
-        if (stringBuilder == null) {
-            throw new NullPointerException("stringBuilder == null");
-        }
-        this.offset = 0;
-        this.count = stringBuilder.length();
-        this.value = new char[this.count];
-        stringBuilder.getChars(0, this.count, this.value, 0);
-    }
-
-    /*
-     * Creates a {@code String} that is s1 + v1. May be used by JIT code.
-     */
-    @SuppressWarnings("unused")
-    private String(String s1, int v1) {
-        if (s1 == null) {
-            s1 = "null";
-        }
-        String s2 = String.valueOf(v1);
-        int len = s1.count + s2.count;
-        value = new char[len];
-        offset = 0;
-        System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
-        System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
-        count = len;
-    }
-
-    /**
-     * Returns the character at {@code index}.
-     * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
-     */
-    public char charAt(int index) {
-        if (index < 0 || index >= count) {
-            throw indexAndLength(index);
-        }
-        return value[offset + index];
-    }
-
-    private StringIndexOutOfBoundsException indexAndLength(int index) {
-        throw new StringIndexOutOfBoundsException(this, index);
-    }
-
-    private StringIndexOutOfBoundsException startEndAndLength(int start, int end) {
-        throw new StringIndexOutOfBoundsException(this, start, end - start);
-    }
-
-    private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) {
-        throw new StringIndexOutOfBoundsException(arrayLength, offset, count);
-    }
-
-    /**
-     * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode
-     * case folds, but it's what the RI uses.
-     */
-    private char foldCase(char ch) {
-        if (ch < 128) {
-            if ('A' <= ch && ch <= 'Z') {
-                return (char) (ch + ('a' - 'A'));
-            }
-            return ch;
-        }
-        return Character.toLowerCase(Character.toUpperCase(ch));
-    }
-
-    /**
-     * Compares the specified string to this string using the Unicode values of
-     * the characters. Returns 0 if the strings contain the same characters in
-     * the same order. Returns a negative integer if the first non-equal
-     * character in this string has a Unicode value which is less than the
-     * Unicode value of the character at the same position in the specified
-     * string, or if this string is a prefix of the specified string. Returns a
-     * positive integer if the first non-equal character in this string has a
-     * Unicode value which is greater than the Unicode value of the character at
-     * the same position in the specified string, or if the specified string is
-     * a prefix of this string.
-     *
-     * @param string
-     *            the string to compare.
-     * @return 0 if the strings are equal, a negative integer if this string is
-     *         before the specified string, or a positive integer if this string
-     *         is after the specified string.
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public native int compareTo(String string);
-
-    /**
-     * Compares the specified string to this string using the Unicode values of
-     * the characters, ignoring case differences. Returns 0 if the strings
-     * contain the same characters in the same order. Returns a negative integer
-     * if the first non-equal character in this string has a Unicode value which
-     * is less than the Unicode value of the character at the same position in
-     * the specified string, or if this string is a prefix of the specified
-     * string. Returns a positive integer if the first non-equal character in
-     * this string has a Unicode value which is greater than the Unicode value
-     * of the character at the same position in the specified string, or if the
-     * specified string is a prefix of this string.
-     *
-     * @param string
-     *            the string to compare.
-     * @return 0 if the strings are equal, a negative integer if this string is
-     *         before the specified string, or a positive integer if this string
-     *         is after the specified string.
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public int compareToIgnoreCase(String string) {
-        int o1 = offset, o2 = string.offset, result;
-        int end = offset + (count < string.count ? count : string.count);
-        char c1, c2;
-        char[] target = string.value;
-        while (o1 < end) {
-            if ((c1 = value[o1++]) == (c2 = target[o2++])) {
-                continue;
-            }
-            c1 = foldCase(c1);
-            c2 = foldCase(c2);
-            if ((result = c1 - c2) != 0) {
-                return result;
-            }
-        }
-        return count - string.count;
-    }
-
-    /**
-     * Concatenates this string and the specified string.
-     *
-     * @param string
-     *            the string to concatenate
-     * @return a new string which is the concatenation of this string and the
-     *         specified string.
-     */
-    public String concat(String string) {
-        if (string.count > 0 && count > 0) {
-            char[] buffer = new char[count + string.count];
-            System.arraycopy(value, offset, buffer, 0, count);
-            System.arraycopy(string.value, string.offset, buffer, count, string.count);
-            return new String(0, buffer.length, buffer);
-        }
-        return count == 0 ? string : this;
-    }
-
-    /**
-     * Creates a new string containing the characters in the specified character
-     * array. Modifying the character array after creating the string has no
-     * effect on the string.
-     *
-     * @param data
-     *            the array of characters.
-     * @return the new string.
-     * @throws NullPointerException
-     *             if {@code data} is {@code null}.
-     */
-    public static String copyValueOf(char[] data) {
-        return new String(data, 0, data.length);
-    }
-
-    /**
-     * Creates a new string containing the specified characters in the character
-     * array. Modifying the character array after creating the string has no
-     * effect on the string.
-     *
-     * @param data
-     *            the array of characters.
-     * @param start
-     *            the starting offset in the character array.
-     * @param length
-     *            the number of characters to use.
-     * @return the new string.
-     * @throws NullPointerException
-     *             if {@code data} is {@code null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code length < 0, start < 0} or {@code start + length >
-     *             data.length}.
-     */
-    public static String copyValueOf(char[] data, int start, int length) {
-        return new String(data, start, length);
-    }
-
-    /**
-     * Compares the specified string to this string to determine if the
-     * specified string is a suffix.
-     *
-     * @param suffix
-     *            the suffix to look for.
-     * @return {@code true} if the specified string is a suffix of this string,
-     *         {@code false} otherwise.
-     * @throws NullPointerException
-     *             if {@code suffix} is {@code null}.
-     */
-    public boolean endsWith(String suffix) {
-        return regionMatches(count - suffix.count, suffix, 0, suffix.count);
-    }
-
-    /**
-     * Compares the specified object to this string and returns true if they are
-     * equal. The object must be an instance of string with the same characters
-     * in the same order.
-     *
-     * @param other
-     *            the object to compare.
-     * @return {@code true} if the specified object is equal to this string,
-     *         {@code false} otherwise.
-     * @see #hashCode
-     */
-    @Override public boolean equals(Object other) {
-        if (other == this) {
-          return true;
-        }
-        if (other instanceof String) {
-            String s = (String)other;
-            int count = this.count;
-            if (s.count != count) {
-                return false;
-            }
-            // TODO: we want to avoid many boundchecks in the loop below
-            // for long Strings until we have array equality intrinsic.
-            // Bad benchmarks just push .equals without first getting a
-            // hashCode hit (unlike real world use in a Hashtable). Filter
-            // out these long strings here. When we get the array equality
-            // intrinsic then remove this use of hashCode.
-            if (hashCode() != s.hashCode()) {
-                return false;
-            }
-            char[] value1 = value;
-            int offset1 = offset;
-            char[] value2 = s.value;
-            int offset2 = s.offset;
-            for (int end = offset1 + count; offset1 < end; ) {
-                if (value1[offset1] != value2[offset2]) {
-                    return false;
-                }
-                offset1++;
-                offset2++;
-            }
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Compares the specified string to this string ignoring the case of the
-     * characters and returns true if they are equal.
-     *
-     * @param string
-     *            the string to compare.
-     * @return {@code true} if the specified string is equal to this string,
-     *         {@code false} otherwise.
-     */
-    @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
-    public boolean equalsIgnoreCase(String string) {
-        if (string == this) {
-            return true;
-        }
-        if (string == null || count != string.count) {
-            return false;
-        }
-        int o1 = offset, o2 = string.offset;
-        int end = offset + count;
-        char[] target = string.value;
-        while (o1 < end) {
-            char c1 = value[o1++];
-            char c2 = target[o2++];
-            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Mangles this string into a byte array by stripping the high order bits from
-     * each character. Use {@link #getBytes()} or {@link #getBytes(String)} instead.
-     *
-     * @param start
-     *            the starting offset of characters to copy.
-     * @param end
-     *            the ending offset of characters to copy.
-     * @param data
-     *            the destination byte array.
-     * @param index
-     *            the starting offset in the destination byte array.
-     * @throws NullPointerException
-     *             if {@code data} is {@code null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code start < 0}, {@code end > length()}, {@code index <
-     *             0} or {@code end - start > data.length - index}.
-     * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)} instead.
-     */
-    @Deprecated
-    public void getBytes(int start, int end, byte[] data, int index) {
-        // Note: last character not copied!
-        if (start >= 0 && start <= end && end <= count) {
-            end += offset;
-            try {
-                for (int i = offset + start; i < end; i++) {
-                    data[index++] = (byte) value[i];
-                }
-            } catch (ArrayIndexOutOfBoundsException ignored) {
-                throw failedBoundsCheck(data.length, index, end - start);
-            }
-        } else {
-            throw startEndAndLength(start, end);
-        }
-    }
-
-    /**
-     * Returns a new byte array containing the characters of this string encoded using the
-     * system's {@link java.nio.charset.Charset#defaultCharset default charset}.
-     *
-     * <p>The behavior when this string cannot be represented in the system's default charset
-     * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android),
-     * all strings can be encoded.
-     */
-    public byte[] getBytes() {
-        return getBytes(Charset.defaultCharset());
-    }
-
-    /**
-     * Returns a new byte array containing the characters of this string encoded using the
-     * named charset.
-     *
-     * <p>The behavior when this string cannot be represented in the named charset
-     * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control.
-     *
-     * @throws UnsupportedEncodingException if the charset is not supported
-     */
-    public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
-        return getBytes(Charset.forNameUEE(charsetName));
-    }
-
-    /**
-     * Returns a new byte array containing the characters of this string encoded using the
-     * given charset.
-     *
-     * <p>The behavior when this string cannot be represented in the given charset
-     * is to replace malformed input and unmappable characters with the charset's default
-     * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control.
-     *
-     * @since 1.6
-     */
-    public byte[] getBytes(Charset charset) {
-        String canonicalCharsetName = charset.name();
-        if (canonicalCharsetName.equals("UTF-8")) {
-            return Charsets.toUtf8Bytes(value, offset, count);
-        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
-            return Charsets.toIsoLatin1Bytes(value, offset, count);
-        } else if (canonicalCharsetName.equals("US-ASCII")) {
-            return Charsets.toAsciiBytes(value, offset, count);
-        } else if (canonicalCharsetName.equals("UTF-16BE")) {
-            return Charsets.toBigEndianUtf16Bytes(value, offset, count);
-        } else {
-            CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
-            ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
-            byte[] bytes = new byte[buffer.limit()];
-            buffer.get(bytes);
-            return bytes;
-        }
-    }
-
-    /**
-     * Copies the specified characters in this string to the character array
-     * starting at the specified offset in the character array.
-     *
-     * @param start
-     *            the starting offset of characters to copy.
-     * @param end
-     *            the ending offset of characters to copy.
-     * @param buffer
-     *            the destination character array.
-     * @param index
-     *            the starting offset in the character array.
-     * @throws NullPointerException
-     *             if {@code buffer} is {@code null}.
-     * @throws IndexOutOfBoundsException
-     *             if {@code start < 0}, {@code end > length()}, {@code start >
-     *             end}, {@code index < 0}, {@code end - start > buffer.length -
-     *             index}
-     */
-    public void getChars(int start, int end, char[] buffer, int index) {
-        // Note: last character not copied!
-        if (start >= 0 && start <= end && end <= count) {
-            System.arraycopy(value, start + offset, buffer, index, end - start);
-        } else {
-            // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE.
-            throw startEndAndLength(start, end);
-        }
-    }
-
-    /**
-     * Version of getChars without bounds checks, for use by other classes
-     * within the java.lang package only.  The caller is responsible for
-     * ensuring that start >= 0 && start <= end && end <= count.
-     */
-    void _getChars(int start, int end, char[] buffer, int index) {
-        // NOTE last character not copied!
-        System.arraycopy(value, start + offset, buffer, index, end - start);
-    }
-
-    @Override public int hashCode() {
-        int hash = hashCode;
-        if (hash == 0) {
-            if (count == 0) {
-                return 0;
-            }
-            final int end = count + offset;
-            final char[] chars = value;
-            for (int i = offset; i < end; ++i) {
-                hash = 31*hash + chars[i];
-            }
-            hashCode = hash;
-        }
-        return hash;
-    }
-
-    /**
-     * Searches in this string for the first index of the specified character.
-     * The search for the character starts at the beginning and moves towards
-     * the end of this string.
-     *
-     * @param c
-     *            the character to find.
-     * @return the index in this string of the specified character, -1 if the
-     *         character isn't found.
-     */
-    public int indexOf(int c) {
-        // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
-        if (c > 0xffff) {
-            return indexOfSupplementary(c, 0);
-        }
-        return fastIndexOf(c, 0);
-    }
-
-    /**
-     * Searches in this string for the index of the specified character. The
-     * search for the character starts at the specified offset and moves towards
-     * the end of this string.
-     *
-     * @param c
-     *            the character to find.
-     * @param start
-     *            the starting offset.
-     * @return the index in this string of the specified character, -1 if the
-     *         character isn't found.
-     */
-    public int indexOf(int c, int start) {
-        if (c > 0xffff) {
-            return indexOfSupplementary(c, start);
-        }
-        return fastIndexOf(c, start);
-    }
-
-    private native int fastIndexOf(int c, int start);
-
-    private int indexOfSupplementary(int c, int start) {
-        if (!Character.isSupplementaryCodePoint(c)) {
-            return -1;
-        }
-        char[] chars = Character.toChars(c);
-        String needle = new String(0, chars.length, chars);
-        return indexOf(needle, start);
-    }
-
-    /**
-     * Searches in this string for the first index of the specified string. The
-     * search for the string starts at the beginning and moves towards the end
-     * of this string.
-     *
-     * @param string
-     *            the string to find.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public int indexOf(String string) {
-        int start = 0;
-        int subCount = string.count;
-        int _count = count;
-        if (subCount > 0) {
-            if (subCount > _count) {
-                return -1;
-            }
-            char[] target = string.value;
-            int subOffset = string.offset;
-            char firstChar = target[subOffset];
-            int end = subOffset + subCount;
-            while (true) {
-                int i = indexOf(firstChar, start);
-                if (i == -1 || subCount + i > _count) {
-                    return -1; // handles subCount > count || start >= count
-                }
-                int o1 = offset + i, o2 = subOffset;
-                char[] _value = value;
-                while (++o2 < end && _value[++o1] == target[o2]) {
-                    // Intentionally empty
-                }
-                if (o2 == end) {
-                    return i;
-                }
-                start = i + 1;
-            }
-        }
-        return start < _count ? start : _count;
-    }
-
-    /**
-     * Searches in this string for the index of the specified string. The search
-     * for the string starts at the specified offset and moves towards the end
-     * of this string.
-     *
-     * @param subString
-     *            the string to find.
-     * @param start
-     *            the starting offset.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
-     * @throws NullPointerException
-     *             if {@code subString} is {@code null}.
-     */
-    public int indexOf(String subString, int start) {
-        if (start < 0) {
-            start = 0;
-        }
-        int subCount = subString.count;
-        int _count = count;
-        if (subCount > 0) {
-            if (subCount + start > _count) {
-                return -1;
-            }
-            char[] target = subString.value;
-            int subOffset = subString.offset;
-            char firstChar = target[subOffset];
-            int end = subOffset + subCount;
-            while (true) {
-                int i = indexOf(firstChar, start);
-                if (i == -1 || subCount + i > _count) {
-                    return -1; // handles subCount > count || start >= count
-                }
-                int o1 = offset + i, o2 = subOffset;
-                char[] _value = value;
-                while (++o2 < end && _value[++o1] == target[o2]) {
-                    // Intentionally empty
-                }
-                if (o2 == end) {
-                    return i;
-                }
-                start = i + 1;
-            }
-        }
-        return start < _count ? start : _count;
-    }
-
-    /**
-     * Returns an interned string equal to this string. The VM maintains an internal set of
-     * unique strings. All string literals found in loaded classes'
-     * constant pools are automatically interned. Manually-interned strings are only weakly
-     * referenced, so calling {@code intern} won't lead to unwanted retention.
-     *
-     * <p>Interning is typically used because it guarantees that for interned strings
-     * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to
-     * {@code a == b}. (This is not true of non-interned strings.)
-     *
-     * <p>Many applications find it simpler and more convenient to use an explicit
-     * {@link java.util.HashMap} to implement their own pools.
-     */
-    public native String intern();
-
-    /**
-     * Returns true if the length of this string is 0.
-     *
-     * @since 1.6
-     */
-    public boolean isEmpty() {
-        return count == 0;
-    }
-
-    /**
-     * Returns the last index of the code point {@code c}, or -1.
-     * The search for the character starts at the end and moves towards the
-     * beginning of this string.
-     */
-    public int lastIndexOf(int c) {
-        if (c > 0xffff) {
-            return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
-        }
-        int _count = count;
-        int _offset = offset;
-        char[] _value = value;
-        for (int i = _offset + _count - 1; i >= _offset; --i) {
-            if (_value[i] == c) {
-                return i - _offset;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the last index of the code point {@code c}, or -1.
-     * The search for the character starts at offset {@code start} and moves towards
-     * the beginning of this string.
-     */
-    public int lastIndexOf(int c, int start) {
-        if (c > 0xffff) {
-            return lastIndexOfSupplementary(c, start);
-        }
-        int _count = count;
-        int _offset = offset;
-        char[] _value = value;
-        if (start >= 0) {
-            if (start >= _count) {
-                start = _count - 1;
-            }
-            for (int i = _offset + start; i >= _offset; --i) {
-                if (_value[i] == c) {
-                    return i - _offset;
-                }
-            }
-        }
-        return -1;
-    }
-
-    private int lastIndexOfSupplementary(int c, int start) {
-        if (!Character.isSupplementaryCodePoint(c)) {
-            return -1;
-        }
-        char[] chars = Character.toChars(c);
-        String needle = new String(0, chars.length, chars);
-        return lastIndexOf(needle, start);
-    }
-
-    /**
-     * Searches in this string for the last index of the specified string. The
-     * search for the string starts at the end and moves towards the beginning
-     * of this string.
-     *
-     * @param string
-     *            the string to find.
-     * @return the index of the first character of the specified string in this
-     *         string, -1 if the specified string is not a substring.
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public int lastIndexOf(String string) {
-        // Use count instead of count - 1 so lastIndexOf("") returns count
-        return lastIndexOf(string, count);
-    }
-
-    /**
-     * Searches in this string for the index of the specified string. The search
-     * for the string starts at the specified offset and moves towards the
-     * beginning of this string.
-     *
-     * @param subString
-     *            the string to find.
-     * @param start
-     *            the starting offset.
-     * @return the index of the first character of the specified string in this
-     *         string , -1 if the specified string is not a substring.
-     * @throws NullPointerException
-     *             if {@code subString} is {@code null}.
-     */
-    public int lastIndexOf(String subString, int start) {
-        int subCount = subString.count;
-        if (subCount <= count && start >= 0) {
-            if (subCount > 0) {
-                if (start > count - subCount) {
-                    start = count - subCount;
-                }
-                // count and subCount are both >= 1
-                char[] target = subString.value;
-                int subOffset = subString.offset;
-                char firstChar = target[subOffset];
-                int end = subOffset + subCount;
-                while (true) {
-                    int i = lastIndexOf(firstChar, start);
-                    if (i == -1) {
-                        return -1;
-                    }
-                    int o1 = offset + i, o2 = subOffset;
-                    while (++o2 < end && value[++o1] == target[o2]) {
-                        // Intentionally empty
-                    }
-                    if (o2 == end) {
-                        return i;
-                    }
-                    start = i - 1;
-                }
-            }
-            return start < count ? start : count;
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the number of characters in this string.
-     */
-    public int length() {
-        return count;
-    }
-
-    /**
-     * Compares the specified string to this string and compares the specified
-     * range of characters to determine if they are the same.
-     *
-     * @param thisStart
-     *            the starting offset in this string.
-     * @param string
-     *            the string to compare.
-     * @param start
-     *            the starting offset in the specified string.
-     * @param length
-     *            the number of characters to compare.
-     * @return {@code true} if the ranges of characters are equal, {@code false}
-     *         otherwise
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public boolean regionMatches(int thisStart, String string, int start, int length) {
-        if (string == null) {
-            throw new NullPointerException("string == null");
-        }
-        if (start < 0 || string.count - start < length) {
-            return false;
-        }
-        if (thisStart < 0 || count - thisStart < length) {
-            return false;
-        }
-        if (length <= 0) {
-            return true;
-        }
-        int o1 = offset + thisStart, o2 = string.offset + start;
-        char[] value1 = value;
-        char[] value2 = string.value;
-        for (int i = 0; i < length; ++i) {
-            if (value1[o1 + i] != value2[o2 + i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Compares the specified string to this string and compares the specified
-     * range of characters to determine if they are the same. When ignoreCase is
-     * true, the case of the characters is ignored during the comparison.
-     *
-     * @param ignoreCase
-     *            specifies if case should be ignored.
-     * @param thisStart
-     *            the starting offset in this string.
-     * @param string
-     *            the string to compare.
-     * @param start
-     *            the starting offset in the specified string.
-     * @param length
-     *            the number of characters to compare.
-     * @return {@code true} if the ranges of characters are equal, {@code false}
-     *         otherwise.
-     * @throws NullPointerException
-     *             if {@code string} is {@code null}.
-     */
-    public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) {
-        if (!ignoreCase) {
-            return regionMatches(thisStart, string, start, length);
-        }
-        if (string == null) {
-            throw new NullPointerException("string == null");
-        }
-        if (thisStart < 0 || length > count - thisStart) {
-            return false;
-        }
-        if (start < 0 || length > string.count - start) {
-            return false;
-        }
-        thisStart += offset;
-        start += string.offset;
-        int end = thisStart + length;
-        char[] target = string.value;
-        while (thisStart < end) {
-            char c1 = value[thisStart++];
-            char c2 = target[start++];
-            if (c1 != c2 && foldCase(c1) != foldCase(c2)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Copies this string replacing occurrences of the specified character with
-     * another character.
-     *
-     * @param oldChar
-     *            the character to replace.
-     * @param newChar
-     *            the replacement character.
-     * @return a new string with occurrences of oldChar replaced by newChar.
-     */
-    public String replace(char oldChar, char newChar) {
-        char[] buffer = value;
-        int _offset = offset;
-        int _count = count;
-
-        int idx = _offset;
-        int last = _offset + _count;
-        boolean copied = false;
-        while (idx < last) {
-            if (buffer[idx] == oldChar) {
-                if (!copied) {
-                    char[] newBuffer = new char[_count];
-                    System.arraycopy(buffer, _offset, newBuffer, 0, _count);
-                    buffer = newBuffer;
-                    idx -= _offset;
-                    last -= _offset;
-                    copied = true;
-                }
-                buffer[idx] = newChar;
-            }
-            idx++;
-        }
-
-        return copied ? new String(0, count, buffer) : this;
-    }
-
-    /**
-     * Copies this string replacing occurrences of the specified target sequence
-     * with another sequence. The string is processed from the beginning to the
-     * end.
-     *
-     * @param target
-     *            the sequence to replace.
-     * @param replacement
-     *            the replacement sequence.
-     * @return the resulting string.
-     * @throws NullPointerException
-     *             if {@code target} or {@code replacement} is {@code null}.
-     */
-    public String replace(CharSequence target, CharSequence replacement) {
-        if (target == null) {
-            throw new NullPointerException("target == null");
-        }
-        if (replacement == null) {
-            throw new NullPointerException("replacement == null");
-        }
-
-        String targetString = target.toString();
-        int matchStart = indexOf(targetString, 0);
-        if (matchStart == -1) {
-            // If there's nothing to replace, return the original string untouched.
-            return this;
-        }
-
-        String replacementString = replacement.toString();
-
-        // The empty target matches at the start and end and between each character.
-        int targetLength = targetString.length();
-        if (targetLength == 0) {
-            // The result contains the original 'count' characters, a copy of the
-            // replacement string before every one of those characters, and a final
-            // copy of the replacement string at the end.
-            int resultLength = count + (count + 1) * replacementString.length();
-            StringBuilder result = new StringBuilder(resultLength);
-            result.append(replacementString);
-            int end = offset + count;
-            for (int i = offset; i != end; ++i) {
-                result.append(value[i]);
-                result.append(replacementString);
-            }
-            return result.toString();
-        }
-
-        StringBuilder result = new StringBuilder(count);
-        int searchStart = 0;
-        do {
-            // Copy characters before the match...
-            result.append(value, offset + searchStart, matchStart - searchStart);
-            // Insert the replacement...
-            result.append(replacementString);
-            // And skip over the match...
-            searchStart = matchStart + targetLength;
-        } while ((matchStart = indexOf(targetString, searchStart)) != -1);
-        // Copy any trailing chars...
-        result.append(value, offset + searchStart, count - searchStart);
-        return result.toString();
-    }
-
-    /**
-     * Compares the specified string to this string to determine if the
-     * specified string is a prefix.
-     *
-     * @param prefix
-     *            the string to look for.
-     * @return {@code true} if the specified string is a prefix of this string,
-     *         {@code false} otherwise
-     * @throws NullPointerException
-     *             if {@code prefix} is {@code null}.
-     */
-    public boolean startsWith(String prefix) {
-        return startsWith(prefix, 0);
-    }
-
-    /**
-     * Compares the specified string to this string, starting at the specified
-     * offset, to determine if the specified string is a prefix.
-     *
-     * @param prefix
-     *            the string to look for.
-     * @param start
-     *            the starting offset.
-     * @return {@code true} if the specified string occurs in this string at the
-     *         specified offset, {@code false} otherwise.
-     * @throws NullPointerException
-     *             if {@code prefix} is {@code null}.
-     */
-    public boolean startsWith(String prefix, int start) {
-        return regionMatches(start, prefix, 0, prefix.count);
-    }
-
-    /**
-     * Returns a string containing a suffix of this string. The returned string
-     * shares this string's <a href="#backing_array">backing array</a>.
-     *
-     * @param start
-     *            the offset of the first character.
-     * @return a new string containing the characters from start to the end of
-     *         the string.
-     * @throws IndexOutOfBoundsException
-     *             if {@code start < 0} or {@code start > length()}.
-     */
-    public String substring(int start) {
-        if (start == 0) {
-            return this;
-        }
-        if (start >= 0 && start <= count) {
-            return new String(offset + start, count - start, value);
-        }
-        throw indexAndLength(start);
-    }
-
-    /**
-     * Returns a string containing a subsequence of characters from this string.
-     * The returned string shares this string's <a href="#backing_array">backing
-     * array</a>.
-     *
-     * @param start
-     *            the offset of the first character.
-     * @param end
-     *            the offset one past the last character.
-     * @return a new string containing the characters from start to end - 1
-     * @throws IndexOutOfBoundsException
-     *             if {@code start < 0}, {@code start > end} or {@code end >
-     *             length()}.
-     */
-    public String substring(int start, int end) {
-        if (start == 0 && end == count) {
-            return this;
-        }
-        // NOTE last character not copied!
-        // Fast range check.
-        if (start >= 0 && start <= end && end <= count) {
-            return new String(offset + start, end - start, value);
-        }
-        throw startEndAndLength(start, end);
-    }
-
-    /**
-     * Returns a new {@code char} array containing a copy of the characters in this string.
-     * This is expensive and rarely useful. If you just want to iterate over the characters in
-     * the string, use {@link #charAt} instead.
-     */
-    public char[] toCharArray() {
-        char[] buffer = new char[count];
-        System.arraycopy(value, offset, buffer, 0, count);
-        return buffer;
-    }
-
-    /**
-     * Converts this string to lower case, using the rules of the user's default locale.
-     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
-     *
-     * @return a new lower case string, or {@code this} if it's already all lower case.
-     */
-    public String toLowerCase() {
-        return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count);
-    }
-
-    /**
-     * Converts this string to lower case, using the rules of {@code locale}.
-     *
-     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
-     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
-     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
-     * correct case mapping of Greek characters: any locale will do.
-     *
-     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
-     * for full details of context- and language-specific special cases.
-     *
-     * @return a new lower case string, or {@code this} if it's already all lower case.
-     */
-    public String toLowerCase(Locale locale) {
-        return CaseMapper.toLowerCase(locale, this, value, offset, count);
-    }
-
-    /**
-     * Returns this string.
-     */
-    @Override
-    public String toString() {
-        return this;
-    }
-
-    /**
-     * Converts this this string to upper case, using the rules of the user's default locale.
-     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
-     *
-     * @return a new upper case string, or {@code this} if it's already all upper case.
-     */
-    public String toUpperCase() {
-        return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
-    }
-
-    /**
-     * Converts this this string to upper case, using the rules of {@code locale}.
-     *
-     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
-     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
-     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
-     * correct case mapping of Greek characters: any locale will do.
-     *
-     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
-     * for full details of context- and language-specific special cases.
-     *
-     * @return a new upper case string, or {@code this} if it's already all upper case.
-     */
-    public String toUpperCase(Locale locale) {
-        return CaseMapper.toUpperCase(locale, this, value, offset, count);
-    }
-
-    /**
-     * Copies this string removing white space characters from the beginning and
-     * end of the string.
-     *
-     * @return a new string with characters <code><= \\u0020</code> removed from
-     *         the beginning and the end.
-     */
-    public String trim() {
-        int start = offset, last = offset + count - 1;
-        int end = last;
-        while ((start <= end) && (value[start] <= ' ')) {
-            start++;
-        }
-        while ((end >= start) && (value[end] <= ' ')) {
-            end--;
-        }
-        if (start == offset && end == last) {
-            return this;
-        }
-        return new String(start, end - start + 1, value);
-    }
-
-    /**
-     * Creates a new string containing the characters in the specified character
-     * array. Modifying the character array after creating the string has no
-     * effect on the string.
-     *
-     * @param data
-     *            the array of characters.
-     * @return the new string.
-     * @throws NullPointerException
-     *             if {@code data} is {@code null}.
-     */
-    public static String valueOf(char[] data) {
-        return new String(data, 0, data.length);
-    }
-
-    /**
-     * Creates a new string containing the specified characters in the character
-     * array. Modifying the character array after creating the string has no
-     * effect on the string.
-     *
-     * @param data
-     *            the array of characters.
-     * @param start
-     *            the starting offset in the character array.
-     * @param length
-     *            the number of characters to use.
-     * @return the new string.
-     * @throws IndexOutOfBoundsException
-     *             if {@code length < 0}, {@code start < 0} or {@code start +
-     *             length > data.length}
-     * @throws NullPointerException
-     *             if {@code data} is {@code null}.
-     */
-    public static String valueOf(char[] data, int start, int length) {
-        return new String(data, start, length);
-    }
-
-    /**
-     * Converts the specified character to its string representation.
-     *
-     * @param value
-     *            the character.
-     * @return the character converted to a string.
-     */
-    public static String valueOf(char value) {
-        String s;
-        if (value < 128) {
-            s = new String(value, 1, ASCII);
-        } else {
-            s = new String(0, 1, new char[] { value });
-        }
-        s.hashCode = value;
-        return s;
-    }
-
-    /**
-     * Converts the specified double to its string representation.
-     *
-     * @param value
-     *            the double.
-     * @return the double converted to a string.
-     */
-    public static String valueOf(double value) {
-        return Double.toString(value);
-    }
-
-    /**
-     * Converts the specified float to its string representation.
-     *
-     * @param value
-     *            the float.
-     * @return the float converted to a string.
-     */
-    public static String valueOf(float value) {
-        return Float.toString(value);
-    }
-
-    /**
-     * Converts the specified integer to its string representation.
-     *
-     * @param value
-     *            the integer.
-     * @return the integer converted to a string.
-     */
-    public static String valueOf(int value) {
-        return Integer.toString(value);
-    }
-
-    /**
-     * Converts the specified long to its string representation.
-     *
-     * @param value
-     *            the long.
-     * @return the long converted to a string.
-     */
-    public static String valueOf(long value) {
-        return Long.toString(value);
-    }
-
-    /**
-     * Converts the specified object to its string representation. If the object
-     * is null return the string {@code "null"}, otherwise use {@code
-     * toString()} to get the string representation.
-     *
-     * @param value
-     *            the object.
-     * @return the object converted to a string, or the string {@code "null"}.
-     */
-    public static String valueOf(Object value) {
-        return value != null ? value.toString() : "null";
-    }
-
-    /**
-     * Converts the specified boolean to its string representation. When the
-     * boolean is {@code true} return {@code "true"}, otherwise return {@code
-     * "false"}.
-     *
-     * @param value
-     *            the boolean.
-     * @return the boolean converted to a string.
-     */
-    public static String valueOf(boolean value) {
-        return value ? "true" : "false";
-    }
-
-    /**
-     * Returns whether the characters in the StringBuffer {@code strbuf} are the
-     * same as those in this string.
-     *
-     * @param strbuf
-     *            the StringBuffer to compare this string to.
-     * @return {@code true} if the characters in {@code strbuf} are identical to
-     *         those in this string. If they are not, {@code false} will be
-     *         returned.
-     * @throws NullPointerException
-     *             if {@code strbuf} is {@code null}.
-     * @since 1.4
-     */
-    public boolean contentEquals(StringBuffer strbuf) {
-        synchronized (strbuf) {
-            int size = strbuf.length();
-            if (count != size) {
-                return false;
-            }
-            return regionMatches(0, new String(0, size, strbuf.getValue()), 0,
-                    size);
-        }
-    }
-
-    /**
-     * Compares a {@code CharSequence} to this {@code String} to determine if
-     * their contents are equal.
-     *
-     * @param cs
-     *            the character sequence to compare to.
-     * @return {@code true} if equal, otherwise {@code false}
-     * @since 1.5
-     */
-    public boolean contentEquals(CharSequence cs) {
-        if (cs == null) {
-            throw new NullPointerException("cs == null");
-        }
-
-        int len = cs.length();
-
-        if (len != count) {
-            return false;
-        }
-
-        if (len == 0 && count == 0) {
-            return true; // since both are empty strings
-        }
-
-        return regionMatches(0, cs.toString(), 0, len);
-    }
-
-    /**
-     * Tests whether this string matches the given {@code regularExpression}. This method returns
-     * true only if the regular expression matches the <i>entire</i> input string. A common mistake is
-     * to assume that this method behaves like {@link #contains}; if you want to match anywhere
-     * within the input string, you need to add {@code .*} to the beginning and end of your
-     * regular expression. See {@link Pattern#matches}.
-     *
-     * <p>If the same regular expression is to be used for multiple operations, it may be more
-     * efficient to reuse a compiled {@code Pattern}.
-     *
-     * @throws PatternSyntaxException
-     *             if the syntax of the supplied regular expression is not
-     *             valid.
-     * @throws NullPointerException if {@code regularExpression == null}
-     * @since 1.4
-     */
-    public boolean matches(String regularExpression) {
-        return Pattern.matches(regularExpression, this);
-    }
-
-    /**
-     * Replaces all matches for {@code regularExpression} within this string with the given
-     * {@code replacement}.
-     * See {@link Pattern} for regular expression syntax.
-     *
-     * <p>If the same regular expression is to be used for multiple operations, it may be more
-     * efficient to reuse a compiled {@code Pattern}.
-     *
-     * @throws PatternSyntaxException
-     *             if the syntax of the supplied regular expression is not
-     *             valid.
-     * @throws NullPointerException if {@code regularExpression == null}
-     * @see Pattern
-     * @since 1.4
-     */
-    public String replaceAll(String regularExpression, String replacement) {
-        return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement);
-    }
-
-    /**
-     * Replaces the first match for {@code regularExpression} within this string with the given
-     * {@code replacement}.
-     * See {@link Pattern} for regular expression syntax.
-     *
-     * <p>If the same regular expression is to be used for multiple operations, it may be more
-     * efficient to reuse a compiled {@code Pattern}.
-     *
-     * @throws PatternSyntaxException
-     *             if the syntax of the supplied regular expression is not
-     *             valid.
-     * @throws NullPointerException if {@code regularExpression == null}
-     * @see Pattern
-     * @since 1.4
-     */
-    public String replaceFirst(String regularExpression, String replacement) {
-        return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement);
-    }
-
-    /**
-     * Splits this string using the supplied {@code regularExpression}.
-     * Equivalent to {@code split(regularExpression, 0)}.
-     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
-     * See {@link Pattern} for regular expression syntax.
-     *
-     * <p>If the same regular expression is to be used for multiple operations, it may be more
-     * efficient to reuse a compiled {@code Pattern}.
-     *
-     * @throws NullPointerException if {@code regularExpression ==  null}
-     * @throws PatternSyntaxException
-     *             if the syntax of the supplied regular expression is not
-     *             valid.
-     * @see Pattern
-     * @since 1.4
-     */
-    public String[] split(String regularExpression) {
-        return split(regularExpression, 0);
-    }
-
-    /**
-     * Splits this string using the supplied {@code regularExpression}.
-     * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}.
-     * See {@link Pattern} for regular expression syntax.
-     *
-     * <p>If the same regular expression is to be used for multiple operations, it may be more
-     * efficient to reuse a compiled {@code Pattern}.
-     *
-     * @throws NullPointerException if {@code regularExpression ==  null}
-     * @throws PatternSyntaxException
-     *             if the syntax of the supplied regular expression is not
-     *             valid.
-     * @since 1.4
-     */
-    public String[] split(String regularExpression, int limit) {
-        String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);
-        return result != null ? result : Pattern.compile(regularExpression).split(this, limit);
-    }
-
-    /**
-     * Has the same result as the substring function, but is present so that
-     * string may implement the CharSequence interface.
-     *
-     * @param start
-     *            the offset the first character.
-     * @param end
-     *            the offset of one past the last character to include.
-     * @return the subsequence requested.
-     * @throws IndexOutOfBoundsException
-     *             if {@code start < 0}, {@code end < 0}, {@code start > end} or
-     *             {@code end > length()}.
-     * @see java.lang.CharSequence#subSequence(int, int)
-     * @since 1.4
-     */
-    public CharSequence subSequence(int start, int end) {
-        return substring(start, end);
-    }
-
-    /**
-     * Returns the Unicode code point at the given {@code index}.
-     *
-     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
-     * @see Character#codePointAt(char[], int, int)
-     * @since 1.5
-     */
-    public int codePointAt(int index) {
-        if (index < 0 || index >= count) {
-            throw indexAndLength(index);
-        }
-        return Character.codePointAt(value, offset + index, offset + count);
-    }
-
-    /**
-     * Returns the Unicode code point that precedes the given {@code index}.
-     *
-     * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
-     * @see Character#codePointBefore(char[], int, int)
-     * @since 1.5
-     */
-    public int codePointBefore(int index) {
-        if (index < 1 || index > count) {
-            throw indexAndLength(index);
-        }
-        return Character.codePointBefore(value, offset + index, offset);
-    }
-
-    /**
-     * Calculates the number of Unicode code points between {@code start}
-     * and {@code end}.
-     *
-     * @param start
-     *            the inclusive beginning index of the subsequence.
-     * @param end
-     *            the exclusive end index of the subsequence.
-     * @return the number of Unicode code points in the subsequence.
-     * @throws IndexOutOfBoundsException
-     *         if {@code start < 0 || end > length() || start > end}
-     * @see Character#codePointCount(CharSequence, int, int)
-     * @since 1.5
-     */
-    public int codePointCount(int start, int end) {
-        if (start < 0 || end > count || start > end) {
-            throw startEndAndLength(start, end);
-        }
-        return Character.codePointCount(value, offset + start, end - start);
-    }
-
-    /**
-     * Determines if this {@code String} contains the sequence of characters in
-     * the {@code CharSequence} passed.
-     *
-     * @param cs
-     *            the character sequence to search for.
-     * @return {@code true} if the sequence of characters are contained in this
-     *         string, otherwise {@code false}.
-     * @since 1.5
-     */
-    public boolean contains(CharSequence cs) {
-        if (cs == null) {
-            throw new NullPointerException("cs == null");
-        }
-        return indexOf(cs.toString()) >= 0;
-    }
-
-    /**
-     * Returns the index within this object that is offset from {@code index} by
-     * {@code codePointOffset} code points.
-     *
-     * @param index
-     *            the index within this object to calculate the offset from.
-     * @param codePointOffset
-     *            the number of code points to count.
-     * @return the index within this object that is the offset.
-     * @throws IndexOutOfBoundsException
-     *             if {@code index} is negative or greater than {@code length()}
-     *             or if there aren't enough code points before or after {@code
-     *             index} to match {@code codePointOffset}.
-     * @since 1.5
-     */
-    public int offsetByCodePoints(int index, int codePointOffset) {
-        int s = index + offset;
-        int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
-        return r - offset;
-    }
-
-    /**
-     * Returns a localized formatted string, using the supplied format and arguments,
-     * using the user's default locale.
-     *
-     * <p>If you're formatting a string other than for human
-     * consumption, you should use the {@code format(Locale, String, Object...)}
-     * overload and supply {@code Locale.US}. See
-     * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
-     *
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     * @return the formatted string.
-     * @throws NullPointerException if {@code format == null}
-     * @throws java.util.IllegalFormatException
-     *             if the format is invalid.
-     * @since 1.5
-     */
-    public static String format(String format, Object... args) {
-        return format(Locale.getDefault(), format, args);
-    }
-
-    /**
-     * Returns a formatted string, using the supplied format and arguments,
-     * localized to the given locale.
-     *
-     * @param locale
-     *            the locale to apply; {@code null} value means no localization.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     * @return the formatted string.
-     * @throws NullPointerException if {@code format == null}
-     * @throws java.util.IllegalFormatException
-     *             if the format is invalid.
-     * @since 1.5
-     */
-    public static String format(Locale locale, String format, Object... args) {
-        if (format == null) {
-            throw new NullPointerException("format == null");
-        }
-        int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
-        Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
-        return f.format(format, args).toString();
-    }
-
-    /*
-     * An implementation of a String.indexOf that is supposed to perform
-     * substantially better than the default algorithm if the "needle" (the
-     * subString being searched for) is a constant string.
-     *
-     * For example, a JIT, upon encountering a call to String.indexOf(String),
-     * where the needle is a constant string, may compute the values cache, md2
-     * and lastChar, and change the call to the following method.
-     */
-    @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
-    @SuppressWarnings("unused")
-    private static int indexOf(String haystackString, String needleString,
-            int cache, int md2, char lastChar) {
-        char[] haystack = haystackString.value;
-        int haystackOffset = haystackString.offset;
-        int haystackLength = haystackString.count;
-        char[] needle = needleString.value;
-        int needleOffset = needleString.offset;
-        int needleLength = needleString.count;
-        int needleLengthMinus1 = needleLength - 1;
-        int haystackEnd = haystackOffset + haystackLength;
-        outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) {
-            if (lastChar == haystack[i]) {
-                for (int j = 0; j < needleLengthMinus1; ++j) {
-                    if (needle[j + needleOffset] != haystack[i + j
-                            - needleLengthMinus1]) {
-                        int skip = 1;
-                        if ((cache & (1 << haystack[i])) == 0) {
-                            skip += j;
-                        }
-                        i += Math.max(md2, skip);
-                        continue outer_loop;
-                    }
-                }
-                return i - needleLengthMinus1 - haystackOffset;
-            }
-
-            if ((cache & (1 << haystack[i])) == 0) {
-                i += needleLengthMinus1;
-            }
-            i++;
-        }
-        return -1;
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/Thread.java b/libdvm/src/main/java/java/lang/Thread.java
deleted file mode 100644
index a40dde1..0000000
--- a/libdvm/src/main/java/java/lang/Thread.java
+++ /dev/null
@@ -1,1288 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang;
-
-import dalvik.system.VMStack;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import libcore.util.EmptyArray;
-
-/**
- * A {@code Thread} is a concurrent unit of execution. It has its own call stack
- * for methods being invoked, their arguments and local variables. Each application
- * has at least one thread running when it is started, the main thread, in the main
- * {@link ThreadGroup}. The runtime keeps its own threads in the system thread
- * group.
- *
- * <p>There are two ways to execute code in a new thread.
- * You can either subclass {@code Thread} and overriding its {@link #run()} method,
- * or construct a new {@code Thread} and pass a {@link Runnable} to the constructor.
- * In either case, the {@link #start()} method must be called to actually execute
- * the new {@code Thread}.
- *
- * <p>Each {@code Thread} has an integer priority that affect how the thread is
- * scheduled by the OS. A new thread inherits the priority of its parent.
- * A thread's priority can be set using the {@link #setPriority(int)} method.
- */
-public class Thread implements Runnable {
-    private static final int NANOS_PER_MILLI = 1000000;
-
-    /** Park states */
-    private static class ParkState {
-        /** park state indicating unparked */
-        private static final int UNPARKED = 1;
-
-        /** park state indicating preemptively unparked */
-        private static final int PREEMPTIVELY_UNPARKED = 2;
-
-        /** park state indicating parked */
-        private static final int PARKED = 3;
-    }
-
-    /**
-     * A representation of a thread's state. A given thread may only be in one
-     * state at a time.
-     */
-    public enum State {
-        /**
-         * The thread has been created, but has never been started.
-         */
-        NEW,
-        /**
-         * The thread may be run.
-         */
-        RUNNABLE,
-        /**
-         * The thread is blocked and waiting for a lock.
-         */
-        BLOCKED,
-        /**
-         * The thread is waiting.
-         */
-        WAITING,
-        /**
-         * The thread is waiting for a specified amount of time.
-         */
-        TIMED_WAITING,
-        /**
-         * The thread has been terminated.
-         */
-        TERMINATED
-    }
-
-    /**
-     * The maximum priority value allowed for a thread.
-     * This corresponds to (but does not have the same value as)
-     * {@code android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY}.
-     */
-    public static final int MAX_PRIORITY = 10;
-
-    /**
-     * The minimum priority value allowed for a thread.
-     * This corresponds to (but does not have the same value as)
-     * {@code android.os.Process.THREAD_PRIORITY_LOWEST}.
-     */
-    public static final int MIN_PRIORITY = 1;
-
-    /**
-     * The normal (default) priority value assigned to the main thread.
-     * This corresponds to (but does not have the same value as)
-     * {@code android.os.Process.THREAD_PRIORITY_DEFAULT}.
-
-     */
-    public static final int NORM_PRIORITY = 5;
-
-    /* some of these are accessed directly by the VM; do not rename them */
-    volatile VMThread vmThread;
-    volatile ThreadGroup group;
-    volatile boolean daemon;
-    volatile String name;
-    volatile int priority;
-    volatile long stackSize;
-    Runnable target;
-    private static int count = 0;
-
-    /**
-     * Holds the thread's ID. We simply count upwards, so
-     * each Thread has a unique ID.
-     */
-    private long id;
-
-    /**
-     * Normal thread local values.
-     */
-    ThreadLocal.Values localValues;
-
-    /**
-     * Inheritable thread local values.
-     */
-    ThreadLocal.Values inheritableValues;
-
-    /** Callbacks to run on interruption. */
-    private final List<Runnable> interruptActions = new ArrayList<Runnable>();
-
-    /**
-     * Holds the class loader for this Thread, in case there is one.
-     */
-    private ClassLoader contextClassLoader;
-
-    /**
-     * Holds the handler for uncaught exceptions in this Thread,
-     * in case there is one.
-     */
-    private UncaughtExceptionHandler uncaughtHandler;
-
-    /**
-     * Holds the default handler for uncaught exceptions, in case there is one.
-     */
-    private static UncaughtExceptionHandler defaultUncaughtHandler;
-
-    /**
-     * Reflects whether this Thread has already been started. A Thread
-     * can only be started once (no recycling). Also, we need it to deduce
-     * the proper Thread status.
-     */
-    boolean hasBeenStarted = false;
-
-    /** the park state of the thread */
-    private int parkState = ParkState.UNPARKED;
-
-    /** The synchronization object responsible for this thread parking. */
-    private Object parkBlocker;
-
-    /**
-     * Constructs a new {@code Thread} with no {@code Runnable} object and a
-     * newly generated name. The new {@code Thread} will belong to the same
-     * {@code ThreadGroup} as the {@code Thread} calling this constructor.
-     *
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread() {
-        create(null, null, null, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with a {@code Runnable} object and a
-     * newly generated name. The new {@code Thread} will belong to the same
-     * {@code ThreadGroup} as the {@code Thread} calling this constructor.
-     *
-     * @param runnable
-     *            a {@code Runnable} whose method <code>run</code> will be
-     *            executed by the new {@code Thread}
-     *
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(Runnable runnable) {
-        create(null, runnable, null, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with a {@code Runnable} object and name
-     * provided. The new {@code Thread} will belong to the same {@code
-     * ThreadGroup} as the {@code Thread} calling this constructor.
-     *
-     * @param runnable
-     *            a {@code Runnable} whose method <code>run</code> will be
-     *            executed by the new {@code Thread}
-     * @param threadName
-     *            the name for the {@code Thread} being created
-     *
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(Runnable runnable, String threadName) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-
-        create(null, runnable, threadName, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with no {@code Runnable} object and the
-     * name provided. The new {@code Thread} will belong to the same {@code
-     * ThreadGroup} as the {@code Thread} calling this constructor.
-     *
-     * @param threadName
-     *            the name for the {@code Thread} being created
-     *
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     *
-     */
-    public Thread(String threadName) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-
-        create(null, null, threadName, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with a {@code Runnable} object and a
-     * newly generated name. The new {@code Thread} will belong to the {@code
-     * ThreadGroup} passed as parameter.
-     *
-     * @param group
-     *            {@code ThreadGroup} to which the new {@code Thread} will
-     *            belong
-     * @param runnable
-     *            a {@code Runnable} whose method <code>run</code> will be
-     *            executed by the new {@code Thread}
-     * @throws IllegalThreadStateException
-     *             if <code>group.destroy()</code> has already been done
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(ThreadGroup group, Runnable runnable) {
-        create(group, runnable, null, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with a {@code Runnable} object, the given
-     * name and belonging to the {@code ThreadGroup} passed as parameter.
-     *
-     * @param group
-     *            ThreadGroup to which the new {@code Thread} will belong
-     * @param runnable
-     *            a {@code Runnable} whose method <code>run</code> will be
-     *            executed by the new {@code Thread}
-     * @param threadName
-     *            the name for the {@code Thread} being created
-     * @throws IllegalThreadStateException
-     *             if <code>group.destroy()</code> has already been done
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(ThreadGroup group, Runnable runnable, String threadName) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-
-        create(group, runnable, threadName, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with no {@code Runnable} object, the
-     * given name and belonging to the {@code ThreadGroup} passed as parameter.
-     *
-     * @param group
-     *            {@code ThreadGroup} to which the new {@code Thread} will belong
-     * @param threadName
-     *            the name for the {@code Thread} being created
-     * @throws IllegalThreadStateException
-     *             if <code>group.destroy()</code> has already been done
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(ThreadGroup group, String threadName) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-
-        create(group, null, threadName, 0);
-    }
-
-    /**
-     * Constructs a new {@code Thread} with a {@code Runnable} object, the given
-     * name and belonging to the {@code ThreadGroup} passed as parameter.
-     *
-     * @param group
-     *            {@code ThreadGroup} to which the new {@code Thread} will
-     *            belong
-     * @param runnable
-     *            a {@code Runnable} whose method <code>run</code> will be
-     *            executed by the new {@code Thread}
-     * @param threadName
-     *            the name for the {@code Thread} being created
-     * @param stackSize
-     *            a stack size for the new {@code Thread}. This has a highly
-     *            platform-dependent interpretation. It may even be ignored
-     *            completely.
-     * @throws IllegalThreadStateException
-     *             if <code>group.destroy()</code> has already been done
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-        create(group, runnable, threadName, stackSize);
-    }
-
-    /**
-     * Package-scope method invoked by Dalvik VM to create "internal"
-     * threads or attach threads created externally.
-     *
-     * Don't call Thread.currentThread(), since there may not be such
-     * a thing (e.g. for Main).
-     */
-    Thread(ThreadGroup group, String name, int priority, boolean daemon) {
-        synchronized (Thread.class) {
-            id = ++Thread.count;
-        }
-
-        if (name == null) {
-            this.name = "Thread-" + id;
-        } else {
-            this.name = name;
-        }
-
-        if (group == null) {
-            throw new InternalError("group not specified");
-        }
-
-        this.group = group;
-
-        this.target = null;
-        this.stackSize = 0;
-        this.priority = priority;
-        this.daemon = daemon;
-
-        /* add ourselves to our ThreadGroup of choice */
-        this.group.addThread(this);
-    }
-
-    /**
-     * Initializes a new, existing Thread object with a runnable object,
-     * the given name and belonging to the ThreadGroup passed as parameter.
-     * This is the method that the several public constructors delegate their
-     * work to.
-     *
-     * @param group ThreadGroup to which the new Thread will belong
-     * @param runnable a java.lang.Runnable whose method <code>run</code> will
-     *        be executed by the new Thread
-     * @param threadName Name for the Thread being created
-     * @param stackSize Platform dependent stack size
-     * @throws IllegalThreadStateException if <code>group.destroy()</code> has
-     *         already been done
-     * @see java.lang.ThreadGroup
-     * @see java.lang.Runnable
-     */
-    private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
-        Thread currentThread = Thread.currentThread();
-        if (group == null) {
-            group = currentThread.getThreadGroup();
-        }
-
-        if (group.isDestroyed()) {
-            throw new IllegalThreadStateException("Group already destroyed");
-        }
-
-        this.group = group;
-
-        synchronized (Thread.class) {
-            id = ++Thread.count;
-        }
-
-        if (threadName == null) {
-            this.name = "Thread-" + id;
-        } else {
-            this.name = threadName;
-        }
-
-        this.target = runnable;
-        this.stackSize = stackSize;
-
-        this.priority = currentThread.getPriority();
-
-        this.contextClassLoader = currentThread.contextClassLoader;
-
-        // Transfer over InheritableThreadLocals.
-        if (currentThread.inheritableValues != null) {
-            inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
-        }
-
-        // add ourselves to our ThreadGroup of choice
-        this.group.addThread(this);
-    }
-
-    /**
-     * Returns the number of active {@code Thread}s in the running {@code
-     * Thread}'s group and its subgroups.
-     *
-     * @return the number of {@code Thread}s
-     */
-    public static int activeCount() {
-        return currentThread().getThreadGroup().activeCount();
-    }
-
-    /**
-     * Does nothing.
-     */
-    public final void checkAccess() {
-    }
-
-    /**
-     * Returns the number of stack frames in this thread.
-     *
-     * @return Number of stack frames
-     * @deprecated The results of this call were never well defined. To make
-     *             things worse, it would depend on whether the Thread was
-     *             suspended or not, and suspend was deprecated too.
-     */
-    @Deprecated
-    public int countStackFrames() {
-        return getStackTrace().length;
-    }
-
-    /**
-     * Returns the Thread of the caller, that is, the current Thread.
-     *
-     * @return the current Thread.
-     */
-    public static Thread currentThread() {
-        return VMThread.currentThread();
-    }
-
-    /**
-     * Throws {@code UnsupportedOperationException}.
-     * @deprecated Not implemented.
-     */
-    @Deprecated
-    public void destroy() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Prints to the standard error stream a text representation of the current
-     * stack for this Thread.
-     *
-     * @see Throwable#printStackTrace()
-     */
-    public static void dumpStack() {
-        new Throwable("stack dump").printStackTrace();
-    }
-
-    /**
-     * Copies an array with all Threads which are in the same ThreadGroup as the
-     * receiver - and subgroups - into the array <code>threads</code> passed as
-     * parameter. If the array passed as parameter is too small no exception is
-     * thrown - the extra elements are simply not copied.
-     *
-     * @param threads
-     *            array into which the Threads will be copied
-     * @return How many Threads were copied over
-     */
-    public static int enumerate(Thread[] threads) {
-        Thread thread = Thread.currentThread();
-        return thread.getThreadGroup().enumerate(threads);
-    }
-
-    /**
-     * Returns a map of all the currently live threads to their stack traces.
-     */
-    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
-        Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>();
-
-        // Find out how many live threads we have. Allocate a bit more
-        // space than needed, in case new ones are just being created.
-        int count = ThreadGroup.mSystem.activeCount();
-        Thread[] threads = new Thread[count + count / 2];
-
-        // Enumerate the threads and collect the stacktraces.
-        count = ThreadGroup.mSystem.enumerate(threads);
-        for (int i = 0; i < count; i++) {
-            map.put(threads[i], threads[i].getStackTrace());
-        }
-
-        return map;
-    }
-
-    /**
-     * Returns the context ClassLoader for this Thread.
-     *
-     * @return ClassLoader The context ClassLoader
-     * @see java.lang.ClassLoader
-     * @see #getContextClassLoader()
-     */
-    public ClassLoader getContextClassLoader() {
-        return contextClassLoader;
-    }
-
-    /**
-     * Returns the default exception handler that's executed when uncaught
-     * exception terminates a thread.
-     *
-     * @return an {@link UncaughtExceptionHandler} or <code>null</code> if
-     *         none exists.
-     */
-    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
-        return defaultUncaughtHandler;
-    }
-
-    /**
-     * Returns the thread's identifier. The ID is a positive <code>long</code>
-     * generated on thread creation, is unique to the thread, and doesn't change
-     * during the lifetime of the thread; the ID may be reused after the thread
-     * has been terminated.
-     *
-     * @return the thread's ID.
-     */
-    public long getId() {
-        return id;
-    }
-
-    /**
-     * Returns the name of the Thread.
-     */
-    public final String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the priority of the Thread.
-     */
-    public final int getPriority() {
-        return priority;
-    }
-
-    /**
-     * Returns an array of {@link StackTraceElement} representing the current thread's stack.
-     */
-    public StackTraceElement[] getStackTrace() {
-        StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
-        return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
-    }
-
-    /**
-     * Returns the current state of the Thread. This method is useful for
-     * monitoring purposes.
-     *
-     * @return a {@link State} value.
-     */
-    public State getState() {
-        // TODO This is ugly and should be implemented better.
-        VMThread vmt = this.vmThread;
-
-        // Make sure we have a valid reference to an object. If native code
-        // deletes the reference we won't run into a null reference later.
-        VMThread thread = vmThread;
-        if (thread != null) {
-            // If the Thread Object became invalid or was not yet started,
-            // getStatus() will return -1.
-            int state = thread.getStatus();
-            if(state != -1) {
-                return VMThread.STATE_MAP[state];
-            }
-        }
-        return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
-    }
-
-    /**
-     * Returns the ThreadGroup to which this Thread belongs.
-     *
-     * @return the Thread's ThreadGroup
-     */
-    public final ThreadGroup getThreadGroup() {
-        // TODO This should actually be done at native termination.
-        if (getState() == Thread.State.TERMINATED) {
-            return null;
-        } else {
-            return group;
-        }
-    }
-
-    /**
-     * Returns the thread's uncaught exception handler. If not explicitly set,
-     * then the ThreadGroup's handler is returned. If the thread is terminated,
-     * then <code>null</code> is returned.
-     *
-     * @return an {@link UncaughtExceptionHandler} instance or {@code null}.
-     */
-    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
-        if (uncaughtHandler != null)
-            return uncaughtHandler;
-        else
-            return group;           // ThreadGroup is instance of UEH
-    }
-
-    /**
-     * Posts an interrupt request to this {@code Thread}. The behavior depends on
-     * the state of this {@code Thread}:
-     * <ul>
-     * <li>
-     * {@code Thread}s blocked in one of {@code Object}'s {@code wait()} methods
-     * or one of {@code Thread}'s {@code join()} or {@code sleep()} methods will
-     * be woken up, their interrupt status will be cleared, and they receive an
-     * {@link InterruptedException}.
-     * <li>
-     * {@code Thread}s blocked in an I/O operation of an
-     * {@link java.nio.channels.InterruptibleChannel} will have their interrupt
-     * status set and receive an
-     * {@link java.nio.channels.ClosedByInterruptException}. Also, the channel
-     * will be closed.
-     * <li>
-     * {@code Thread}s blocked in a {@link java.nio.channels.Selector} will have
-     * their interrupt status set and return immediately. They don't receive an
-     * exception in this case.
-     * <ul>
-     *
-     * @see Thread#interrupted
-     * @see Thread#isInterrupted
-     */
-    public void interrupt() {
-        // Interrupt this thread before running actions so that other
-        // threads that observe the interrupt as a result of an action
-        // will see that this thread is in the interrupted state.
-        VMThread vmt = this.vmThread;
-        if (vmt != null) {
-            vmt.interrupt();
-        }
-
-        synchronized (interruptActions) {
-            for (int i = interruptActions.size() - 1; i >= 0; i--) {
-                interruptActions.get(i).run();
-            }
-        }
-    }
-
-    /**
-     * Returns a <code>boolean</code> indicating whether the current Thread (
-     * <code>currentThread()</code>) has a pending interrupt request (<code>
-     * true</code>) or not (<code>false</code>). It also has the side-effect of
-     * clearing the flag.
-     *
-     * @return a <code>boolean</code> indicating the interrupt status
-     * @see Thread#currentThread
-     * @see Thread#interrupt
-     * @see Thread#isInterrupted
-     */
-    public static boolean interrupted() {
-        return VMThread.interrupted();
-    }
-
-    /**
-     * Returns <code>true</code> if the receiver has already been started and
-     * still runs code (hasn't died yet). Returns <code>false</code> either if
-     * the receiver hasn't been started yet or if it has already started and run
-     * to completion and died.
-     *
-     * @return a <code>boolean</code> indicating the liveness of the Thread
-     * @see Thread#start
-     */
-    public final boolean isAlive() {
-        return (vmThread != null);
-    }
-
-    /**
-     * Tests whether this is a daemon thread.
-     * A daemon thread only runs as long as there are non-daemon threads running.
-     * When the last non-daemon thread ends, the runtime will exit. This is not
-     * normally relevant to applications with a UI.
-     */
-    public final boolean isDaemon() {
-        return daemon;
-    }
-
-    /**
-     * Returns a <code>boolean</code> indicating whether the receiver has a
-     * pending interrupt request (<code>true</code>) or not (
-     * <code>false</code>)
-     *
-     * @return a <code>boolean</code> indicating the interrupt status
-     * @see Thread#interrupt
-     * @see Thread#interrupted
-     */
-    public boolean isInterrupted() {
-        VMThread vmt = this.vmThread;
-        if (vmt != null) {
-            return vmt.isInterrupted();
-        }
-
-        return false;
-    }
-
-    /**
-     * Blocks the current Thread (<code>Thread.currentThread()</code>) until
-     * the receiver finishes its execution and dies.
-     *
-     * @throws InterruptedException if the current thread has been interrupted.
-     *         The interrupted status of the current thread will be cleared before the exception is
-     *         thrown.
-     * @see Object#notifyAll
-     * @see java.lang.ThreadDeath
-     */
-    public final void join() throws InterruptedException {
-        VMThread t = vmThread;
-        if (t == null) {
-            return;
-        }
-
-        synchronized (t) {
-            while (isAlive()) {
-                t.wait();
-            }
-        }
-    }
-
-    /**
-     * Blocks the current Thread (<code>Thread.currentThread()</code>) until
-     * the receiver finishes its execution and dies or the specified timeout
-     * expires, whatever happens first.
-     *
-     * <p>A timeout of zero means the calling thread should wait forever unless interrupted.
-     *
-     * @param millis The maximum time to wait (in milliseconds).
-     * @throws InterruptedException if the current thread has been interrupted.
-     *         The interrupted status of the current thread will be cleared before the exception is
-     *         thrown.
-     * @see Object#notifyAll
-     * @see java.lang.ThreadDeath
-     */
-    public final void join(long millis) throws InterruptedException {
-        join(millis, 0);
-    }
-
-    /**
-     * Blocks the current Thread (<code>Thread.currentThread()</code>) until
-     * the receiver finishes its execution and dies or the specified timeout
-     * expires, whatever happens first.
-     *
-     * <p>A timeout of zero means the calling thread should wait forever unless interrupted.
-     *
-     * @param millis The maximum time to wait (in milliseconds).
-     * @param nanos Extra nanosecond precision
-     * @throws InterruptedException if the current thread has been interrupted.
-     *         The interrupted status of the current thread will be cleared before the exception is
-     *         thrown.
-     * @see Object#notifyAll
-     * @see java.lang.ThreadDeath
-     */
-    public final void join(long millis, int nanos) throws InterruptedException {
-        if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) {
-            throw new IllegalArgumentException("bad timeout: millis=" + millis + ",nanos=" + nanos);
-        }
-
-        // avoid overflow: if total > 292,277 years, just wait forever
-        boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI;
-        boolean forever = (millis | nanos) == 0;
-        if (forever | overflow) {
-            join();
-            return;
-        }
-
-        VMThread t = vmThread;
-        if (t == null) {
-            return;
-        }
-
-        synchronized (t) {
-            if (!isAlive()) {
-                return;
-            }
-
-            // guaranteed not to overflow
-            long nanosToWait = millis * NANOS_PER_MILLI + nanos;
-
-            // wait until this thread completes or the timeout has elapsed
-            long start = System.nanoTime();
-            while (true) {
-                t.wait(millis, nanos);
-                if (!isAlive()) {
-                    break;
-                }
-                long nanosElapsed = System.nanoTime() - start;
-                long nanosRemaining = nanosToWait - nanosElapsed;
-                if (nanosRemaining <= 0) {
-                    break;
-                }
-                millis = nanosRemaining / NANOS_PER_MILLI;
-                nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI);
-            }
-        }
-    }
-
-    /**
-     * Throws {@code UnsupportedOperationException}.
-     * @deprecated Only useful in conjunction with deprecated method {@link Thread#suspend}.
-     */
-    @Deprecated
-    public final void resume() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Calls the <code>run()</code> method of the Runnable object the receiver
-     * holds. If no Runnable is set, does nothing.
-     *
-     * @see Thread#start
-     */
-    public void run() {
-        if (target != null) {
-            target.run();
-        }
-    }
-
-    /**
-     * Set the context ClassLoader for the receiver.
-     *
-     * @param cl The context ClassLoader
-     * @see #getContextClassLoader()
-     */
-    public void setContextClassLoader(ClassLoader cl) {
-        contextClassLoader = cl;
-    }
-
-    /**
-     * Marks this thread as a daemon thread.
-     * A daemon thread only runs as long as there are non-daemon threads running.
-     * When the last non-daemon thread ends, the runtime will exit. This is not
-     * normally relevant to applications with a UI.
-     * @throws IllegalThreadStateException - if this thread has already started.
-     */
-    public final void setDaemon(boolean isDaemon) {
-        checkNotStarted();
-        if (vmThread == null) {
-            daemon = isDaemon;
-        }
-    }
-
-    private void checkNotStarted() {
-        if (hasBeenStarted) {
-            throw new IllegalThreadStateException("Thread already started");
-        }
-    }
-
-    /**
-     * Sets the default uncaught exception handler. This handler is invoked in
-     * case any Thread dies due to an unhandled exception.
-     *
-     * @param handler
-     *            The handler to set or null.
-     */
-    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
-        Thread.defaultUncaughtHandler = handler;
-    }
-
-    /**
-     * Adds a runnable to be invoked upon interruption. If this thread has
-     * already been interrupted, the runnable will be invoked immediately. The
-     * action should be idempotent as it may be invoked multiple times for a
-     * single interruption.
-     *
-     * <p>Each call to this method must be matched with a corresponding call to
-     * {@link #popInterruptAction$}.
-     *
-     * @hide used by NIO
-     */
-    public final void pushInterruptAction$(Runnable interruptAction) {
-        synchronized (interruptActions) {
-            interruptActions.add(interruptAction);
-        }
-
-        if (interruptAction != null && isInterrupted()) {
-            interruptAction.run();
-        }
-    }
-
-    /**
-     * Removes {@code interruptAction} so it is not invoked upon interruption.
-     *
-     * @param interruptAction the pushed action, used to check that the call
-     *     stack is correctly nested.
-     *
-     * @hide used by NIO
-     */
-    public final void popInterruptAction$(Runnable interruptAction) {
-        synchronized (interruptActions) {
-            Runnable removed = interruptActions.remove(interruptActions.size() - 1);
-            if (interruptAction != removed) {
-                throw new IllegalArgumentException(
-                        "Expected " + interruptAction + " but was " + removed);
-            }
-        }
-    }
-
-    /**
-     * Sets the name of the Thread.
-     *
-     * @param threadName the new name for the Thread
-     * @see Thread#getName
-     */
-    public final void setName(String threadName) {
-        if (threadName == null) {
-            throw new NullPointerException("threadName == null");
-        }
-
-        name = threadName;
-        VMThread vmt = this.vmThread;
-        if (vmt != null) {
-            /* notify the VM that the thread name has changed */
-            vmt.nameChanged(threadName);
-        }
-    }
-
-    /**
-     * Sets the priority of this thread. If the requested priority is greater than the
-     * parent thread group's {@link java.lang.ThreadGroup#getMaxPriority}, the group's maximum
-     * priority will be used instead.
-     *
-     * @throws IllegalArgumentException - if the new priority is greater than {@link #MAX_PRIORITY}
-     *     or less than {@link #MIN_PRIORITY}
-     */
-    public final void setPriority(int priority) {
-        if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
-            throw new IllegalArgumentException("Priority out of range: " + priority);
-        }
-
-        if (priority > group.getMaxPriority()) {
-            priority = group.getMaxPriority();
-        }
-
-        this.priority = priority;
-
-        VMThread vmt = this.vmThread;
-        if (vmt != null) {
-            vmt.setPriority(priority);
-        }
-    }
-
-    /**
-     * <p>
-     * Sets the uncaught exception handler. This handler is invoked in case this
-     * Thread dies due to an unhandled exception.
-     * </p>
-     *
-     * @param handler
-     *            The handler to set or <code>null</code>.
-     */
-    public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
-        uncaughtHandler = handler;
-    }
-
-    /**
-     * Causes the thread which sent this message to sleep for the given interval
-     * of time (given in milliseconds). The precision is not guaranteed - the
-     * Thread may sleep more or less than requested.
-     *
-     * @param time
-     *            The time to sleep in milliseconds.
-     * @throws InterruptedException if the current thread has been interrupted.
-     *            The interrupted status of the current thread will be cleared before the exception
-     *            is thrown.
-     * @see Thread#interrupt()
-     */
-    public static void sleep(long time) throws InterruptedException {
-        Thread.sleep(time, 0);
-    }
-
-    /**
-     * Causes the thread which sent this message to sleep for the given interval
-     * of time (given in milliseconds and nanoseconds). The precision is not
-     * guaranteed - the Thread may sleep more or less than requested.
-     *
-     * @param millis
-     *            The time to sleep in milliseconds.
-     * @param nanos
-     *            Extra nanosecond precision
-     * @throws InterruptedException if the current thread has been interrupted.
-     *            The interrupted status of the current thread will be cleared before the exception
-     *            is thrown.
-     * @see Thread#interrupt()
-     */
-    public static void sleep(long millis, int nanos) throws InterruptedException {
-        VMThread.sleep(millis, nanos);
-    }
-
-    /**
-     * Starts the new Thread of execution. The <code>run()</code> method of
-     * the receiver will be called by the receiver Thread itself (and not the
-     * Thread calling <code>start()</code>).
-     *
-     * @throws IllegalThreadStateException - if this thread has already started.
-     * @see Thread#run
-     */
-    public synchronized void start() {
-        checkNotStarted();
-
-        hasBeenStarted = true;
-
-        VMThread.create(this, stackSize);
-    }
-
-    /**
-     * Requests the receiver Thread to stop and throw ThreadDeath. The Thread is
-     * resumed if it was suspended and awakened if it was sleeping, so that it
-     * can proceed to throw ThreadDeath.
-     *
-     * @deprecated Stopping a thread in this manner is unsafe and can
-     * leave your application and the VM in an unpredictable state.
-     */
-    @Deprecated
-    public final void stop() {
-        stop(new ThreadDeath());
-    }
-
-    /**
-     * Throws {@code UnsupportedOperationException}.
-     * @deprecated Stopping a thread in this manner is unsafe and can
-     * leave your application and the VM in an unpredictable state.
-     */
-    @Deprecated
-    public final synchronized void stop(Throwable throwable) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Throws {@code UnsupportedOperationException}.
-     * @deprecated May cause deadlocks.
-     */
-    @Deprecated
-    public final void suspend() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Returns a string containing a concise, human-readable description of the
-     * Thread. It includes the Thread's name, priority, and group name.
-     *
-     * @return a printable representation for the receiver.
-     */
-    @Override
-    public String toString() {
-        return "Thread[" + name + "," + priority + "," + group.getName() + "]";
-    }
-
-    /**
-     * Causes the calling Thread to yield execution time to another Thread that
-     * is ready to run. The actual scheduling is implementation-dependent.
-     */
-    public static void yield() {
-        VMThread.yield();
-    }
-
-    /**
-     * Indicates whether the current Thread has a monitor lock on the specified
-     * object.
-     *
-     * @param object the object to test for the monitor lock
-     * @return true if the current thread has a monitor lock on the specified
-     *         object; false otherwise
-     */
-    public static boolean holdsLock(Object object) {
-        return currentThread().vmThread.holdsLock(object);
-    }
-
-    /**
-     * Implemented by objects that want to handle cases where a thread is being
-     * terminated by an uncaught exception. Upon such termination, the handler
-     * is notified of the terminating thread and causal exception. If there is
-     * no explicit handler set then the thread's group is the default handler.
-     */
-    public static interface UncaughtExceptionHandler {
-        /**
-         * The thread is being terminated by an uncaught exception. Further
-         * exceptions thrown in this method are prevent the remainder of the
-         * method from executing, but are otherwise ignored.
-         *
-         * @param thread the thread that has an uncaught exception
-         * @param ex the exception that was thrown
-         */
-        void uncaughtException(Thread thread, Throwable ex);
-    }
-
-    /**
-     * Unparks this thread. This unblocks the thread it if it was
-     * previously parked, or indicates that the thread is "preemptively
-     * unparked" if it wasn't already parked. The latter means that the
-     * next time the thread is told to park, it will merely clear its
-     * latent park bit and carry on without blocking.
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * @hide for Unsafe
-     */
-    public void unpark() {
-        VMThread vmt = vmThread;
-
-        if (vmt == null) {
-            /*
-             * vmThread is null before the thread is start()ed. In
-             * this case, we just go ahead and set the state to
-             * PREEMPTIVELY_UNPARKED. Since this happens before the
-             * thread is started, we don't have to worry about
-             * synchronizing with it.
-             */
-            parkState = ParkState.PREEMPTIVELY_UNPARKED;
-            return;
-        }
-
-        synchronized (vmt) {
-            switch (parkState) {
-                case ParkState.PREEMPTIVELY_UNPARKED: {
-                    /*
-                     * Nothing to do in this case: By definition, a
-                     * preemptively unparked thread is to remain in
-                     * the preemptively unparked state if it is told
-                     * to unpark.
-                     */
-                    break;
-                }
-                case ParkState.UNPARKED: {
-                    parkState = ParkState.PREEMPTIVELY_UNPARKED;
-                    break;
-                }
-                default /*parked*/: {
-                    parkState = ParkState.UNPARKED;
-                    vmt.notifyAll();
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Parks the current thread for a particular number of nanoseconds, or
-     * indefinitely. If not indefinitely, this method unparks the thread
-     * after the given number of nanoseconds if no other thread unparks it
-     * first. If the thread has been "preemptively unparked," this method
-     * cancels that unparking and returns immediately. This method may
-     * also return spuriously (that is, without the thread being told to
-     * unpark and without the indicated amount of time elapsing).
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * <p>This method must only be called when <code>this</code> is the current
-     * thread.
-     *
-     * @param nanos number of nanoseconds to park for or <code>0</code>
-     * to park indefinitely
-     * @throws IllegalArgumentException thrown if <code>nanos &lt; 0</code>
-     *
-     * @hide for Unsafe
-     */
-    public void parkFor(long nanos) {
-        VMThread vmt = vmThread;
-
-        if (vmt == null) {
-            // Running threads should always have an associated vmThread.
-            throw new AssertionError();
-        }
-
-        synchronized (vmt) {
-            switch (parkState) {
-                case ParkState.PREEMPTIVELY_UNPARKED: {
-                    parkState = ParkState.UNPARKED;
-                    break;
-                }
-                case ParkState.UNPARKED: {
-                    long millis = nanos / NANOS_PER_MILLI;
-                    nanos %= NANOS_PER_MILLI;
-
-                    parkState = ParkState.PARKED;
-                    try {
-                        vmt.wait(millis, (int) nanos);
-                    } catch (InterruptedException ex) {
-                        interrupt();
-                    } finally {
-                        /*
-                         * Note: If parkState manages to become
-                         * PREEMPTIVELY_UNPARKED before hitting this
-                         * code, it should left in that state.
-                         */
-                        if (parkState == ParkState.PARKED) {
-                            parkState = ParkState.UNPARKED;
-                        }
-                    }
-                    break;
-                }
-                default /*parked*/: {
-                    throw new AssertionError(
-                            "shouldn't happen: attempt to repark");
-                }
-            }
-        }
-    }
-
-    /**
-     * Parks the current thread until the specified system time. This
-     * method attempts to unpark the current thread immediately after
-     * <code>System.currentTimeMillis()</code> reaches the specified
-     * value, if no other thread unparks it first. If the thread has
-     * been "preemptively unparked," this method cancels that
-     * unparking and returns immediately. This method may also return
-     * spuriously (that is, without the thread being told to unpark
-     * and without the indicated amount of time elapsing).
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * <p>This method must only be called when <code>this</code> is the
-     * current thread.
-     *
-     * @param time the time after which the thread should be unparked,
-     * in absolute milliseconds-since-the-epoch
-     *
-     * @hide for Unsafe
-     */
-    public void parkUntil(long time) {
-        VMThread vmt = vmThread;
-
-        if (vmt == null) {
-            // Running threads should always have an associated vmThread.
-            throw new AssertionError();
-        }
-
-        synchronized (vmt) {
-            /*
-             * Note: This conflates the two time bases of "wall clock"
-             * time and "monotonic uptime" time. However, given that
-             * the underlying system can only wait on monotonic time,
-             * it is unclear if there is any way to avoid the
-             * conflation. The downside here is that if, having
-             * calculated the delay, the wall clock gets moved ahead,
-             * this method may not return until well after the wall
-             * clock has reached the originally designated time. The
-             * reverse problem (the wall clock being turned back)
-             * isn't a big deal, since this method is allowed to
-             * spuriously return for any reason, and this situation
-             * can safely be construed as just such a spurious return.
-             */
-            long delayMillis = time - System.currentTimeMillis();
-
-            if (delayMillis <= 0) {
-                parkState = ParkState.UNPARKED;
-            } else {
-                parkFor(delayMillis * NANOS_PER_MILLI);
-            }
-        }
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/ThreadGroup.java b/libdvm/src/main/java/java/lang/ThreadGroup.java
deleted file mode 100644
index 7fc6b72..0000000
--- a/libdvm/src/main/java/java/lang/ThreadGroup.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import libcore.util.CollectionUtils;
-
-/**
- * {@code ThreadGroup} is a means of organizing threads into a hierarchical structure.
- * This class is obsolete. See <i>Effective Java</i> Item 73, "Avoid thread groups" for details.
- * @see Thread
- */
-public class ThreadGroup implements Thread.UncaughtExceptionHandler {
-
-    // Name of this ThreadGroup
-    // VM needs this field name for debugging.
-    private String name;
-
-    // Maximum priority for Threads inside this ThreadGroup
-    private int maxPriority = Thread.MAX_PRIORITY;
-
-    // The ThreadGroup to which this ThreadGroup belongs
-    // VM needs this field name for debugging.
-    final ThreadGroup parent;
-
-    /**
-     * Weak references to the threads in this group.
-     * Access is guarded by synchronizing on this field.
-     */
-    private final List<WeakReference<Thread>> threadRefs = new ArrayList<WeakReference<Thread>>(5);
-
-    /**
-     * View of the threads.
-     * Access is guarded by synchronizing on threadRefs.
-     */
-    private final Iterable<Thread> threads = CollectionUtils.dereferenceIterable(threadRefs, true);
-
-    /**
-     * Thread groups. Access is guarded by synchronizing on this field.
-     */
-    private final List<ThreadGroup> groups = new ArrayList<ThreadGroup>(3);
-
-    // Whether this ThreadGroup is a daemon ThreadGroup or not
-    private boolean isDaemon;
-
-    // Whether this ThreadGroup has already been destroyed or not
-    private boolean isDestroyed;
-
-    /* the VM uses these directly; do not rename */
-    static final ThreadGroup mSystem = new ThreadGroup();
-    static final ThreadGroup mMain = new ThreadGroup(mSystem, "main");
-
-    /**
-     * Constructs a new {@code ThreadGroup} with the given name. The new {@code ThreadGroup}
-     * will be child of the {@code ThreadGroup} to which the calling thread belongs.
-     *
-     * @param name the name
-     * @see Thread#currentThread
-     */
-    public ThreadGroup(String name) {
-        this(Thread.currentThread().getThreadGroup(), name);
-    }
-
-    /**
-     * Constructs a new {@code ThreadGroup} with the given name, as a child of the
-     * given {@code ThreadGroup}.
-     *
-     * @param parent the parent
-     * @param name the name
-     * @throws NullPointerException if {@code parent == null}
-     * @throws IllegalThreadStateException if {@code parent} has been
-     *         destroyed already
-     */
-    public ThreadGroup(ThreadGroup parent, String name) {
-        if (parent == null) {
-            throw new NullPointerException("parent == null");
-        }
-        this.name = name;
-        this.parent = parent;
-        if (parent != null) {
-            parent.add(this);
-            this.setMaxPriority(parent.getMaxPriority());
-            if (parent.isDaemon()) {
-                this.setDaemon(true);
-            }
-        }
-    }
-
-    /**
-     * Initialize the special "system" ThreadGroup. Was "main" in Harmony,
-     * but we have an additional group above that in Android.
-     */
-    private ThreadGroup() {
-        this.name = "system";
-        this.parent = null;
-    }
-
-    /**
-     * Returns the number of running {@code Thread}s which are children of this thread group,
-     * directly or indirectly.
-     *
-     * @return the number of children
-     */
-    public int activeCount() {
-        int count = 0;
-        synchronized (threadRefs) {
-            for (Thread thread : threads) {
-                if (thread.isAlive()) {
-                    count++;
-                }
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                count += group.activeCount();
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Returns the number of {@code ThreadGroup}s which are children of this group,
-     * directly or indirectly.
-     *
-     * @return the number of children
-     */
-    public int activeGroupCount() {
-        int count = 0;
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                // One for this group & the subgroups
-                count += 1 + group.activeGroupCount();
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Adds a {@code ThreadGroup} to this thread group.
-     *
-     * @param g ThreadGroup to add
-     * @throws IllegalThreadStateException if this group has been destroyed already
-     */
-    private void add(ThreadGroup g) throws IllegalThreadStateException {
-        synchronized (groups) {
-            if (isDestroyed) {
-                throw new IllegalThreadStateException();
-            }
-            groups.add(g);
-        }
-    }
-
-    /**
-     * Does nothing. The definition of this method depends on the deprecated
-     * method {@link #suspend()}. The exact behavior of this call was never
-     * specified.
-     *
-     * @param b Used to control low memory implicit suspension
-     * @return {@code true} (always)
-     *
-     * @deprecated Required deprecated method {@link #suspend()}.
-     */
-    @Deprecated
-    public boolean allowThreadSuspension(boolean b) {
-        // Does not apply to this VM, no-op
-        return true;
-    }
-
-    /**
-     * Does nothing.
-     */
-    public final void checkAccess() {
-    }
-
-    /**
-     * Destroys this thread group and recursively all its subgroups. It is only legal
-     * to destroy a {@code ThreadGroup} that has no threads in it. Any daemon
-     * {@code ThreadGroup} is destroyed automatically when it becomes empty (no threads
-     * or thread groups in it).
-     *
-     * @throws IllegalThreadStateException if this thread group or any of its
-     *         subgroups has been destroyed already or if it still contains
-     *         threads.
-     */
-    public final void destroy() {
-        synchronized (threadRefs) {
-            synchronized (groups) {
-                if (isDestroyed) {
-                    throw new IllegalThreadStateException(
-                            "Thread group was already destroyed: "
-                            + (this.name != null ? this.name : "n/a"));
-                }
-                if (threads.iterator().hasNext()) {
-                    throw new IllegalThreadStateException(
-                            "Thread group still contains threads: "
-                            + (this.name != null ? this.name : "n/a"));
-                }
-                // Call recursively for subgroups
-                while (!groups.isEmpty()) {
-                    // We always get the first element - remember, when the
-                    // child dies it removes itself from our collection. See
-                    // below.
-                    groups.get(0).destroy();
-                }
-
-                if (parent != null) {
-                    parent.remove(this);
-                }
-
-                // Now that the ThreadGroup is really destroyed it can be tagged as so
-                this.isDestroyed = true;
-            }
-        }
-    }
-
-    /*
-     * Auxiliary method that destroys this thread group and recursively all its
-     * subgroups if this is a daemon ThreadGroup.
-     *
-     * @see #destroy
-     * @see #setDaemon
-     * @see #isDaemon
-     */
-    private void destroyIfEmptyDaemon() {
-        // Has to be non-destroyed daemon to make sense
-        synchronized (threadRefs) {
-            if (isDaemon && !isDestroyed && !threads.iterator().hasNext()) {
-                synchronized (groups) {
-                    if (groups.isEmpty()) {
-                        destroy();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Iterates over all active threads in this group (and its sub-groups) and
-     * stores the threads in the given array. Returns when the array is full or
-     * no more threads remain, whichever happens first.
-     *
-     * <p>Note that this method will silently ignore any threads that don't fit in the
-     * supplied array.
-     *
-     * @param threads the array into which the {@code Thread}s will be copied
-     * @return the number of {@code Thread}s that were copied
-     */
-    public int enumerate(Thread[] threads) {
-        return enumerate(threads, true);
-    }
-
-    /**
-     * Iterates over all active threads in this group (and, optionally, its
-     * sub-groups) and stores the threads in the given array. Returns when the
-     * array is full or no more threads remain, whichever happens first.
-     *
-     * <p>Note that this method will silently ignore any threads that don't fit in the
-     * supplied array.
-     *
-     * @param threads the array into which the {@code Thread}s will be copied
-     * @param recurse indicates whether {@code Thread}s in subgroups should be
-     *        recursively copied as well
-     * @return the number of {@code Thread}s that were copied
-     */
-    public int enumerate(Thread[] threads, boolean recurse) {
-        return enumerateGeneric(threads, recurse, 0, true);
-    }
-
-    /**
-     * Iterates over all thread groups in this group (and its sub-groups) and
-     * and stores the groups in the given array. Returns when the array is full
-     * or no more groups remain, whichever happens first.
-     *
-     * <p>Note that this method will silently ignore any thread groups that don't fit in the
-     * supplied array.
-     *
-     * @param groups the array into which the {@code ThreadGroup}s will be copied
-     * @return the number of {@code ThreadGroup}s that were copied
-     */
-    public int enumerate(ThreadGroup[] groups) {
-        return enumerate(groups, true);
-    }
-
-    /**
-     * Iterates over all thread groups in this group (and, optionally, its
-     * sub-groups) and stores the groups in the given array. Returns when
-     * the array is full or no more groups remain, whichever happens first.
-     *
-     * <p>Note that this method will silently ignore any thread groups that don't fit in the
-     * supplied array.
-     *
-     * @param groups the array into which the {@code ThreadGroup}s will be copied
-     * @param recurse indicates whether {@code ThreadGroup}s in subgroups should be
-     *        recursively copied as well or not
-     * @return the number of {@code ThreadGroup}s that were copied
-     */
-    public int enumerate(ThreadGroup[] groups, boolean recurse) {
-        return enumerateGeneric(groups, recurse, 0, false);
-    }
-
-    /**
-     * Copies into <param>enumeration</param> starting at
-     * <param>enumerationIndex</param> all Threads or ThreadGroups in the
-     * receiver. If <param>recurse</param> is true, recursively enumerate the
-     * elements in subgroups.
-     *
-     * If the array passed as parameter is too small no exception is thrown -
-     * the extra elements are simply not copied.
-     *
-     * @param enumeration array into which the elements will be copied
-     * @param recurse Indicates whether subgroups should be enumerated or not
-     * @param enumerationIndex Indicates in which position of the enumeration
-     *        array we are
-     * @param enumeratingThreads Indicates whether we are enumerating Threads or
-     *        ThreadGroups
-     * @return How many elements were enumerated/copied over
-     */
-    private int enumerateGeneric(Object[] enumeration, boolean recurse, int enumerationIndex,
-            boolean enumeratingThreads) {
-        if (enumeratingThreads) {
-            synchronized (threadRefs) {
-                // walk the references directly so we can iterate in reverse order
-                for (int i = threadRefs.size() - 1; i >= 0; --i) {
-                    Thread thread = threadRefs.get(i).get();
-                    if (thread != null && thread.isAlive()) {
-                        if (enumerationIndex >= enumeration.length) {
-                            return enumerationIndex;
-                        }
-                        enumeration[enumerationIndex++] = thread;
-                    }
-                }
-            }
-        } else {
-            synchronized (groups) {
-                for (int i = groups.size() - 1; i >= 0; --i) {
-                    if (enumerationIndex >= enumeration.length) {
-                        return enumerationIndex;
-                    }
-                    enumeration[enumerationIndex++] = groups.get(i);
-                }
-            }
-        }
-
-        if (recurse) {
-            synchronized (groups) {
-                for (ThreadGroup group : groups) {
-                    if (enumerationIndex >= enumeration.length) {
-                        return enumerationIndex;
-                    }
-                    enumerationIndex = group.enumerateGeneric(enumeration, recurse,
-                            enumerationIndex, enumeratingThreads);
-                }
-            }
-        }
-        return enumerationIndex;
-    }
-
-    /**
-     * Returns the maximum allowed priority for a {@code Thread} in this thread group.
-     *
-     * @return the maximum priority
-     *
-     * @see #setMaxPriority
-     */
-    public final int getMaxPriority() {
-        return maxPriority;
-    }
-
-    /**
-     * Returns the name of this thread group.
-     *
-     * @return the group's name
-     */
-    public final String getName() {
-        return name;
-    }
-
-    /**
-     * Returns this thread group's parent {@code ThreadGroup}. It can be null if this
-     * is the the root ThreadGroup.
-     *
-     * @return the parent
-     */
-    public final ThreadGroup getParent() {
-        return parent;
-    }
-
-    /**
-     * Interrupts every {@code Thread} in this group and recursively in all its
-     * subgroups.
-     *
-     * @see Thread#interrupt
-     */
-    public final void interrupt() {
-        synchronized (threadRefs) {
-            for (Thread thread : threads) {
-                thread.interrupt();
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                group.interrupt();
-            }
-        }
-    }
-
-    /**
-     * Checks whether this thread group is a daemon {@code ThreadGroup}.
-     *
-     * @return true if this thread group is a daemon {@code ThreadGroup}
-     *
-     * @see #setDaemon
-     * @see #destroy
-     */
-    public final boolean isDaemon() {
-        return isDaemon;
-    }
-
-    /**
-     * Checks whether this thread group has already been destroyed.
-     *
-     * @return true if this thread group has already been destroyed
-     * @see #destroy
-     */
-    public synchronized boolean isDestroyed() {
-        return isDestroyed;
-    }
-
-    /**
-     * Outputs to {@code System.out} a text representation of the
-     * hierarchy of {@code Thread}s and {@code ThreadGroup}s in this thread group (and recursively).
-     * Proper indentation is used to show the nesting of groups inside groups
-     * and threads inside groups.
-     */
-    public void list() {
-        // We start in a fresh line
-        System.out.println();
-        list(0);
-    }
-
-    /*
-     * Outputs to {@code System.out}a text representation of the
-     * hierarchy of Threads and ThreadGroups in this thread group (and recursively).
-     * The indentation will be four spaces per level of nesting.
-     *
-     * @param levels How many levels of nesting, so that proper indentation can
-     * be output.
-     */
-    private void list(int levels) {
-        indent(levels);
-        System.out.println(this.toString());
-
-        ++levels;
-        synchronized (threadRefs) {
-            for (Thread thread : threads) {
-                indent(levels);
-                System.out.println(thread);
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                group.list(levels);
-            }
-        }
-    }
-
-    private void indent(int levels) {
-        for (int i = 0; i < levels; i++) {
-            System.out.print("    "); // 4 spaces for each level
-        }
-    }
-
-    /**
-     * Checks whether this thread group is a direct or indirect parent group of a
-     * given {@code ThreadGroup}.
-     *
-     * @param g the potential child {@code ThreadGroup}
-     * @return true if this thread group is parent of {@code g}
-     */
-    public final boolean parentOf(ThreadGroup g) {
-        while (g != null) {
-            if (this == g) {
-                return true;
-            }
-            g = g.parent;
-        }
-        return false;
-    }
-
-    /**
-     * Removes an immediate subgroup.
-     *
-     * @param g ThreadGroup to remove
-     *
-     * @see #add(Thread)
-     * @see #add(ThreadGroup)
-     */
-    private void remove(ThreadGroup g) {
-        synchronized (groups) {
-            for (Iterator<ThreadGroup> i = groups.iterator(); i.hasNext(); ) {
-                ThreadGroup threadGroup = i.next();
-                if (threadGroup.equals(g)) {
-                    i.remove();
-                    break;
-                }
-            }
-        }
-        destroyIfEmptyDaemon();
-    }
-
-    /**
-     * Resumes every thread in this group and recursively in all its
-     * subgroups.
-     *
-     * @see Thread#resume
-     * @see #suspend
-     *
-     * @deprecated Requires deprecated method {@link Thread#resume()}.
-     */
-    @SuppressWarnings("deprecation")
-    @Deprecated
-    public final void resume() {
-        synchronized (threadRefs) {
-            for (Thread thread : threads) {
-                thread.resume();
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                group.resume();
-            }
-        }
-    }
-
-    /**
-     * Sets whether this is a daemon {@code ThreadGroup} or not. Daemon
-     * thread groups are automatically destroyed when they become empty.
-     *
-     * @param isDaemon the new value
-     * @see #isDaemon
-     * @see #destroy
-     */
-    public final void setDaemon(boolean isDaemon) {
-        this.isDaemon = isDaemon;
-    }
-
-    /**
-     * Configures the maximum allowed priority for a {@code Thread} in this group and
-     * recursively in all its subgroups.
-     *
-     * <p>A caller can never increase the maximum priority of a thread group.
-     * Such an attempt will not result in an exception, it will
-     * simply leave the thread group with its current maximum priority.
-     *
-     * @param newMax the new maximum priority to be set
-     *
-     * @throws IllegalArgumentException if the new priority is greater than
-     *         Thread.MAX_PRIORITY or less than Thread.MIN_PRIORITY
-     *
-     * @see #getMaxPriority
-     */
-    public final void setMaxPriority(int newMax) {
-        if (newMax <= this.maxPriority) {
-            if (newMax < Thread.MIN_PRIORITY) {
-                newMax = Thread.MIN_PRIORITY;
-            }
-
-            int parentPriority = parent == null ? newMax : parent.getMaxPriority();
-            this.maxPriority = parentPriority <= newMax ? parentPriority : newMax;
-            synchronized (groups) {
-                for (ThreadGroup group : groups) {
-                    group.setMaxPriority(newMax);
-                }
-            }
-        }
-    }
-
-    /**
-     * Stops every thread in this group and recursively in all its subgroups.
-     *
-     * @see Thread#stop()
-     * @see Thread#stop(Throwable)
-     * @see ThreadDeath
-     *
-     * @deprecated Requires deprecated method {@link Thread#stop()}.
-     */
-    @SuppressWarnings("deprecation")
-    @Deprecated
-    public final void stop() {
-        if (stopHelper()) {
-            Thread.currentThread().stop();
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private boolean stopHelper() {
-        boolean stopCurrent = false;
-        synchronized (threadRefs) {
-            Thread current = Thread.currentThread();
-            for (Thread thread : threads) {
-                if (thread == current) {
-                    stopCurrent = true;
-                } else {
-                    thread.stop();
-                }
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                stopCurrent |= group.stopHelper();
-            }
-        }
-        return stopCurrent;
-    }
-
-    /**
-     * Suspends every thread in this group and recursively in all its
-     * subgroups.
-     *
-     * @see Thread#suspend
-     * @see #resume
-     *
-     * @deprecated Requires deprecated method {@link Thread#suspend()}.
-     */
-    @SuppressWarnings("deprecation")
-    @Deprecated
-    public final void suspend() {
-        if (suspendHelper()) {
-            Thread.currentThread().suspend();
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private boolean suspendHelper() {
-        boolean suspendCurrent = false;
-        synchronized (threadRefs) {
-            Thread current = Thread.currentThread();
-            for (Thread thread : threads) {
-                if (thread == current) {
-                    suspendCurrent = true;
-                } else {
-                    thread.suspend();
-                }
-            }
-        }
-        synchronized (groups) {
-            for (ThreadGroup group : groups) {
-                suspendCurrent |= group.suspendHelper();
-            }
-        }
-        return suspendCurrent;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getName() + "[name=" + getName()
-                + ",maxPriority=" + getMaxPriority() + "]";
-    }
-
-    /**
-     * Handles uncaught exceptions. Any uncaught exception in any {@code Thread}
-     * is forwarded to the thread's {@code ThreadGroup} by invoking this
-     * method.
-     *
-     * <p>New code should use {@link Thread#setUncaughtExceptionHandler} instead of thread groups.
-     *
-     * @param t the Thread that terminated with an uncaught exception
-     * @param e the uncaught exception itself
-     */
-    public void uncaughtException(Thread t, Throwable e) {
-        if (parent != null) {
-            parent.uncaughtException(t, e);
-        } else if (Thread.getDefaultUncaughtExceptionHandler() != null) {
-            // TODO The spec is unclear regarding this. What do we do?
-            Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, e);
-        } else if (!(e instanceof ThreadDeath)) {
-            // No parent group, has to be 'system' Thread Group
-            e.printStackTrace(System.err);
-        }
-    }
-
-    /**
-     * Called by the Thread constructor.
-     */
-    final void addThread(Thread thread) throws IllegalThreadStateException {
-        synchronized (threadRefs) {
-            if (isDestroyed) {
-                throw new IllegalThreadStateException();
-            }
-            threadRefs.add(new WeakReference<Thread>(thread));
-        }
-    }
-
-    /**
-     * Called by the VM when a Thread dies.
-     */
-    final void removeThread(Thread thread) throws IllegalThreadStateException {
-        synchronized (threadRefs) {
-            for (Iterator<Thread> i = threads.iterator(); i.hasNext(); ) {
-                if (i.next().equals(thread)) {
-                    i.remove();
-                    break;
-                }
-            }
-        }
-        destroyIfEmptyDaemon();
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/VMClassLoader.java b/libdvm/src/main/java/java/lang/VMClassLoader.java
deleted file mode 100644
index d7162c6..0000000
--- a/libdvm/src/main/java/java/lang/VMClassLoader.java
+++ /dev/null
@@ -1,85 +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 java.lang;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-class VMClassLoader {
-
-    /**
-     * Get a resource from a file in the bootstrap class path.
-     *
-     * It would be simpler to just walk through the class path elements
-     * ourselves, but that would require reopening Jar files.
-     *
-     * We assume that the bootclasspath can't change once the VM has
-     * started.  This assumption seems to be supported by the spec.
-     */
-    static URL getResource(String name) {
-        int numEntries = getBootClassPathSize();
-        for (int i = 0; i < numEntries; i++) {
-            String urlStr = getBootClassPathResource(name, i);
-            if (urlStr != null) {
-                try {
-                    return new URL(urlStr);
-                } catch (MalformedURLException mue) {
-                    mue.printStackTrace();
-                    // unexpected; keep going
-                }
-            }
-        }
-        return null;
-    }
-
-    /*
-     * Get an enumeration with all matching resources.
-     */
-    static List<URL> getResources(String name) {
-        ArrayList<URL> list = new ArrayList<URL>();
-        int numEntries = getBootClassPathSize();
-        for (int i = 0; i < numEntries; i++) {
-            String urlStr = getBootClassPathResource(name, i);
-            if (urlStr != null) {
-                try {
-                    list.add(new URL(urlStr));
-                } catch (MalformedURLException mue) {
-                    mue.printStackTrace();
-                    // unexpected; keep going
-                }
-            }
-        }
-        return list;
-    }
-
-    /**
-     * Load class with bootstrap class loader.
-     */
-    native static Class loadClass(String name, boolean resolve) throws ClassNotFoundException;
-
-    native static Class getPrimitiveClass(char type);
-
-    native static Class findLoadedClass(ClassLoader cl, String name);
-
-    /**
-     * Boot class path manipulation, for getResources().
-     */
-    native private static int getBootClassPathSize();
-    native private static String getBootClassPathResource(String name, int index);
-}
diff --git a/libdvm/src/main/java/java/lang/VMThread.java b/libdvm/src/main/java/java/lang/VMThread.java
deleted file mode 100644
index 01f6ee3..0000000
--- a/libdvm/src/main/java/java/lang/VMThread.java
+++ /dev/null
@@ -1,77 +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 java.lang;
-
-class VMThread {
-    Thread thread;
-    int vmData;
-
-    VMThread(Thread t) {
-        thread = t;
-    }
-
-    native static void create(Thread t, long stackSize);
-
-    static native Thread currentThread();
-    static native boolean interrupted();
-    static native void sleep (long msec, int nsec) throws InterruptedException;
-    static native void yield();
-
-    native void interrupt();
-
-    native boolean isInterrupted();
-
-    /**
-     *  Starts the VMThread (and thus the Java Thread) with the given
-     *  stack size.
-     */
-    void start(long stackSize) {
-        VMThread.create(thread, stackSize);
-    }
-
-    /**
-     * Queries whether this Thread holds a monitor lock on the
-     * given object.
-     */
-    native boolean holdsLock(Object object);
-
-    native void setPriority(int newPriority);
-    native int getStatus();
-
-    /**
-     * Holds a mapping from native Thread statuses to Java one. Required for
-     * translating back the result of getStatus().
-     */
-    static final Thread.State[] STATE_MAP = new Thread.State[] {
-        Thread.State.TERMINATED,     // ZOMBIE
-        Thread.State.RUNNABLE,       // RUNNING
-        Thread.State.TIMED_WAITING,  // TIMED_WAIT
-        Thread.State.BLOCKED,        // MONITOR
-        Thread.State.WAITING,        // WAIT
-        Thread.State.NEW,            // INITIALIZING
-        Thread.State.NEW,            // STARTING
-        Thread.State.RUNNABLE,       // NATIVE
-        Thread.State.WAITING,        // VMWAIT
-        Thread.State.RUNNABLE        // SUSPENDED
-    };
-
-    /**
-     * Tell the VM that the thread's name has changed.  This is useful for
-     * DDMS, which would otherwise be oblivious to Thread.setName calls.
-     */
-    native void nameChanged(String newName);
-}
diff --git a/libdvm/src/main/java/java/lang/ref/Reference.java b/libdvm/src/main/java/java/lang/ref/Reference.java
deleted file mode 100644
index bd63535..0000000
--- a/libdvm/src/main/java/java/lang/ref/Reference.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang.ref;
-
-/**
- * Provides an abstract class which describes behavior common to all reference
- * objects. It is not possible to create immediate subclasses of
- * {@code Reference} in addition to the ones provided by this package. It is
- * also not desirable to do so, since references require very close cooperation
- * with the system's garbage collector. The existing, specialized reference
- * classes should be used instead.
- *
- * <p>Three different type of references exist, each being weaker than the preceding one:
- * {@link java.lang.ref.SoftReference}, {@link java.lang.ref.WeakReference}, and
- * {@link java.lang.ref.PhantomReference}. "Weakness" here means that less restrictions are
- * being imposed on the garbage collector as to when it is allowed to
- * actually garbage-collect the referenced object.
- *
- * <p>In order to use reference objects properly it is important to understand
- * the different types of reachability that trigger their clearing and
- * enqueueing. The following table lists these, from strongest to weakest.
- * For each row, an object is said to have the reachability on the left side
- * if (and only if) it fulfills all of the requirements on the right side. In
- * all rows, consider the <em>root set</em> to be a set of references that
- * are "resistant" to garbage collection (that is, running threads, method
- * parameters, local variables, static fields and the like).
- *
- * <p><table>
- * <tr>
- * <td>Strongly reachable</td>
- * <td> <ul>
- * <li>There exists at least one path from the root set to the object that does not traverse any
- * instance of a {@code java.lang.ref.Reference} subclass.
- * </li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Softly reachable</td>
- * <td> <ul>
- * <li>The object is not strongly reachable.</li>
- * <li>There exists at least one path from the root set to the object that does traverse
- * a {@code java.lang.ref.SoftReference} instance, but no {@code java.lang.ref.WeakReference}
- * or {@code java.lang.ref.PhantomReference} instances.</li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Weakly reachable</td>
- * <td> <ul>
- * <li>The object is neither strongly nor softly reachable.</li>
- * <li>There exists at least one path from the root set to the object that does traverse a
- * {@code java.lang.ref.WeakReference} instance, but no {@code java.lang.ref.PhantomReference}
- * instances.</li>
- * </ul> </td>
- * </tr>
- *
- * <tr>
- * <td>Phantom-reachable</td>
- * <td> <ul>
- * <li>The object is neither strongly, softly, nor weakly reachable.</li>
- * <li>The object is referenced by a {@code java.lang.ref.PhantomReference} instance.</li>
- * <li>The object has already been finalized.</li>
- * </ul> </td>
- * </tr>
- * </table>
- */
-public abstract class Reference<T> {
-
-    /**
-     * The object to which this reference refers.
-     * VM requirement: this field <em>must</em> be called "referent"
-     * and be an object.
-     */
-    volatile T referent;
-
-    /**
-     * If non-null, the queue on which this reference will be enqueued
-     * when the referent is appropriately reachable.
-     * VM requirement: this field <em>must</em> be called "queue"
-     * and be a java.lang.ref.ReferenceQueue.
-     */
-    volatile ReferenceQueue<? super T> queue;
-
-    /**
-     * Used internally by java.lang.ref.ReferenceQueue.
-     * VM requirement: this field <em>must</em> be called "queueNext"
-     * and be a java.lang.ref.Reference.
-     */
-    @SuppressWarnings("unchecked")
-    volatile Reference queueNext;
-
-    /**
-     * Used internally by the VM.  This field forms a circular and
-     * singly linked list of reference objects discovered by the
-     * garbage collector and awaiting processing by the reference
-     * queue thread.
-     *
-     * @hide
-     */
-    public volatile Reference<?> pendingNext;
-
-    /**
-     * Constructs a new instance of this class.
-     */
-    Reference() {
-    }
-
-    Reference(T r, ReferenceQueue<? super T> q) {
-        referent = r;
-        queue = q;
-    }
-
-    /**
-     * Makes the referent {@code null}. This does not force the reference
-     * object to be enqueued.
-     */
-    public void clear() {
-        referent = null;
-    }
-
-    /**
-     * Adds an object to its reference queue.
-     *
-     * @return {@code true} if this call has caused the {@code Reference} to
-     * become enqueued, or {@code false} otherwise
-     *
-     * @hide
-     */
-    public final synchronized boolean enqueueInternal() {
-        if (queue != null && queueNext == null) {
-            queue.enqueue(this);
-            queue = null;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Forces the reference object to be enqueued if it has been associated with
-     * a queue.
-     *
-     * @return {@code true} if this call has caused the {@code Reference} to
-     * become enqueued, or {@code false} otherwise
-     */
-    public boolean enqueue() {
-        return enqueueInternal();
-    }
-
-    /**
-     * Returns the referent of the reference object.
-     *
-     * @return the referent to which reference refers, or {@code null} if the
-     *         object has been cleared.
-     */
-    public T get() {
-        return referent;
-    }
-
-    /**
-     * Checks whether the reference object has been enqueued.
-     *
-     * @return {@code true} if the {@code Reference} has been enqueued, {@code
-     *         false} otherwise
-     */
-    public boolean isEnqueued() {
-        return queueNext != null;
-    }
-
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java b/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java
deleted file mode 100644
index f3d96af..0000000
--- a/libdvm/src/main/java/java/lang/reflect/AccessibleObject.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Hashtable;
-import org.apache.harmony.kernel.vm.StringUtils;
-
-/**
- * {@code AccessibleObject} is the superclass of all member reflection classes
- * (Field, Constructor, Method). AccessibleObject provides the ability to toggle
- * a flag controlling access checks for these objects. By default, accessing a
- * member (for example, setting a field or invoking a method) checks the
- * validity of the access (for example, invoking a private method from outside
- * the defining class is prohibited) and throws IllegalAccessException if the
- * operation is not permitted. If the accessible flag is set to true, these
- * checks are omitted. This allows privileged code, such as Java object
- * serialization, object inspectors, and debuggers to have complete access to
- * objects.
- *
- * @see Field
- * @see Constructor
- * @see Method
- */
-public class AccessibleObject implements AnnotatedElement {
-
-    /**
-     * If true, object is accessible, bypassing normal access checks
-     */
-    boolean flag = false;
-
-    // Holds a mapping from Java type names to native type codes.
-    static Hashtable<String, String> trans;
-
-    static {
-        trans = new Hashtable<String, String>(9);
-        trans.put("byte", "B");
-        trans.put("char", "C");
-        trans.put("short", "S");
-        trans.put("int", "I");
-        trans.put("long", "J");
-        trans.put("float", "F");
-        trans.put("double", "D");
-        trans.put("void", "V");
-        trans.put("boolean", "Z");
-    }
-
-    /**
-     * Attempts to set the value of the accessible flag for all the objects in
-     * the array provided. Setting this
-     * flag to {@code false} will enable access checks, setting to {@code true}
-     * will disable them.
-     *
-     * @param objects
-     *            the accessible objects
-     * @param flag
-     *            the new value for the accessible flag
-     *
-     * @see #setAccessible(boolean)
-     */
-    public static void setAccessible(AccessibleObject[] objects, boolean flag) {
-        for (AccessibleObject object : objects) {
-            object.flag = flag;
-        }
-    }
-
-    /**
-     * Constructs a new {@code AccessibleObject} instance. {@code
-     * AccessibleObject} instances can only be constructed by the virtual
-     * machine.
-     */
-    protected AccessibleObject() {
-    }
-
-    /**
-     * Indicates whether this object is accessible without access checks being
-     * performed. Returns the accessible flag.
-     *
-     * @return {@code true} if this object is accessible without access
-     *         checks, {@code false} otherwise
-     */
-    public boolean isAccessible() {
-        return flag;
-    }
-
-    /**
-     * Attempts to set the value of the accessible flag. Setting this flag to
-     * {@code false} will enable access checks, setting to {@code true} will
-     * disable them.
-     *
-     * @param flag
-     *            the new value for the accessible flag
-     */
-    public void setAccessible(boolean flag) {
-        this.flag = flag;
-    }
-
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Annotation[] getDeclaredAnnotations() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Annotation[] getAnnotations() {
-        // for all but Class, getAnnotations == getDeclaredAnnotations
-        return getDeclaredAnnotations();
-    }
-
-    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Returns the signature for a class. This is the kind of signature used
-     * internally by the JVM, with one-character codes representing the basic
-     * types. It is not suitable for printing.
-     *
-     * @param clazz
-     *            the class for which a signature is required
-     *
-     * @return The signature as a string
-     */
-    String getSignature(Class<?> clazz) {
-        String result = "";
-        String nextType = clazz.getName();
-
-        if(trans.containsKey(nextType)) {
-            result = trans.get(nextType);
-        } else {
-            if(clazz.isArray()) {
-                result = "[" + getSignature(clazz.getComponentType());
-            } else {
-                result = "L" + nextType + ";";
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Returns a printable String consisting of the canonical names of the
-     * classes contained in an array. The form is that used in parameter and
-     * exception lists, that is, the class or type names are separated by
-     * commas.
-     *
-     * @param types
-     *            the array of classes
-     *
-     * @return The String of names
-     */
-    String toString(Class<?>[] types) {
-        StringBuilder result = new StringBuilder();
-
-        if (types.length != 0) {
-            appendTypeName(result, types[0]);
-            for (int i = 1; i < types.length; i++) {
-                result.append(',');
-                appendTypeName(result, types[i]);
-            }
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * Gets the Signature attribute for this instance. Returns {@code null}
-     * if not found.
-     */
-    /*package*/ String getSignatureAttribute() {
-        /*
-         * Note: This method would have been declared abstract, but the
-         * standard API lists this class as concrete.
-         */
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Retrieve the signature attribute from an arbitrary class.  This is
-     * the same as Class.getSignatureAttribute(), but it can be used from
-     * the java.lang.reflect package.
-     */
-    /*package*/ static String getClassSignatureAttribute(Class clazz) {
-        Object[] annotation = getClassSignatureAnnotation(clazz);
-
-        if (annotation == null) {
-            return null;
-        }
-
-        return StringUtils.combineStrings(annotation);
-    }
-
-    /**
-     * Retrieve the signature annotation from an arbitrary class.  This is
-     * the same as Class.getSignatureAttribute(), but it can be used from
-     * the java.lang.reflect package.
-     */
-    private static native Object[] getClassSignatureAnnotation(Class clazz);
-
-    /**
-     * Appends the best {@link #toString} name for {@code c} to {@code out}.
-     * This works around the fact that {@link Class#getName} is lousy for
-     * primitive arrays (it writes "[C" instead of "char[]") and {@link
-     * Class#getCanonicalName()} is lousy for nested classes (it uses a "."
-     * separator rather than a "$" separator).
-     */
-    void appendTypeName(StringBuilder out, Class<?> c) {
-        int dimensions = 0;
-        while (c.isArray()) {
-            c = c.getComponentType();
-            dimensions++;
-        }
-        out.append(c.getName());
-        for (int d = 0; d < dimensions; d++) {
-            out.append("[]");
-        }
-    }
-
-    /**
-     * Appends names of the specified array classes to the buffer. The array
-     * elements may represent a simple type, a reference type or an array type.
-     * Output format: java.lang.Object[], java.io.File, void
-     *
-     * @param types array of classes to print the names
-     * @throws NullPointerException if any of the arguments is null
-     */
-    void appendArrayGenericType(StringBuilder sb, Type[] types) {
-        if (types.length > 0) {
-            appendGenericType(sb, types[0]);
-            for (int i = 1; i < types.length; i++) {
-                sb.append(',');
-                appendGenericType(sb, types[i]);
-            }
-        }
-    }
-
-    /**
-     * Appends the generic type representation to the buffer.
-     *
-     * @param sb buffer
-     * @param obj the generic type which representation should be appended to the buffer
-     *
-     * @throws NullPointerException if any of the arguments is null
-     */
-    void appendGenericType(StringBuilder sb, Type obj) {
-        if (obj instanceof TypeVariable) {
-            sb.append(((TypeVariable)obj).getName());
-        } else if (obj instanceof ParameterizedType) {
-            sb.append(obj.toString());
-        } else if (obj instanceof GenericArrayType) { //XXX: is it a working branch?
-            Type simplified = ((GenericArrayType)obj).getGenericComponentType();
-            appendGenericType(sb, simplified);
-            sb.append("[]");
-        } else if (obj instanceof Class) {
-            Class c = ((Class<?>)obj);
-            if (c.isArray()){
-                String as[] = c.getName().split("\\[");
-                int len = as.length-1;
-                if (as[len].length() > 1){
-                    sb.append(as[len].substring(1, as[len].length()-1));
-                } else {
-                    char ch = as[len].charAt(0);
-                    if (ch == 'I')
-                        sb.append("int");
-                    else if (ch == 'B')
-                        sb.append("byte");
-                    else if (ch == 'J')
-                        sb.append("long");
-                    else if (ch == 'F')
-                        sb.append("float");
-                    else if (ch == 'D')
-                        sb.append("double");
-                    else if (ch == 'S')
-                        sb.append("short");
-                    else if (ch == 'C')
-                        sb.append("char");
-                    else if (ch == 'Z')
-                        sb.append("boolean");
-                    else if (ch == 'V') //XXX: is it a working branch?
-                        sb.append("void");
-                }
-                for (int i = 0; i < len; i++){
-                    sb.append("[]");
-                }
-            } else {
-                sb.append(c.getName());
-            }
-        }
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Constructor.java b/libdvm/src/main/java/java/lang/reflect/Constructor.java
deleted file mode 100644
index acce44f..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Constructor.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import libcore.util.EmptyArray;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.ListOfTypes;
-import libcore.reflect.Types;
-
-/**
- * This class represents a constructor. Information about the constructor can be
- * accessed, and the constructor can be invoked dynamically.
- *
- * @param <T> the class that declares this constructor
- */
-public final class Constructor<T> extends AccessibleObject implements GenericDeclaration,
-        Member {
-
-    Class<T> declaringClass;
-
-    Class<?>[] parameterTypes;
-
-    Class<?>[] exceptionTypes;
-
-    ListOfTypes genericExceptionTypes;
-    ListOfTypes genericParameterTypes;
-    TypeVariable<Constructor<T>>[] formalTypeParameters;
-    private volatile boolean genericTypesAreInitialized = false;
-
-    private synchronized void initGenericTypes() {
-        if (!genericTypesAreInitialized) {
-            String signatureAttribute = getSignatureAttribute();
-            GenericSignatureParser parser = new GenericSignatureParser(
-                    declaringClass.getClassLoader());
-            parser.parseForConstructor(this, signatureAttribute, exceptionTypes);
-            formalTypeParameters = parser.formalTypeParameters;
-            genericParameterTypes = parser.parameterTypes;
-            genericExceptionTypes = parser.exceptionTypes;
-            genericTypesAreInitialized = true;
-        }
-    }
-
-    int slot;
-
-    private int methodDexIndex;
-
-    /**
-     * Prevent this class from being instantiated.
-     */
-    private Constructor(){
-        //do nothing
-    }
-
-    /**
-     * Creates an instance of the class. Only called from native code, thus
-     * private.
-     *
-     * @param declaringClass
-     *            the class this constructor object belongs to
-     * @param ptypes
-     *            the parameter types of the constructor
-     * @param extypes
-     *            the exception types of the constructor
-     * @param slot
-     *            the slot of the constructor inside the VM class structure
-     */
-    private Constructor(Class<T> declaringClass, Class<?>[] ptypes, Class<?>[] extypes, int slot, int methodDexIndex) {
-        this.declaringClass = declaringClass;
-        this.parameterTypes = ptypes;
-        this.exceptionTypes = extypes;          // may be null
-        this.slot = slot;
-        this.methodDexIndex = methodDexIndex;
-    }
-
-    /** @hide */
-    public int getDexMethodIndex() {
-        return methodDexIndex;
-    }
-
-    @Override /*package*/ String getSignatureAttribute() {
-        Object[] annotation = Method.getSignatureAnnotation(declaringClass, slot);
-
-        if (annotation == null) {
-            return null;
-        }
-
-        return StringUtils.combineStrings(annotation);
-    }
-
-    public TypeVariable<Constructor<T>>[] getTypeParameters() {
-        initGenericTypes();
-        return formalTypeParameters.clone();
-    }
-
-    /**
-     * Returns the string representation of the constructor's declaration,
-     * including the type parameters.
-     *
-     * @return the string representation of the constructor's declaration
-     */
-    public String toGenericString() {
-        StringBuilder sb = new StringBuilder(80);
-        initGenericTypes();
-        // append modifiers if any
-        int modifier = getModifiers();
-        if (modifier != 0) {
-            sb.append(Modifier.toString(modifier & ~Modifier.VARARGS)).append(' ');
-        }
-        // append type parameters
-        if (formalTypeParameters != null && formalTypeParameters.length > 0) {
-            sb.append('<');
-            for (int i = 0; i < formalTypeParameters.length; i++) {
-                appendGenericType(sb, formalTypeParameters[i]);
-                if (i < formalTypeParameters.length - 1) {
-                    sb.append(",");
-                }
-            }
-            sb.append("> ");
-        }
-        // append constructor name
-        appendTypeName(sb, getDeclaringClass());
-        // append parameters
-        sb.append('(');
-        appendArrayGenericType(sb, Types.getTypeArray(genericParameterTypes, false));
-        sb.append(')');
-        // append exceptions if any
-        Type[] genericExceptionTypeArray = Types.getTypeArray(genericExceptionTypes, false);
-        if (genericExceptionTypeArray.length > 0) {
-            sb.append(" throws ");
-            appendArrayGenericType(sb, genericExceptionTypeArray);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns the generic parameter types as an array of {@code Type}
-     * instances, in declaration order. If this constructor has no generic
-     * parameters, an empty array is returned.
-     *
-     * @return the parameter types
-     *
-     * @throws GenericSignatureFormatError
-     *             if the generic constructor signature is invalid
-     * @throws TypeNotPresentException
-     *             if any parameter type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if any parameter type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type[] getGenericParameterTypes() {
-        initGenericTypes();
-        return Types.getTypeArray(genericParameterTypes, true);
-    }
-
-    /**
-     * Returns the exception types as an array of {@code Type} instances. If
-     * this constructor has no declared exceptions, an empty array will be
-     * returned.
-     *
-     * @return an array of generic exception types
-     *
-     * @throws GenericSignatureFormatError
-     *             if the generic constructor signature is invalid
-     * @throws TypeNotPresentException
-     *             if any exception type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if any exception type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type[] getGenericExceptionTypes() {
-        initGenericTypes();
-        return Types.getTypeArray(genericExceptionTypes, true);
-    }
-
-    @Override
-    public Annotation[] getDeclaredAnnotations() {
-        return Method.getDeclaredAnnotations(declaringClass, slot);
-    }
-
-    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return Method.getAnnotation(declaringClass, slot, annotationType);
-    }
-
-    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return Method.isAnnotationPresent(declaringClass, slot, annotationType);
-    }
-
-    /**
-     * Returns an array of arrays that represent the annotations of the formal
-     * parameters of this constructor. If there are no parameters on this
-     * constructor, then an empty array is returned. If there are no annotations
-     * set, then an array of empty arrays is returned.
-     *
-     * @return an array of arrays of {@code Annotation} instances
-     */
-    public Annotation[][] getParameterAnnotations() {
-        Annotation[][] parameterAnnotations
-                = Method.getParameterAnnotations(declaringClass, slot);
-        if (parameterAnnotations.length == 0) {
-            return Method.noAnnotations(parameterTypes.length);
-        }
-        return parameterAnnotations;
-    }
-
-    /**
-     * Indicates whether or not this constructor takes a variable number of
-     * arguments.
-     *
-     * @return {@code true} if a vararg is declare, otherwise
-     *         {@code false}
-     */
-    public boolean isVarArgs() {
-        int mods = Method.getMethodModifiers(declaringClass, slot);
-        return (mods & Modifier.VARARGS) != 0;
-    }
-
-    /**
-     * Indicates whether or not this constructor is synthetic (artificially
-     * introduced by the compiler).
-     *
-     * @return {@code true} if this constructor is synthetic, {@code false}
-     *         otherwise
-     */
-    public boolean isSynthetic() {
-        int mods = Method.getMethodModifiers(declaringClass, slot);
-        return (mods & Modifier.SYNTHETIC) != 0;
-    }
-
-    /**
-     * Indicates whether or not the specified {@code object} is equal to this
-     * constructor. To be equal, the specified object must be an instance
-     * of {@code Constructor} with the same declaring class and parameter types
-     * as this constructor.
-     *
-     * @param object
-     *            the object to compare
-     *
-     * @return {@code true} if the specified object is equal to this
-     *         constructor, {@code false} otherwise
-     *
-     * @see #hashCode
-     */
-    @Override
-    public boolean equals(Object object) {
-        return object instanceof Constructor && toString().equals(object.toString());
-    }
-
-    /**
-     * Returns the class that declares this constructor.
-     *
-     * @return the declaring class
-     */
-    public Class<T> getDeclaringClass() {
-        return declaringClass;
-    }
-
-    /**
-     * Returns the exception types as an array of {@code Class} instances. If
-     * this constructor has no declared exceptions, an empty array will be
-     * returned.
-     *
-     * @return the declared exception classes
-     */
-    public Class<?>[] getExceptionTypes() {
-        if (exceptionTypes == null) {
-            return EmptyArray.CLASS;
-        }
-        return exceptionTypes.clone();
-    }
-
-    /**
-     * Returns the modifiers for this constructor. The {@link Modifier} class
-     * should be used to decode the result.
-     *
-     * @return the modifiers for this constructor
-     *
-     * @see Modifier
-     */
-    public int getModifiers() {
-        return Method.getMethodModifiers(declaringClass, slot);
-    }
-
-    /**
-     * Returns the name of this constructor.
-     *
-     * @return the name of this constructor
-     */
-    public String getName() {
-        return declaringClass.getName();
-    }
-
-    /**
-     * Returns an array of the {@code Class} objects associated with the
-     * parameter types of this constructor. If the constructor was declared with
-     * no parameters, an empty array will be returned.
-     *
-     * @return the parameter types
-     */
-    public Class<?>[] getParameterTypes() {
-        return parameterTypes.clone();
-    }
-
-    /**
-     * Returns the constructor's signature in non-printable form. This is called
-     * (only) from IO native code and needed for deriving the serialVersionUID
-     * of the class
-     *
-     * @return the constructor's signature
-     */
-    @SuppressWarnings("unused")
-    private String getSignature() {
-        StringBuilder result = new StringBuilder();
-
-        result.append('(');
-        for (int i = 0; i < parameterTypes.length; i++) {
-            result.append(getSignature(parameterTypes[i]));
-        }
-        result.append(")V");
-
-        return result.toString();
-    }
-
-    /**
-     * Returns an integer hash code for this constructor. Constructors which are
-     * equal return the same value for this method. The hash code for a
-     * Constructor is the hash code of the name of the declaring class.
-     *
-     * @return the hash code
-     *
-     * @see #equals
-     */
-    @Override
-    public int hashCode() {
-        return declaringClass.getName().hashCode();
-    }
-
-    /**
-     * Returns a new instance of the declaring class, initialized by dynamically
-     * invoking the constructor represented by this {@code Constructor} object.
-     * This reproduces the effect of {@code new declaringClass(arg1, arg2, ... ,
-     * argN)} This method performs the following:
-     * <ul>
-     * <li>A new instance of the declaring class is created. If the declaring
-     * class cannot be instantiated (i.e. abstract class, an interface, an array
-     * type, or a primitive type) then an InstantiationException is thrown.</li>
-     * <li>If this Constructor object is enforcing access control (see
-     * {@link AccessibleObject}) and this constructor is not accessible from the
-     * current context, an IllegalAccessException is thrown.</li>
-     * <li>If the number of arguments passed and the number of parameters do not
-     * match, an IllegalArgumentException is thrown.</li>
-     * <li>For each argument passed:
-     * <ul>
-     * <li>If the corresponding parameter type is a primitive type, the argument
-     * is unboxed. If the unboxing fails, an IllegalArgumentException is
-     * thrown.</li>
-     * <li>If the resulting argument cannot be converted to the parameter type
-     * via a widening conversion, an IllegalArgumentException is thrown.</li>
-     * </ul>
-     * <li>The constructor represented by this {@code Constructor} object is
-     * then invoked. If an exception is thrown during the invocation, it is
-     * caught and wrapped in an InvocationTargetException. This exception is
-     * then thrown. If the invocation completes normally, the newly initialized
-     * object is returned.
-     * </ul>
-     *
-     * @param args
-     *            the arguments to the constructor
-     *
-     * @return the new, initialized, object
-     *
-     * @throws InstantiationException
-     *                if the class cannot be instantiated
-     * @throws IllegalAccessException
-     *                if this constructor is not accessible
-     * @throws IllegalArgumentException
-     *                if an incorrect number of arguments are passed, or an
-     *                argument could not be converted by a widening conversion
-     * @throws InvocationTargetException
-     *                if an exception was thrown by the invoked constructor
-     *
-     * @see AccessibleObject
-     */
-    public T newInstance(Object... args) throws InstantiationException, IllegalAccessException,
-            IllegalArgumentException, InvocationTargetException {
-        return constructNative (args, declaringClass, parameterTypes, slot, flag);
-    }
-
-    private native T constructNative(Object[] args, Class<T> declaringClass,
-            Class<?>[] parameterTypes, int slot,
-            boolean noAccessCheck) throws InstantiationException, IllegalAccessException,
-            InvocationTargetException;
-
-    /**
-     * Returns a string containing a concise, human-readable description of this
-     * constructor. The format of the string is:
-     *
-     * <ol>
-     *   <li>modifiers (if any)
-     *   <li>declaring class name
-     *   <li>'('
-     *   <li>parameter types, separated by ',' (if any)
-     *   <li>')'
-     *   <li>'throws' plus exception types, separated by ',' (if any)
-     * </ol>
-     *
-     * For example:
-     * {@code public String(byte[],String) throws UnsupportedEncodingException}
-     *
-     * @return a printable representation for this constructor
-     */
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
-
-        if (result.length() != 0)
-            result.append(' ');
-        result.append(declaringClass.getName());
-        result.append("(");
-        result.append(toString(parameterTypes));
-        result.append(")");
-        if (exceptionTypes != null && exceptionTypes.length != 0) {
-            result.append(" throws ");
-            result.append(toString(exceptionTypes));
-        }
-
-        return result.toString();
-    }
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Field.java b/libdvm/src/main/java/java/lang/reflect/Field.java
deleted file mode 100644
index fa8e5e7..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Field.java
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Comparator;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.Types;
-
-/**
- * This class represents a field. Information about the field can be accessed,
- * and the field's value can be accessed dynamically.
- */
-public final class Field extends AccessibleObject implements Member {
-
-    /**
-     * Orders fields by their name and declaring class.
-     *
-     * @hide
-     */
-    public static final Comparator<Field> ORDER_BY_NAME_AND_DECLARING_CLASS
-            = new Comparator<Field>() {
-        @Override public int compare(Field a, Field b) {
-            int comparison = a.name.compareTo(b.name);
-            if (comparison != 0) {
-                return comparison;
-            }
-
-            return a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName());
-        }
-    };
-
-    private Class<?> declaringClass;
-
-    private Class<?> type;
-
-    private Type genericType;
-
-    private volatile boolean genericTypesAreInitialized = false;
-
-    private String name;
-
-    private int slot;
-
-    private final int fieldDexIndex;
-
-    private static final char TYPE_BOOLEAN = 'Z';
-
-    private static final char TYPE_BYTE = 'B';
-
-    private static final char TYPE_CHAR = 'C';
-
-    private static final char TYPE_SHORT = 'S';
-
-    private static final char TYPE_INTEGER = 'I';
-
-    private static final char TYPE_FLOAT = 'F';
-
-    private static final char TYPE_LONG = 'J';
-
-    private static final char TYPE_DOUBLE = 'D';
-
-    private Field(Class<?> declaringClass, Class<?> type, String name, int slot, int fieldDexIndex) {
-        this.declaringClass = declaringClass;
-        this.type = type;
-        this.name = name;
-        this.slot = slot;
-        this.fieldDexIndex = fieldDexIndex;
-    }
-
-    /**
-     * Returns the index of this field's ID in its dex file.
-     * @hide
-     */
-    public int getDexFieldIndex() {
-        return fieldDexIndex;
-    }
-
-    private synchronized void initGenericType() {
-        if (!genericTypesAreInitialized) {
-            String signatureAttribute = getSignatureAttribute();
-            GenericSignatureParser parser = new GenericSignatureParser(
-                    declaringClass.getClassLoader());
-            parser.parseForField(this.declaringClass, signatureAttribute);
-            genericType = parser.fieldType;
-            if (genericType == null) {
-                genericType = getType();
-            }
-            genericTypesAreInitialized = true;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    /* package */String getSignatureAttribute() {
-        Object[] annotation = getSignatureAnnotation(declaringClass, slot);
-
-        if (annotation == null) {
-            return null;
-        }
-
-        return StringUtils.combineStrings(annotation);
-    }
-
-    /**
-     * Get the Signature annotation for this field. Returns null if not found.
-     */
-    native private Object[] getSignatureAnnotation(Class declaringClass, int slot);
-
-    /**
-     * Indicates whether or not this field is synthetic.
-     *
-     * @return {@code true} if this field is synthetic, {@code false} otherwise
-     */
-    public boolean isSynthetic() {
-        int flags = getFieldModifiers(declaringClass, slot);
-        return (flags & Modifier.SYNTHETIC) != 0;
-    }
-
-    /**
-     * Returns the string representation of this field, including the field's
-     * generic type.
-     *
-     * @return the string representation of this field
-     */
-    public String toGenericString() {
-        StringBuilder sb = new StringBuilder(80);
-        // append modifiers if any
-        int modifier = getModifiers();
-        if (modifier != 0) {
-            sb.append(Modifier.toString(modifier)).append(' ');
-        }
-        // append generic type
-        appendGenericType(sb, getGenericType());
-        sb.append(' ');
-        // append full field name
-        sb.append(getDeclaringClass().getName()).append('.').append(getName());
-        return sb.toString();
-    }
-
-    /**
-     * Indicates whether or not this field is an enumeration constant.
-     *
-     * @return {@code true} if this field is an enumeration constant, {@code
-     *         false} otherwise
-     */
-    public boolean isEnumConstant() {
-        int flags = getFieldModifiers(declaringClass, slot);
-        return (flags & Modifier.ENUM) != 0;
-    }
-
-    /**
-     * Returns the generic type of this field.
-     *
-     * @return the generic type
-     * @throws GenericSignatureFormatError
-     *             if the generic field signature is invalid
-     * @throws TypeNotPresentException
-     *             if the generic type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if the generic type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type getGenericType() {
-        initGenericType();
-        return Types.getType(genericType);
-    }
-
-    @Override public Annotation[] getDeclaredAnnotations() {
-        return getDeclaredAnnotations(declaringClass, slot);
-    }
-    private static native Annotation[] getDeclaredAnnotations(Class declaringClass, int slot);
-
-    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return getAnnotation(declaringClass, slot, annotationType);
-    }
-    private static native <A extends Annotation> A getAnnotation(
-            Class<?> declaringClass, int slot, Class<A> annotationType);
-
-    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return isAnnotationPresent(declaringClass, slot, annotationType);
-    }
-    private static native boolean isAnnotationPresent(
-            Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType);
-
-    /**
-     * Indicates whether or not the specified {@code object} is equal to this
-     * field. To be equal, the specified object must be an instance of
-     * {@code Field} with the same declaring class, type and name as this field.
-     *
-     * @param object
-     *            the object to compare
-     * @return {@code true} if the specified object is equal to this method,
-     *         {@code false} otherwise
-     * @see #hashCode
-     */
-    @Override
-    public boolean equals(Object object) {
-        return object instanceof Field && toString().equals(object.toString());
-    }
-
-    /**
-     * Returns the value of the field in the specified object. This reproduces
-     * the effect of {@code object.fieldName}
-     *
-     * <p>If the type of this field is a primitive type, the field value is
-     * automatically boxed.
-     *
-     * <p>If this field is static, the object argument is ignored.
-     * Otherwise, if the object is null, a NullPointerException is thrown. If
-     * the object is not an instance of the declaring class of the method, an
-     * IllegalArgumentException is thrown.
-     *
-     * <p>If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value, possibly boxed
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getField(object, declaringClass, type, slot, flag);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code
-     * boolean}. This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public boolean getBoolean(Object object) throws IllegalAccessException,
-            IllegalArgumentException {
-        return getZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code byte}.
-     * This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code char}.
-     * This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR);
-    }
-
-    /**
-     * Returns the class that declares this field.
-     *
-     * @return the declaring class
-     */
-    public Class<?> getDeclaringClass() {
-        return declaringClass;
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code
-     * double}. This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code float}
-     * . This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as an {@code int}.
-     * This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER);
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code long}.
-     * This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getJField(object, declaringClass, type, slot, flag, TYPE_LONG);
-    }
-
-    /**
-     * Returns the modifiers for this field. The {@link Modifier} class should
-     * be used to decode the result.
-     *
-     * @return the modifiers for this field
-     * @see Modifier
-     */
-    public int getModifiers() {
-        return getFieldModifiers(declaringClass, slot);
-    }
-
-    private native int getFieldModifiers(Class<?> declaringClass, int slot);
-
-    /**
-     * Returns the name of this field.
-     *
-     * @return the name of this field
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the value of the field in the specified object as a {@code short}
-     * . This reproduces the effect of {@code object.fieldName}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @return the field value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
-        return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT);
-    }
-
-    /**
-     * Returns the constructor's signature in non-printable form. This is called
-     * (only) from IO native code and needed for deriving the serialVersionUID
-     * of the class
-     *
-     * @return the constructor's signature.
-     */
-    @SuppressWarnings("unused")
-    private String getSignature() {
-        return getSignature(type);
-    }
-
-    /**
-     * Return the {@link Class} associated with the type of this field.
-     *
-     * @return the type of this field
-     */
-    public Class<?> getType() {
-        return type;
-    }
-
-    /**
-     * Returns an integer hash code for this field. Objects which are equal
-     * return the same value for this method.
-     * <p>
-     * The hash code for a Field is the exclusive-or combination of the hash
-     * code of the field's name and the hash code of the name of its declaring
-     * class.
-     *
-     * @return the hash code for this field
-     * @see #equals
-     */
-    @Override
-    public int hashCode() {
-        return name.hashCode() ^ getDeclaringClass().getName().hashCode();
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the value. This
-     * reproduces the effect of {@code object.fieldName = value}
-     *
-     * <p>If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     *
-     * <p>If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     *
-     * <p>If the field type is a primitive type, the value is automatically
-     * unboxed. If the unboxing fails, an IllegalArgumentException is thrown. If
-     * the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void set(Object object, Object value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setField(object, declaringClass, type, slot, flag, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code
-     * boolean} value. This reproduces the effect of {@code object.fieldName =
-     * value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setBoolean(Object object, boolean value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code byte}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setByte(Object object, byte value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setBField(object, declaringClass, type, slot, flag, TYPE_BYTE, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code char}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setChar(Object object, char value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setCField(object, declaringClass, type, slot, flag, TYPE_CHAR, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code double}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setDouble(Object object, double value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code float}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setFloat(Object object, float value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setFField(object, declaringClass, type, slot, flag, TYPE_FLOAT, value);
-    }
-
-    /**
-     * Set the value of the field in the specified object to the {@code int}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setInt(Object object, int value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setIField(object, declaringClass, type, slot, flag, TYPE_INTEGER, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code long}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setLong(Object object, long value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setJField(object, declaringClass, type, slot, flag, TYPE_LONG, value);
-    }
-
-    /**
-     * Sets the value of the field in the specified object to the {@code short}
-     * value. This reproduces the effect of {@code object.fieldName = value}
-     * <p>
-     * If this field is static, the object argument is ignored.
-     * Otherwise, if the object is {@code null}, a NullPointerException is
-     * thrown. If the object is not an instance of the declaring class of the
-     * method, an IllegalArgumentException is thrown.
-     * <p>
-     * If this Field object is enforcing access control (see AccessibleObject)
-     * and this field is not accessible from the current context, an
-     * IllegalAccessException is thrown.
-     * <p>
-     * If the value cannot be converted to the field type via a widening
-     * conversion, an IllegalArgumentException is thrown.
-     *
-     * @param object
-     *            the object to access
-     * @param value
-     *            the new value
-     * @throws NullPointerException
-     *             if the object is {@code null} and the field is non-static
-     * @throws IllegalArgumentException
-     *             if the object is not compatible with the declaring class
-     * @throws IllegalAccessException
-     *             if this field is not accessible
-     */
-    public void setShort(Object object, short value) throws IllegalAccessException,
-            IllegalArgumentException {
-        setSField(object, declaringClass, type, slot, flag, TYPE_SHORT, value);
-    }
-
-    /**
-     * Returns a string containing a concise, human-readable description of this
-     * field.
-     * <p>
-     * The format of the string is:
-     * <ol>
-     *   <li>modifiers (if any)
-     *   <li>type
-     *   <li>declaring class name
-     *   <li>'.'
-     *   <li>field name
-     * </ol>
-     * <p>
-     * For example: {@code public static java.io.InputStream
-     * java.lang.System.in}
-     *
-     * @return a printable representation for this field
-     */
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
-        if (result.length() != 0) {
-            result.append(' ');
-        }
-        appendTypeName(result, type);
-        result.append(' ');
-        appendTypeName(result, declaringClass);
-        result.append('.');
-        result.append(name);
-        return result.toString();
-    }
-
-    private native Object getField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck) throws IllegalAccessException;
-
-    private native double getDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native int getIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native long getJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native boolean getZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native float getFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native char getCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native short getSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native byte getBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor) throws IllegalAccessException;
-
-    private native void setField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, Object value) throws IllegalAccessException;
-
-    private native void setDField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, double v) throws IllegalAccessException;
-
-    private native void setIField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, int i) throws IllegalAccessException;
-
-    private native void setJField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, long j) throws IllegalAccessException;
-
-    private native void setZField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, boolean z) throws IllegalAccessException;
-
-    private native void setFField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, float f) throws IllegalAccessException;
-
-    private native void setCField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, char c) throws IllegalAccessException;
-
-    private native void setSField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, short s) throws IllegalAccessException;
-
-    private native void setBField(Object o, Class<?> declaringClass, Class<?> type, int slot,
-            boolean noAccessCheck, char descriptor, byte b) throws IllegalAccessException;
-
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Method.java b/libdvm/src/main/java/java/lang/reflect/Method.java
deleted file mode 100644
index f8efbf4..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Method.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * 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 java.lang.reflect;
-
-import java.lang.annotation.Annotation;
-import java.util.Arrays;
-import java.util.Comparator;
-import libcore.util.EmptyArray;
-import org.apache.harmony.kernel.vm.StringUtils;
-import libcore.reflect.GenericSignatureParser;
-import libcore.reflect.ListOfTypes;
-import libcore.reflect.Types;
-
-/**
- * This class represents a method. Information about the method can be accessed,
- * and the method can be invoked dynamically.
- */
-public final class Method extends AccessibleObject implements GenericDeclaration, Member {
-
-    /**
-     * Orders methods by their name, parameters and return type.
-     *
-     * @hide
-     */
-    public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
-        public int compare(Method a, Method b) {
-            int comparison = a.name.compareTo(b.name);
-            if (comparison != 0) {
-                return comparison;
-            }
-
-            Class<?>[] aParameters = a.parameterTypes;
-            Class<?>[] bParameters = b.parameterTypes;
-            int length = Math.min(aParameters.length, bParameters.length);
-            for (int i = 0; i < length; i++) {
-                comparison = aParameters[i].getName().compareTo(bParameters[i].getName());
-                if (comparison != 0) {
-                    return comparison;
-                }
-            }
-
-            if (aParameters.length != bParameters.length) {
-                return aParameters.length - bParameters.length;
-            }
-
-            // this is necessary for methods that have covariant return types.
-            return a.getReturnType().getName().compareTo(b.getReturnType().getName());
-        }
-    };
-
-    private int slot;
-
-    private final int methodDexIndex;
-
-    private Class<?> declaringClass;
-
-    private String name;
-
-    private Class<?>[] parameterTypes;
-
-    private Class<?>[] exceptionTypes;
-
-    private Class<?> returnType;
-
-    private ListOfTypes genericExceptionTypes;
-    private ListOfTypes genericParameterTypes;
-    private Type genericReturnType;
-    private TypeVariable<Method>[] formalTypeParameters;
-    private volatile boolean genericTypesAreInitialized = false;
-
-    private synchronized void initGenericTypes() {
-        if (!genericTypesAreInitialized) {
-            String signatureAttribute = getSignatureAttribute();
-            GenericSignatureParser parser = new GenericSignatureParser(
-                    declaringClass.getClassLoader());
-            parser.parseForMethod(this, signatureAttribute, exceptionTypes);
-            formalTypeParameters = parser.formalTypeParameters;
-            genericParameterTypes = parser.parameterTypes;
-            genericExceptionTypes = parser.exceptionTypes;
-            genericReturnType = parser.returnType;
-            genericTypesAreInitialized = true;
-        }
-    }
-
-    private Method(Class<?> declaring, Class<?>[] paramTypes, Class<?>[] exceptTypes, Class<?> returnType, String name, int slot, int methodDexIndex) {
-        this.declaringClass = declaring;
-        this.name = name;
-        this.slot = slot;
-        this.parameterTypes = paramTypes;
-        this.exceptionTypes = exceptTypes;      // may be null
-        this.returnType = returnType;
-        this.methodDexIndex = methodDexIndex;
-    }
-
-    /** @hide */
-    public int getDexMethodIndex() {
-        return methodDexIndex;
-    }
-
-    public TypeVariable<Method>[] getTypeParameters() {
-        initGenericTypes();
-        return formalTypeParameters.clone();
-    }
-
-    /** {@inheritDoc} */
-    @Override /*package*/ String getSignatureAttribute() {
-        Object[] annotation = getSignatureAnnotation(declaringClass, slot);
-
-        if (annotation == null) {
-            return null;
-        }
-
-        return StringUtils.combineStrings(annotation);
-    }
-
-    /**
-     * Returns the Signature annotation for this method. Returns {@code null} if
-     * not found.
-     */
-    static native Object[] getSignatureAnnotation(Class declaringClass, int slot);
-
-    /**
-     * Returns the string representation of the method's declaration, including
-     * the type parameters.
-     *
-     * @return the string representation of this method
-     */
-    public String toGenericString() {
-        StringBuilder sb = new StringBuilder(80);
-
-        initGenericTypes();
-
-        // append modifiers if any
-        int modifier = getModifiers();
-        if (modifier != 0) {
-            sb.append(Modifier.toString(modifier & ~(Modifier.BRIDGE +
-                    Modifier.VARARGS))).append(' ');
-        }
-        // append type parameters
-        if (formalTypeParameters != null && formalTypeParameters.length > 0) {
-            sb.append('<');
-            for (int i = 0; i < formalTypeParameters.length; i++) {
-                appendGenericType(sb, formalTypeParameters[i]);
-                if (i < formalTypeParameters.length - 1) {
-                    sb.append(",");
-                }
-            }
-            sb.append("> ");
-        }
-        // append return type
-        appendGenericType(sb, Types.getType(genericReturnType));
-        sb.append(' ');
-        // append method name
-        appendTypeName(sb, getDeclaringClass());
-        sb.append(".").append(getName());
-        // append parameters
-        sb.append('(');
-        appendArrayGenericType(sb, Types.getTypeArray(genericParameterTypes, false));
-        sb.append(')');
-        // append exceptions if any
-        Type[] genericExceptionTypeArray = Types.getTypeArray(genericExceptionTypes, false);
-        if (genericExceptionTypeArray.length > 0) {
-            sb.append(" throws ");
-            appendArrayGenericType(sb, genericExceptionTypeArray);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns the parameter types as an array of {@code Type} instances, in
-     * declaration order. If this method has no parameters, an empty array is
-     * returned.
-     *
-     * @return the parameter types
-     *
-     * @throws GenericSignatureFormatError
-     *             if the generic method signature is invalid
-     * @throws TypeNotPresentException
-     *             if any parameter type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if any parameter type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type[] getGenericParameterTypes() {
-        initGenericTypes();
-        return Types.getTypeArray(genericParameterTypes, true);
-    }
-
-    /**
-     * Returns the exception types as an array of {@code Type} instances. If
-     * this method has no declared exceptions, an empty array will be returned.
-     *
-     * @return an array of generic exception types
-     *
-     * @throws GenericSignatureFormatError
-     *             if the generic method signature is invalid
-     * @throws TypeNotPresentException
-     *             if any exception type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if any exception type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type[] getGenericExceptionTypes() {
-        initGenericTypes();
-        return Types.getTypeArray(genericExceptionTypes, true);
-    }
-
-    /**
-     * Returns the return type of this method as a {@code Type} instance.
-     *
-     * @return the return type of this method
-     *
-     * @throws GenericSignatureFormatError
-     *             if the generic method signature is invalid
-     * @throws TypeNotPresentException
-     *             if the return type points to a missing type
-     * @throws MalformedParameterizedTypeException
-     *             if the return type points to a type that cannot be
-     *             instantiated for some reason
-     */
-    public Type getGenericReturnType() {
-        initGenericTypes();
-        return Types.getType(genericReturnType);
-    }
-
-    @Override
-    public Annotation[] getDeclaredAnnotations() {
-        return getDeclaredAnnotations(declaringClass, slot);
-    }
-    static native Annotation[] getDeclaredAnnotations(Class<?> declaringClass, int slot);
-
-    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return getAnnotation(declaringClass, slot, annotationType);
-    }
-    static native <A extends Annotation> A getAnnotation(
-            Class<?> declaringClass, int slot, Class<A> annotationType);
-
-    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        if (annotationType == null) {
-            throw new NullPointerException("annotationType == null");
-        }
-        return isAnnotationPresent(declaringClass, slot, annotationType);
-    }
-    static native boolean isAnnotationPresent(
-            Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType);
-
-    private static final Annotation[] NO_ANNOTATIONS = new Annotation[0];
-
-    /**
-     * Creates an array of empty Annotation arrays.
-     */
-    /*package*/ static Annotation[][] noAnnotations(int size) {
-        Annotation[][] annotations = new Annotation[size][];
-        for (int i = 0; i < size; i++) {
-            annotations[i] = NO_ANNOTATIONS;
-        }
-        return annotations;
-    }
-
-    /**
-     * Returns an array of arrays that represent the annotations of the formal
-     * parameters of this method. If there are no parameters on this method,
-     * then an empty array is returned. If there are no annotations set, then
-     * and array of empty arrays is returned.
-     *
-     * @return an array of arrays of {@code Annotation} instances
-     */
-    public Annotation[][] getParameterAnnotations() {
-        Annotation[][] parameterAnnotations
-                = getParameterAnnotations(declaringClass, slot);
-        if (parameterAnnotations.length == 0) {
-            return noAnnotations(parameterTypes.length);
-        }
-        return parameterAnnotations;
-    }
-
-    static native Annotation[][] getParameterAnnotations(Class declaringClass, int slot);
-
-    /**
-     * Indicates whether or not this method takes a variable number argument.
-     *
-     * @return {@code true} if a vararg is declared, {@code false} otherwise
-     */
-    public boolean isVarArgs() {
-        int modifiers = getMethodModifiers(declaringClass, slot);
-        return (modifiers & Modifier.VARARGS) != 0;
-    }
-
-    /**
-     * Indicates whether or not this method is a bridge.
-     *
-     * @return {@code true} if this method is a bridge, {@code false} otherwise
-     */
-    public boolean isBridge() {
-        int modifiers = getMethodModifiers(declaringClass, slot);
-        return (modifiers & Modifier.BRIDGE) != 0;
-    }
-
-    /**
-     * Indicates whether or not this method is synthetic.
-     *
-     * @return {@code true} if this method is synthetic, {@code false} otherwise
-     */
-    public boolean isSynthetic() {
-        int modifiers = getMethodModifiers(declaringClass, slot);
-        return (modifiers & Modifier.SYNTHETIC) != 0;
-    }
-
-    /**
-     * Returns the default value for the annotation member represented by this
-     * method.
-     *
-     * @return the default value, or {@code null} if none
-     *
-     * @throws TypeNotPresentException
-     *             if this annotation member is of type {@code Class} and no
-     *             definition can be found
-     */
-    public Object getDefaultValue() {
-        return getDefaultValue(declaringClass, slot);
-    }
-    native private Object getDefaultValue(Class declaringClass, int slot);
-
-    /**
-     * Indicates whether or not the specified {@code object} is equal to this
-     * method. To be equal, the specified object must be an instance
-     * of {@code Method} with the same declaring class and parameter types
-     * as this method.
-     *
-     * @param object
-     *            the object to compare
-     *
-     * @return {@code true} if the specified object is equal to this
-     *         method, {@code false} otherwise
-     *
-     * @see #hashCode
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (this == object) {
-            return true;
-        }
-        if (!(object instanceof Method)) {
-            return false;
-        }
-        Method rhs = (Method) object;
-        // We don't compare exceptionTypes because two methods
-        // can't differ only by their declared exceptions.
-        return declaringClass.equals(rhs.declaringClass) &&
-            name.equals(rhs.name) &&
-            getModifiers() == rhs.getModifiers() &&
-            returnType.equals(rhs.returnType) &&
-            Arrays.equals(parameterTypes, rhs.parameterTypes);
-    }
-
-    /**
-     * Returns the class that declares this method.
-     *
-     * @return the declaring class
-     */
-    public Class<?> getDeclaringClass() {
-        return declaringClass;
-    }
-
-    /**
-     * Returns the exception types as an array of {@code Class} instances. If
-     * this method has no declared exceptions, an empty array is returned.
-     *
-     * @return the declared exception classes
-     */
-    public Class<?>[] getExceptionTypes() {
-        if (exceptionTypes == null) {
-            return EmptyArray.CLASS;
-        }
-        return exceptionTypes.clone();
-    }
-
-    /**
-     * Returns the modifiers for this method. The {@link Modifier} class should
-     * be used to decode the result.
-     *
-     * @return the modifiers for this method
-     *
-     * @see Modifier
-     */
-    public int getModifiers() {
-        return getMethodModifiers(declaringClass, slot);
-    }
-
-    static native int getMethodModifiers(Class<?> declaringClass, int slot);
-
-    /**
-     * Returns the name of the method represented by this {@code Method}
-     * instance.
-     *
-     * @return the name of this method
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns an array of {@code Class} objects associated with the parameter
-     * types of this method. If the method was declared with no parameters, an
-     * empty array will be returned.
-     *
-     * @return the parameter types
-     */
-    public Class<?>[] getParameterTypes() {
-        return parameterTypes.clone();
-    }
-
-    /**
-     * Returns the {@code Class} associated with the return type of this
-     * method.
-     *
-     * @return the return type
-     */
-    public Class<?> getReturnType() {
-        return returnType;
-    }
-
-    /**
-     * Returns an integer hash code for this method. Objects which are equal
-     * return the same value for this method. The hash code for this Method is
-     * the hash code of the name of this method.
-     *
-     * @return hash code for this method
-     *
-     * @see #equals
-     */
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    /**
-     * Returns the result of dynamically invoking this method. Equivalent to
-     * {@code receiver.methodName(arg1, arg2, ... , argN)}.
-     *
-     * <p>If the method is static, the receiver argument is ignored (and may be null).
-     *
-     * <p>If the method takes no arguments, you can pass {@code (Object[]) null} instead of
-     * allocating an empty array.
-     *
-     * <p>If you're calling a varargs method, you need to pass an {@code Object[]} for the
-     * varargs parameter: that conversion is usually done in {@code javac}, not the VM, and
-     * the reflection machinery does not do this for you. (It couldn't, because it would be
-     * ambiguous.)
-     *
-     * <p>Reflective method invocation follows the usual process for method lookup.
-     *
-     * <p>If an exception is thrown during the invocation it is caught and
-     * wrapped in an InvocationTargetException. This exception is then thrown.
-     *
-     * <p>If the invocation completes normally, the return value itself is
-     * returned. If the method is declared to return a primitive type, the
-     * return value is boxed. If the return type is void, null is returned.
-     *
-     * @param receiver
-     *            the object on which to call this method (or null for static methods)
-     * @param args
-     *            the arguments to the method
-     * @return the result
-     *
-     * @throws NullPointerException
-     *             if {@code receiver == null} for a non-static method
-     * @throws IllegalAccessException
-     *             if this method is not accessible (see {@link AccessibleObject})
-     * @throws IllegalArgumentException
-     *             if the number of arguments doesn't match the number of parameters, the receiver
-     *             is incompatible with the declaring class, or an argument could not be unboxed
-     *             or converted by a widening conversion to the corresponding parameter type
-     * @throws InvocationTargetException
-     *             if an exception was thrown by the invoked method
-     */
-    public Object invoke(Object receiver, Object... args)
-            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-        if (args == null) {
-            args = EmptyArray.OBJECT;
-        }
-        return invokeNative(receiver, args, declaringClass, parameterTypes, returnType, slot, flag);
-    }
-
-    private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass,
-            Class<?>[] parameterTypes, Class<?> returnType, int slot, boolean noAccessCheck)
-                    throws IllegalAccessException, IllegalArgumentException,
-                            InvocationTargetException;
-
-    /**
-     * Returns a string containing a concise, human-readable description of this
-     * method. The format of the string is:
-     *
-     * <ol>
-     *   <li>modifiers (if any)
-     *   <li>return type or 'void'
-     *   <li>declaring class name
-     *   <li>'('
-     *   <li>parameter types, separated by ',' (if any)
-     *   <li>')'
-     *   <li>'throws' plus exception types, separated by ',' (if any)
-     * </ol>
-     *
-     * For example: {@code public native Object
-     * java.lang.Method.invoke(Object,Object) throws
-     * IllegalAccessException,IllegalArgumentException
-     * ,InvocationTargetException}
-     *
-     * @return a printable representation for this method
-     */
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
-
-        if (result.length() != 0)
-            result.append(' ');
-        result.append(returnType.getName());
-        result.append(' ');
-        result.append(declaringClass.getName());
-        result.append('.');
-        result.append(name);
-        result.append("(");
-        result.append(toString(parameterTypes));
-        result.append(")");
-        if (exceptionTypes != null && exceptionTypes.length != 0) {
-            result.append(" throws ");
-            result.append(toString(exceptionTypes));
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * Returns the constructor's signature in non-printable form. This is called
-     * (only) from IO native code and needed for deriving the serialVersionUID
-     * of the class
-     *
-     * @return The constructor's signature.
-     */
-    @SuppressWarnings("unused")
-    private String getSignature() {
-        StringBuilder result = new StringBuilder();
-
-        result.append('(');
-        for (int i = 0; i < parameterTypes.length; i++) {
-            result.append(getSignature(parameterTypes[i]));
-        }
-        result.append(')');
-        result.append(getSignature(returnType));
-
-        return result.toString();
-    }
-
-}
diff --git a/libdvm/src/main/java/java/lang/reflect/Proxy.java b/libdvm/src/main/java/java/lang/reflect/Proxy.java
deleted file mode 100644
index 3b10887..0000000
--- a/libdvm/src/main/java/java/lang/reflect/Proxy.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package java.lang.reflect;
-
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-/**
- * {@code Proxy} defines methods for creating dynamic proxy classes and instances.
- * A proxy class implements a declared set of interfaces and delegates method
- * invocations to an {@code InvocationHandler}.
- *
- * @see InvocationHandler
- * @since 1.3
- */
-public class Proxy implements Serializable {
-
-    private static final long serialVersionUID = -2222568056686623797L;
-
-    // maps class loaders to created classes by interface names
-    private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> loaderCache = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
-
-    // to find previously created types
-    private static final Map<Class<?>, String> proxyCache = new WeakHashMap<Class<?>, String>();
-
-    private static int NextClassNameIndex = 0;
-
-    /**
-     * The invocation handler on which the method calls are dispatched.
-     */
-    protected InvocationHandler h;
-
-    @SuppressWarnings("unused")
-    private Proxy() {
-    }
-
-    /**
-     * Constructs a new {@code Proxy} instance with the specified invocation
-     * handler.
-     *
-     * @param h
-     *            the invocation handler for the newly created proxy
-     */
-    protected Proxy(InvocationHandler h) {
-        this.h = h;
-    }
-
-    /**
-     * Returns the dynamically built {@code Class} for the specified interfaces.
-     * Creates a new {@code Class} when necessary. The order of the interfaces
-     * is relevant. Invocations of this method with the same interfaces but
-     * different order result in different generated classes. The interfaces
-     * must be visible from the supplied class loader; no duplicates are
-     * permitted. All non-public interfaces must be defined in the same package.
-     *
-     * @param loader
-     *            the class loader that will define the proxy class
-     * @param interfaces
-     *            an array of {@code Class} objects, each one identifying an
-     *            interface that will be implemented by the returned proxy
-     *            class
-     * @return a proxy class that implements all of the interfaces referred to
-     *         in the contents of {@code interfaces}
-     * @throws IllegalArgumentException
-     *                if any of the interface restrictions are violated
-     * @throws NullPointerException
-     *                if either {@code interfaces} or any of its elements are
-     *                {@code null}
-     */
-    public static Class<?> getProxyClass(ClassLoader loader,
-            Class<?>... interfaces) throws IllegalArgumentException {
-        // check that interfaces are a valid array of visible interfaces
-        if (interfaces == null) {
-            throw new NullPointerException("interfaces == null");
-        }
-        String commonPackageName = null;
-        for (int i = 0, length = interfaces.length; i < length; i++) {
-            Class<?> next = interfaces[i];
-            if (next == null) {
-                throw new NullPointerException("interfaces[" + i + "] == null");
-            }
-            String name = next.getName();
-            if (!next.isInterface()) {
-                throw new IllegalArgumentException(name + " is not an interface");
-            }
-            if (loader != next.getClassLoader()) {
-                try {
-                    if (next != Class.forName(name, false, loader)) {
-                        throw new IllegalArgumentException(name +
-                                " is not visible from class loader");
-                    }
-                } catch (ClassNotFoundException ex) {
-                    throw new IllegalArgumentException(name + " is not visible from class loader");
-                }
-            }
-            for (int j = i + 1; j < length; j++) {
-                if (next == interfaces[j]) {
-                    throw new IllegalArgumentException(name + " appears more than once");
-                }
-            }
-            if (!Modifier.isPublic(next.getModifiers())) {
-                int last = name.lastIndexOf('.');
-                String p = last == -1 ? "" : name.substring(0, last);
-                if (commonPackageName == null) {
-                    commonPackageName = p;
-                } else if (!commonPackageName.equals(p)) {
-                    throw new IllegalArgumentException("non-public interfaces must be " +
-                            "in the same package");
-                }
-            }
-        }
-
-        // search cache for matching proxy class using the class loader
-        synchronized (loaderCache) {
-            Map<String, WeakReference<Class<?>>> interfaceCache = loaderCache
-                    .get(loader);
-            if (interfaceCache == null) {
-                loaderCache
-                        .put(
-                                loader,
-                                (interfaceCache = new HashMap<String, WeakReference<Class<?>>>()));
-            }
-
-            String interfaceKey = "";
-            if (interfaces.length == 1) {
-                interfaceKey = interfaces[0].getName();
-            } else {
-                StringBuilder names = new StringBuilder();
-                for (int i = 0, length = interfaces.length; i < length; i++) {
-                    names.append(interfaces[i].getName());
-                    names.append(' ');
-                }
-                interfaceKey = names.toString();
-            }
-
-            Class<?> newClass;
-            WeakReference<Class<?>> ref = interfaceCache.get(interfaceKey);
-            if (ref == null) {
-                String nextClassName = "$Proxy" + NextClassNameIndex++;
-                if (commonPackageName != null && commonPackageName.length() > 0) {
-                    nextClassName = commonPackageName + "." + nextClassName;
-                }
-                if (loader == null) {
-                    loader = ClassLoader.getSystemClassLoader();
-                }
-                newClass = generateProxy(nextClassName.replace('.', '/'), interfaces, loader);
-                // Need a weak reference to the class so it can
-                // be unloaded if the class loader is discarded
-                interfaceCache.put(interfaceKey, new WeakReference<Class<?>>(newClass));
-                synchronized (proxyCache) {
-                    // the value is unused
-                    proxyCache.put(newClass, "");
-                }
-            } else {
-                newClass = ref.get();
-                assert newClass != null : "\ninterfaceKey=\"" + interfaceKey + "\""
-                                        + "\nloaderCache=\"" + loaderCache + "\""
-                                        + "\nintfCache=\"" + interfaceCache + "\""
-                                        + "\nproxyCache=\"" + proxyCache + "\"";
-            }
-            return newClass;
-        }
-    }
-
-    /**
-     * Returns an instance of the dynamically built class for the specified
-     * interfaces. Method invocations on the returned instance are forwarded to
-     * the specified invocation handler. The interfaces must be visible from the
-     * supplied class loader; no duplicates are permitted. All non-public
-     * interfaces must be defined in the same package.
-     *
-     * @param loader
-     *            the class loader that will define the proxy class
-     * @param interfaces
-     *            an array of {@code Class} objects, each one identifying an
-     *            interface that will be implemented by the returned proxy
-     *            object
-     * @param h
-     *            the invocation handler that handles the dispatched method
-     *            invocations
-     * @return a new proxy object that delegates to the handler {@code h}
-     * @throws IllegalArgumentException
-     *                if any of the interface restrictions are violated
-     * @throws NullPointerException
-     *                if the interfaces or any of its elements are null
-     */
-    public static Object newProxyInstance(ClassLoader loader,
-            Class<?>[] interfaces, InvocationHandler h)
-            throws IllegalArgumentException {
-        if (h == null) {
-            throw new NullPointerException("h == null");
-        }
-        try {
-            return getProxyClass(loader, interfaces).getConstructor(
-                    new Class<?>[] { InvocationHandler.class }).newInstance(
-                    new Object[] { h });
-        } catch (NoSuchMethodException ex) {
-            throw (InternalError) (new InternalError(ex.toString())
-                    .initCause(ex));
-        } catch (IllegalAccessException ex) {
-            throw (InternalError) (new InternalError(ex.toString())
-                    .initCause(ex));
-        } catch (InstantiationException ex) {
-            throw (InternalError) (new InternalError(ex.toString())
-                    .initCause(ex));
-        } catch (InvocationTargetException ex) {
-            Throwable target = ex.getTargetException();
-            throw (InternalError) (new InternalError(target.toString())
-                    .initCause(target));
-        }
-    }
-
-    /**
-     * Indicates whether or not the specified class is a dynamically generated
-     * proxy class.
-     *
-     * @param cl
-     *            the class
-     * @return {@code true} if the class is a proxy class, {@code false}
-     *         otherwise
-     * @throws NullPointerException
-     *                if the class is {@code null}
-     */
-    public static boolean isProxyClass(Class<?> cl) {
-        if (cl == null) {
-            throw new NullPointerException("cl == null");
-        }
-        synchronized (proxyCache) {
-            return proxyCache.containsKey(cl);
-        }
-    }
-
-    /**
-     * Returns the invocation handler of the specified proxy instance.
-     *
-     * @param proxy
-     *            the proxy instance
-     * @return the invocation handler of the specified proxy instance
-     * @throws IllegalArgumentException
-     *                if the supplied {@code proxy} is not a proxy object
-     */
-    public static InvocationHandler getInvocationHandler(Object proxy)
-            throws IllegalArgumentException {
-
-        if (isProxyClass(proxy.getClass())) {
-            return ((Proxy) proxy).h;
-        }
-
-        throw new IllegalArgumentException("not a proxy instance");
-    }
-
-    native private static Class generateProxy(String name, Class[] interfaces,
-        ClassLoader loader);
-
-    /*
-     * The VM clones this method's descriptor when generating a proxy class.
-     * There is no implementation.
-     */
-    native private static void constructorPrototype(InvocationHandler h);
-}
diff --git a/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java b/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java
deleted file mode 100644
index 01d0e30..0000000
--- a/libdvm/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java
+++ /dev/null
@@ -1,63 +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 org.apache.harmony.kernel.vm;
-
-/**
- * String utility functions.
- */
-public final class StringUtils {
-    /**
-     * This class is uninstantiable.
-     */
-    private StringUtils() {
-        // This space intentionally left blank.
-    }
-
-    /**
-     * Combine a list of strings in an <code>Object[]</code> into a single
-     * string.
-     *
-     * @param list non-null; the strings to combine
-     * @return non-null; the combined form
-     */
-    public static String combineStrings(Object[] list) {
-        int listLength = list.length;
-
-        switch (listLength) {
-            case 0: {
-                return "";
-            }
-            case 1: {
-                return (String) list[0];
-            }
-        }
-
-        int strLength = 0;
-
-        for (int i = 0; i < listLength; i++) {
-            strLength += ((String) list[i]).length();
-        }
-
-        StringBuilder sb = new StringBuilder(strLength);
-
-        for (int i = 0; i < listLength; i++) {
-            sb.append(list[i]);
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/libdvm/src/main/java/sun/misc/Unsafe.java b/libdvm/src/main/java/sun/misc/Unsafe.java
deleted file mode 100644
index 884340b..0000000
--- a/libdvm/src/main/java/sun/misc/Unsafe.java
+++ /dev/null
@@ -1,350 +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 sun.misc;
-
-import dalvik.system.VMStack;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-/**
- * The package name notwithstanding, this class is the quasi-standard
- * way for Java code to gain access to and use functionality which,
- * when unsupervised, would allow one to break the pointer/type safety
- * of Java.
- */
-public final class Unsafe {
-    /** Traditional dalvik name. */
-    private static final Unsafe THE_ONE = new Unsafe();
-    /** Traditional RI name. */
-    private static final Unsafe theUnsafe = THE_ONE;
-
-    /**
-     * This class is only privately instantiable.
-     */
-    private Unsafe() {}
-
-    /**
-     * Gets the unique instance of this class. This is only allowed in
-     * very limited situations.
-     */
-    public static Unsafe getUnsafe() {
-        /*
-         * Only code on the bootclasspath is allowed to get at the
-         * Unsafe instance.
-         */
-        ClassLoader calling = VMStack.getCallingClassLoader();
-        if ((calling != null) && (calling != Unsafe.class.getClassLoader())) {
-            throw new SecurityException("Unsafe access denied");
-        }
-
-        return THE_ONE;
-    }
-
-    /**
-     * Gets the raw byte offset from the start of an object's memory to
-     * the memory used to store the indicated instance field.
-     *
-     * @param field non-null; the field in question, which must be an
-     * instance field
-     * @return the offset to the field
-     */
-    public long objectFieldOffset(Field field) {
-        if (Modifier.isStatic(field.getModifiers())) {
-            throw new IllegalArgumentException(
-                    "valid for instance fields only");
-        }
-
-        return objectFieldOffset0(field);
-    }
-
-    /**
-     * Helper for {@link #objectFieldOffset}, which does all the work,
-     * assuming the parameter is deemed valid.
-     *
-     * @param field non-null; the instance field
-     * @return the offset to the field
-     */
-    private static native long objectFieldOffset0(Field field);
-
-    /**
-     * Gets the offset from the start of an array object's memory to
-     * the memory used to store its initial (zeroeth) element.
-     *
-     * @param clazz non-null; class in question; must be an array class
-     * @return the offset to the initial element
-     */
-    public int arrayBaseOffset(Class clazz) {
-        if (! clazz.isArray()) {
-            throw new IllegalArgumentException(
-                    "valid for array classes only");
-        }
-
-        return arrayBaseOffset0(clazz);
-    }
-
-    /**
-     * Helper for {@link #arrayBaseOffset}, which does all the work,
-     * assuming the parameter is deemed valid.
-     *
-     * @return the offset to the field
-     */
-    private static native int arrayBaseOffset0(Class clazz);
-
-    /**
-     * Gets the size of each element of the given array class.
-     *
-     * @param clazz non-null; class in question; must be an array class
-     * @return &gt; 0; the size of each element of the array
-     */
-    public int arrayIndexScale(Class clazz) {
-        if (! clazz.isArray()) {
-            throw new IllegalArgumentException(
-                    "valid for array classes only");
-        }
-
-        return arrayIndexScale0(clazz);
-    }
-
-    /**
-     * Helper for {@link #arrayIndexScale}, which does all the work,
-     * assuming the parameter is deemed valid.
-     *
-     * @return the offset to the field
-     */
-    private static native int arrayIndexScale0(Class clazz);
-
-    /**
-     * Performs a compare-and-set operation on an <code>int</code>
-     * field within the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param expectedValue expected value of the field
-     * @param newValue new value to store in the field if the contents are
-     * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
-     */
-    public native boolean compareAndSwapInt(Object obj, long offset,
-            int expectedValue, int newValue);
-
-    /**
-     * Performs a compare-and-set operation on a <code>long</code>
-     * field within the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param expectedValue expected value of the field
-     * @param newValue new value to store in the field if the contents are
-     * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
-     */
-    public native boolean compareAndSwapLong(Object obj, long offset,
-            long expectedValue, long newValue);
-
-    /**
-     * Performs a compare-and-set operation on an <code>Object</code>
-     * field (that is, a reference field) within the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param expectedValue expected value of the field
-     * @param newValue new value to store in the field if the contents are
-     * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
-     */
-    public native boolean compareAndSwapObject(Object obj, long offset,
-            Object expectedValue, Object newValue);
-
-    /**
-     * Gets an <code>int</code> field from the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native int getIntVolatile(Object obj, long offset);
-
-    /**
-     * Stores an <code>int</code> field into the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putIntVolatile(Object obj, long offset, int newValue);
-
-    /**
-     * Gets a <code>long</code> field from the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native long getLongVolatile(Object obj, long offset);
-
-    /**
-     * Stores a <code>long</code> field into the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putLongVolatile(Object obj, long offset, long newValue);
-
-    /**
-     * Gets an <code>Object</code> field from the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native Object getObjectVolatile(Object obj, long offset);
-
-    /**
-     * Stores an <code>Object</code> field into the given object,
-     * using <code>volatile</code> semantics.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putObjectVolatile(Object obj, long offset,
-            Object newValue);
-
-    /**
-     * Gets an <code>int</code> field from the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native int getInt(Object obj, long offset);
-
-    /**
-     * Stores an <code>int</code> field into the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putInt(Object obj, long offset, int newValue);
-
-    /**
-     * Lazy set an int field.
-     */
-    public native void putOrderedInt(Object obj, long offset, int newValue);
-
-    /**
-     * Gets a <code>long</code> field from the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native long getLong(Object obj, long offset);
-
-    /**
-     * Stores a <code>long</code> field into the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putLong(Object obj, long offset, long newValue);
-
-    /**
-     * Lazy set a long field.
-     */
-    public native void putOrderedLong(Object obj, long offset, long newValue);
-
-    /**
-     * Gets an <code>Object</code> field from the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @return the retrieved value
-     */
-    public native Object getObject(Object obj, long offset);
-
-    /**
-     * Stores an <code>Object</code> field into the given object.
-     *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
-     * @param newValue the value to store
-     */
-    public native void putObject(Object obj, long offset, Object newValue);
-
-    /**
-     * Lazy set an object field.
-     */
-    public native void putOrderedObject(Object obj, long offset,
-            Object newValue);
-
-    /**
-     * Parks the calling thread for the specified amount of time,
-     * unless the "permit" for the thread is already available (due to
-     * a previous call to {@link #unpark}. This method may also return
-     * spuriously (that is, without the thread being told to unpark
-     * and without the indicated amount of time elapsing).
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * @param absolute whether the given time value is absolute
-     * milliseconds-since-the-epoch (<code>true</code>) or relative
-     * nanoseconds-from-now (<code>false</code>)
-     * @param time the (absolute millis or relative nanos) time value
-     */
-    public void park(boolean absolute, long time) {
-        if (absolute) {
-            Thread.currentThread().parkUntil(time);
-        } else {
-            Thread.currentThread().parkFor(time);
-        }
-    }
-
-    /**
-     * Unparks the given object, which must be a {@link Thread}.
-     *
-     * <p>See {@link java.util.concurrent.locks.LockSupport} for more
-     * in-depth information of the behavior of this method.</p>
-     *
-     * @param obj non-null; the object to unpark
-     */
-    public void unpark(Object obj) {
-        if (obj instanceof Thread) {
-            ((Thread) obj).unpark();
-        } else {
-            throw new IllegalArgumentException("valid for Threads only");
-        }
-    }
-
-    /**
-     * Allocates an instance of the given class without running the constructor.
-     * The class' <clinit> will be run, if necessary.
-     */
-    public native Object allocateInstance(Class<?> c);
-}
diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/luni/src/main/java/java/lang/CaseMapper.java
index 4e411d1..1da621c 100644
--- a/luni/src/main/java/java/lang/CaseMapper.java
+++ b/luni/src/main/java/java/lang/CaseMapper.java
@@ -49,7 +49,7 @@
         // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase.
         String languageCode = locale.getLanguage();
         if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
-            return ICU.toLowerCase(s, locale.toString());
+            return ICU.toLowerCase(s, locale);
         }
 
         char[] newValue = null;
@@ -59,7 +59,7 @@
             char newCh;
             if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) {
                 // Punt these hard cases.
-                return ICU.toLowerCase(s, locale.toString());
+                return ICU.toLowerCase(s, locale);
             } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(value, offset, count, i)) {
                 newCh = GREEK_SMALL_FINAL_SIGMA;
             } else {
@@ -150,7 +150,7 @@
     public static String toUpperCase(Locale locale, String s, char[] value, int offset, int count) {
         String languageCode = locale.getLanguage();
         if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
-            return ICU.toUpperCase(s, locale.toString());
+            return ICU.toUpperCase(s, locale);
         }
         if (languageCode.equals("el")) {
             return EL_UPPER.get().transliterate(s);
@@ -161,7 +161,7 @@
         for (int o = offset, end = offset + count; o < end; o++) {
             char ch = value[o];
             if (Character.isHighSurrogate(ch)) {
-                return ICU.toUpperCase(s, locale.toString());
+                return ICU.toUpperCase(s, locale);
             }
             int index = upperIndex(ch);
             if (index == -1) {
diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java
index 4b66c2d..a3cb83e 100644
--- a/luni/src/main/java/java/lang/Runtime.java
+++ b/luni/src/main/java/java/lang/Runtime.java
@@ -307,57 +307,64 @@
     }
 
     /**
-     * Loads and links the dynamic library that is identified through the
-     * specified path. This method is similar to {@link #loadLibrary(String)},
-     * but it accepts a full path specification whereas {@code loadLibrary} just
-     * accepts the name of the library to load.
+     * Loads the shared library found at the given absolute path.
+     * This should be of the form {@code /path/to/library/libMyLibrary.so}.
+     * Most callers should use {@link #loadLibrary(String)} instead, and
+     * let the system find the correct file to load.
      *
-     * @param pathName
-     *            the absolute (platform dependent) path to the library to load.
-     * @throws UnsatisfiedLinkError
-     *             if the library can not be loaded.
+     * @throws UnsatisfiedLinkError if the library can not be loaded,
+     * either because it's not found or because there is something wrong with it.
      */
-    public void load(String pathName) {
-        load(pathName, VMStack.getCallingClassLoader());
+    public void load(String absolutePath) {
+        load(absolutePath, VMStack.getCallingClassLoader());
     }
 
     /*
-     * Loads and links the given library without security checks.
+     * Loads the given shared library using the given ClassLoader.
      */
-    void load(String pathName, ClassLoader loader) {
-        if (pathName == null) {
-            throw new NullPointerException("pathName == null");
+    void load(String absolutePath, ClassLoader loader) {
+        if (absolutePath == null) {
+            throw new NullPointerException("absolutePath == null");
         }
-        String error = doLoad(pathName, loader);
+        String error = doLoad(absolutePath, loader);
         if (error != null) {
             throw new UnsatisfiedLinkError(error);
         }
     }
 
     /**
-     * Loads and links the library with the specified name. The mapping of the
-     * specified library name to the full path for loading the library is
-     * implementation-dependent.
+     * Loads a shared library. Class loaders have some influence over this
+     * process, but for a typical Android app, it works as follows:
      *
-     * @param libName
-     *            the name of the library to load.
-     * @throws UnsatisfiedLinkError
-     *             if the library can not be loaded.
+     * <p>Given the name {@code "MyLibrary"}, that string will be passed to
+     * {@link System#mapLibraryName}. That means it would be a mistake
+     * for the caller to include the usual {@code "lib"} prefix and {@code ".so"}
+     * suffix.
+     *
+     * <p>That file will then be searched for on the application's native library
+     * search path. This consists of the application's own native library directory
+     * followed by the system's native library directories.
+     *
+     * @throws UnsatisfiedLinkError if the library can not be loaded,
+     * either because it's not found or because there is something wrong with it.
      */
-    public void loadLibrary(String libName) {
-        loadLibrary(libName, VMStack.getCallingClassLoader());
+    public void loadLibrary(String nickname) {
+        loadLibrary(nickname, VMStack.getCallingClassLoader());
     }
 
     /*
-     * Searches for a library, then loads and links it without security checks.
+     * Searches for and loads the given shared library using the given ClassLoader.
      */
     void loadLibrary(String libraryName, ClassLoader loader) {
         if (loader != null) {
             String filename = loader.findLibrary(libraryName);
             if (filename == null) {
-                throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
-                                               " from loader " + loader +
-                                               ": findLibrary returned null");
+                // It's not necessarily true that the ClassLoader used
+                // System.mapLibraryName, but the default setup does, and it's
+                // misleading to say we didn't find "libMyLibrary.so" when we
+                // actually searched for "liblibMyLibrary.so.so".
+                throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
+                                               System.mapLibraryName(libraryName) + "\"");
             }
             String error = doLoad(filename, loader);
             if (error != null) {
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 2d33bc6..185701e 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -584,27 +584,14 @@
     }
 
     /**
-     * Loads and links the dynamic library that is identified through the
-     * specified path. This method is similar to {@link #loadLibrary(String)},
-     * but it accepts a full path specification whereas {@code loadLibrary} just
-     * accepts the name of the library to load.
-     *
-     * @param pathName
-     *            the path of the file to be loaded.
+     * See {@link Runtime#load}.
      */
     public static void load(String pathName) {
         Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
     }
 
     /**
-     * Loads and links the library with the specified name. The mapping of the
-     * specified library name to the full path for loading the library is
-     * implementation-dependent.
-     *
-     * @param libName
-     *            the name of the library to load.
-     * @throws UnsatisfiedLinkError
-     *             if the library could not be loaded.
+     * See {@link Runtime#loadLibrary}.
      */
     public static void loadLibrary(String libName) {
         Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
@@ -722,24 +709,15 @@
 
     /**
      * Returns the platform specific file name format for the shared library
-     * named by the argument.
-     *
-     * @param userLibName
-     *            the name of the library to look up.
-     * @return the platform specific filename for the library.
+     * named by the argument. On Android, this would turn {@code "MyLibrary"} into
+     * {@code "libMyLibrary.so"}.
      */
-    public static native String mapLibraryName(String userLibName);
+    public static native String mapLibraryName(String nickname);
 
     /**
-     * Sets the value of the named static field in the receiver to the passed in
-     * argument.
-     *
-     * @param fieldName
-     *            the name of the field to set, one of in, out, or err
-     * @param stream
-     *            the new value of the field
+     * Used to set System.err, System.in, and System.out.
      */
-    private static native void setFieldImpl(String fieldName, String signature, Object stream);
+    private static native void setFieldImpl(String field, String signature, Object stream);
 
     /**
      * A properties class that prohibits changes to any of the properties
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index 7dd7d93..a39d59b 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -703,7 +703,7 @@
 
         @Override
         public Object clone() throws CloneNotSupportedException {
-            SignatureSpi spi = (SignatureSpi) spiImpl.clone();
+            SignatureSpi spi = spiImpl != null ? (SignatureSpi) spiImpl.clone() : null;
             return new SignatureImpl(getAlgorithm(), getProvider(), spi);
         }
 
diff --git a/luni/src/main/java/java/text/BreakIterator.java b/luni/src/main/java/java/text/BreakIterator.java
index b14647c..81545b2 100644
--- a/luni/src/main/java/java/text/BreakIterator.java
+++ b/luni/src/main/java/java/text/BreakIterator.java
@@ -268,13 +268,9 @@
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * characters using the given locale.
-     *
-     * @param where
-     *            the given locale.
-     * @return a new instance of {@code BreakIterator} using the given locale.
      */
-    public static BreakIterator getCharacterInstance(Locale where) {
-        return new RuleBasedBreakIterator(NativeBreakIterator.getCharacterInstance(where));
+    public static BreakIterator getCharacterInstance(Locale locale) {
+        return new RuleBasedBreakIterator(NativeBreakIterator.getCharacterInstance(locale));
     }
 
     /**
@@ -290,14 +286,9 @@
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * line breaks using the given locale.
-     *
-     * @param where
-     *            the given locale.
-     * @return a new instance of {@code BreakIterator} using the given locale.
-     * @throws NullPointerException if {@code where} is {@code null}.
      */
-    public static BreakIterator getLineInstance(Locale where) {
-        return new RuleBasedBreakIterator(NativeBreakIterator.getLineInstance(where));
+    public static BreakIterator getLineInstance(Locale locale) {
+        return new RuleBasedBreakIterator(NativeBreakIterator.getLineInstance(locale));
     }
 
     /**
@@ -313,14 +304,9 @@
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * sentence-breaks using the given locale.
-     *
-     * @param where
-     *            the given locale.
-     * @return a new instance of {@code BreakIterator} using the given locale.
-     * @throws NullPointerException if {@code where} is {@code null}.
      */
-    public static BreakIterator getSentenceInstance(Locale where) {
-        return new RuleBasedBreakIterator(NativeBreakIterator.getSentenceInstance(where));
+    public static BreakIterator getSentenceInstance(Locale locale) {
+        return new RuleBasedBreakIterator(NativeBreakIterator.getSentenceInstance(locale));
     }
 
     /**
@@ -336,14 +322,9 @@
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * word-breaks using the given locale.
-     *
-     * @param where
-     *            the given locale.
-     * @return a new instance of {@code BreakIterator} using the given locale.
-     * @throws NullPointerException if {@code where} is {@code null}.
      */
-    public static BreakIterator getWordInstance(Locale where) {
-        return new RuleBasedBreakIterator(NativeBreakIterator.getWordInstance(where));
+    public static BreakIterator getWordInstance(Locale locale) {
+        return new RuleBasedBreakIterator(NativeBreakIterator.getWordInstance(locale));
     }
 
     /**
diff --git a/luni/src/main/java/java/text/DecimalFormat.java b/luni/src/main/java/java/text/DecimalFormat.java
index fbbc172..dc70886 100644
--- a/luni/src/main/java/java/text/DecimalFormat.java
+++ b/luni/src/main/java/java/text/DecimalFormat.java
@@ -900,8 +900,9 @@
      */
     @Override
     public void setCurrency(Currency currency) {
-        ndf.setCurrency(Currency.getInstance(currency.getCurrencyCode()));
-        symbols.setCurrency(currency);
+        Currency instance = Currency.getInstance(currency.getCurrencyCode());
+        symbols.setCurrency(instance);
+        ndf.setCurrency(symbols.getCurrencySymbol(), currency.getCurrencyCode());
     }
 
     /**
diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java
index e8ecdde..11b5af1 100644
--- a/luni/src/main/java/java/util/Currency.java
+++ b/luni/src/main/java/java/util/Currency.java
@@ -35,7 +35,7 @@
 
     private Currency(String currencyCode) {
         this.currencyCode = currencyCode;
-        String symbol = ICU.getCurrencySymbol(Locale.US.toString(), currencyCode);
+        String symbol = ICU.getCurrencySymbol(Locale.US, currencyCode);
         if (symbol == null) {
             throw new IllegalArgumentException("Unsupported ISO 4217 currency code: " +
                     currencyCode);
@@ -123,7 +123,7 @@
      * @since 1.7
      */
     public String getDisplayName(Locale locale) {
-        return ICU.getCurrencyDisplayName(locale.toString(), currencyCode);
+        return ICU.getCurrencyDisplayName(locale, currencyCode);
     }
 
     /**
@@ -157,10 +157,6 @@
      * <p>If there is no locale-specific currency symbol, the ISO 4217 currency code is returned.
      */
     public String getSymbol(Locale locale) {
-        if (locale.getCountry().length() == 0) {
-            return currencyCode;
-        }
-
         // Check the locale first, in case the locale has the same currency.
         LocaleData localeData = LocaleData.get(locale);
         if (localeData.internationalCurrencySymbol.equals(currencyCode)) {
@@ -168,7 +164,7 @@
         }
 
         // Try ICU, and fall back to the currency code if ICU has nothing.
-        String symbol = ICU.getCurrencySymbol(locale.toString(), currencyCode);
+        String symbol = ICU.getCurrencySymbol(locale, currencyCode);
         return symbol != null ? symbol : currencyCode;
     }
 
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 163a627..a3eaf21 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -340,9 +340,13 @@
          * @throws IllformedLocaleException if the language was invalid.
          */
         public Builder setLanguage(String language) {
+            this.language = normalizeAndValidateLanguage(language);
+            return this;
+        }
+
+        private static String normalizeAndValidateLanguage(String language) {
             if (language == null || language.isEmpty()) {
-                this.language = "";
-                return this;
+                return "";
             }
 
             final String lowercaseLanguage = language.toLowerCase(Locale.ROOT);
@@ -350,8 +354,7 @@
                 throw new IllformedLocaleException("Invalid language: " + language);
             }
 
-            this.language = lowercaseLanguage;
-            return this;
+            return lowercaseLanguage;
         }
 
         /**
@@ -397,9 +400,13 @@
          * @throws IllformedLocaleException if {@code} region is invalid.
          */
         public Builder setRegion(String region) {
+            this.region = normalizeAndValidateRegion(region);
+            return this;
+        }
+
+        private static String normalizeAndValidateRegion(String region) {
             if (region == null || region.isEmpty()) {
-                this.region = "";
-                return this;
+                return "";
             }
 
             final String uppercaseRegion = region.toUpperCase(Locale.ROOT);
@@ -408,8 +415,7 @@
                 throw new IllformedLocaleException("Invalid region: " + region);
             }
 
-            this.region = uppercaseRegion;
-            return this;
+            return uppercaseRegion;
         }
 
         /**
@@ -432,9 +438,13 @@
          * @throws IllformedLocaleException if {@code} variant is invalid.
          */
         public Builder setVariant(String variant) {
+            this.variant = normalizeAndValidateVariant(variant);
+            return this;
+        }
+
+        private static String normalizeAndValidateVariant(String variant) {
             if (variant == null || variant.isEmpty()) {
-                this.variant = "";
-                return this;
+                return "";
             }
 
             // Note that unlike extensions, we canonicalize to lower case alphabets
@@ -461,8 +471,7 @@
             }
 
 
-            this.variant = normalizedVariant;
-            return this;
+            return normalizedVariant;
         }
 
         /**
@@ -766,14 +775,15 @@
             // because the RI allows this builder to reused.
             return new Locale(language, region, variant, script,
                     attributes, keywords, extensions,
-                    false /* from public constructor */);
+                    true /* has validated fields */);
         }
     }
 
     /**
      * Returns a locale for a given BCP-47 language tag. This method is more
      * lenient than {@link Builder#setLanguageTag}. For a given language tag, parsing
-     * will proceed upto the first malformed subtag. All subsequent tags are discarded.
+     * will proceed up to the first malformed subtag. All subsequent tags are discarded.
+     * Note that language tags use {@code -} rather than {@code _}, for example {@code en-US}.
      *
      * @throws NullPointerException if {@code languageTag} is {@code null}.
      *
@@ -793,10 +803,6 @@
     private transient String variantCode;
     private transient String scriptCode;
 
-    private transient String cachedToStringResult;
-    private transient String cachedLanguageTag;
-    private transient String cachedIcuLocaleId;
-
     /* Sorted, Unmodifiable */
     private transient Set<String> unicodeAttributes;
     /* Sorted, Unmodifiable */
@@ -805,13 +811,23 @@
     private transient Map<Character, String> extensions;
 
     /**
+     * Whether this instance was constructed from a builder. We can make
+     * stronger assumptions about the validity of Locale fields if this was
+     * constructed by a builder.
+     */
+    private transient final boolean hasValidatedFields;
+
+    private transient String cachedToStringResult;
+    private transient String cachedLanguageTag;
+    private transient String cachedIcuLocaleId;
+
+    /**
      * There's a circular dependency between toLowerCase/toUpperCase and
      * Locale.US. Work around this by avoiding these methods when constructing
      * the built-in locales.
-     *
-     * @param unused required for this constructor to have a unique signature
      */
-    private Locale(boolean unused, String lowerCaseLanguageCode, String upperCaseCountryCode) {
+    private Locale(boolean hasValidatedFields, String lowerCaseLanguageCode,
+            String upperCaseCountryCode) {
         this.languageCode = lowerCaseLanguageCode;
         this.countryCode = upperCaseCountryCode;
         this.variantCode = "";
@@ -820,6 +836,8 @@
         this.unicodeAttributes = Collections.EMPTY_SET;
         this.unicodeKeywords = Collections.EMPTY_MAP;
         this.extensions = Collections.EMPTY_MAP;
+
+        this.hasValidatedFields = hasValidatedFields;
     }
 
     /**
@@ -827,7 +845,7 @@
      */
     public Locale(String language) {
         this(language, "", "", "", Collections.EMPTY_SET, Collections.EMPTY_MAP,
-                Collections.EMPTY_MAP, true /* from public constructor */);
+                Collections.EMPTY_MAP, false /* has validated fields */);
     }
 
     /**
@@ -835,7 +853,7 @@
      */
     public Locale(String language, String country) {
         this(language, country, "", "", Collections.EMPTY_SET, Collections.EMPTY_MAP,
-                Collections.EMPTY_MAP, true /* from public constructor */);
+                Collections.EMPTY_MAP, false /* has validated fields */);
     }
 
     /**
@@ -847,14 +865,18 @@
             /* nonnull */ Set<String> unicodeAttributes,
             /* nonnull */ Map<String, String> unicodeKeywords,
             /* nonnull */ Map<Character, String> extensions,
-            boolean fromPublicConstructor) {
+            boolean hasValidatedFields) {
         if (language == null || country == null || variant == null) {
             throw new NullPointerException("language=" + language +
                     ",country=" + country +
                     ",variant=" + variant);
         }
 
-        if (fromPublicConstructor) {
+        if (hasValidatedFields) {
+            this.languageCode = adjustLanguageCode(language);
+            this.countryCode = country;
+            this.variantCode = variant;
+        } else {
             if (language.isEmpty() && country.isEmpty()) {
                 languageCode = "";
                 countryCode = "";
@@ -864,36 +886,31 @@
                 countryCode = country.toUpperCase(Locale.US);
                 variantCode = variant;
             }
-        } else {
-            this.languageCode = adjustLanguageCode(language);
-            this.countryCode = country;
-            this.variantCode = variant;
         }
 
         this.scriptCode = scriptCode;
 
-        if (fromPublicConstructor) {
-            this.unicodeAttributes = unicodeAttributes;
-            this.unicodeKeywords = unicodeKeywords;
-            this.extensions = extensions;
-        } else {
+        if (hasValidatedFields) {
             Set<String> attribsCopy = new TreeSet<String>(unicodeAttributes);
-            Map<String, String> keywordsCopy = new TreeMap<String, String>(
-                    unicodeKeywords);
-            Map<Character, String> extensionsCopy = new TreeMap<Character, String>(
-                    extensions);
+            Map<String, String> keywordsCopy = new TreeMap<String, String>(unicodeKeywords);
+            Map<Character, String> extensionsCopy = new TreeMap<Character, String>(extensions);
 
             // We need to transform the list of attributes & keywords set on the
             // builder to a unicode locale extension. i.e, if we have any keywords
             // or attributes set, Locale#getExtension('u') should return a well
             // formed extension.
-            addUnicodeExtensionToExtensionsMap(attribsCopy, keywordsCopy,
-                    extensionsCopy);
+            addUnicodeExtensionToExtensionsMap(attribsCopy, keywordsCopy, extensionsCopy);
 
             this.unicodeAttributes = Collections.unmodifiableSet(attribsCopy);
             this.unicodeKeywords = Collections.unmodifiableMap(keywordsCopy);
             this.extensions = Collections.unmodifiableMap(extensionsCopy);
+        } else {
+            this.unicodeAttributes = unicodeAttributes;
+            this.unicodeKeywords = unicodeKeywords;
+            this.extensions = extensions;
         }
+
+        this.hasValidatedFields = hasValidatedFields;
     }
 
     /**
@@ -903,7 +920,7 @@
     public Locale(String language, String country, String variant) {
         this(language, country, variant, "", Collections.EMPTY_SET,
                 Collections.EMPTY_MAP, Collections.EMPTY_MAP,
-                true /* from public constructor */);
+                false /* has validated fields */);
     }
 
     @Override public Object clone() {
@@ -987,10 +1004,16 @@
         if (countryCode.isEmpty()) {
             return "";
         }
-        String result = ICU.getDisplayCountryNative(getIcuLocaleId(), locale.getIcuLocaleId());
+
+        try {
+            Builder.normalizeAndValidateRegion(countryCode);
+        } catch (IllformedLocaleException ex) {
+            return countryCode;
+        }
+
+        String result = ICU.getDisplayCountry(this, locale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = ICU.getDisplayCountryNative(getIcuLocaleId(),
-                    Locale.getDefault().getIcuLocaleId());
+            result = ICU.getDisplayCountry(this, Locale.getDefault());
         }
         return result;
     }
@@ -1011,19 +1034,24 @@
             return "";
         }
 
-        // http://b/8049507 --- frameworks/base should use fil_PH instead of tl_PH.
-        // Until then, we're stuck covering their tracks, making it look like they're
-        // using "fil" when they're not.
-        String localeString = toString();
-        if (languageCode.equals("tl")) {
-            localeString = toNewString("fil", countryCode, variantCode, scriptCode,
-                    extensions);
+        // Hacks for backward compatibility.
+        //
+        // Our language tag will contain "und" if the languageCode is invalid
+        // or missing. ICU will then return "langue indéterminée" or the equivalent
+        // display language for the indeterminate language code.
+        //
+        // Sigh... ugh... and what not.
+        try {
+            Builder.normalizeAndValidateLanguage(languageCode);
+        } catch (IllformedLocaleException ex) {
+            return languageCode;
         }
 
-        String result = ICU.getDisplayLanguageNative(localeString, locale.getIcuLocaleId());
+        // TODO: We need a new hack or a complete fix for http://b/8049507 --- We would
+        // cover the frameworks' tracks when they were using "tl" instead of "fil".
+        String result = ICU.getDisplayLanguage(this, locale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = ICU.getDisplayLanguageNative(localeString,
-                    Locale.getDefault().getIcuLocaleId());
+            result = ICU.getDisplayLanguage(this, Locale.getDefault());
         }
         return result;
     }
@@ -1108,13 +1136,27 @@
      * returned.
      */
     public String getDisplayVariant(Locale locale) {
-        if (variantCode.length() == 0) {
+        if (variantCode.isEmpty()) {
+            return "";
+        }
+
+        try {
+            Builder.normalizeAndValidateVariant(variantCode);
+        } catch (IllformedLocaleException ilfe) {
             return variantCode;
         }
-        String result = ICU.getDisplayVariantNative(getIcuLocaleId(), locale.getIcuLocaleId());
+
+        String result = ICU.getDisplayVariant(this, locale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = ICU.getDisplayVariantNative(getIcuLocaleId(),
-                    Locale.getDefault().getIcuLocaleId());
+            result = ICU.getDisplayVariant(this, Locale.getDefault());
+        }
+
+        // The "old style" locale constructors allow us to pass in variants that aren't
+        // valid BCP-47 variant subtags. When that happens, toLanguageTag will not emit
+        // them. Note that we know variantCode.length() > 0 due to the isEmpty check at
+        // the beginning of this function.
+        if (result.isEmpty()) {
+            return variantCode;
         }
         return result;
     }
@@ -1125,7 +1167,10 @@
      * @throws MissingResourceException if there's no 3-letter country code for this locale.
      */
     public String getISO3Country() {
-        String code = ICU.getISO3CountryNative(getIcuLocaleId());
+        // The results of getISO3Country do not depend on the languageCode,
+        // so we pass an arbitrarily selected language code here. This guards
+        // against errors caused by malformed or invalid language codes.
+        String code = ICU.getISO3Country("en-" + countryCode);
         if (!countryCode.isEmpty() && code.isEmpty()) {
             throw new MissingResourceException("No 3-letter country code for locale: " + this, "FormatData_" + this, "ShortCountry");
         }
@@ -1138,7 +1183,16 @@
      * @throws MissingResourceException if there's no 3-letter language code for this locale.
      */
     public String getISO3Language() {
-        String code = ICU.getISO3LanguageNative(getIcuLocaleId());
+        // For backward compatibility, we must return "" for an empty language
+        // code and not "und" which is the accurate ISO-639-3 code for an
+        // undetermined language.
+        if (languageCode.isEmpty()) {
+            return "";
+        }
+
+        // The results of getISO3Language do not depend on the country code
+        // or any of the other locale fields, so we pass just the language here.
+        String code = ICU.getISO3Language(languageCode);
         if (!languageCode.isEmpty() && code.isEmpty()) {
             throw new MissingResourceException("No 3-letter language code for locale: " + this, "FormatData_" + this, "ShortLanguage");
         }
@@ -1214,10 +1268,9 @@
             return "";
         }
 
-        String result = ICU.getDisplayScriptNative(getIcuLocaleId(), locale.getIcuLocaleId());
+        String result = ICU.getDisplayScript(this, locale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = ICU.getDisplayScriptNative(getIcuLocaleId(),
-                    Locale.getDefault().getIcuLocaleId());
+            result = ICU.getDisplayScript(this, Locale.getDefault());
         }
 
         return result;
@@ -1238,7 +1291,7 @@
      * where they will appear after a subtag whose value is {@code "lvariant"}.
      *
      * It's also important to note that the BCP-47 tag is well formed in the sense
-     * that it is unambiguously parsable into its specified components. We do not
+     * that it is unambiguously parseable into its specified components. We do not
      * require that any of the components are registered with the applicable registries.
      * For example, we do not require scripts to be a registered ISO 15924 scripts or
      * languages to appear in the ISO-639-2 code list.
@@ -1248,13 +1301,212 @@
      */
     public String toLanguageTag() {
         if (cachedLanguageTag == null) {
-            cachedLanguageTag = ICU.toLanguageTag(this);
+            cachedLanguageTag = makeLanguageTag();
         }
 
         return cachedLanguageTag;
     }
 
     /**
+     * Constructs a valid BCP-47 language tag from locale fields. Additional validation
+     * is required when this Locale was not constructed using a Builder and variants
+     * set this way are treated specially.
+     *
+     * In both cases, we convert empty language tags to "und", omit invalid country tags
+     * and perform a special case conversion of "no-NO-NY" to "nn-NO".
+     */
+    private String makeLanguageTag() {
+        // We only need to revalidate the language, country and variant because
+        // the rest of the fields can only be set via the builder which validates
+        // them anyway.
+        String language = "";
+        String region = "";
+        String variant = "";
+        String illFormedVariantSubtags = "";
+
+        if (hasValidatedFields) {
+            language = languageCode;
+            region = countryCode;
+            // Note that we are required to normalize hyphens to underscores
+            // in the builder, but we must use hyphens in the BCP-47 language tag.
+            variant = variantCode.replace('_', '-');
+        } else {
+            try {
+                language = Builder.normalizeAndValidateLanguage(languageCode);
+            } catch (IllformedLocaleException ilfe) {
+                // Ignored, continue processing with "".
+            }
+
+            try {
+                region = Builder.normalizeAndValidateRegion(countryCode);
+            } catch (IllformedLocaleException ilfe) {
+                // Ignored, continue processing with "".
+            }
+
+            try {
+                variant = Builder.normalizeAndValidateVariant(variantCode);
+            } catch (IllformedLocaleException ilfe) {
+                // If our variant is ill formed, we must attempt to split it into
+                // its constituent subtags and preserve the well formed bits and
+                // move the rest to the private use extension (if they're well
+                // formed extension subtags).
+                String split[] = splitIllformedVariant(variantCode);
+
+                variant = split[0];
+                illFormedVariantSubtags = split[1];
+            }
+        }
+
+        if (language.isEmpty()) {
+            language = "und";
+        }
+
+        if ("no".equals(language) && "NO".equals(region) && "NY".equals(variant)) {
+            language = "nn";
+            region = "NO";
+            variant = "";
+        }
+
+        final StringBuilder sb = new StringBuilder(16);
+        sb.append(language);
+
+        if (!scriptCode.isEmpty()) {
+            sb.append('-');
+            sb.append(scriptCode);
+        }
+
+        if (!region.isEmpty()) {
+            sb.append('-');
+            sb.append(region);
+        }
+
+        if (!variant.isEmpty()) {
+            sb.append('-');
+            sb.append(variant);
+        }
+
+        // Extensions (optional, omitted if empty). Note that we don't
+        // emit the private use extension here, but add it in the end.
+        for (Map.Entry<Character, String> extension : extensions.entrySet()) {
+            if (!extension.getKey().equals('x')) {
+                sb.append('-').append(extension.getKey());
+                sb.append('-').append(extension.getValue());
+            }
+        }
+
+        // The private use extension comes right at the very end.
+        final String privateUse = extensions.get('x');
+        if (privateUse != null) {
+            sb.append("-x-");
+            sb.append(privateUse);
+        }
+
+        // If we have any ill-formed variant subtags, we append them to the
+        // private use extension (or add a private use extension if one doesn't
+        // exist).
+        if (!illFormedVariantSubtags.isEmpty()) {
+            if (privateUse == null) {
+                sb.append("-x-lvariant-");
+            } else {
+                sb.append('-');
+            }
+            sb.append(illFormedVariantSubtags);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Splits ill formed variants into a set of valid variant subtags (which
+     * can be used directly in language tag construction) and a set of invalid
+     * variant subtags (which can be appended to the private use extension),
+     * provided that each subtag is a valid private use extension subtag.
+     *
+     * This method returns a two element String array. The first element is a string
+     * containing the concatenation of valid variant subtags which can be appended
+     * to a BCP-47 tag directly and the second containing the concatenation of
+     * invalid variant subtags which can be appended to the private use extension
+     * directly.
+     *
+     * This method assumes that {@code variant} contains at least one ill formed
+     * variant subtag.
+     */
+    private static String[] splitIllformedVariant(String variant) {
+        final String normalizedVariant = variant.replace('_', '-');
+        final String[] subTags = normalizedVariant.split("-");
+
+        final String[] split = new String[] { "", "" };
+
+        // First go through the list of variant subtags and check if they're
+        // valid private use extension subtags. If they're not, we will omit
+        // the first such subtag and all subtags after.
+        //
+        // NOTE: |firstInvalidSubtag| is the index of the first variant
+        // subtag we decide to omit altogether, whereas |firstIllformedSubtag| is the
+        // index of the first subtag we decide to append to the private use extension.
+        //
+        // In other words:
+        // [0, firstIllformedSubtag) => expressed as variant subtags.
+        // [firstIllformedSubtag, firstInvalidSubtag) => expressed as private use
+        // extension subtags.
+        // [firstInvalidSubtag, subTags.length) => omitted.
+        int firstInvalidSubtag = subTags.length;
+        for (int i = 0; i < subTags.length; ++i) {
+            if (!isValidBcp47Alphanum(subTags[i], 1, 8)) {
+                firstInvalidSubtag = i;
+                break;
+            }
+        }
+
+        if (firstInvalidSubtag == 0) {
+            return split;
+        }
+
+        // We now consider each subtag that could potentially be appended to
+        // the private use extension and check if it's valid.
+        int firstIllformedSubtag = firstInvalidSubtag;
+        for (int i = 0; i < firstInvalidSubtag; ++i) {
+            final String subTag = subTags[i];
+            // The BCP-47 spec states that :
+            // - Subtags can be between [5, 8] alphanumeric chars in length.
+            // - Subtags that start with a number are allowed to be 4 chars in length.
+            if (subTag.length() >= 5 && subTag.length() <= 8) {
+                if (!isAsciiAlphaNum(subTag)) {
+                    firstIllformedSubtag = i;
+                }
+            } else if (subTag.length() == 4) {
+                final char firstChar = subTag.charAt(0);
+                if (!(firstChar >= '0' && firstChar <= '9') || !isAsciiAlphaNum(subTag)) {
+                    firstIllformedSubtag = i;
+                }
+            } else {
+                firstIllformedSubtag = i;
+            }
+        }
+
+        split[0] = concatenateRange(subTags, 0, firstIllformedSubtag);
+        split[1] = concatenateRange(subTags, firstIllformedSubtag, firstInvalidSubtag);
+
+        return split;
+    }
+
+    /**
+     * Builds a string by concatenating array elements within the range [start, end).
+     * The supplied range is assumed to be valid and no checks are performed.
+     */
+    private static String concatenateRange(String[] array, int start, int end) {
+        StringBuilder builder = new StringBuilder(32);
+        for (int i = start; i < end; ++i) {
+            if (i != 0) {
+                builder.append('-');
+            }
+            builder.append(array[i]);
+        }
+
+        return builder.toString();
+    }
+
+    /**
      * Returns the set of BCP-47 extensions this locale contains.
      *
      * See <a href="https://tools.ietf.org/html/bcp47#section-2.1">
@@ -1340,8 +1592,9 @@
         if (locale == null) {
             throw new NullPointerException("locale == null");
         }
+        String languageTag = locale.toLanguageTag();
         defaultLocale = locale;
-        ICU.setDefaultLocale(ICU.localeIdFromLocale(locale));
+        ICU.setDefaultLocale(languageTag);
     }
 
     /**
@@ -1359,20 +1612,12 @@
     public final String toString() {
         String result = cachedToStringResult;
         if (result == null) {
-            result = cachedToStringResult = toNewString(languageCode, countryCode,
-                    variantCode, scriptCode, extensions);
+            result = cachedToStringResult = toNewString(languageCode, countryCode, variantCode,
+                                                        scriptCode, extensions);
         }
         return result;
     }
 
-    private String getIcuLocaleId() {
-        if (cachedIcuLocaleId == null) {
-            cachedIcuLocaleId = ICU.localeIdFromLocale(this);
-        }
-
-        return cachedIcuLocaleId;
-    }
-
     private static String toNewString(String languageCode, String countryCode,
             String variantCode, String scriptCode, Map<Character, String> extensions) {
         // The string form of a locale that only has a variant is the empty string.
@@ -1387,8 +1632,7 @@
         StringBuilder result = new StringBuilder(11);
         result.append(languageCode);
 
-        final boolean hasScriptOrExtensions = !scriptCode.isEmpty() ||
-                !extensions.isEmpty();
+        final boolean hasScriptOrExtensions = !scriptCode.isEmpty() || !extensions.isEmpty();
 
         if (!countryCode.isEmpty() || !variantCode.isEmpty() || hasScriptOrExtensions) {
             result.append('_');
@@ -1594,8 +1838,7 @@
         return true;
     }
 
-    private static boolean isValidBcp47Alpha(String string,
-            int lowerBound, int upperBound) {
+    private static boolean isValidBcp47Alpha(String string, int lowerBound, int upperBound) {
         final int length = string.length();
         if (length < lowerBound || length > upperBound) {
             return false;
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index f60f427..33c899e 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -70,10 +70,6 @@
     return localeFromIcuLocaleId(icuLocaleId);
   }
 
-  public static String toLanguageTag(Locale locale) {
-    return languageTagForLocale(localeIdFromLocale(locale));
-  }
-
   private static final int IDX_LANGUAGE = 0;
   private static final int IDX_SCRIPT = 1;
   private static final int IDX_REGION = 2;
@@ -239,71 +235,8 @@
 
     return new Locale(outputArray[IDX_LANGUAGE], outputArray[IDX_REGION],
         outputArray[IDX_VARIANT], outputArray[IDX_SCRIPT],
-        unicodeAttributeSet, unicodeKeywordsMap, extensionsMap, false);
-  }
-
-  /**
-   * Builds an ICU locale ID from the given locale. The format is very
-   * straightforward. It is a series of subtags in BCP 47 order
-   * {@code lang[_script][_country][_variant]} followed by the keyword
-   * separator {@code @} followed by a list of keywords. Each keyword is
-   * a key value pair, and appear in the form {@code k1=v1;k2=v2;...}.
-   *
-   * In this use case, each key is an extension identifier, and each value
-   * is the value of the extension.
-   */
-  public static String localeIdFromLocale(Locale l) {
-      StringBuilder b = new StringBuilder(16);
-      b.append(l.getLanguage());
-
-      final boolean hasScript = !l.getScript().isEmpty();
-      final boolean hasCountry = !l.getCountry().isEmpty();
-      final boolean hasVariant = !l.getVariant().isEmpty();
-
-      if (hasScript || hasCountry || hasVariant) {
-          b.append('_');
-          if (hasScript) {
-              b.append(l.getScript());
-              if (hasCountry || hasVariant) {
-                  b.append('_');
-              }
-          }
-
-          if (hasCountry) {
-              b.append(l.getCountry());
-              if (hasVariant) {
-                  b.append('_');
-              }
-          }
-
-          b.append(l.getVariant());
-      }
-
-      if (!l.getExtensionKeys().isEmpty()) {
-        b.append('@');
-        // The private use extension ('x') must show up last in the list
-        // so we cache its value here and append it right at the end.
-        String privateUseExtensionValue = null;
-        for (char c : l.getExtensionKeys()) {
-          if (c == Locale.PRIVATE_USE_EXTENSION) {
-            privateUseExtensionValue = l.getExtension(Locale.PRIVATE_USE_EXTENSION);
-          } else {
-            b.append(c);
-            b.append('=');
-            b.append(l.getExtension(c));
-            b.append(';');
-          }
-        }
-
-        if (privateUseExtensionValue != null) {
-          b.append(Locale.PRIVATE_USE_EXTENSION);
-          b.append('=');
-          b.append(privateUseExtensionValue);
-          b.append(';');
-        }
-      }
-
-      return b.toString();
+        unicodeAttributeSet, unicodeKeywordsMap, extensionsMap,
+        true /* has validated fields */);
   }
 
   public static Locale[] localesFromStrings(String[] localeNames) {
@@ -352,19 +285,20 @@
     return localesFromStrings(getAvailableNumberFormatLocalesNative());
   }
 
-  public static String getBestDateTimePattern(String skeleton, String localeName) {
-    String key = skeleton + "\t" + localeName;
+  public static String getBestDateTimePattern(String skeleton, Locale locale) {
+    String languageTag = locale.toLanguageTag();
+    String key = skeleton + "\t" + languageTag;
     synchronized (CACHED_PATTERNS) {
       String pattern = CACHED_PATTERNS.get(key);
       if (pattern == null) {
-        pattern = getBestDateTimePatternNative(skeleton, localeName);
+        pattern = getBestDateTimePatternNative(skeleton, languageTag);
         CACHED_PATTERNS.put(key, pattern);
       }
       return pattern;
     }
   }
 
-  private static native String getBestDateTimePatternNative(String skeleton, String localeName);
+  private static native String getBestDateTimePatternNative(String skeleton, String languageTag);
 
   public static char[] getDateFormatOrder(String pattern) {
     char[] result = new char[3];
@@ -424,8 +358,17 @@
 
   // --- Case mapping.
 
-  public static native String toLowerCase(String s, String localeName);
-  public static native String toUpperCase(String s, String localeName);
+  public static String toLowerCase(String s, Locale locale) {
+    return toLowerCase(s, locale.toLanguageTag());
+  }
+
+  private static native String toLowerCase(String s, String languageTag);
+
+  public static String toUpperCase(String s, Locale locale) {
+    return toUpperCase(s, locale.toLanguageTag());
+  }
+
+  private static native String toUpperCase(String s, String languageTag);
 
   // --- Errors.
 
@@ -451,18 +394,49 @@
 
   public static native String[] getAvailableCurrencyCodes();
   public static native String getCurrencyCode(String countryCode);
-  public static native String getCurrencyDisplayName(String locale, String currencyCode);
+
+  public static String getCurrencyDisplayName(Locale locale, String currencyCode) {
+    return getCurrencyDisplayName(locale.toLanguageTag(), currencyCode);
+  }
+
+  private static native String getCurrencyDisplayName(String languageTag, String currencyCode);
+
   public static native int getCurrencyFractionDigits(String currencyCode);
   public static native int getCurrencyNumericCode(String currencyCode);
-  public static native String getCurrencySymbol(String locale, String currencyCode);
 
-  public static native String getDisplayCountryNative(String countryCode, String locale);
-  public static native String getDisplayLanguageNative(String languageCode, String locale);
-  public static native String getDisplayVariantNative(String variantCode, String locale);
-  public static native String getDisplayScriptNative(String variantCode, String locale);
+  public static String getCurrencySymbol(Locale locale, String currencyCode) {
+    return getCurrencySymbol(locale.toLanguageTag(), currencyCode);
+  }
 
-  public static native String getISO3CountryNative(String locale);
-  public static native String getISO3LanguageNative(String locale);
+  private static native String getCurrencySymbol(String languageTag, String currencyCode);
+
+  public static String getDisplayCountry(Locale targetLocale, Locale locale) {
+    return getDisplayCountryNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+  }
+
+  private static native String getDisplayCountryNative(String targetLanguageTag, String languageTag);
+
+  public static String getDisplayLanguage(Locale targetLocale, Locale locale) {
+    return getDisplayLanguageNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+  }
+
+  private static native String getDisplayLanguageNative(String targetLanguageTag, String languageTag);
+
+  public static String getDisplayVariant(Locale targetLocale, Locale locale) {
+    return getDisplayVariantNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+  }
+
+  private static native String getDisplayVariantNative(String targetLanguageTag, String languageTag);
+
+  public static String getDisplayScript(Locale targetLocale, Locale locale) {
+    return getDisplayScriptNative(targetLocale.toLanguageTag(), locale.toLanguageTag());
+  }
+
+  private static native String getDisplayScriptNative(String targetLanguageTag, String languageTag);
+
+  public static native String getISO3Country(String languageTag);
+
+  public static native String getISO3Language(String languageTag);
 
   public static native String addLikelySubtags(String locale);
   public static native String getScript(String locale);
@@ -471,10 +445,16 @@
   private static native String[] getISOCountriesNative();
 
   private static native String localeForLanguageTag(String languageTag, boolean strict);
-  public static native String languageTagForLocale(String locale);
 
   static native boolean initLocaleDataNative(String locale, LocaleData result);
 
-  public static native void setDefaultLocale(String locale);
+  /**
+   * Takes a BCP-47 language tag (Locale.toLanguageTag()). e.g. en-US, not en_US
+   */
+  public static native void setDefaultLocale(String languageTag);
+
+  /**
+   * Returns a locale name, not a BCP-47 language tag. e.g. en_US not en-US.
+   */
   public static native String getDefaultLocale();
 }
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index 49228b3..845ba32 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -176,8 +176,8 @@
         }
 
         // Get the "h:mm a" and "HH:mm" 12- and 24-hour time format strings.
-        localeData.timeFormat12 = ICU.getBestDateTimePattern("hm", locale.toString());
-        localeData.timeFormat24 = ICU.getBestDateTimePattern("Hm", locale.toString());
+        localeData.timeFormat12 = ICU.getBestDateTimePattern("hm", locale);
+        localeData.timeFormat24 = ICU.getBestDateTimePattern("Hm", locale);
 
         // Fix up a couple of patterns.
         if (localeData.fullTimeFormat != null) {
diff --git a/luni/src/main/java/libcore/icu/NativeBreakIterator.java b/luni/src/main/java/libcore/icu/NativeBreakIterator.java
index 7168d96..992aac2 100644
--- a/luni/src/main/java/libcore/icu/NativeBreakIterator.java
+++ b/luni/src/main/java/libcore/icu/NativeBreakIterator.java
@@ -138,23 +138,23 @@
     }
 
     public int preceding(int offset) {
-      return precedingImpl(this.address, this.string, offset);
+        return precedingImpl(this.address, this.string, offset);
     }
 
-    public static NativeBreakIterator getCharacterInstance(Locale where) {
-        return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE);
+    public static NativeBreakIterator getCharacterInstance(Locale locale) {
+        return new NativeBreakIterator(getCharacterInstanceImpl(locale.toLanguageTag()), BI_CHAR_INSTANCE);
     }
 
-    public static NativeBreakIterator getLineInstance(Locale where) {
-        return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE);
+    public static NativeBreakIterator getLineInstance(Locale locale) {
+        return new NativeBreakIterator(getLineInstanceImpl(locale.toLanguageTag()), BI_LINE_INSTANCE);
     }
 
-    public static NativeBreakIterator getSentenceInstance(Locale where) {
-        return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE);
+    public static NativeBreakIterator getSentenceInstance(Locale locale) {
+        return new NativeBreakIterator(getSentenceInstanceImpl(locale.toLanguageTag()), BI_SENT_INSTANCE);
     }
 
-    public static NativeBreakIterator getWordInstance(Locale where) {
-        return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE);
+    public static NativeBreakIterator getWordInstance(Locale locale) {
+        return new NativeBreakIterator(getWordInstanceImpl(locale.toLanguageTag()), BI_WORD_INSTANCE);
     }
 
     private static native long getCharacterInstanceImpl(String locale);
diff --git a/luni/src/main/java/libcore/icu/NativeCollation.java b/luni/src/main/java/libcore/icu/NativeCollation.java
index 64e0278..b4b4f46 100644
--- a/luni/src/main/java/libcore/icu/NativeCollation.java
+++ b/luni/src/main/java/libcore/icu/NativeCollation.java
@@ -10,6 +10,8 @@
 
 package libcore.icu;
 
+import java.util.Locale;
+
 /**
 * Package static class for declaring all native methods for collation use.
 * @author syn wee quek
@@ -26,7 +28,10 @@
     public static native long getCollationElementIterator(long address, String source);
     public static native String getRules(long address);
     public static native byte[] getSortKey(long address, String source);
-    public static native long openCollator(String locale);
+    public static long openCollator(Locale locale) {
+      return openCollator(locale.toLanguageTag());
+    }
+    private static native long openCollator(String languageTag);
     public static native long openCollatorFromRules(String rules, int normalizationMode, int collationStrength);
     public static native long safeClone(long address);
     public static native void setAttribute(long address, int type, int value);
diff --git a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
index f512002..fd179c1 100644
--- a/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
+++ b/luni/src/main/java/libcore/icu/NativeDecimalFormat.java
@@ -475,9 +475,9 @@
         setAttribute(this.address, UNUM_DECIMAL_ALWAYS_SHOWN, i);
     }
 
-    public void setCurrency(Currency currency) {
-        setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currency.getSymbol());
-        setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currency.getCurrencyCode());
+    public void setCurrency(String currencySymbol, String currencyCode) {
+        setSymbol(this.address, UNUM_CURRENCY_SYMBOL, currencySymbol);
+        setSymbol(this.address, UNUM_INTL_CURRENCY_SYMBOL, currencyCode);
     }
 
     public void setGroupingSize(int value) {
diff --git a/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java b/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
index 3ea942d..b23013b 100644
--- a/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
+++ b/luni/src/main/java/libcore/icu/RuleBasedCollatorICU.java
@@ -52,7 +52,7 @@
     }
 
     public RuleBasedCollatorICU(Locale locale) {
-        address = NativeCollation.openCollator(locale.toString());
+        address = NativeCollation.openCollator(locale);
     }
 
     private RuleBasedCollatorICU(long address) {
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp
index c6f3950..7ce2168 100644
--- a/luni/src/main/native/IcuUtilities.cpp
+++ b/luni/src/main/native/IcuUtilities.cpp
@@ -28,10 +28,6 @@
 #include "unicode/uloc.h"
 #include "unicode/ustring.h"
 
-Locale getLocale(JNIEnv* env, jstring localeName) {
-  return Locale::createFromName(ScopedUtfChars(env, localeName).c_str());
-}
-
 jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration* se) {
   if (maybeThrowIcuException(env, provider, status)) {
     return NULL;
diff --git a/luni/src/main/native/IcuUtilities.h b/luni/src/main/native/IcuUtilities.h
index ffcfcda..737379e 100644
--- a/luni/src/main/native/IcuUtilities.h
+++ b/luni/src/main/native/IcuUtilities.h
@@ -23,9 +23,7 @@
 #include "jni.h"
 #include "ustrenum.h" // For UStringEnumeration.
 #include "unicode/utypes.h" // For UErrorCode.
-#include "unicode/locid.h" // For Locale.
 
-extern Locale getLocale(JNIEnv* env, jstring localeName);
 extern jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration*);
 bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error);
 
diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h
index 60b7062..fb60ed4 100644
--- a/luni/src/main/native/Portability.h
+++ b/luni/src/main/native/Portability.h
@@ -64,7 +64,6 @@
 // For statfs(3).
 #include <sys/param.h>
 #include <sys/mount.h>
-#define f_frsize f_bsize // TODO: close enough?
 
 #else
 
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index cc3054a..87ebc21 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -30,15 +30,19 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#ifndef __APPLE__
 #include <sys/prctl.h>
+#endif
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
 // After the others because these are not necessarily self-contained in glibc.
+#ifndef __APPLE__
 #include <linux/if_addr.h>
 #include <linux/rtnetlink.h>
+#endif
 
 #include <net/if.h> // After <sys/socket.h> to work around a Mac header file bug.
 
@@ -229,14 +233,30 @@
 #if defined(IFA_F_DADFAILED)
     initConstant(env, c, "IFA_F_DADFAILED", IFA_F_DADFAILED);
 #endif
+#if defined(IFA_F_DEPRECATED)
     initConstant(env, c, "IFA_F_DEPRECATED", IFA_F_DEPRECATED);
+#endif
+#if defined(IFA_F_HOMEADDRESS)
     initConstant(env, c, "IFA_F_HOMEADDRESS", IFA_F_HOMEADDRESS);
+#endif
+#if defined(IFA_F_NODAD)
     initConstant(env, c, "IFA_F_NODAD", IFA_F_NODAD);
+#endif
+#if defined(IFA_F_OPTIMISTIC)
     initConstant(env, c, "IFA_F_OPTIMISTIC", IFA_F_OPTIMISTIC);
+#endif
+#if defined(IFA_F_PERMANENT)
     initConstant(env, c, "IFA_F_PERMANENT", IFA_F_PERMANENT);
+#endif
+#if defined(IFA_F_SECONDARY)
     initConstant(env, c, "IFA_F_SECONDARY", IFA_F_SECONDARY);
+#endif
+#if defined(IFA_F_TEMPORARY)
     initConstant(env, c, "IFA_F_TEMPORARY", IFA_F_TEMPORARY);
+#endif
+#if defined(IFA_F_TENTATIVE)
     initConstant(env, c, "IFA_F_TENTATIVE", IFA_F_TENTATIVE);
+#endif
     initConstant(env, c, "IFF_ALLMULTI", IFF_ALLMULTI);
 #if defined(IFF_AUTOMEDIA)
     initConstant(env, c, "IFF_AUTOMEDIA", IFF_AUTOMEDIA);
@@ -370,11 +390,17 @@
     initConstant(env, c, "PROT_READ", PROT_READ);
     initConstant(env, c, "PROT_WRITE", PROT_WRITE);
     initConstant(env, c, "R_OK", R_OK);
+// NOTE: The RT_* constants are not preprocessor defines, they're enum
+// members. The best we can do (barring UAPI / kernel version checks) is
+// to hope they exist on all host linuxes we're building on. These
+// constants have been around since 2.6.35 at least, so we should be ok.
+#if !defined(__APPLE__)
     initConstant(env, c, "RT_SCOPE_HOST", RT_SCOPE_HOST);
     initConstant(env, c, "RT_SCOPE_LINK", RT_SCOPE_LINK);
     initConstant(env, c, "RT_SCOPE_NOWHERE", RT_SCOPE_NOWHERE);
     initConstant(env, c, "RT_SCOPE_SITE", RT_SCOPE_SITE);
     initConstant(env, c, "RT_SCOPE_UNIVERSE", RT_SCOPE_UNIVERSE);
+#endif
     initConstant(env, c, "SEEK_CUR", SEEK_CUR);
     initConstant(env, c, "SEEK_END", SEEK_END);
     initConstant(env, c, "SEEK_SET", SEEK_SET);
@@ -441,8 +467,12 @@
     initConstant(env, c, "SO_KEEPALIVE", SO_KEEPALIVE);
     initConstant(env, c, "SO_LINGER", SO_LINGER);
     initConstant(env, c, "SO_OOBINLINE", SO_OOBINLINE);
+#if defined(SO_PASSCRED)
     initConstant(env, c, "SO_PASSCRED", SO_PASSCRED);
+#endif
+#if defined(SO_PEERCRED)
     initConstant(env, c, "SO_PEERCRED", SO_PEERCRED);
+#endif
     initConstant(env, c, "SO_RCVBUF", SO_RCVBUF);
     initConstant(env, c, "SO_RCVLOWAT", SO_RCVLOWAT);
     initConstant(env, c, "SO_RCVTIMEO", SO_RCVTIMEO);
diff --git a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
index bb05193..e0638bd 100644
--- a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
+++ b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
@@ -20,6 +20,7 @@
 #include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JniException.h"
+#include "ScopedIcuLocale.h"
 #include "ScopedJavaUnicodeString.h"
 #include "unicode/alphaindex.h"
 #include "unicode/uniset.h"
@@ -28,9 +29,13 @@
   return reinterpret_cast<AlphabeticIndex*>(static_cast<uintptr_t>(peer));
 }
 
-static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocaleName) {
   UErrorCode status = U_ZERO_ERROR;
-  AlphabeticIndex* ai = new AlphabeticIndex(getLocale(env, javaLocale), status);
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return 0;
+  }
+  AlphabeticIndex* ai = new AlphabeticIndex(icuLocale.locale(), status);
   if (maybeThrowIcuException(env, "AlphabeticIndex", status)) {
     return 0;
   }
@@ -53,10 +58,14 @@
   maybeThrowIcuException(env, "AlphabeticIndex::setMaxLabelCount", status);
 }
 
-static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocale) {
+static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocaleName) {
   AlphabeticIndex* ai = fromPeer(peer);
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return;
+  }
   UErrorCode status = U_ZERO_ERROR;
-  ai->addLabels(getLocale(env, javaLocale), status);
+  ai->addLabels(icuLocale.locale(), status);
   maybeThrowIcuException(env, "AlphabeticIndex::addLabels", status);
 }
 
diff --git a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp b/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
index 72bc631..a3258c1 100644
--- a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
+++ b/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp
@@ -18,13 +18,17 @@
 
 #include "IcuUtilities.h"
 #include "JniConstants.h"
+#include "ScopedIcuLocale.h"
 #include "ScopedJavaUnicodeString.h"
 #include "UniquePtr.h"
 #include "cutils/log.h"
 #include "unicode/dtitvfmt.h"
 
 static jlong DateIntervalFormat_createDateIntervalFormat(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName, jstring javaTzName) {
-  Locale locale = getLocale(env, javaLocaleName);
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return 0;
+  }
 
   ScopedJavaUnicodeString skeletonHolder(env, javaSkeleton);
   if (!skeletonHolder.valid()) {
@@ -32,7 +36,7 @@
   }
 
   UErrorCode status = U_ZERO_ERROR;
-  DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), locale, status));
+  DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), icuLocale.locale(), status));
   if (maybeThrowIcuException(env, "DateIntervalFormat::createInstance", status)) {
     return 0;
   }
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index cc51722..163d19c 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -21,6 +21,7 @@
 #include "JniConstants.h"
 #include "JniException.h"
 #include "ScopedFd.h"
+#include "ScopedIcuLocale.h"
 #include "ScopedJavaUnicodeString.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
@@ -96,30 +97,30 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedResourceBundle);
 };
 
-static jstring ICU_addLikelySubtags(JNIEnv* env, jclass, jstring javaLocale) {
+static jstring ICU_addLikelySubtags(JNIEnv* env, jclass, jstring javaLocaleName) {
     UErrorCode status = U_ZERO_ERROR;
-    ScopedUtfChars localeID(env, javaLocale);
+    ScopedUtfChars localeID(env, javaLocaleName);
     char maximizedLocaleID[ULOC_FULLNAME_CAPACITY];
     uloc_addLikelySubtags(localeID.c_str(), maximizedLocaleID, sizeof(maximizedLocaleID), &status);
     if (U_FAILURE(status)) {
-        return javaLocale;
+        return javaLocaleName;
     }
     return env->NewStringUTF(maximizedLocaleID);
 }
 
-static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocale) {
-    UErrorCode status = U_ZERO_ERROR;
-    ScopedUtfChars localeID(env, javaLocale);
-    char script[ULOC_SCRIPT_CAPACITY];
-    uloc_getScript(localeID.c_str(), script, sizeof(script), &status);
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-    return env->NewStringUTF(script);
+static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocaleName) {
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  return env->NewStringUTF(icuLocale.locale().getScript());
 }
 
 static jstring ICU_localeForLanguageTag(JNIEnv* env, jclass, jstring languageTag, jboolean strict) {
     ScopedUtfChars languageTagChars(env, languageTag);
+    if (languageTagChars.c_str() == NULL) {
+      return NULL;
+    }
 
     // Naively assume that in the average case, the size of
     // the normalized language tag will be very nearly the same as the
@@ -131,23 +132,23 @@
     int32_t parsedLength = 0;
 
     UErrorCode status = U_ZERO_ERROR;
-    while (true) {
-        const size_t outputLength = uloc_forLanguageTag(languageTagChars.c_str(),
-               &buffer[0], buffer.size(), &parsedLength, &status);
-        if (U_FAILURE(status)) {
-            return NULL;
-        }
-
-        // Assume that we've run out of buffer space when this happens. Double
-        // the buffer size and try again. This should happen very infrequently.
-        if (outputLength == buffer.size()) {
-            buffer.resize(buffer.size() << 1);
-        } else {
-            break;
-        }
+    size_t outputLength = uloc_forLanguageTag(languageTagChars.c_str(), &buffer[0],
+                                              buffer.size(), &parsedLength, &status);
+    // Note that we always allocate 1 char more than ICU asks us for,
+    // so that we can cleanly assert that it didn't overflow after the
+    // second call to uloc_forLanguageTag.
+    if (status == U_STRING_NOT_TERMINATED_WARNING) {
+        const size_t unterminated_size = buffer.size();
+        buffer.resize(unterminated_size + 1);
+        buffer[unterminated_size] = '\0';
+    } else if (status == U_BUFFER_OVERFLOW_ERROR) {
+        buffer.resize(outputLength + 1);
+        status = U_ZERO_ERROR;
+        outputLength = uloc_forLanguageTag(languageTagChars.c_str(), &buffer[0], buffer.size(),
+                                           &parsedLength, &status);
     }
 
-    if (parsedLength < 0) {
+    if (U_FAILURE(status) || outputLength >= buffer.size()) {
         return NULL;
     }
 
@@ -158,38 +159,7 @@
     // NOTE: The cast is safe because parsedLength can never be negative thanks
     // to the check above. ICU does not document any negative return values for
     // that field, but check for it anyway.
-    if ((strict == JNI_TRUE) &&
-        (static_cast<uint32_t>(parsedLength) != languageTagChars.size())) {
-        return NULL;
-    }
-
-    return env->NewStringUTF(&buffer[0]);
-}
-
-static jstring ICU_languageTagForLocale(JNIEnv* env, jclass, jstring javaLocaleId) {
-    ScopedUtfChars localeID(env, javaLocaleId);
-
-    // In most common cases, the BCP 47 tag will be the same size as the ICU
-    // locale ID
-    const size_t initialBufferSize = localeID.size() + 1;
-    std::vector<char> buffer(initialBufferSize);
-
-    UErrorCode status = U_ZERO_ERROR;
-    const size_t outputLength = uloc_toLanguageTag(localeID.c_str(),
-            &buffer[0], buffer.size(), false /* strict */, &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        buffer.resize(outputLength + 1);
-        status = U_ZERO_ERROR;
-        uloc_toLanguageTag(localeID.c_str(), &buffer[0], buffer.size(),
-                false /* strict */, &status);
-    }
-
-    if (status == U_STRING_NOT_TERMINATED_WARNING) {
-        buffer.resize(buffer.size() + 1);
-        buffer[buffer.size() -1] = '\0';
-    }
-
-    if (maybeThrowIcuException(env, "ICU::languageTagForLocale", status)) {
+    if ((strict == JNI_TRUE) && (static_cast<uint32_t>(parsedLength) != languageTagChars.size())) {
         return NULL;
     }
 
@@ -258,9 +228,9 @@
     return (charCount == 0) ? env->NewStringUTF("XXX") : env->NewString(chars, charCount);
 }
 
-static jstring getCurrencyName(JNIEnv* env, jstring javaLocaleName, jstring javaCurrencyCode, UCurrNameStyle nameStyle) {
-  ScopedUtfChars localeName(env, javaLocaleName);
-  if (localeName.c_str() == NULL) {
+static jstring getCurrencyName(JNIEnv* env, jstring javaLanguageTag, jstring javaCurrencyCode, UCurrNameStyle nameStyle) {
+  ScopedUtfChars languageTag(env, javaLanguageTag);
+  if (languageTag.c_str() == NULL) {
     return NULL;
   }
   ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode);
@@ -271,7 +241,7 @@
   UErrorCode status = U_ZERO_ERROR;
   UBool isChoiceFormat = false;
   int32_t charCount;
-  const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), localeName.c_str(),
+  const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), languageTag.c_str(),
                                      nameStyle, &isChoiceFormat, &charCount, &status);
   if (status == U_USING_DEFAULT_WARNING) {
     if (nameStyle == UCURR_SYMBOL_NAME) {
@@ -290,54 +260,88 @@
   return (charCount == 0) ? NULL : env->NewString(chars, charCount);
 }
 
-static jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) {
-  return getCurrencyName(env, javaLocaleName, javaCurrencyCode, UCURR_LONG_NAME);
+static jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLanguageTag, jstring javaCurrencyCode) {
+  return getCurrencyName(env, javaLanguageTag, javaCurrencyCode, UCURR_LONG_NAME);
 }
 
-static jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) {
-  return getCurrencyName(env, javaLocaleName, javaCurrencyCode, UCURR_SYMBOL_NAME);
+static jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring javaLanguageTag, jstring javaCurrencyCode) {
+  return getCurrencyName(env, javaLanguageTag, javaCurrencyCode, UCURR_SYMBOL_NAME);
 }
 
-static jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    Locale targetLoc = getLocale(env, targetLocale);
-    UnicodeString str;
-    targetLoc.getDisplayCountry(loc, str);
-    return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+  if (!icuTargetLocale.valid()) {
+    return NULL;
+  }
+
+  UnicodeString str;
+  icuTargetLocale.locale().getDisplayCountry(icuLocale.locale(), str);
+  return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    Locale targetLoc = getLocale(env, targetLocale);
-    UnicodeString str;
-    targetLoc.getDisplayLanguage(loc, str);
-    return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+  if (!icuTargetLocale.valid()) {
+    return NULL;
+  }
+
+  UnicodeString str;
+  icuTargetLocale.locale().getDisplayLanguage(icuLocale.locale(), str);
+  return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring ICU_getDisplayScriptNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    Locale targetLoc = getLocale(env, targetLocale);
-    UnicodeString str;
-    targetLoc.getDisplayScript(loc, str);
-    return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayScriptNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+  if (!icuTargetLocale.valid()) {
+    return NULL;
+  }
+
+  UnicodeString str;
+  icuTargetLocale.locale().getDisplayScript(icuLocale.locale(), str);
+  return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    Locale targetLoc = getLocale(env, targetLocale);
-    UnicodeString str;
-    targetLoc.getDisplayVariant(loc, str);
-    return env->NewString(str.getBuffer(), str.length());
+static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag);
+  if (!icuTargetLocale.valid()) {
+    return NULL;
+  }
+
+  UnicodeString str;
+  icuTargetLocale.locale().getDisplayVariant(icuLocale.locale(), str);
+  return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring ICU_getISO3CountryNative(JNIEnv* env, jclass, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    return env->NewStringUTF(loc.getISO3Country());
+static jstring ICU_getISO3Country(JNIEnv* env, jclass, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  return env->NewStringUTF(icuLocale.locale().getISO3Country());
 }
 
-static jstring ICU_getISO3LanguageNative(JNIEnv* env, jclass, jstring locale) {
-    Locale loc = getLocale(env, locale);
-    return env->NewStringUTF(loc.getISO3Language());
+static jstring ICU_getISO3Language(JNIEnv* env, jclass, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+  return env->NewStringUTF(icuLocale.locale().getISO3Language());
 }
 
 static jobjectArray ICU_getISOCountriesNative(JNIEnv* env, jclass) {
@@ -568,7 +572,10 @@
         return JNI_FALSE; // ICU has a fixed-length limit.
     }
 
-    Locale locale = getLocale(env, javaLocaleName);
+    ScopedIcuLocale icuLocale(env, javaLocaleName);
+    if (!icuLocale.valid()) {
+      return JNI_FALSE;
+    }
 
     // Get the DateTimePatterns.
     UErrorCode status = U_ZERO_ERROR;
@@ -587,7 +594,7 @@
     // Get the "Yesterday", "Today", and "Tomorrow" strings.
     bool foundYesterdayTodayAndTomorrow = false;
     for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) {
-      if (getYesterdayTodayAndTomorrow(env, localeData, locale, it.Get())) {
+      if (getYesterdayTodayAndTomorrow(env, localeData, icuLocale.locale(), it.Get())) {
         foundYesterdayTodayAndTomorrow = true;
         break;
       }
@@ -598,7 +605,7 @@
     }
 
     status = U_ZERO_ERROR;
-    UniquePtr<Calendar> cal(Calendar::createInstance(locale, status));
+    UniquePtr<Calendar> cal(Calendar::createInstance(icuLocale.locale(), status));
     if (U_FAILURE(status)) {
         return JNI_FALSE;
     }
@@ -608,7 +615,7 @@
 
     // Get DateFormatSymbols.
     status = U_ZERO_ERROR;
-    DateFormatSymbols dateFormatSym(locale, status);
+    DateFormatSymbols dateFormatSym(icuLocale.locale(), status);
     if (U_FAILURE(status)) {
         return JNI_FALSE;
     }
@@ -661,8 +668,8 @@
     status = U_ZERO_ERROR;
 
     // For numberPatterns and symbols.
-    setNumberPatterns(env, localeData, locale);
-    setDecimalFormatSymbolsData(env, localeData, locale);
+    setNumberPatterns(env, localeData, icuLocale.locale());
+    setDecimalFormatSymbolsData(env, localeData, icuLocale.locale());
 
     jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry());
     jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode);
@@ -685,25 +692,33 @@
     return JNI_TRUE;
 }
 
-static jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+static jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring javaLanguageTag) {
   ScopedJavaUnicodeString scopedString(env, javaString);
   if (!scopedString.valid()) {
     return NULL;
   }
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
   UnicodeString& s(scopedString.unicodeString());
   UnicodeString original(s);
-  s.toLower(getLocale(env, localeName));
+  s.toLower(icuLocale.locale());
   return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
 }
 
-static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring javaLanguageTag) {
   ScopedJavaUnicodeString scopedString(env, javaString);
   if (!scopedString.valid()) {
     return NULL;
   }
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
   UnicodeString& s(scopedString.unicodeString());
   UnicodeString original(s);
-  s.toUpper(getLocale(env, localeName));
+  s.toUpper(icuLocale.locale());
   return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
 }
 
@@ -738,10 +753,14 @@
   return fromStringEnumeration(env, status, "ucurr_openISOCurrencies", &e);
 }
 
-static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName) {
-  Locale locale = getLocale(env, javaLocaleName);
+static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
+
   UErrorCode status = U_ZERO_ERROR;
-  UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(locale, status));
+  UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(icuLocale.locale(), status));
   if (maybeThrowIcuException(env, "DateTimePatternGenerator::createInstance", status)) {
     return NULL;
   }
@@ -758,16 +777,14 @@
   return env->NewString(result.getBuffer(), result.length());
 }
 
-static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLocaleName) {
-  Locale locale = getLocale(env, javaLocaleName);
-  UErrorCode status = U_ZERO_ERROR;
+static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLanguageTag) {
+  ScopedIcuLocale icuLocale(env, javaLanguageTag);
+  if (!icuLocale.valid()) {
+    return;
+  }
 
-  // TODO: Should we check whether locale.isBogus() here ? ICU will
-  // accept bogus locales as the default without complaint. It
-  // shouldn't make a difference in practice, users that set a bogus
-  // locale as the default shouldn't have any realistic expectation that
-  // things like defaults etc. will work correctly.
-  Locale::setDefault(locale, status);
+  UErrorCode status = U_ZERO_ERROR;
+  Locale::setDefault(icuLocale.locale(), status);
   maybeThrowIcuException(env, "Locale::setDefault", status);
 }
 
@@ -796,14 +813,13 @@
     NATIVE_METHOD(ICU, getDisplayLanguageNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getDisplayScriptNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getDisplayVariantNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, getISO3CountryNative, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, getISO3LanguageNative, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(ICU, getISO3Country, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(ICU, getISO3Language, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISOCountriesNative, "()[Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISOLanguagesNative, "()[Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getIcuVersion, "()Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getScript, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getUnicodeVersion, "()Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, languageTagForLocale, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, localeForLanguageTag, "(Ljava/lang/String;Z)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, initLocaleDataNative, "(Ljava/lang/String;Llibcore/icu/LocaleData;)Z"),
     NATIVE_METHOD(ICU, setDefaultLocale, "(Ljava/lang/String;)V"),
diff --git a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
index 0c8c3c9..ef0c2a9 100644
--- a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
+++ b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp
@@ -20,6 +20,7 @@
 #include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JniException.h"
+#include "ScopedIcuLocale.h"
 #include "ScopedUtfChars.h"
 #include "unicode/brkiter.h"
 #include "unicode/putil.h"
@@ -107,13 +108,12 @@
 };
 
 #define MAKE_BREAK_ITERATOR_INSTANCE(F) \
-  UErrorCode status = U_ZERO_ERROR; \
-  const ScopedUtfChars localeChars(env, javaLocale); \
-  if (localeChars.c_str() == NULL) { \
+  ScopedIcuLocale icuLocale(env, javaLocaleName); \
+  if (!icuLocale.valid()) { \
     return 0; \
   } \
-  Locale locale(Locale::createFromName(localeChars.c_str())); \
-  BreakIterator* it = F(locale, status); \
+  UErrorCode status = U_ZERO_ERROR; \
+  BreakIterator* it = F(icuLocale.locale(), status); \
   if (maybeThrowIcuException(env, "ubrk_open", status)) { \
     return 0; \
   } \
@@ -143,19 +143,19 @@
   return it->following(offset);
 }
 
-static jlong NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
   MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createCharacterInstance);
 }
 
-static jlong NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
   MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createLineInstance);
 }
 
-static jlong NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
   MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createSentenceInstance);
 }
 
-static jlong NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring javaLocale) {
+static jlong NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
   MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createWordInstance);
 }
 
diff --git a/luni/src/main/native/libcore_icu_NativeCollation.cpp b/luni/src/main/native/libcore_icu_NativeCollation.cpp
index 00ec9ae..4ce42ec 100644
--- a/luni/src/main/native/libcore_icu_NativeCollation.cpp
+++ b/luni/src/main/native/libcore_icu_NativeCollation.cpp
@@ -180,11 +180,12 @@
     return result;
 }
 
-static jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName) {
-    ScopedUtfChars localeChars(env, localeName);
+static jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring javaLocaleName) {
+    ScopedUtfChars localeChars(env, javaLocaleName);
     if (localeChars.c_str() == NULL) {
         return 0;
     }
+
     UErrorCode status = U_ZERO_ERROR;
     UCollator* c = ucol_open(localeChars.c_str(), &status);
     maybeThrowIcuException(env, "ucol_open", status);
diff --git a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
index ef1743e..faf87f1 100644
--- a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
+++ b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
@@ -20,6 +20,7 @@
 #include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JniException.h"
+#include "ScopedIcuLocale.h"
 #include "ScopedJavaUnicodeString.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
@@ -59,11 +60,14 @@
   return true;
 }
 
-static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring localeName, jobjectArray result) {
-  Locale locale = getLocale(env, localeName);
+static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocaleName, jobjectArray result) {
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return;
+  }
 
   UErrorCode status = U_ZERO_ERROR;
-  UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(locale, status));
+  UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status));
   if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) {
     return;
   }
@@ -118,11 +122,14 @@
   }
 }
 
-static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring javaLocale, jstring javaTz) {
-  Locale locale = getLocale(env, javaLocale);
+static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaTz) {
+  ScopedIcuLocale icuLocale(env, javaLocaleName);
+  if (!icuLocale.valid()) {
+    return NULL;
+  }
 
   UErrorCode status = U_ZERO_ERROR;
-  UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(locale, status));
+  UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status));
   if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) {
     return NULL;
   }
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index c04f73e..2592fe7 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -44,9 +44,14 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#ifndef __APPLE__
 #include <sys/prctl.h>
+#endif
 #include <sys/socket.h>
 #include <sys/stat.h>
+#ifdef __APPLE__
+#include <sys/statvfs.h>
+#endif
 #include <sys/syscall.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -56,6 +61,11 @@
 #include <termios.h>
 #include <unistd.h>
 
+
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
 #define TO_JAVA_STRING(NAME, EXP) \
         jstring NAME = env->NewStringUTF(EXP); \
         if (NAME == NULL) return NULL;
@@ -330,9 +340,14 @@
             static_cast<jlong>(tv.tv_sec), static_cast<jlong>(tv.tv_usec));
 }
 
-static jobject makeStructUcred(JNIEnv* env, const struct ucred& u) {
+static jobject makeStructUcred(JNIEnv* env, const struct ucred& u __unused) {
+#ifdef __APPLE__
+  jniThrowException(env, "java/lang/UnsupportedOperationException", "unimplemented support for ucred on a Mac");
+  return NULL;
+#else
   static jmethodID ctor = env->GetMethodID(JniConstants::structUcredClass, "<init>", "(III)V");
   return env->NewObject(JniConstants::structUcredClass, ctor, u.pid, u.uid, u.gid);
+#endif
 }
 
 static jobject makeStructUtsname(JNIEnv* env, const struct utsname& buf) {
@@ -847,9 +862,19 @@
   return makeStructUcred(env, u);
 }
 
-static jint Posix_gettid(JNIEnv*, jobject) {
+static jint Posix_gettid(JNIEnv* env __unused, jobject) {
+#if defined(__APPLE__)
+  uint64_t owner;
+  int rc = pthread_threadid_np(NULL, &owner);  // Requires Mac OS 10.6
+  if (rc != 0) {
+    throwErrnoException(env, "gettid");
+    return NULL;
+  }
+  return static_cast<jint>(owner);
+#else
   // Neither bionic nor glibc exposes gettid(2).
   return syscall(__NR_gettid);
+#endif
 }
 
 static jint Posix_getuid(JNIEnv*, jobject) {
@@ -1082,19 +1107,31 @@
     return rc;
 }
 
-static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd, jlong offset, jlong length) {
+static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
+                                  jlong offset __unused, jlong length __unused) {
+#ifdef __APPLE__
+    jniThrowException(env, "java/lang/UnsupportedOperationException",
+                      "fallocate doesn't exist on a Mac");
+#else
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     errno = TEMP_FAILURE_RETRY(posix_fallocate64(fd, offset, length));
     if (errno != 0) {
         throwErrnoException(env, "posix_fallocate");
     }
+#endif
 }
 
-static jint Posix_prctl(JNIEnv* env, jobject, jint option, jlong arg2, jlong arg3, jlong arg4, jlong arg5) {
+static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
+                        jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
+#ifdef __APPLE__
+    jniThrowException(env, "java/lang/UnsupportedOperationException", "prctl doesn't exist on a Mac");
+    return 0;
+#else
     int result = prctl(static_cast<int>(option),
                        static_cast<unsigned long>(arg2), static_cast<unsigned long>(arg3),
                        static_cast<unsigned long>(arg4), static_cast<unsigned long>(arg5));
     return throwIfMinusOne(env, "prctl", result);
+#endif
 }
 
 static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
diff --git a/luni/src/test/java/libcore/android/system/OsConstantsTest.java b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
new file mode 100644
index 0000000..681d68c
--- /dev/null
+++ b/luni/src/test/java/libcore/android/system/OsConstantsTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system;
+
+import junit.framework.TestCase;
+
+public class OsConstantsTest extends TestCase {
+
+    // http://b/15602893
+    public void testBug15602893() {
+        assertTrue(OsConstants.RT_SCOPE_HOST > 0);
+        assertTrue(OsConstants.RT_SCOPE_LINK > 0);
+        assertTrue(OsConstants.RT_SCOPE_SITE > 0);
+
+        assertTrue(OsConstants.IFA_F_TENTATIVE > 0);
+    }
+}
diff --git a/luni/src/test/java/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/icu/ICUTest.java
index 60ed0ca..3fa1f46 100644
--- a/luni/src/test/java/libcore/icu/ICUTest.java
+++ b/luni/src/test/java/libcore/icu/ICUTest.java
@@ -16,6 +16,8 @@
 
 package libcore.icu;
 
+import java.text.BreakIterator;
+import java.text.Collator;
 import java.util.Arrays;
 import java.util.Locale;
 
@@ -42,12 +44,12 @@
   }
 
   public void test_getBestDateTimePattern() throws Exception {
-    assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", "ca_ES"));
-    assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", "es_ES"));
-    assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", "de_CH"));
-    assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", "en_US"));
-    assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", "fa_IR"));
-    assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", "ja_JP"));
+    assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("ca", "ES")));
+    assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("es", "ES")));
+    assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("de", "CH")));
+    assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", new Locale("en", "US")));
+    assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", new Locale("fa", "IR")));
+    assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", new Locale("ja", "JP")));
   }
 
   public void test_localeFromString() throws Exception {
@@ -73,7 +75,7 @@
   }
 
   private String best(Locale l, String skeleton) {
-    return ICU.getBestDateTimePattern(skeleton, l.toString());
+    return ICU.getBestDateTimePattern(skeleton, l);
   }
 
   public void test_getDateFormatOrder() throws Exception {
@@ -123,4 +125,130 @@
     } catch (IllegalArgumentException expected) {
     }
   }
+
+  public void testScriptsPassedToIcu() throws Exception {
+    Locale sr_Cyrl_BA = Locale.forLanguageTag("sr-Cyrl-BA");
+    Locale sr_Cyrl_ME = Locale.forLanguageTag("sr-Cyrl-ME");
+    Locale sr_Latn_BA = Locale.forLanguageTag("sr-Latn-BA");
+    Locale sr_Latn_ME = Locale.forLanguageTag("sr-Latn-ME");
+
+    assertEquals("sr_BA_#Cyrl", sr_Cyrl_BA.toString());
+    assertEquals("Cyrl",        sr_Cyrl_BA.getScript());
+
+    assertEquals("sr_ME_#Cyrl", sr_Cyrl_ME.toString());
+    assertEquals("Cyrl",        sr_Cyrl_ME.getScript());
+
+    assertEquals("sr_BA_#Latn", sr_Latn_BA.toString());
+    assertEquals("Latn",        sr_Latn_BA.getScript());
+
+    assertEquals("sr_ME_#Latn", sr_Latn_ME.toString());
+    assertEquals("Latn",        sr_Latn_ME.getScript());
+
+    assertEquals("Српски",              sr_Cyrl_BA.getDisplayLanguage(sr_Cyrl_BA));
+    assertEquals("Босна и Херцеговина", sr_Cyrl_BA.getDisplayCountry(sr_Cyrl_BA));
+    assertEquals("Ћирилица",            sr_Cyrl_BA.getDisplayScript(sr_Cyrl_BA));
+    assertEquals("",                    sr_Cyrl_BA.getDisplayVariant(sr_Cyrl_BA));
+
+    assertEquals("Српски",    sr_Cyrl_ME.getDisplayLanguage(sr_Cyrl_ME));
+    assertEquals("Црна Гора", sr_Cyrl_ME.getDisplayCountry(sr_Cyrl_ME));
+    assertEquals("Ћирилица",  sr_Cyrl_ME.getDisplayScript(sr_Cyrl_ME));
+    assertEquals("",          sr_Cyrl_ME.getDisplayVariant(sr_Cyrl_ME));
+
+    assertEquals("Srpski",              sr_Latn_BA.getDisplayLanguage(sr_Latn_BA));
+    assertEquals("Bosna i Hercegovina", sr_Latn_BA.getDisplayCountry(sr_Latn_BA));
+    assertEquals("Latinica",            sr_Latn_BA.getDisplayScript(sr_Latn_BA));
+    assertEquals("",                    sr_Latn_BA.getDisplayVariant(sr_Latn_BA));
+
+    assertEquals("Srpski",    sr_Latn_ME.getDisplayLanguage(sr_Latn_ME));
+    assertEquals("Crna Gora", sr_Latn_ME.getDisplayCountry(sr_Latn_ME));
+    assertEquals("Latinica",  sr_Latn_ME.getDisplayScript(sr_Latn_ME));
+    assertEquals("",          sr_Latn_ME.getDisplayVariant(sr_Latn_ME));
+
+    assertEquals("BIH", sr_Cyrl_BA.getISO3Country());
+    assertEquals("srp", sr_Cyrl_BA.getISO3Language());
+    assertEquals("MNE", sr_Cyrl_ME.getISO3Country());
+    assertEquals("srp", sr_Cyrl_ME.getISO3Language());
+    assertEquals("BIH", sr_Latn_BA.getISO3Country());
+    assertEquals("srp", sr_Latn_BA.getISO3Language());
+    assertEquals("MNE", sr_Latn_ME.getISO3Country());
+    assertEquals("srp", sr_Latn_ME.getISO3Language());
+
+    BreakIterator.getCharacterInstance(sr_Cyrl_BA);
+    BreakIterator.getCharacterInstance(sr_Cyrl_ME);
+    BreakIterator.getCharacterInstance(sr_Latn_BA);
+    BreakIterator.getCharacterInstance(sr_Latn_ME);
+
+    BreakIterator.getLineInstance(sr_Cyrl_BA);
+    BreakIterator.getLineInstance(sr_Cyrl_ME);
+    BreakIterator.getLineInstance(sr_Latn_BA);
+    BreakIterator.getLineInstance(sr_Latn_ME);
+
+    BreakIterator.getSentenceInstance(sr_Cyrl_BA);
+    BreakIterator.getSentenceInstance(sr_Cyrl_ME);
+    BreakIterator.getSentenceInstance(sr_Latn_BA);
+    BreakIterator.getSentenceInstance(sr_Latn_ME);
+
+    BreakIterator.getWordInstance(sr_Cyrl_BA);
+    BreakIterator.getWordInstance(sr_Cyrl_ME);
+    BreakIterator.getWordInstance(sr_Latn_BA);
+    BreakIterator.getWordInstance(sr_Latn_ME);
+
+    Collator.getInstance(sr_Cyrl_BA);
+    Collator.getInstance(sr_Cyrl_ME);
+    Collator.getInstance(sr_Latn_BA);
+    Collator.getInstance(sr_Latn_ME);
+
+    // TODO: This needs to be fixed. We shouldn't output attribute key
+    // expansions in the language tag or the toString output. The tests
+    // will fail with something like:
+    //
+    // expected:<de-u-co[-phonebk-kf-upper-kn]> but was:
+    // <de-u-co[lcasefirst-upper-collation-phonebook-colnumeric-yes]>
+    Locale l = Locale.forLanguageTag("de-u-co-phonebk-kf-upper-kn");
+    assertEquals("de__#u-co-phonebk-kf-upper-kn", l.toString());
+    assertEquals("de-u-co-phonebk-kf-upper-kn", l.toLanguageTag());
+
+    Collator c = Collator.getInstance(l);
+    assertTrue(c.compare("2", "11") < 0);
+    assertTrue(c.compare("11", "ae") < 0);
+    assertTrue(c.compare("ae", "Ä") < 0);
+    assertTrue(c.compare("Ä", "ä") < 0);
+    assertTrue(c.compare("ä", "AF") < 0);
+    assertTrue(c.compare("AF", "af") < 0);
+  }
+
+  // Test for the behavior of currency symbol lookup when an unrecognized locale has been set as the
+  // default.
+  public void testIcuDefaultAffectsCurrencySymbol() {
+    // A locale that is not going to be recognized by ICU and should fallback to "root" for the
+    // currency symbol.
+    final Locale unrecognizedLocale = new Locale("xy", "KR");
+
+    // A known locale with a relatively stable representation for its currency symbol.
+    final Locale enUsLocale = new Locale("en", "US");
+    final String usDollar = "USD";
+
+    String initialDefaultLocale = ICU.getDefaultLocale();
+    try {
+      // Confirm the "$" symbol for USD in en-US.
+      assertEquals("$", ICU.getCurrencySymbol(enUsLocale, usDollar));
+
+      // Set the default so this will be used as fallback for the unrecognized locale symbol lookup.
+      ICU.setDefaultLocale(enUsLocale.toLanguageTag());
+
+      // Demonstrate the USD symbol is reported as "$" for the unrecognized locale (which is using
+      // the default).
+      assertEquals("$", ICU.getCurrencySymbol(unrecognizedLocale, usDollar));
+
+      // Change the default.
+      ICU.setDefaultLocale(unrecognizedLocale.toLanguageTag());
+
+      String currencySymbolAfterDefaultChange = ICU.getCurrencySymbol(unrecognizedLocale, usDollar);
+      // "$US" is the value from root. With an unrecognized locale argument, and an unrecognized
+      // locale as the default, ICU has returns the value in root.
+      assertEquals("US$", currencySymbolAfterDefaultChange);
+    } finally {
+      ICU.setDefaultLocale(initialDefaultLocale);
+    }
+  }
 }
diff --git a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
index 0926569..294cea2 100644
--- a/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldRuntimeTest.java
@@ -34,28 +34,6 @@
 
     InputStream is;
 
-    public void test_freeMemory() {
-        // Heap might grow or do GC at any time,
-        // so we can't really test a lot. Hence
-        // we are just doing some basic sanity
-        // checks here.
-        assertTrue("must have some free memory",
-                r.freeMemory() > 0);
-
-        assertTrue("must not exceed total memory",
-                r.freeMemory() < r.totalMemory());
-
-        long before = r.totalMemory() - r.freeMemory();
-        Vector<byte[]> v = new Vector<byte[]>();
-        for (int i = 1; i < 10; i++) {
-            v.addElement(new byte[10000]);
-        }
-        long after =  r.totalMemory() - r.freeMemory();
-
-        assertTrue("free memory must change with allocations",
-                after != before);
-    }
-
     public void test_getRuntime() {
         // Test for method java.lang.Runtime java.lang.Runtime.getRuntime()
         assertNotNull(Runtime.getRuntime());
@@ -451,10 +429,6 @@
         }
     }
 
-    public void test_maxMemory() {
-        assertTrue(Runtime.getRuntime().maxMemory() < Long.MAX_VALUE);
-    }
-
     public void test_traceInstructions() {
         Runtime.getRuntime().traceInstructions(false);
         Runtime.getRuntime().traceInstructions(true);
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
index a7eac3a..f0db3ba 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
@@ -19,6 +19,7 @@
 import java.nio.channels.MembershipKey;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.List;
 
 /**
  * Tests associated with multicast behavior of DatagramChannel.
@@ -34,8 +35,8 @@
   }
 
   // These IP addresses aren't inherently "good" or "bad"; they're just used like that.
-  // We use the "good" addresses for our actual group, and the "bad" addresses are for
-  // a group that we won't actually set up.
+  // We use the "good" addresses for our actual group, and the "bad" addresses are for a group that
+  // we won't actually set up.
   private static final InetAddress GOOD_MULTICAST_IPv4 = lookup("239.255.0.1");
   private static final InetAddress BAD_MULTICAST_IPv4 = lookup("239.255.0.2");
   private static final InetAddress GOOD_MULTICAST_IPv6 = lookup("ff05::7:7");
@@ -52,54 +53,44 @@
   private static final InetAddress UNICAST_IPv6_1 = lookup("2001:db8::1");
   private static final InetAddress UNICAST_IPv6_2 = lookup("2001:db8::2");
 
-  private NetworkInterface networkInterface1;
-  private NetworkInterface IPV6networkInterface1;
+  private List<NetworkInterface> ipv4networkInterfaces = new ArrayList<NetworkInterface>();
+  private List<NetworkInterface> ipv6networkInterfaces = new ArrayList<NetworkInterface>();
+  private NetworkInterface ipv4networkInterface;
+  private NetworkInterface ipv6networkInterface;
   private NetworkInterface loopbackInterface;
 
   @Override
   protected void setUp() throws Exception {
-    // The loopback interface isn't actually useful for sending/receiving multicast messages
-    // but it can be used as a dummy for tests where that does not matter.
+    // The loopback interface isn't actually useful for sending/receiving multicast messages but it
+    // can be used as a dummy for tests where that does not matter.
     loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
     assertNotNull(loopbackInterface);
     assertTrue(loopbackInterface.isLoopback());
     assertFalse(loopbackInterface.supportsMulticast());
 
     Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
-
-    // only consider interfaces that have addresses associated with them.
-    // Otherwise tests don't work so well
-    if (interfaces != null) {
-      boolean atLeastOneInterface = false;
-      while (interfaces.hasMoreElements() && (atLeastOneInterface == false)) {
-        networkInterface1 = interfaces.nextElement();
-        if (willWorkForMulticast(networkInterface1)) {
-          atLeastOneInterface = true;
-        }
-      }
-
-      assertTrue("Test environment must have at least one network interface capable of multicast",
-              atLeastOneInterface);
-
-      // Find the first multicast-compatible interface that supports IPV6 if one exists
-      interfaces = NetworkInterface.getNetworkInterfaces();
-
-      boolean found = false;
-      while (interfaces.hasMoreElements() && !found) {
-        NetworkInterface nextInterface = interfaces.nextElement();
-        if (willWorkForMulticast(nextInterface)) {
-          Enumeration<InetAddress> addresses = nextInterface.getInetAddresses();
-          while (addresses.hasMoreElements()) {
-            final InetAddress nextAddress = addresses.nextElement();
-            if (nextAddress instanceof Inet6Address) {
-              IPV6networkInterface1 = nextInterface;
-              found = true;
-              break;
-            }
+    assertNotNull(interfaces);
+    // Only consider interfaces that have addresses associated with them. Otherwise tests don't work
+    // so well.
+    while (interfaces.hasMoreElements()) {
+      NetworkInterface networkInterface = interfaces.nextElement();
+      if (willWorkForMulticast(networkInterface)) {
+        Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
+        while (addresses.hasMoreElements()) {
+          final InetAddress nextAddress = addresses.nextElement();
+          if (nextAddress instanceof Inet4Address) {
+            ipv4networkInterfaces.add(networkInterface);
+          } else if (nextAddress instanceof Inet6Address) {
+            ipv6networkInterfaces.add(networkInterface);
           }
         }
       }
     }
+    assertTrue(
+        "Test environment must have network interfaces capable of both IPv4 and IPv6 multicast",
+        ipv4networkInterfaces.size() > 0 && ipv6networkInterfaces.size() > 0);
+    ipv4networkInterface = ipv4networkInterfaces.get(0);
+    ipv6networkInterface = ipv6networkInterfaces.get(0);
   }
 
   public void test_open() throws IOException {
@@ -108,9 +99,15 @@
     // Unlike MulticastSocket, DatagramChannel has SO_REUSEADDR set to false by default.
     assertFalse(dc.getOption(StandardSocketOptions.SO_REUSEADDR));
 
+    // Confirm multicast loop is on by default as specified in the docs. Many tests in this class
+    // depend on this being true.
+    assertTrue(dc.getOption(StandardSocketOptions.IP_MULTICAST_LOOP));
+
     assertNull(dc.getLocalAddress());
     assertTrue(dc.isOpen());
     assertFalse(dc.isConnected());
+
+    dc.close();
   }
 
   public void test_bind_null() throws Exception {
@@ -133,7 +130,7 @@
     DatagramChannel dc = createReceiverChannel();
     dc.close();
     try {
-      dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
       fail();
     } catch (ClosedChannelException expected) {
     }
@@ -142,7 +139,7 @@
   public void test_joinAnySource_nullGroupAddress() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(null, networkInterface1);
+      dc.join(null, ipv4networkInterface);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -160,19 +157,22 @@
   }
 
   public void test_joinAnySource_nonMulticastGroupAddress_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    try {
-      dc.join(UNICAST_IPv4_1, networkInterface1);
-      fail();
-    } catch (IllegalArgumentException expected) {
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      test_joinAnySource_illegalArgumentExpected(networkInterface, UNICAST_IPv4_1);
     }
-    dc.close();
   }
 
   public void test_joinAnySource_nonMulticastGroupAddress_IPv6() throws Exception {
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      test_joinAnySource_illegalArgumentExpected(networkInterface, UNICAST_IPv6_1);
+    }
+  }
+
+  private void test_joinAnySource_illegalArgumentExpected(NetworkInterface networkInterface,
+      InetAddress group) throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(UNICAST_IPv6_1, networkInterface1);
+      dc.join(group, networkInterface);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -180,36 +180,42 @@
   }
 
   public void test_joinAnySource_IPv4() throws Exception {
-    test_joinAnySource(GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4);
+    test_joinAnySource(ipv4networkInterfaces, GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4);
   }
 
   public void test_joinAnySource_IPv6() throws Exception {
-    test_joinAnySource(GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6);
+    test_joinAnySource(ipv6networkInterfaces, GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6);
   }
 
-  private void test_joinAnySource(InetAddress group, InetAddress group2) throws Exception {
-    // Set up a receiver join the group on networkInterface1
-    DatagramChannel receiverChannel = createReceiverChannel();
-    InetSocketAddress localAddress = (InetSocketAddress) receiverChannel.getLocalAddress();
-    receiverChannel.join(group, networkInterface1);
+  private void test_joinAnySource(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group, InetAddress group2)
+      throws Exception {
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      // Set up a receiver join the group on networkInterface.
+      DatagramChannel receiverChannel = createReceiverChannel();
+      InetSocketAddress localAddress = (InetSocketAddress) receiverChannel.getLocalAddress();
+      receiverChannel.join(group, networkInterface);
 
-    String msg = "Hello World";
-    sendMulticastMessage(group, localAddress.getPort(), msg);
+      // Send a message to the group we joined.
+      String msg = "Hello World";
+      sendMessage(group, localAddress.getPort(), msg, networkInterface);
 
-    // now verify that we received the data as expected
-    ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-    SocketAddress sourceAddress = receiverChannel.receive(recvBuffer);
-    assertNotNull(sourceAddress);
-    assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
+      // Now verify that we received the data as expected.
+      ByteBuffer recvBuffer = ByteBuffer.allocate(100);
+      SocketAddress sourceAddress = receiverChannel.receive(recvBuffer);
+      assertNotNull(sourceAddress);
+      assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
 
-    // now verify that we didn't receive the second message
-    String msg2 = "Hello World - Different Group";
-    sendMulticastMessage(group2, localAddress.getPort(), msg2);
-    recvBuffer.position(0);
-    SocketAddress sourceAddress2 = receiverChannel.receive(recvBuffer);
-    assertNull(sourceAddress2);
+      // Send a message to the group we did not join.
+      String msg2 = "Hello World - Different Group";
+      sendMessage(group2, localAddress.getPort(), msg2, networkInterface);
+      recvBuffer.position(0);
+      // Now verify that we didn't receive the second message.
+      SocketAddress sourceAddress2 = receiverChannel.receive(recvBuffer);
+      assertNull(sourceAddress2);
 
-    receiverChannel.close();
+      receiverChannel.close();
+    }
   }
 
   public void test_joinAnySource_processLimit() throws Exception {
@@ -217,11 +223,11 @@
     for (byte i = 1; i <= 25; i++) {
       InetAddress groupAddress = Inet4Address.getByName("239.255.0." + i);
       try {
-        dc.join(groupAddress, networkInterface1);
+        dc.join(groupAddress, ipv4networkInterface);
       } catch (SocketException e) {
         // There is a limit, that's ok according to the RI docs. For this test a lower bound of 20
         // is used, which appears to be the default linux limit.
-        // See /proc/sys/net/ipv4/igmp_max_memberships
+        // See /proc/sys/net/ipv4/igmp_max_memberships.
         assertTrue(i > 20);
         break;
       }
@@ -232,7 +238,7 @@
 
   public void test_joinAnySource_blockLimit() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey key = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey key = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     for (byte i = 1; i <= 15; i++) {
       InetAddress sourceAddress = Inet4Address.getByName("10.0.0." + i);
       try {
@@ -240,7 +246,7 @@
       } catch (SocketException e) {
         // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10
         // is used, which appears to be the default linux limit.
-        // See /proc/sys/net/ipv4/igmp_max_msf
+        // See /proc/sys/net/ipv4/igmp_max_msf.
         assertTrue(i > 10);
         break;
       }
@@ -250,12 +256,22 @@
   }
 
   /** Confirms that calling join() does not cause an implicit bind() to take place. */
-  public void test_joinAnySource_doesNotCauseBind() throws Exception {
-    DatagramChannel dc = DatagramChannel.open();
-    dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
-    assertNull(dc.getLocalAddress());
+  public void test_joinAnySource_doesNotCauseBind_IPv4() throws Exception {
+    test_joinAnySource_doesNotCauseBind(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
+  }
 
-    dc.close();
+  public void test_joinAnySource_doesNotCauseBind_IPv6() throws Exception {
+    test_joinAnySource_doesNotCauseBind(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
+  }
+
+  private void test_joinAnySource_doesNotCauseBind(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws IOException {
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = DatagramChannel.open();
+      dc.join(group, networkInterface);
+      assertNull(dc.getLocalAddress());
+      dc.close();
+    }
   }
 
   public void test_joinAnySource_networkInterfaces() throws Exception {
@@ -267,191 +283,192 @@
     Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
     while (theInterfaces.hasMoreElements()) {
       NetworkInterface thisInterface = theInterfaces.nextElement();
-      if (thisInterface.getInetAddresses().hasMoreElements()) {
+      // Skip interfaces that do not support multicast - there's no point in proving they cannot
+      // send / receive multicast messages.
+      if (willWorkForMulticast(thisInterface)) {
         realInterfaces.add(thisInterface);
       }
     }
 
-    for (int i = 0; i < realInterfaces.size(); i++) {
-      NetworkInterface thisInterface = realInterfaces.get(i);
-      if (!thisInterface.supportsMulticast()) {
-        // Skip interfaces that do not support multicast - there's no point in proving
-        // they cannot send / receive multicast messages.
-        continue;
-      }
-
-      // get the first address on the interface
-
-      // start server which is joined to the group and has
-      // only asked for packets on this interface
+    for (NetworkInterface thisInterface : realInterfaces) {
+      // Get the first address on the interface.
       Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
 
-      NetworkInterface sendingInterface = null;
-      InetAddress group = null;
-      if (addresses.hasMoreElements()) {
-        InetAddress firstAddress = addresses.nextElement();
-        if (firstAddress instanceof Inet4Address) {
+      while (addresses.hasMoreElements()) {
+        InetAddress listenAddress = addresses.nextElement();
+
+        // Start a server which is joined to the group and has only asked for packets on this
+        // interface.
+        NetworkInterface sendingInterface;
+        InetAddress group;
+        if (listenAddress instanceof Inet4Address) {
           group = GOOD_MULTICAST_IPv4;
-          sendingInterface = networkInterface1;
+          sendingInterface = ipv4networkInterface;
         } else {
-          // if this interface only seems to support IPV6 addresses
           group = GOOD_MULTICAST_IPv6;
-          sendingInterface = IPV6networkInterface1;
+          sendingInterface = ipv6networkInterface;
         }
+        DatagramChannel dc = createReceiverChannel();
+        InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
+        dc.join(group, thisInterface);
+
+        // Now send out a packet on sendingInterface. We should only see the packet if we send
+        // it on the same interface we are listening on (thisInterface).
+        String msg = "Hello World - Again " + thisInterface.getName();
+        sendMessage(group, localAddress.getPort(), msg, sendingInterface);
+
+        ByteBuffer recvBuffer = ByteBuffer.allocate(100);
+        SocketAddress sourceAddress = dc.receive(recvBuffer);
+        if (thisInterface.equals(sendingInterface)) {
+          assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
+        } else {
+          assertNull(sourceAddress);
+        }
+
+        dc.close();
       }
-
-      DatagramChannel dc = createReceiverChannel();
-      InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
-      dc.join(group, thisInterface);
-
-      // Now send out a package on sendingInterface. We should only see the packet if we send
-      // it on the same interface we are listening on (thisInterface).
-      String msg = "Hello World - Again" + thisInterface.getName();
-      sendMulticastMessage(group, localAddress.getPort(), msg, sendingInterface);
-
-      ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-      SocketAddress sourceAddress = dc.receive(recvBuffer);
-      if (thisInterface.equals(sendingInterface)) {
-        assertEquals(msg, new String(recvBuffer.array(), 0, recvBuffer.position()));
-      } else {
-        assertNull(sourceAddress);
-      }
-
-      dc.close();
     }
   }
 
   /** Confirms that the scope of each membership is network interface-level. */
-  public void test_join_canMixTypesOnDifferentInterfaces() throws Exception {
+  public void test_join_canMixJoinTypesOnDifferentInterfaces() throws Exception {
     DatagramChannel dc = DatagramChannel.open();
-    MembershipKey membershipKey1 = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey1 = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     MembershipKey membershipKey2 = dc.join(GOOD_MULTICAST_IPv4, loopbackInterface, UNICAST_IPv4_1);
     assertNotSame(membershipKey1, membershipKey2);
 
     dc.close();
   }
 
-
-  private DatagramChannel createReceiverChannel() throws Exception {
-    DatagramChannel dc = DatagramChannel.open();
-    dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
-    configureChannelForReceiving(dc);
-    return dc;
-  }
-
   public void test_joinAnySource_multiple_joins_IPv4()
       throws Exception {
-    test_joinAnySource_multiple_joins(GOOD_MULTICAST_IPv4);
+    test_joinAnySource_multiple_joins(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
   }
 
   public void test_joinAnySource_multiple_joins_IPv6()
       throws Exception {
-    test_joinAnySource_multiple_joins(GOOD_MULTICAST_IPv6);
+    test_joinAnySource_multiple_joins(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
   }
 
-  private void test_joinAnySource_multiple_joins(InetAddress group) throws Exception {
-    DatagramChannel dc = createReceiverChannel();
+  private void test_joinAnySource_multiple_joins(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = createReceiverChannel();
 
-    MembershipKey membershipKey1 = dc.join(group, networkInterface1);
+      MembershipKey membershipKey1 = dc.join(group, networkInterface);
 
-    MembershipKey membershipKey2 = dc.join(group, loopbackInterface);
-    assertFalse(membershipKey1.equals(membershipKey2));
+      MembershipKey membershipKey2 = dc.join(group, loopbackInterface);
+      assertFalse(membershipKey1.equals(membershipKey2));
 
-    MembershipKey membershipKey1_2 = dc.join(group, networkInterface1);
-    assertEquals(membershipKey1, membershipKey1_2);
+      MembershipKey membershipKey1_2 = dc.join(group, networkInterface);
+      assertEquals(membershipKey1, membershipKey1_2);
 
-    dc.close();
+      dc.close();
+    }
   }
 
   public void test_joinAnySource_multicastLoopOption_IPv4() throws Exception {
-    test_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv4);
+    test_joinAnySource_multicastLoopOption(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
   }
 
-  public void test_multicastLoopOption_IPv6() throws Exception {
-    test_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv6);
+  public void test_joinAnySource_multicastLoopOption_IPv6() throws Exception {
+    test_joinAnySource_multicastLoopOption(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
   }
 
-  private void test_joinAnySource_multicastLoopOption(InetAddress group) throws Exception {
+  private void test_joinAnySource_multicastLoopOption(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
     final String message = "Hello, world!";
 
-    DatagramChannel dc = createReceiverChannel();
-    dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */);
-    configureChannelForReceiving(dc);
-    dc.join(group, networkInterface1);
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = DatagramChannel.open();
+      configureChannelForReceiving(dc);
+      dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
 
-    InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
+      // Make sure that the sent packets will be sent via the interface we will be joining with.
+      dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
+      dc.join(group, networkInterface);
 
-    // send the datagram
-    byte[] sendData = message.getBytes();
-    ByteBuffer sendBuffer = ByteBuffer.wrap(sendData);
-    dc.send(sendBuffer, new InetSocketAddress(group, localAddress.getPort()));
+      // Test with loop on.
+      dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */);
 
-    // receive the datagram
-    ByteBuffer recvBuffer = ByteBuffer.allocate(100);
-    SocketAddress sourceAddress = dc.receive(recvBuffer);
-    assertNotNull(sourceAddress);
+      InetSocketAddress localAddress = (InetSocketAddress) dc.getLocalAddress();
 
-    String recvMessage = new String(recvBuffer.array(), 0, recvBuffer.position());
-    assertEquals(message, recvMessage);
+      // Send the datagram.
+      sendMessage(dc, message, new InetSocketAddress(group, localAddress.getPort()));
 
-    // Turn off loop
-    dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false /* enable loopback */);
+      // Receive the datagram.
+      ByteBuffer recvBuffer = ByteBuffer.allocate(100);
+      SocketAddress sourceAddress = dc.receive(recvBuffer);
+      assertNotNull(sourceAddress);
 
-    // send another datagram
-    recvBuffer.position(0);
-    ByteBuffer sendBuffer2 = ByteBuffer.wrap(sendData);
-    dc.send(sendBuffer2, new InetSocketAddress(group, localAddress.getPort()));
+      String recvMessage = new String(recvBuffer.array(), 0, recvBuffer.position());
+      assertEquals(message, recvMessage);
 
-    SocketAddress sourceAddress2 = dc.receive(recvBuffer);
-    assertNull(sourceAddress2);
+      // Turn off loop.
+      dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false /* enable loopback */);
 
-    dc.close();
+      // Send another datagram.
+      recvBuffer.position(0);
+      sendMessage(dc, message, new InetSocketAddress(group, localAddress.getPort()));
+
+      SocketAddress sourceAddress2 = dc.receive(recvBuffer);
+      assertNull(sourceAddress2);
+
+      dc.close();
+    }
   }
 
   public void testMembershipKeyAccessors_IPv4() throws Exception {
-    testMembershipKeyAccessors(GOOD_MULTICAST_IPv4);
+    testMembershipKeyAccessors(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
   }
 
   public void testMembershipKeyAccessors_IPv6() throws Exception {
-    testMembershipKeyAccessors(GOOD_MULTICAST_IPv6);
+    testMembershipKeyAccessors(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
   }
 
-  private void testMembershipKeyAccessors(InetAddress group) throws Exception {
-    DatagramChannel dc = createReceiverChannel();
+  private void testMembershipKeyAccessors(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group) throws Exception {
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = createReceiverChannel();
 
-    MembershipKey key = dc.join(group, networkInterface1);
-    assertSame(dc, key.channel());
-    assertSame(group, key.group());
-    assertTrue(key.isValid());
-    assertSame(networkInterface1, key.networkInterface());
-    assertNull(key.sourceAddress());
+      MembershipKey key = dc.join(group, networkInterface);
+      assertSame(dc, key.channel());
+      assertSame(group, key.group());
+      assertTrue(key.isValid());
+      assertSame(networkInterface, key.networkInterface());
+      assertNull(key.sourceAddress());
+    }
   }
 
   public void test_dropAnySource_twice_IPv4() throws Exception {
-    test_dropAnySource_twice(GOOD_MULTICAST_IPv4);
+    test_dropAnySource_twice(ipv4networkInterfaces, GOOD_MULTICAST_IPv4);
   }
 
   public void test_dropAnySource_twice_IPv6() throws Exception {
-    test_dropAnySource_twice(GOOD_MULTICAST_IPv6);
+    test_dropAnySource_twice(ipv6networkInterfaces, GOOD_MULTICAST_IPv6);
   }
 
-  private void test_dropAnySource_twice(InetAddress group) throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(group, networkInterface1);
+  private void test_dropAnySource_twice(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress group)
+      throws Exception {
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = createReceiverChannel();
+      MembershipKey membershipKey = dc.join(group, networkInterface);
 
-    assertTrue(membershipKey.isValid());
-    membershipKey.drop();
-    assertFalse(membershipKey.isValid());
+      assertTrue(membershipKey.isValid());
+      membershipKey.drop();
+      assertFalse(membershipKey.isValid());
 
-    // Try to leave a group we are no longer a member of - should do nothing.
-    membershipKey.drop();
+      // Try to leave a group we are no longer a member of. It should do nothing.
+      membershipKey.drop();
 
-    dc.close();
+      dc.close();
+    }
   }
 
   public void test_close_invalidatesMembershipKey() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
 
     assertTrue(membershipKey.isValid());
 
@@ -462,7 +479,7 @@
 
   public void test_block_null() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     try {
       membershipKey.block(null);
       fail();
@@ -473,32 +490,34 @@
   }
 
   public void test_block_mixedAddressTypes_IPv4() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
-    try {
-      membershipKey.block(UNICAST_IPv6_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
-
-    dc.close();
+    test_block_illegalArgument(ipv4networkInterfaces, GOOD_MULTICAST_IPv4, UNICAST_IPv6_1);
   }
 
   public void test_block_mixedAddressTypes_IPv6() throws Exception {
-    DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, networkInterface1);
-    try {
-      membershipKey.block(UNICAST_IPv4_1);
-      fail();
-    } catch (IllegalArgumentException expected) {
-    }
+    test_block_illegalArgument(ipv6networkInterfaces, GOOD_MULTICAST_IPv6, UNICAST_IPv4_1);
+  }
 
-    dc.close();
+  private void test_block_illegalArgument(
+      Iterable<NetworkInterface> networkInterfaces, InetAddress groupAddress,
+      InetAddress badBlockAddress) throws Exception {
+
+    for (NetworkInterface networkInterface : networkInterfaces) {
+      DatagramChannel dc = createReceiverChannel();
+      MembershipKey membershipKey = dc.join(groupAddress, networkInterface);
+      try {
+        membershipKey.block(badBlockAddress);
+        fail();
+      } catch (IllegalArgumentException expected) {
+      }
+
+      dc.close();
+    }
   }
 
   public void test_block_cannotBlockWithSourceSpecificMembership() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1, UNICAST_IPv4_1);
+    MembershipKey membershipKey =
+        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
     try {
       membershipKey.block(UNICAST_IPv4_2);
       fail();
@@ -510,7 +529,7 @@
 
   public void test_block_multipleBlocksIgnored() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     membershipKey.block(UNICAST_IPv4_1);
 
     MembershipKey membershipKey2 = membershipKey.block(UNICAST_IPv4_1);
@@ -521,7 +540,7 @@
 
   public void test_block_wildcardAddress() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     try {
       membershipKey.block(WILDCARD_IPv4);
       fail();
@@ -533,7 +552,7 @@
 
   public void test_unblock_multipleUnblocksFail() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
 
     try {
       membershipKey.unblock(UNICAST_IPv4_1);
@@ -557,16 +576,16 @@
 
   public void test_unblock_null() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     membershipKey.block(UNICAST_IPv4_1);
 
     try {
       membershipKey.unblock(null);
       fail();
     } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine
+      // Either of these exceptions are fine.
     } catch (NullPointerException expected) {
-      // Either of these exception are fine
+      // Either of these exception are fine.
     }
 
     dc.close();
@@ -574,14 +593,14 @@
 
   public void test_unblock_mixedAddressTypes_IPv4() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface);
     try {
       membershipKey.unblock(UNICAST_IPv6_1);
       fail();
     } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine
+      // Either of these exceptions are fine.
     } catch (IllegalArgumentException expected) {
-      // Either of these exceptions are fine
+      // Either of these exceptions are fine.
     }
 
     dc.close();
@@ -589,58 +608,70 @@
 
   public void test_unblock_mixedAddressTypes_IPv6() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, networkInterface1);
+    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface);
     try {
       membershipKey.unblock(UNICAST_IPv4_1);
       fail();
     } catch (IllegalStateException expected) {
-      // Either of these exceptions are fine
+      // Either of these exceptions are fine.
     } catch (IllegalArgumentException expected) {
-      // Either of these exceptions are fine
+      // Either of these exceptions are fine.
     }
 
     dc.close();
   }
 
   /** Checks that block() works when the receiver is bound to the multicast group address */
-  public void test_block_filtersAsExpected_groupBind_ipv4() throws Exception {
-    InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface1);
-    test_block_filtersAsExpected(
-        ipv4LocalAddress /* senderBindAddress */,
-        GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv4 /* groupAddress */);
+  public void test_block_filtersAsExpected_groupBind_IPv4() throws Exception {
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
+      test_block_filtersAsExpected(
+          networkInterface,
+          ipv4LocalAddress /* senderBindAddress */,
+          GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv4 /* groupAddress */);
+    }
   }
 
   /** Checks that block() works when the receiver is bound to the multicast group address */
-  public void test_block_filtersAsExpected_groupBind_ipv6() throws Exception {
-    InetAddress ipv6LocalAddress = getLocalIpv6Address(IPV6networkInterface1);
-    test_block_filtersAsExpected(
-        ipv6LocalAddress /* senderBindAddress */,
-        GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv6 /* groupAddress */);
+  public void test_block_filtersAsExpected_groupBind_IPv6() throws Exception {
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
+      test_block_filtersAsExpected(
+          networkInterface,
+          ipv6LocalAddress /* senderBindAddress */,
+          GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv6 /* groupAddress */);
+    }
   }
 
   /** Checks that block() works when the receiver is bound to the "any" address */
-  public void test_block_filtersAsExpected_anyBind_ipv4() throws Exception {
-    InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface1);
-    test_block_filtersAsExpected(
-        ipv4LocalAddress /* senderBindAddress */,
-        WILDCARD_IPv4 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv4 /* groupAddress */);
+  public void test_block_filtersAsExpected_anyBind_IPv4() throws Exception {
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
+      test_block_filtersAsExpected(
+          networkInterface,
+          ipv4LocalAddress /* senderBindAddress */,
+          WILDCARD_IPv4 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv4 /* groupAddress */);
+    }
   }
 
   /** Checks that block() works when the receiver is bound to the "any" address */
-  public void test_block_filtersAsExpected_anyBind_ipv6() throws Exception {
-    InetAddress ipv6LocalAddress = getLocalIpv6Address(IPV6networkInterface1);
-    test_block_filtersAsExpected(
-        ipv6LocalAddress /* senderBindAddress */,
-        WILDCARD_IPv6 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv6 /* groupAddress */);
+  public void test_block_filtersAsExpected_anyBind_IPv6() throws Exception {
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
+      test_block_filtersAsExpected(
+          networkInterface,
+          ipv6LocalAddress /* senderBindAddress */,
+          WILDCARD_IPv6 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv6 /* groupAddress */);
+    }
   }
 
   private void test_block_filtersAsExpected(
-      InetAddress senderBindAddress, InetAddress receiverBindAddress, InetAddress groupAddress)
-      throws Exception {
+      NetworkInterface networkInterface, InetAddress senderBindAddress,
+      InetAddress receiverBindAddress, InetAddress groupAddress) throws Exception {
 
     DatagramChannel sendingChannel = DatagramChannel.open();
     // In order to block a sender the sender's address must be known. The sendingChannel is
@@ -657,7 +688,7 @@
     InetSocketAddress groupSocketAddress =
         new InetSocketAddress(groupAddress, localReceivingAddress.getPort());
     MembershipKey membershipKey =
-        receivingChannel.join(groupSocketAddress.getAddress(), networkInterface1);
+        receivingChannel.join(groupSocketAddress.getAddress(), networkInterface);
 
     ByteBuffer receiveBuffer = ByteBuffer.allocate(10);
 
@@ -665,10 +696,10 @@
     String msg1 = "Hello1";
     sendMessage(sendingChannel, msg1, groupSocketAddress);
     InetSocketAddress sourceAddress1 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
-    assertEquals(sourceAddress1, sendingAddress);
+    assertEquals(sendingAddress, sourceAddress1);
     assertEquals(msg1, new String(receiveBuffer.array(), 0, receiveBuffer.position()));
 
-    // Now block the sender
+    // Now block the sender.
     membershipKey.block(sendingAddress.getAddress());
 
     // Send a message. It should be filtered.
@@ -678,7 +709,7 @@
     InetSocketAddress sourceAddress2 = (InetSocketAddress) receivingChannel.receive(receiveBuffer);
     assertNull(sourceAddress2);
 
-    // Now unblock the sender
+    // Now unblock the sender.
     membershipKey.unblock(sendingAddress.getAddress());
 
     // Send a message. It should be received.
@@ -696,7 +727,7 @@
   public void test_joinSourceSpecific_nullGroupAddress() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(null, networkInterface1, UNICAST_IPv4_1);
+      dc.join(null, ipv4networkInterface, UNICAST_IPv4_1);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -707,7 +738,7 @@
     DatagramChannel dc = createReceiverChannel();
     dc.close();
     try {
-      dc.join(GOOD_MULTICAST_IPv4, networkInterface1, UNICAST_IPv4_1);
+      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
       fail();
     } catch (ClosedChannelException expected) {
     }
@@ -726,7 +757,7 @@
   public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv4() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(UNICAST_IPv4_1, networkInterface1, UNICAST_IPv4_1);
+      dc.join(UNICAST_IPv4_1, ipv4networkInterface, UNICAST_IPv4_1);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -736,7 +767,7 @@
   public void test_joinSourceSpecific_nonMulticastGroupAddress_IPv6() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(UNICAST_IPv6_1, IPV6networkInterface1, UNICAST_IPv6_1);
+      dc.join(UNICAST_IPv6_1, ipv6networkInterface, UNICAST_IPv6_1);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -746,7 +777,7 @@
   public void test_joinSourceSpecific_nullSourceAddress_IPv4() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(GOOD_MULTICAST_IPv4, networkInterface1, null);
+      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, null);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -756,7 +787,7 @@
   public void test_joinSourceSpecific_nullSourceAddress_IPv6() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(GOOD_MULTICAST_IPv6, networkInterface1, null);
+      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, null);
       fail();
     } catch (NullPointerException expected) {
     }
@@ -766,12 +797,12 @@
   public void test_joinSourceSpecific_mixedAddressTypes() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(GOOD_MULTICAST_IPv4, networkInterface1, UNICAST_IPv6_1);
+      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv6_1);
       fail();
     } catch (IllegalArgumentException expected) {
     }
     try {
-      dc.join(GOOD_MULTICAST_IPv6, networkInterface1, UNICAST_IPv4_1);
+      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, UNICAST_IPv4_1);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -781,17 +812,17 @@
   public void test_joinSourceSpecific_nonUnicastSourceAddress_IPv4() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(GOOD_MULTICAST_IPv4, networkInterface1, BAD_MULTICAST_IPv4);
+      dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, BAD_MULTICAST_IPv4);
       fail();
     } catch (IllegalArgumentException expected) {
     }
     dc.close();
   }
 
-  public void test_joinSourceSpecific_nonUniicastSourceAddress_IPv6() throws Exception {
+  public void test_joinSourceSpecific_nonUnicastSourceAddress_IPv6() throws Exception {
     DatagramChannel dc = createReceiverChannel();
     try {
-      dc.join(GOOD_MULTICAST_IPv6, networkInterface1, BAD_MULTICAST_IPv6);
+      dc.join(GOOD_MULTICAST_IPv6, ipv6networkInterface, BAD_MULTICAST_IPv6);
       fail();
     } catch (IllegalArgumentException expected) {
     }
@@ -803,7 +834,7 @@
     for (byte i = 1; i <= 20; i++) {
       InetAddress sourceAddress = Inet4Address.getByAddress(new byte[] { 10, 0, 0, i});
       try {
-        dc.join(GOOD_MULTICAST_IPv4, networkInterface1, sourceAddress);
+        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, sourceAddress);
       } catch (SocketException e) {
         // There is a limit, that's ok according to the RI docs. For this test a lower bound of 10
         // is used, which appears to be the default linux limit. See /proc/sys/net/ipv4/igmp_max_msf
@@ -819,72 +850,72 @@
    * Checks that a source-specific join() works when the receiver is bound to the multicast group
    * address
    */
-  public void test_joinSourceSpecific_null() throws Exception {
-    InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface1);
-    test_joinSourceSpecific(
-        ipv4LocalAddress /* senderBindAddress */,
-        GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv4 /* groupAddress */,
-        UNICAST_IPv4_1 /* badSenderAddress */);
+  public void test_joinSourceSpecific_groupBind_IPv4() throws Exception {
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
+      test_joinSourceSpecific(
+          networkInterface,
+          ipv4LocalAddress /* senderBindAddress */,
+          GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv4 /* groupAddress */,
+          UNICAST_IPv4_1 /* badSenderAddress */);
+    }
   }
 
   /**
    * Checks that a source-specific join() works when the receiver is bound to the multicast group
    * address
    */
-  public void test_joinSourceSpecific_groupBind_ipv4() throws Exception {
-    InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface1);
-    test_joinSourceSpecific(
-        ipv4LocalAddress /* senderBindAddress */,
-        GOOD_MULTICAST_IPv4 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv4 /* groupAddress */,
-        UNICAST_IPv4_1 /* badSenderAddress */);
-  }
-
-  /**
-   * Checks that a source-specific join() works when the receiver is bound to the multicast group
-   * address
-   */
-  public void test_joinSourceSpecific_groupBind_ipv6() throws Exception {
-    InetAddress ipv6LocalAddress = getLocalIpv6Address(IPV6networkInterface1);
-    test_joinSourceSpecific(
-        ipv6LocalAddress /* senderBindAddress */,
-        GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv6 /* groupAddress */,
-        UNICAST_IPv6_1 /* badSenderAddress */);
+  public void test_joinSourceSpecific_groupBind_IPv6() throws Exception {
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
+      test_joinSourceSpecific(
+          networkInterface,
+          ipv6LocalAddress /* senderBindAddress */,
+          GOOD_MULTICAST_IPv6 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv6 /* groupAddress */,
+          UNICAST_IPv6_1 /* badSenderAddress */);
+    }
   }
 
   /** Checks that a source-specific join() works when the receiver is bound to the "any" address */
-  public void test_joinSourceSpecific_anyBind_ipv4() throws Exception {
-    InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface1);
-    test_joinSourceSpecific(
-        ipv4LocalAddress /* senderBindAddress */,
-        WILDCARD_IPv4 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv4 /* groupAddress */,
-        UNICAST_IPv4_1 /* badSenderAddress */);
+  public void test_joinSourceSpecific_anyBind_IPv4() throws Exception {
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      InetAddress ipv4LocalAddress = getLocalIpv4Address(networkInterface);
+      test_joinSourceSpecific(
+          networkInterface,
+          ipv4LocalAddress /* senderBindAddress */,
+          WILDCARD_IPv4 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv4 /* groupAddress */,
+          UNICAST_IPv4_1 /* badSenderAddress */);
+    }
   }
 
   /** Checks that a source-specific join() works when the receiver is bound to the "any" address */
-  public void test_joinSourceSpecific_anyBind_ipv6() throws Exception {
-    InetAddress ipv6LocalAddress = getLocalIpv6Address(IPV6networkInterface1);
-    test_joinSourceSpecific(
-        ipv6LocalAddress /* senderBindAddress */,
-        WILDCARD_IPv6 /* receiverBindAddress */,
-        GOOD_MULTICAST_IPv6 /* groupAddress */,
-        UNICAST_IPv6_1 /* badSenderAddress */);
+  public void test_joinSourceSpecific_anyBind_IPv6() throws Exception {
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      InetAddress ipv6LocalAddress = getLocalIpv6Address(networkInterface);
+      test_joinSourceSpecific(
+          networkInterface,
+          ipv6LocalAddress /* senderBindAddress */,
+          WILDCARD_IPv6 /* receiverBindAddress */,
+          GOOD_MULTICAST_IPv6 /* groupAddress */,
+          UNICAST_IPv6_1 /* badSenderAddress */);
+    }
   }
 
   /**
-   * Checks that the source-specific membership is correctly source-filtering.
-   * 
+   * Checks that the source-specific membership is correctly source-filtered.
+   *
+   * @param networkInterface the network interface to use when joining
    * @param senderBindAddress the address to bind the sender socket to
    * @param receiverBindAddress the address to bind the receiver socket to
    * @param groupAddress the group address to join
    * @param badSenderAddress a unicast address to join to perform a negative test
    */
   private void test_joinSourceSpecific(
-      InetAddress senderBindAddress, InetAddress receiverBindAddress, InetAddress groupAddress,
-      InetAddress badSenderAddress)
+      NetworkInterface networkInterface, InetAddress senderBindAddress,
+      InetAddress receiverBindAddress, InetAddress groupAddress, InetAddress badSenderAddress)
       throws Exception {
     DatagramChannel sendingChannel = DatagramChannel.open();
     // In order to be source-specific the sender's address must be known. The sendingChannel is
@@ -893,16 +924,16 @@
     InetSocketAddress sendingAddress = (InetSocketAddress) sendingChannel.getLocalAddress();
 
     DatagramChannel receivingChannel = DatagramChannel.open();
+    configureChannelForReceiving(receivingChannel);
     receivingChannel.bind(
         new InetSocketAddress(receiverBindAddress, 0) /* local port left to the OS to determine */);
-    configureChannelForReceiving(receivingChannel);
 
     InetSocketAddress localReceivingAddress =
         (InetSocketAddress) receivingChannel.getLocalAddress();
     InetSocketAddress groupSocketAddress =
         new InetSocketAddress(groupAddress, localReceivingAddress.getPort());
     MembershipKey membershipKey1 = receivingChannel
-        .join(groupSocketAddress.getAddress(), networkInterface1, senderBindAddress);
+        .join(groupSocketAddress.getAddress(), networkInterface, senderBindAddress);
 
     ByteBuffer receiveBuffer = ByteBuffer.allocate(10);
 
@@ -915,7 +946,7 @@
 
     membershipKey1.drop();
 
-    receivingChannel.join(groupSocketAddress.getAddress(), networkInterface1, badSenderAddress);
+    receivingChannel.join(groupSocketAddress.getAddress(), networkInterface, badSenderAddress);
 
     // Send a message. It should not be received.
     String msg2 = "Hello2";
@@ -928,50 +959,66 @@
   }
 
   public void test_dropSourceSpecific_twice_IPv4() throws Exception {
-    test_dropSourceSpecific_twice(
-        GOOD_MULTICAST_IPv4 /* groupAddress */, UNICAST_IPv4_1 /* sourceAddress */);
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      test_dropSourceSpecific_twice(
+          networkInterface,
+          GOOD_MULTICAST_IPv4 /* groupAddress */,
+          UNICAST_IPv4_1 /* sourceAddress */);
+    }
   }
 
   public void test_dropSourceSpecific_twice_IPv6() throws Exception {
-    test_dropSourceSpecific_twice(
-        GOOD_MULTICAST_IPv6 /* groupAddress */, UNICAST_IPv6_1 /* sourceAddress */);
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      test_dropSourceSpecific_twice(
+          networkInterface,
+          GOOD_MULTICAST_IPv6 /* groupAddress */,
+          UNICAST_IPv6_1 /* sourceAddress */);
+    }
   }
 
-  private void test_dropSourceSpecific_twice(InetAddress groupAddress, InetAddress sourceAddress)
+  private void test_dropSourceSpecific_twice(
+      NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress)
       throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(groupAddress, networkInterface1, sourceAddress);
+    MembershipKey membershipKey = dc.join(groupAddress, networkInterface, sourceAddress);
 
     assertTrue(membershipKey.isValid());
     membershipKey.drop();
     assertFalse(membershipKey.isValid());
 
-    // Try to leave a group we are no longer a member of - should do nothing.
+    // Try to leave a group we are no longer a member of. It should do nothing.
     membershipKey.drop();
 
     dc.close();
   }
 
   public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv4() throws Exception {
-    test_dropSourceSpecific_sourceKeysAreIndependent(
-        GOOD_MULTICAST_IPv4 /* groupAddress */,
-        UNICAST_IPv4_1 /* sourceAddress1 */,
-        UNICAST_IPv4_2 /* sourceAddress2 */);
+    for (NetworkInterface networkInterface : ipv4networkInterfaces) {
+      test_dropSourceSpecific_sourceKeysAreIndependent(
+          networkInterface,
+          GOOD_MULTICAST_IPv4 /* groupAddress */,
+          UNICAST_IPv4_1 /* sourceAddress1 */,
+          UNICAST_IPv4_2 /* sourceAddress2 */);
+    }
   }
 
   public void test_dropSourceSpecific_sourceKeysAreIndependent_IPv6() throws Exception {
-    test_dropSourceSpecific_sourceKeysAreIndependent(
-        GOOD_MULTICAST_IPv6 /* groupAddress */,
-        UNICAST_IPv6_1 /* sourceAddress1 */,
-        UNICAST_IPv6_2 /* sourceAddress2 */);
+    for (NetworkInterface networkInterface : ipv6networkInterfaces) {
+      test_dropSourceSpecific_sourceKeysAreIndependent(
+          networkInterface,
+          GOOD_MULTICAST_IPv6 /* groupAddress */,
+          UNICAST_IPv6_1 /* sourceAddress1 */,
+          UNICAST_IPv6_2 /* sourceAddress2 */);
+    }
   }
 
   private void test_dropSourceSpecific_sourceKeysAreIndependent(
-      InetAddress groupAddress, InetAddress sourceAddress1, InetAddress sourceAddress2)
+      NetworkInterface networkInterface, InetAddress groupAddress, InetAddress sourceAddress1,
+      InetAddress sourceAddress2)
       throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey1 = dc.join(groupAddress, networkInterface1, sourceAddress1);
-    MembershipKey membershipKey2 = dc.join(groupAddress, networkInterface1, sourceAddress2);
+    MembershipKey membershipKey1 = dc.join(groupAddress, networkInterface, sourceAddress1);
+    MembershipKey membershipKey2 = dc.join(groupAddress, networkInterface, sourceAddress2);
     assertFalse(membershipKey1.equals(membershipKey2));
     assertTrue(membershipKey1.isValid());
     assertTrue(membershipKey2.isValid());
@@ -986,7 +1033,8 @@
 
   public void test_drop_keyBehaviorAfterDrop() throws Exception {
     DatagramChannel dc = createReceiverChannel();
-    MembershipKey membershipKey = dc.join(GOOD_MULTICAST_IPv4, networkInterface1, UNICAST_IPv4_1);
+    MembershipKey membershipKey =
+        dc.join(GOOD_MULTICAST_IPv4, ipv4networkInterface, UNICAST_IPv4_1);
     membershipKey.drop();
     assertFalse(membershipKey.isValid());
 
@@ -1003,18 +1051,26 @@
     assertSame(dc, membershipKey.channel());
     assertSame(GOOD_MULTICAST_IPv4, membershipKey.group());
     assertSame(UNICAST_IPv4_1, membershipKey.sourceAddress());
-    assertSame(networkInterface1, membershipKey.networkInterface());
+    assertSame(ipv4networkInterface, membershipKey.networkInterface());
+  }
+
+  private static DatagramChannel createReceiverChannel() throws Exception {
+    DatagramChannel dc = DatagramChannel.open();
+    configureChannelForReceiving(dc);
+    dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
+    return dc;
   }
 
   private static void configureChannelForReceiving(DatagramChannel receivingChannel)
       throws Exception {
 
     // NOTE: At the time of writing setSoTimeout() has no effect in the RI, making these tests hang
-    // if the channel is in blocking mode. configureBlocking(false) is used instead and rely on the
-    // network to the local host being instantaneous.
-    // receivingChannel.socket().setSoTimeout(200);
-    // receivingChannel.configureBlocking(true);
-    receivingChannel.configureBlocking(false);
+    // if the channel is in blocking mode.
+    receivingChannel.socket().setSoTimeout(200);
+    receivingChannel.configureBlocking(true);
+    // configureBlocking(false) can be used instead in the RI and we rely on the network to the
+    // local host being instantaneous.
+    // receivingChannel.configureBlocking(false);
   }
 
   private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
@@ -1025,22 +1081,13 @@
         && iface.getInetAddresses().hasMoreElements();
   }
 
-  private static void sendMulticastMessage(InetAddress group, int port, String msg)
-      throws IOException {
-    sendMulticastMessage(group, port, msg, null /* networkInterface */);
-  }
-
-  private static void sendMulticastMessage(
-      InetAddress group, int port, String msg, NetworkInterface sendingInterface)
+  private static void sendMessage(
+      InetAddress targetGroup, int targetPort, String msg, NetworkInterface sendingInterface)
       throws IOException {
     // Any datagram socket can send to a group. It does not need to have joined the group.
     DatagramChannel dc = DatagramChannel.open();
-    if (sendingInterface != null) {
-      // For some reason, if set, this must be set to a real (non-loopback) device for an IPv6
-      // group, but can be loopback for an IPv4 group.
-      dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, sendingInterface);
-    }
-    sendMessage(dc, msg, new InetSocketAddress(group, port));
+    dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, sendingInterface);
+    sendMessage(dc, msg, new InetSocketAddress(targetGroup, targetPort));
     dc.close();
   }
 
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
index d0b46ed..09a18e2 100644
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
@@ -53,59 +53,116 @@
 
 public class KeyPairGeneratorTest extends TestCase {
 
-    public void test_getInstance() throws Exception {
+    public void test_providerCount() {
         Provider[] providers = Security.getProviders();
-        for (Provider provider : providers) {
-            Set<Provider.Service> services = provider.getServices();
-            for (Provider.Service service : services) {
-                String type = service.getType();
-                if (!type.equals("KeyPairGenerator")) {
-                    continue;
+        // We expect there to be at least one provider.
+        assertTrue(providers.length > 0);
+        // If this fails remember to add _provider methods below. This test is sharded because it
+        // takes a long time to execute.
+        assertTrue(providers.length < 10);
+    }
+
+    public void test_getInstance_provider0() throws Exception {
+        test_getInstance(0);
+    }
+
+    public void test_getInstance_provider1() throws Exception {
+        test_getInstance(1);
+    }
+
+    public void test_getInstance_provider2() throws Exception {
+        test_getInstance(2);
+    }
+
+    public void test_getInstance_provider3() throws Exception {
+        test_getInstance(3);
+    }
+
+    public void test_getInstance_provider4() throws Exception {
+        test_getInstance(4);
+    }
+
+    public void test_getInstance_provider5() throws Exception {
+        test_getInstance(5);
+    }
+
+    public void test_getInstance_provider6() throws Exception {
+        test_getInstance(6);
+    }
+
+    public void test_getInstance_provider7() throws Exception {
+        test_getInstance(7);
+    }
+
+    public void test_getInstance_provider8() throws Exception {
+        test_getInstance(8);
+    }
+
+    public void test_getInstance_provider9() throws Exception {
+        test_getInstance(9);
+    }
+
+    private void test_getInstance(int providerIndex) throws Exception {
+        Provider[] providers = Security.getProviders();
+        if (providerIndex >= providers.length) {
+            // Providers can be added by vendors and other tests. We do not
+            // specify a fixed number and silenty pass if the provider at the
+            // specified index does not exist.
+            return;
+        }
+        Provider provider = providers[providerIndex];
+        Set<Provider.Service> services = provider.getServices();
+        for (Provider.Service service : services) {
+            String type = service.getType();
+            if (!type.equals("KeyPairGenerator")) {
+                continue;
+            }
+            String algorithm = service.getAlgorithm();
+
+            // AndroidKeyStore is tested in CTS.
+            if ("AndroidKeyStore".equals(provider.getName())) {
+                continue;
+            }
+
+            AlgorithmParameterSpec params = null;
+
+            // TODO: detect if we're running in vogar and run the full test
+            if ("DH".equals(algorithm)) {
+                // Disabled because this takes too long on devices.
+                // TODO: Re-enable DH test. http://b/5513723.
+                // params = getDHParams();
+                continue;
+            }
+
+            try {
+                // KeyPairGenerator.getInstance(String)
+                KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
+                assertEquals(algorithm, kpg1.getAlgorithm());
+                if (params != null) {
+                    kpg1.initialize(params);
                 }
-                String algorithm = service.getAlgorithm();
+                test_KeyPairGenerator(kpg1);
 
-                // AndroidKeyStore is tested in CTS.
-                if ("AndroidKeyStore".equals(provider.getName())) {
-                    continue;
+                // KeyPairGenerator.getInstance(String, Provider)
+                KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
+                assertEquals(algorithm, kpg2.getAlgorithm());
+                assertEquals(provider, kpg2.getProvider());
+                if (params != null) {
+                    kpg2.initialize(params);
                 }
+                test_KeyPairGenerator(kpg2);
 
-                AlgorithmParameterSpec params = null;
-
-                // TODO: detect if we're running in vogar and run the full test
-                if ("DH".equals(algorithm)) {
-                    params = getDHParams();
+                // KeyPairGenerator.getInstance(String, String)
+                KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
+                                                                    provider.getName());
+                assertEquals(algorithm, kpg3.getAlgorithm());
+                assertEquals(provider, kpg3.getProvider());
+                if (params != null) {
+                    kpg3.initialize(params);
                 }
-
-                try {
-                    // KeyPairGenerator.getInstance(String)
-                    KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
-                    assertEquals(algorithm, kpg1.getAlgorithm());
-                    if (params != null) {
-                        kpg1.initialize(params);
-                    }
-                    test_KeyPairGenerator(kpg1);
-
-                    // KeyPairGenerator.getInstance(String, Provider)
-                    KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
-                    assertEquals(algorithm, kpg2.getAlgorithm());
-                    assertEquals(provider, kpg2.getProvider());
-                    if (params != null) {
-                        kpg2.initialize(params);
-                    }
-                    test_KeyPairGenerator(kpg2);
-
-                    // KeyPairGenerator.getInstance(String, String)
-                    KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm,
-                                                                        provider.getName());
-                    assertEquals(algorithm, kpg3.getAlgorithm());
-                    assertEquals(provider, kpg3.getProvider());
-                    if (params != null) {
-                        kpg3.initialize(params);
-                    }
-                    test_KeyPairGenerator(kpg3);
-                } catch (Exception e) {
-                    throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
-                }
+                test_KeyPairGenerator(kpg3);
+            } catch (Exception e) {
+                throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
             }
         }
     }
@@ -341,8 +398,6 @@
     public void testDSAGeneratorWithParams() throws Exception {
         final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G);
 
-        boolean failure = false;
-
         final Provider[] providers = Security.getProviders();
         for (final Provider p : providers) {
             Service s = p.getService("KeyPairGenerator", "DSA");
diff --git a/luni/src/test/java/libcore/java/sql/ConnectionTest.java b/luni/src/test/java/libcore/java/sql/ConnectionTest.java
new file mode 100644
index 0000000..02046fc
--- /dev/null
+++ b/luni/src/test/java/libcore/java/sql/ConnectionTest.java
@@ -0,0 +1,69 @@
+package libcore.java.sql;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+
+public class ConnectionTest extends TestCase {
+
+    private File dbFile = null;
+    private String connectionURL = null;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Trigger the static initializer that will cause the driver to register itself with
+        // DriverManager.
+        Class.forName("SQLite.JDBCDriver");
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (dbFile != null) {
+            dbFile.delete();
+        }
+    }
+
+    public void testDriverManager_getConnection() throws Exception {
+        Connection c = DriverManager.getConnection(getConnectionURL());
+        assertFalse(c.isClosed());
+        c.close();
+        assertTrue(c.isClosed());
+    }
+
+    public void testConnect() throws Exception {
+        Driver driver = DriverManager.getDriver(getConnectionURL());
+        assertNotNull(driver);
+        Connection c = driver.connect(getConnectionURL(), null);
+        assertFalse(c.isClosed());
+        c.close();
+        assertTrue(c.isClosed());
+    }
+
+    private String getConnectionURL() {
+        if (connectionURL == null) {
+            String tmp = System.getProperty("java.io.tmpdir");
+            File tmpDir = new File(tmp);
+            if (tmpDir.isDirectory()) {
+                try {
+                    dbFile = File.createTempFile("OldJDBCDriverTest", ".db", tmpDir);
+                } catch (IOException e) {
+                    System.err.println("error creating temporary DB file.");
+                }
+                dbFile.deleteOnExit();
+            } else {
+                System.err.println("java.io.tmpdir does not exist");
+            }
+
+            connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
+        }
+
+        return connectionURL;
+    }
+}
diff --git a/luni/src/test/java/libcore/java/sql/DriverTest.java b/luni/src/test/java/libcore/java/sql/DriverTest.java
new file mode 100644
index 0000000..59d13bd
--- /dev/null
+++ b/luni/src/test/java/libcore/java/sql/DriverTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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 libcore.java.sql;
+
+import junit.framework.TestCase;
+
+import SQLite.JDBCDriver;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+
+public final class DriverTest extends TestCase {
+
+    public static final String SQLITE_JDBC_URL = "jdbc:sqlite:/only_used_at_connect_time";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Trigger the static initializer that will cause the driver to register itself with
+        // DriverManager.
+        Class.forName("SQLite.JDBCDriver");
+    }
+
+    public void testDriverImplementation() throws Exception {
+        Driver driver = getDriver();
+        assertTrue(driver instanceof JDBCDriver);
+    }
+
+    public void testAcceptsURL() throws Exception {
+        Driver driver = getDriver();
+        assertTrue(driver.acceptsURL(SQLITE_JDBC_URL));
+    }
+
+    public void testGetMajorVersion() throws Exception {
+        assertTrue(getDriver().getMajorVersion() > 0);
+    }
+
+    public void testGetMinorVersion() throws Exception {
+        assertTrue(getDriver().getMinorVersion() > 0);
+    }
+
+    public void testGetPropertyInfo() throws Exception {
+        Driver driver = getDriver();
+        DriverPropertyInfo[] info = driver.getPropertyInfo(SQLITE_JDBC_URL, null);
+        assertNotNull(info);
+        assertTrue(info.length > 0);
+    }
+
+    public void testJdbcCompliant() throws Exception {
+        // The SQLite JDBC driver used by these tests is not actually JDBC compliant.
+        assertFalse(getDriver().jdbcCompliant());
+    }
+
+    private Driver getDriver() throws SQLException {
+        Driver driver = DriverManager.getDriver(SQLITE_JDBC_URL);
+        assertNotNull(driver);
+        return driver;
+    }
+}
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index c58f83a..0eae20a 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -124,21 +124,21 @@
         df.setMaximumFractionDigits(2);
         df.setMultiplier(2);
         assertEquals(df.format(BigDecimal.valueOf(0.16)),
-        df.format(BigDecimal.valueOf(0.16).doubleValue()));
+                df.format(BigDecimal.valueOf(0.16).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.0293)),
-        df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+                df.format(BigDecimal.valueOf(0.0293).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.006)),
-        df.format(BigDecimal.valueOf(0.006).doubleValue()));
+                df.format(BigDecimal.valueOf(0.006).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0.00283)),
-        df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+                df.format(BigDecimal.valueOf(0.00283).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1.60)),
         df.format(BigDecimal.valueOf(1.60).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(15)),
-        df.format(BigDecimal.valueOf(15).doubleValue()));
+                df.format(BigDecimal.valueOf(15).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(170)),
-        df.format(BigDecimal.valueOf(170).doubleValue()));
+                df.format(BigDecimal.valueOf(170).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(234.56)),
-        df.format(BigDecimal.valueOf(234.56).doubleValue()));
+                df.format(BigDecimal.valueOf(234.56).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(0)),
         df.format(BigDecimal.valueOf(0).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(-1)),
@@ -146,11 +146,11 @@
         assertEquals(df.format(BigDecimal.valueOf(-10000)),
         df.format(BigDecimal.valueOf(-10000).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(-0.001)),
-        df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+                df.format(BigDecimal.valueOf(-0.001).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
-        df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+                df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
         assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
-        df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+                df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
     }
 
     private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
@@ -260,4 +260,62 @@
       } catch (NullPointerException expected) {
       }
     }
+
+    // Confirm the fraction digits do not change when the currency is changed.
+    public void testBug71369() {
+        final String nonBreakingSpace = "\u00A0";
+
+        NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.GERMAN);
+        numberFormat.setCurrency(Currency.getInstance("USD"));
+
+        assertEquals("2,01" + nonBreakingSpace + "$", numberFormat.format(2.01));
+
+        numberFormat.setMinimumFractionDigits(0);
+        numberFormat.setMaximumFractionDigits(0);
+
+        String expected = "2" + nonBreakingSpace + "$";
+        assertEquals(expected, numberFormat.format(2.01));
+
+        // Changing the currency must not reset the digits.
+        numberFormat.setCurrency(Currency.getInstance("EUR"));
+        numberFormat.setCurrency(Currency.getInstance("USD"));
+
+        assertEquals(expected, numberFormat.format(2.01));
+    }
+
+    // Confirm the currency symbol used by a format is determined by the locale of the format
+    // not the current default Locale.
+    public void testSetCurrency_symbolOrigin() {
+        Currency currency = Currency.getInstance("CNY");
+        Locale locale1 = Locale.CHINA;
+        Locale locale2 = Locale.US;
+        String locale1Symbol = currency.getSymbol(locale1);
+        String locale2Symbol = currency.getSymbol(locale2);
+        // This test only works if we can tell where the symbol came from, which requires they are
+        // different across the two locales chosen.
+        assertFalse(locale1Symbol.equals(locale2Symbol));
+
+        Locale originalLocale = Locale.getDefault();
+        try {
+            Locale.setDefault(locale1);
+            String amountDefaultLocale1 =
+                    formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+            Locale.setDefault(locale2);
+            String amountDefaultLocale2 =
+                    formatArbitraryCurrencyAmountInLocale(currency, locale2);
+
+            // This used to fail because Currency.getSymbol() was used without providing the
+            // format's locale.
+            assertEquals(amountDefaultLocale1, amountDefaultLocale2);
+        } finally {
+            Locale.setDefault(originalLocale);
+        }
+    }
+
+    private String formatArbitraryCurrencyAmountInLocale(Currency currency, Locale locale) {
+        NumberFormat localeCurrencyFormat = NumberFormat.getCurrencyInstance(locale);
+        localeCurrencyFormat.setCurrency(currency);
+        return localeCurrencyFormat.format(1000);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java b/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java
new file mode 100644
index 0000000..5a8a6cf
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/LocaleInternalsTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package libcore.java.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import junit.framework.TestCase;
+import libcore.icu.ICU;
+
+public class LocaleInternalsTest extends TestCase {
+
+    public void test_serializeExtensions() {
+        Map<Character, String> extensions = new TreeMap<Character, String>();
+
+        extensions.put('x', "fooo-baar-baaz");
+        assertEquals("x-fooo-baar-baaz", Locale.serializeExtensions(extensions));
+
+        extensions.put('y', "gaaa-caar-caaz");
+        // Must show up in lexical order.
+        assertEquals("x-fooo-baar-baaz-y-gaaa-caar-caaz",
+                Locale.serializeExtensions(extensions));
+    }
+
+    public void test_parseSerializedExtensions() {
+        Map<Character, String> extensions = new HashMap<Character, String>();
+
+        Locale.parseSerializedExtensions("x-foo", extensions);
+        assertEquals("foo", extensions.get('x'));
+
+        extensions.clear();
+        Locale.parseSerializedExtensions("x-foo-y-bar-z-baz", extensions);
+        assertEquals("foo", extensions.get('x'));
+        assertEquals("bar", extensions.get('y'));
+        assertEquals("baz", extensions.get('z'));
+
+        extensions.clear();
+        Locale.parseSerializedExtensions("x-fooo-baar-baaz", extensions);
+        assertEquals("fooo-baar-baaz", extensions.get('x'));
+
+        extensions.clear();
+        Locale.parseSerializedExtensions("x-fooo-baar-baaz-y-gaaa-caar-caaz", extensions);
+        assertEquals("fooo-baar-baaz", extensions.get('x'));
+        assertEquals("gaaa-caar-caaz", extensions.get('y'));
+    }
+
+    public void test_parseUnicodeExtension() {
+        Map<String, String> keywords = new HashMap<String, String>();
+        Set<String> attributes = new HashSet<String>();
+
+        // Only attributes.
+        Locale.parseUnicodeExtension("foooo".split("-"), keywords, attributes);
+        assertTrue(attributes.contains("foooo"));
+        assertTrue(keywords.isEmpty());
+
+        attributes.clear();
+        keywords.clear();
+        Locale.parseUnicodeExtension("foooo-baa-baaabaaa".split("-"),
+                keywords, attributes);
+        assertTrue(attributes.contains("foooo"));
+        assertTrue(attributes.contains("baa"));
+        assertTrue(attributes.contains("baaabaaa"));
+        assertTrue(keywords.isEmpty());
+
+        // Only keywords
+        attributes.clear();
+        keywords.clear();
+        Locale.parseUnicodeExtension("ko-koko".split("-"), keywords, attributes);
+        assertTrue(attributes.isEmpty());
+        assertEquals("koko", keywords.get("ko"));
+
+        attributes.clear();
+        keywords.clear();
+        Locale.parseUnicodeExtension("ko-koko-kokoko".split("-"), keywords, attributes);
+        assertTrue(attributes.isEmpty());
+        assertEquals("koko-kokoko", keywords.get("ko"));
+
+        attributes.clear();
+        keywords.clear();
+        Locale.parseUnicodeExtension("ko-koko-kokoko-ba-baba-bababa".split("-"),
+                keywords, attributes);
+        assertTrue(attributes.isEmpty());
+        assertEquals("koko-kokoko", keywords.get("ko"));
+        assertEquals("baba-bababa", keywords.get("ba"));
+
+        // A mixture of attributes and keywords.
+        attributes.clear();
+        keywords.clear();
+        Locale.parseUnicodeExtension("attri1-attri2-k1-type1-type1-k2-type2".split("-"),
+                keywords, attributes);
+        assertTrue(attributes.contains("attri1"));
+        assertTrue(attributes.contains("attri2"));
+        assertEquals("type1-type1", keywords.get("k1"));
+        assertEquals("type2", keywords.get("k2"));
+    }
+
+    public void test_setDefault_setsICUDefaultLocale() {
+        Locale.setDefault(Locale.GERMANY);
+        assertEquals("de_DE", ICU.getDefaultLocale());
+
+        try {
+            Locale.setDefault(null);
+            fail();
+        } catch (NullPointerException expected) {
+            assertEquals(Locale.GERMANY, Locale.getDefault());
+        }
+
+        Locale.setDefault(new Locale("bogus", "LOCALE"));
+        assertEquals("bogus__LOCALE", ICU.getDefaultLocale());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index baa53e9..f3b31bb 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -22,15 +22,9 @@
 import java.text.DateFormatSymbols;
 import java.text.NumberFormat;
 import java.util.Calendar;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.IllformedLocaleException;
 import java.util.Locale;
-import java.util.Map;
 import java.util.MissingResourceException;
-import java.util.Set;
-import java.util.TreeMap;
-import libcore.icu.ICU;
 
 public class LocaleTest extends junit.framework.TestCase {
     // http://b/2611311; if there's no display language/country/variant, use the raw codes.
@@ -45,9 +39,22 @@
         // and variant, but a display name made up of the raw strings.
         // Newer releases return slightly different results, but no less unreasonable.
         assertEquals("aabbcc", invalid.getDisplayLanguage());
-        assertEquals("", invalid.getDisplayCountry());
-        assertEquals("DDEEFF_GGHHII", invalid.getDisplayVariant());
-        assertEquals("aabbcc (DDEEFF,DDEEFF_GGHHII)", invalid.getDisplayName());
+        assertEquals("DDEEFF", invalid.getDisplayCountry());
+        assertEquals("GGHHII", invalid.getDisplayVariant());
+        assertEquals("aabbcc (DDEEFF,GGHHII)", invalid.getDisplayName());
+    }
+
+    public void test_getDisplayName_emptyCodes() {
+        Locale emptyLanguage = new Locale("", "DdeEFf");
+        assertEquals("", emptyLanguage.getDisplayLanguage());
+
+        Locale emptyCountry = new Locale("AaBbCc", "");
+        assertEquals("", emptyCountry.getDisplayCountry());
+
+        Locale emptyCountryAndLanguage = new Locale("", "", "Farl");
+        assertEquals("", emptyCountryAndLanguage.getDisplayLanguage());
+        assertEquals("", emptyCountryAndLanguage.getDisplayCountry());
+        assertEquals("Farl", emptyCountryAndLanguage.getDisplayVariant());
     }
 
     // http://b/2611311; if there's no display language/country/variant, use the raw codes.
@@ -59,8 +66,8 @@
 
         assertEquals("xx", unknown.getDisplayLanguage());
         assertEquals("YY", unknown.getDisplayCountry());
-        assertEquals("TRADITIONAL", unknown.getDisplayVariant());
-        assertEquals("xx (YY,TRADITIONAL)", unknown.getDisplayName());
+        assertEquals("Traditional", unknown.getDisplayVariant());
+        assertEquals("xx (YY,Traditional)", unknown.getDisplayName());
     }
 
     public void test_getDisplayName_easy() throws Exception {
@@ -179,6 +186,10 @@
         assertEquals("CAN", new Locale("", "CA").getISO3Country());
         assertEquals("CAN", new Locale("en", "CA").getISO3Country());
         assertEquals("CAN", new Locale("xx", "CA").getISO3Country());
+
+        // 3 letter country codes.
+        assertEquals("CAN", new Locale("en", "CAN").getISO3Country());
+        assertEquals("CAN", new Locale("frankenderp", "CAN").getISO3Country());
     }
 
     public void test_getISO3Language() {
@@ -198,90 +209,10 @@
         assertEquals("eng", new Locale("en", "").getISO3Language());
         assertEquals("eng", new Locale("en", "CA").getISO3Language());
         assertEquals("eng", new Locale("en", "XX").getISO3Language());
-    }
 
-    public void test_serializeExtensions() {
-        Map<Character, String> extensions = new TreeMap<Character, String>();
-
-        extensions.put('x', "fooo-baar-baaz");
-        assertEquals("x-fooo-baar-baaz", Locale.serializeExtensions(extensions));
-
-        extensions.put('y', "gaaa-caar-caaz");
-        // Must show up in lexical order.
-        assertEquals("x-fooo-baar-baaz-y-gaaa-caar-caaz",
-                Locale.serializeExtensions(extensions));
-    }
-
-    public void test_parseSerializedExtensions() {
-        Map<Character, String> extensions = new HashMap<Character, String>();
-
-        Locale.parseSerializedExtensions("x-foo", extensions);
-        assertEquals("foo", extensions.get('x'));
-
-        extensions.clear();
-        Locale.parseSerializedExtensions("x-foo-y-bar-z-baz", extensions);
-        assertEquals("foo", extensions.get('x'));
-        assertEquals("bar", extensions.get('y'));
-        assertEquals("baz", extensions.get('z'));
-
-        extensions.clear();
-        Locale.parseSerializedExtensions("x-fooo-baar-baaz", extensions);
-        assertEquals("fooo-baar-baaz", extensions.get('x'));
-
-        extensions.clear();
-        Locale.parseSerializedExtensions("x-fooo-baar-baaz-y-gaaa-caar-caaz", extensions);
-        assertEquals("fooo-baar-baaz", extensions.get('x'));
-        assertEquals("gaaa-caar-caaz", extensions.get('y'));
-    }
-
-    public void test_parseUnicodeExtension() {
-        Map<String, String> keywords = new HashMap<String, String>();
-        Set<String> attributes = new HashSet<String>();
-
-        // Only attributes.
-        Locale.parseUnicodeExtension("foooo".split("-"), keywords, attributes);
-        assertTrue(attributes.contains("foooo"));
-        assertTrue(keywords.isEmpty());
-
-        attributes.clear();
-        keywords.clear();
-        Locale.parseUnicodeExtension("foooo-baa-baaabaaa".split("-"),
-                keywords, attributes);
-        assertTrue(attributes.contains("foooo"));
-        assertTrue(attributes.contains("baa"));
-        assertTrue(attributes.contains("baaabaaa"));
-        assertTrue(keywords.isEmpty());
-
-        // Only keywords
-        attributes.clear();
-        keywords.clear();
-        Locale.parseUnicodeExtension("ko-koko".split("-"), keywords, attributes);
-        assertTrue(attributes.isEmpty());
-        assertEquals("koko", keywords.get("ko"));
-
-        attributes.clear();
-        keywords.clear();
-        Locale.parseUnicodeExtension("ko-koko-kokoko".split("-"), keywords, attributes);
-        assertTrue(attributes.isEmpty());
-        assertEquals("koko-kokoko", keywords.get("ko"));
-
-        attributes.clear();
-        keywords.clear();
-        Locale.parseUnicodeExtension("ko-koko-kokoko-ba-baba-bababa".split("-"),
-                keywords, attributes);
-        assertTrue(attributes.isEmpty());
-        assertEquals("koko-kokoko", keywords.get("ko"));
-        assertEquals("baba-bababa", keywords.get("ba"));
-
-        // A mixture of attributes and keywords.
-        attributes.clear();
-        keywords.clear();
-        Locale.parseUnicodeExtension("attri1-attri2-k1-type1-type1-k2-type2".split("-"),
-                keywords, attributes);
-        assertTrue(attributes.contains("attri1"));
-        assertTrue(attributes.contains("attri2"));
-        assertEquals("type1-type1", keywords.get("k1"));
-        assertEquals("type2", keywords.get("k2"));
+        // 3 letter language code.
+        assertEquals("eng", new Locale("eng", "USA").getISO3Language());
+        assertEquals("eng", new Locale("eng", "US").getISO3Language());
     }
 
     public void test_Builder_setLanguage() {
@@ -1105,7 +1036,7 @@
     }
 
     public void test_toString() {
-                Locale.Builder b = new Locale.Builder();
+        Locale.Builder b = new Locale.Builder();
 
         // Empty builder.
         Locale l = b.build();
@@ -1164,21 +1095,6 @@
         Locale posix = new Locale.Builder()
                 .setLanguage("en").setRegion("US").setVariant("POSIX")
                 .build();
-        assertEquals("en-US-u-va-posix", posix.toLanguageTag());
-    }
-
-    public void test_setDefault_setsICUDefaultLocale() {
-        Locale.setDefault(Locale.GERMANY);
-        assertEquals("de_DE", ICU.getDefaultLocale());
-
-        try {
-            Locale.setDefault(null);
-            fail();
-        } catch (NullPointerException expected) {
-            assertEquals(Locale.GERMANY, Locale.getDefault());
-        }
-
-        Locale.setDefault(new Locale("bogus", "LOCALE"));
-        assertEquals("bogus__LOCALE", ICU.getDefaultLocale());
+        assertEquals("en-US-POSIX", posix.toLanguageTag());
     }
 }
diff --git a/luni/src/test/java/libcore/sqlite/AbstractSqlTest.java b/luni/src/test/java/libcore/sqlite/AbstractSqlTest.java
deleted file mode 100644
index d194548..0000000
--- a/luni/src/test/java/libcore/sqlite/AbstractSqlTest.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 libcore.sqlite;
-
-import SQLite.Exception;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import junit.framework.TestCase;
-
-
-/**
- * This class provides SQL unit test, which can be used by subclasses eg. to
- * test JDBC drivers.
- */
-abstract class AbstractSqlTest extends TestCase {
-
-    /**
-     * The first connection.
-     */
-    private Connection firstConnection;
-
-    /**
-     * The second connection.
-     */
-    private Connection secondConnection;
-
-    /**
-     * The statement from the first connection.
-     */
-    private Statement firstStmt;
-
-    /**
-     * The statement from the second connection.
-     */
-    private Statement secondStmt;
-
-    /**
-     * The values of the first column "one".
-     */
-    private final String[] ones = {"hello!", "goodbye"};
-
-    /**
-     * The values of the second column "two".
-     */
-    private final short[] twos = {10, 20};
-
-    /**
-     * The updated values of the first column "one".
-     */
-    private final String[] ones_updated;
-
-    /** Creates a new instance of this class */
-    public AbstractSqlTest() {
-        super();
-        ones_updated = new String[ones.length];
-        for (int i = 0; i < ones.length; i++) {
-            ones_updated[i] = ones[i] + twos[i];
-        }
-    }
-
-    /**
-     * Sets up a unit test, by creating two statements from two connections and
-     * creating a test table.
-     *
-     * @exception SQLException if there is a problem accessing the database
-     * @throws Exception
-     * @exception Exception may be thrown by subclasses
-     */
-    @Override
-    protected void setUp() throws java.lang.Exception {
-        Class.forName(getDriverClassName()).newInstance();
-        firstConnection = DriverManager.getConnection(getConnectionURL());
-        firstConnection.setTransactionIsolation(getTransactionIsolation());
-        secondConnection = DriverManager.getConnection(getConnectionURL());
-        secondConnection.setTransactionIsolation(getTransactionIsolation());
-        firstStmt = firstConnection.createStatement();
-        firstStmt.execute("create table tbl1(one varchar(10), two smallint)");
-        secondStmt = secondConnection.createStatement();
-    }
-
-    /**
-     * Tears down a unit test, by setting the auto commit property of the first
-     * connection back to true, dropping the test table and closing the two
-     * connections.
-     */
-    @Override
-    protected void tearDown() throws SQLException {
-        firstStmt.close();
-        secondStmt.close();
-        firstConnection.setAutoCommit(true);
-        firstStmt = firstConnection.createStatement();
-        firstStmt.execute("drop table tbl1");
-        firstStmt.close();
-        firstConnection.close();
-        secondConnection.close();
-    }
-
-    /**
-     * Adds some rows to the test table and asserts that the rows can be
-     * retrieved again.
-     *
-     * @throws SQLException if there is a problem accessing the database
-     */
-    private void autoCommitInsertSelect() throws SQLException {
-        firstStmt.getConnection().setAutoCommit(true);
-        for (int i = 0; i < ones.length; i++) {
-            firstStmt.execute("insert into tbl1 values('" + ones[i] + "',"
-                    + twos[i] + ")");
-        }
-        assertAllFromTbl1(firstStmt, ones, twos);
-    }
-
-    /**
-     * Asserts that the expected values can be selected from the test table.
-     *
-     * @param stmt the statement to be used for the selection of the data
-     * @param ones the expected values of the column 'one'
-     * @param twos the expected values of the column 'two'
-     * @throws SQLException if there is a problem accessing the database
-     */
-    private void assertAllFromTbl1(Statement stmt, String[] ones, short[] twos)
-            throws SQLException {
-        ResultSet rs = stmt.executeQuery("select * from tbl1");
-        int i = 0;
-        for (; rs.next(); i++) {
-            assertTrue(i < ones.length);
-            assertEquals(ones[i], rs.getString("one"));
-            assertEquals(twos[i], rs.getShort("two"));
-        }
-        assertTrue(i == ones.length);
-    }
-
-    public void testAutoCommitInsertSelect() throws SQLException{
-        autoCommitInsertSelect();
-    }
-
-    /**
-     * Tests the following sequence after successful insertion of some test
-     * data:
-     * - update data from connection one
-     * - select data from connection two (-> should have the old values)
-     * - commit data from connection one
-     * - select data from connection two (-> should have the new values)
-     *
-     * @throws SQLException if there is a problem accessing the database
-     */
-    public void testUpdateSelectCommitSelect() throws SQLException {
-        autoCommitInsertSelect();
-        firstStmt.getConnection().setAutoCommit(false);
-        updateOnes(firstStmt, ones_updated, twos);
-        assertAllFromTbl1(secondStmt, ones, twos);
-        firstStmt.getConnection().commit();
-        assertAllFromTbl1(secondStmt, ones_updated, twos);
-    }
-
-    /**
-     * Tests the following sequence after successful insertion of some test
-     * data:
-     * - update data from connection one
-     * - select data from connection two (-> should have the old values)
-     * - rollback data from connection one
-     * - select data from connection two (-> should still have the old values)
-     *
-     * @throws SQLException if there is a problem accessing the database
-     */
-    public void testUpdateSelectRollbackSelect() throws SQLException {
-        autoCommitInsertSelect();
-        firstStmt.getConnection().setAutoCommit(false);
-        updateOnes(firstStmt, ones_updated, twos);
-        assertAllFromTbl1(secondStmt, ones, twos);
-        firstStmt.getConnection().rollback();
-        assertAllFromTbl1(secondStmt, ones, twos);
-    }
-
-    /**
-     * Updates the values in column 'one'
-     * @param stmt the statement to be used to update the data
-     * @param ones_updated the updated valus of column 'one'
-     * @param twos the reference values of column 'two'
-     * @throws SQLException if there is a problem accessing the database
-     */
-    private void updateOnes(Statement stmt, String[] ones_updated, short[] twos)
-            throws SQLException {
-        for (int i = 0; i < ones_updated.length; i++) {
-            stmt.execute("UPDATE tbl1 SET one = '" + ones_updated[i]
-                    + "' WHERE two = " + twos[i]);
-        }
-    }
-
-    protected abstract String getConnectionURL();
-
-    protected abstract String getDriverClassName();
-
-    protected abstract int getTransactionIsolation();
-
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldBlobTest.java b/luni/src/test/java/libcore/sqlite/OldBlobTest.java
deleted file mode 100644
index 3289d38..0000000
--- a/luni/src/test/java/libcore/sqlite/OldBlobTest.java
+++ /dev/null
@@ -1,135 +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 libcore.sqlite;
-
-import SQLite.Blob;
-import SQLite.Database;
-import SQLite.Exception;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import tests.support.Support_SQL;
-
-public final class OldBlobTest extends OldSQLiteTest {
-
-    private static Blob testBlob = null;
-
-    private static Database db = null;
-
-    public void setUp() throws java.lang.Exception {
-        super.setUp();
-        testBlob = new Blob();
-
-        super.setUp();
-        Support_SQL.loadDriver();
-        db = new Database();
-        db.open(dbFile.getPath(), 0);
-
-        db.exec("create table B(id integer primary key, val blob)",null);
-        db.exec("insert into B values(1, zeroblob(128))", null);
-        db.exec("insert into B values(2, zeroblob(128))", null);
-        db.exec("insert into B values(3, zeroblob(128))", null);
-
-        // can not fill Blob with data at this point...
-        /*
-        File resources = Support_Resources.createTempFolder();
-        BufferedReader r = null;
-        try {
-            Class c = Class.forName(this.getClass().getName());
-            assertNotNull(c);
-            file = Class.forName(this.getClass().getName())
-                    .getResourceAsStream("/blob.c");
-            r = new BufferedReader(new InputStreamReader(file));
-        } catch (NullPointerException e) {
-            fail("Should not throw NullPointerException reading file"
-                    + e.getMessage());
-        }
-        OutputStream out = testBlob.getOutputStream();
-        String s = null;
-        while ((s = r.readLine()) != null) {
-            out.write(r.readLine().getBytes());
-        }
-        out.flush();
-        out.close();
-        testBlob.close();
-        */
-    }
-
-    @Override public void tearDown() throws java.lang.Exception {
-        testBlob.close();
-        super.tearDown();
-    }
-
-    /**
-     * db.open_blob is not supported.
-     */
-    public void testBlob() throws Exception, IOException {
-        byte[] b = new byte[4];
-        byte[] b128 = new byte[128];
-        for (int i = 0; i < b128.length; i++) {
-        b128[i] = (byte) i;
-        }
-        Blob blob = db.open_blob(dbFile.getPath(), "B", "val", 1, true);
-        try {
-
-        OutputStream os = blob.getOutputStream();
-        os.write(b128);
-        os.close();
-
-        InputStream is = blob.getInputStream();
-        is.skip(96);
-        assertEquals(4,is.read(b));
-        is.close();
-        } finally {
-        blob.close();
-        }
-    }
-
-    public void testGetInputStream() {
-        InputStream in = testBlob.getInputStream();
-        try {
-            in.read();
-            fail("Exception not thrown for invalid Blob.");
-        } catch (Throwable e) {
-            //ok
-        }
-    }
-
-    public void testGetOutputStream() {
-        OutputStream out = testBlob.getOutputStream();
-
-        try {
-           out.write(null);
-           fail("Write operation unsupported");
-        } catch (Throwable e) {
-            assertEquals("Write operation unsupported", e.getMessage());
-        }
-    }
-
-    public void testClose() {
-        assertNotNull(testBlob);
-
-        testBlob.close();
-        // inputStream either null or some error occurs
-        try {
-            // TODO This does look a bit weird. Revisit later.
-            assertNull(testBlob.getInputStream());
-        } catch (Throwable e) {
-            //ok
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java b/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java
deleted file mode 100644
index f2cbc57..0000000
--- a/luni/src/test/java/libcore/sqlite/OldDatabaseTest.java
+++ /dev/null
@@ -1,1224 +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 libcore.sqlite;
-
-import SQLite.Authorizer;
-import SQLite.Blob;
-import SQLite.BusyHandler;
-import SQLite.Callback;
-import SQLite.Constants;
-import SQLite.Database;
-import SQLite.Exception;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.ProgressHandler;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import SQLite.Trace;
-import SQLite.Vm;
-import java.io.File;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Logger;
-import tests.support.DatabaseCreator;
-import tests.support.MockFunction;
-import tests.support.ThreadPool;
-
-public final class OldDatabaseTest extends OldSQLiteTest {
-
-    private static ErrorTracker tracker = null;
-
-    private Statement statement;
-
-    private Database db = null;
-
-    private static final int numThreads = 10;
-
-    private static final int numOfRecords = 30;
-
-    @Override public void setUp() throws java.lang.Exception {
-        super.setUp();
-        assertNotNull("Could not establish DB connection",conn);
-        tracker = new ErrorTracker();
-
-        statement = conn.createStatement();
-
-        // Cleanup tables if necessary
-
-        DatabaseMetaData meta = conn.getMetaData();
-        assertNotNull(meta);
-        ResultSet userTab = meta.getTables(null, null, null, null);
-        while (userTab.next()) {
-            String tableName = userTab.getString("TABLE_NAME");
-            this.statement.execute("drop table " + tableName);
-        }
-
-        // Create default test table
-        statement.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
-        statement.close();
-
-        db = new Database();
-        db.open(dbFile.getPath(), 0);
-        db.busy_handler(null);
-    }
-
-    public void tearDown() throws java.lang.Exception {
-        try {
-            db.close();
-        } catch (Exception e) {
-            if (!(e.getMessage().equals("database already closed"))) {
-                System.err.println("Error closing DB " + dbFile.getPath());
-            }
-        }
-        tracker.reset();
-        super.tearDown();
-    }
-
-    public void testDatabase() throws Exception {
-        // db closed
-        Database db2 = new Database();
-        db.close();
-        db2 = new Database();
-        db2.open(dbFile.getPath(), 0);
-        db2.close();
-        db.open(dbFile.getPath(), 0);
-        //db is open
-        db2.open(dbFile.getPath(), 0);
-        db2.close();
-    }
-
-    public void testOpen() throws Exception {
-        db.close();
-        db.open(dbFile.getPath(), 0);
-        // open second db while db1 still open
-        Database db2 = new Database();
-        db2.open(dbFile.getPath(), 0);
-        db2.open(dbFile.getPath(), 0);
-        db2.close();
-        // open non db file
-        try {
-            URL file = OldDatabaseTest.class.getResource("/blob.c");
-            db2.open(file.getPath(), 0);
-            fail("Should not be able to open non db file");
-        } catch (SQLite.Exception e) {
-            assertEquals("unknown error in open", e.getMessage());
-        }
-    }
-
-    public void testOpen_aux_file() {
-        File temp = null;
-        try {
-            db.open_aux_file("");
-            fail("open should fail");
-        } catch (Exception e) {
-            assertEquals("unsupported", e.getMessage());
-        }
-
-     /*
-        try {
-            temp = File.createTempFile("openAuxMethod", ".db");
-            db.open_aux_file("");
-            db.exec("create table AUX_TABLE", null);
-            db.close();
-        } catch (Exception e) {
-            temp.delete();
-            fail("Error handling temporary file "+e.getMessage());
-            e.printStackTrace();
-        } catch (IOException e) {
-            temp.delete();
-            fail("Could not create temporary File");
-            e.printStackTrace();
-        }
-        try {
-            db.open(dbFile.getPath(),0);
-            db.exec("select * from AUX_TABLE", null);
-            fail("Statement should fail");
-        } catch (Exception e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
-        temp.delete();
-        */
-    }
-
-    public void testClose() throws Exception {
-        try {
-            db.close();
-            db.get_table("test");
-            fail();
-        } catch (Exception e) {
-            assertTrue(e.getMessage().equals("database already closed"));
-            try {
-                db.open(dbFile.getPath(), 0);
-            } catch (Exception e1) {
-                fail("Database object could not be reopened after 'close': "
-                        + e.getMessage());
-                e1.printStackTrace();
-            }
-        }
-
-        try {
-            db.close();
-            db.close();
-            fail();
-        } catch (Exception e) {
-            assertTrue(e.getMessage().equals("database already closed"));
-            db.open(dbFile.getPath(), 0);
-        }
-    }
-
-    public void testExecStringCallback() throws Exception {
-        TableResult res = new TableResult();
-        db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " VALUES(1, 10, 20)", null);
-        db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
-        db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1 + " where 1", null);
-        String row[] = (String[]) res.rows.elementAt(0);
-        assertEquals(Integer.parseInt(row[0]), 1);
-        assertEquals(Integer.parseInt(row[1]), 10);
-        assertEquals(Integer.parseInt(row[2]), 20);
-    }
-
-    public void testExecStringCallbackStringArray() throws Exception {
-        TableResult res = new TableResult();
-        String args[] = new String[1];
-        args[0] = "table";
-        db.exec("select name from sqlite_master where type = '%q';", res, args);
-        String[] s = (String[]) res.rows.elementAt(0);
-        assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
-
-        try {
-            db.exec("select name from sqlite_master where type = ", res, args);
-            fail("Testmethod should fail");
-        } catch (Exception e) {
-            // Ok
-        }
-    }
-
-    public void testLast_insert_rowid() throws Exception {
-        assertEquals(0, db.last_insert_rowid());
-        db.exec("create table TEST5(id integer, firstname text, lastname text);", null);
-        db.exec("insert into TEST5 values (1,'James','Bond');", null);
-        db.exec("insert into TEST5 values (2,'Fiona','Apple');", null);
-        assertEquals(2, db.last_insert_rowid());
-        assertEquals(db.last_insert_rowid(), db.last_insert_rowid());
-
-        db.exec("drop table TEST5;", null);
-        assertEquals(2, db.last_insert_rowid());
-    }
-
-    /**
-     * Reason for failure unknown: Database should be locked. Specification
-     * of interrupt is scarce.
-     */
-    public void testInterrupt() throws Exception, SQLException {
-        ThreadPool threadPool = new ThreadPool(numThreads);
-
-        // initialization
-        ResultSet userTabs;
-        userTabs = conn.getMetaData().getTables(null, null, null, null);
-        while (userTabs.next()) {
-            String tableName = userTabs.getString("TABLE_NAME");
-            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
-                statement.execute(DatabaseCreator.DROP_TABLE1);
-            }
-        }
-        db.exec(DatabaseCreator.CREATE_TABLE3, null);
-        db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
-        int id1 = numOfRecords - 3;
-        threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
-        // should not be able to do any other insertions since task 1 holds lock
-        int id2 = numOfRecords + 3;
-        threadPool
-                .runTask(createTask2Interrupt(id2, dbFile.getPath(), tracker));
-
-        threadPool.join();
-
-        List<String> errors = tracker.getErrors();
-        System.out.println("Last error: " + db.error_message());
-        if (errors.size() > 0) {
-            assertEquals(errors.get(0), db.error_string(Constants.SQLITE_LOCKED));
-            for (String s : errors) {
-                Logger.global.info("INTERRUPT Error: " + s);
-            }
-
-        } else {
-            fail("Should have one exception: database should be locked.");
-        }
-
-        // reset
-        db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1", null);
-        db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1", null);
-    }
-
-    /**
-     * Returns wrong number for updates: returns value > 1 for select.
-     */
-    public void testChanges() throws Exception {
-        TableResult res = new TableResult();
-        assertTrue(db.changes() == 0);
-        db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
-                + " VALUES(2, 5, 7);", null);
-        int rows = (int) db.changes();
-        assertEquals(1,db.changes());
-        db.exec("update " + DatabaseCreator.SIMPLE_TABLE1
-                + " set speed = 7, size= 5 where id = 2;", null);
-        assertEquals(1,db.changes());
-        db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
-        assertEquals(0,db.changes());
-        db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
-                + " VALUES(8, 5, 7);", null);
-        db.exec("Update "+DatabaseCreator.SIMPLE_TABLE1+" set speed = 10;",null);
-        assertTrue(db.changes() > 2);
-    }
-
-    /**
-     * method test fails once in a while. Cannot be sure that exception is
-     * thrown in every test execution.
-     */
-    public void testBusy_handler() throws SQLException, Exception {
-        TestBusyHandler bh = new TestBusyHandler();
-        db.busy_handler(bh);
-        int counter = 0;
-        ThreadPool threadPool = new ThreadPool(numThreads);
-
-        // initialization
-        ResultSet userTabs;
-        userTabs = conn.getMetaData().getTables(null, null, null, null);
-        while (userTabs.next()) {
-            String tableName = userTabs.getString("TABLE_NAME");
-            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
-                statement.execute(DatabaseCreator.DROP_TABLE1);
-            }
-        }
-        db.exec(DatabaseCreator.CREATE_TABLE3, null);
-        db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
-
-        try {
-            conn.setAutoCommit(false);
-            int id1 = numOfRecords - 3;
-            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
-            int id2 = numOfRecords + 3;
-            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
-            int oldID = 5;
-            int newID = 100;
-            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
-                    tracker));
-
-            threadPool.join();
-
-            List<String> errors = tracker.getErrors();
-            if (errors.size() > 0) {
-//                 assertEquals(errors.get(0),
-//                 db.error_string(Constants.SQLITE_LOCKED));
-                for (String s: errors) {
-                  System.out.println("Round 2 Error: "+s);
-              }
-            } else {
-                fail("No error happened");
-            }
-
-            // reset
-
-
-            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
-                    null);
-            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
-                            null);
-//
-//            // increase timeout for retry
-//            db.busy_timeout(1000);
-//            db.busy_handler(bh);
-//            tracker.reset();
-
-//            threadPool = new ThreadPool(numThreads);
-//
-//            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
-//            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
-//
-//            threadPool.join();
-//
-//            errors = tracker.getErrors();
-//            if (errors.size() > 0) {
-//                // assertEquals(errors.get(0),
-//                // db.error_string(Constants.SQLITE_LOCKED));
-//                for (String s: errors) {
-//                    System.out.println("Round 2 Error"+s);
-//                }
-//            } else {
-//                // ok
-//                System.out.println("BUSY: No Error!");
-//            }
-//
-//
-        } finally {
-            conn.setAutoCommit(true);
-            db.exec(DatabaseCreator.DROP_TABLE1, null);
-            db.exec(DatabaseCreator.DROP_TABLE3, null);
-        }
-    }
-
-    /**
-     * test fails. Cannot be sure that exception is thrown every time.
-     * Database does not lock values.
-     */
-    public void testBusy_timeout() throws Exception, SQLException {
-        int counter = 0;
-        ThreadPool threadPool = new ThreadPool(numThreads);
-
-        // initialization
-        ResultSet userTabs = conn.getMetaData().getTables(null, null, null, null);
-        while (userTabs.next()) {
-            String tableName = userTabs.getString("TABLE_NAME");
-            if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
-                statement.execute(DatabaseCreator.DROP_TABLE1);
-            }
-        }
-        db.exec(DatabaseCreator.CREATE_TABLE3, null);
-        db.exec(DatabaseCreator.CREATE_TABLE1, null);
-
-        // test run
-        try {
-            conn.setAutoCommit(false);
-
-//            DatabaseCreator.fillTestTable1(conn, numOfRecords);
-            // set to fail immediately if table is locked.
-            db.busy_handler(null);
-            db.busy_timeout(0);
-            int id1 = numOfRecords - 3;
-
-            threadPool.runTask(createTask2(id1, dbFile.getPath(), tracker));
-            int id2 = numOfRecords + 3;
-            threadPool.runTask(createTask1(id2, dbFile.getPath(), tracker));
-            int oldID = 5;
-            int newID = 100;
-            threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
-                    tracker));
-
-            threadPool.join();
-
-            List<String> errors = tracker.getErrors();
-            assertTrue("No error occurred on DB but should have",errors.size() > 0);
-
-            assertEquals(errors.get(0),
-            db.error_string(Constants.SQLITE_LOCKED));
-            assertEquals(errors.get(0), "database is locked");
-
-            // reset
-
-            db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
-                    null);
-            db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
-                            null);
-
-            // increase timeout for retry
-            db.busy_timeout(10000);
-            db.busy_handler(null);
-            tracker.reset();
-            threadPool = new ThreadPool(numThreads);
-
-            threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
-            threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
-
-            threadPool.join();
-
-            errors = tracker.getErrors();
-            if (errors.size() > 0) {
-                fail("busy timeout should prevent from lock exception!");
-                for (String s: errors) {
-                    System.out.println("Round 2 Error"+s);
-                }
-            } else {
-                // ok
-            }
-        } finally {
-            conn.setAutoCommit(true);
-            // cleanup
-            db.exec(DatabaseCreator.DROP_TABLE1, null);
-            db.exec(DatabaseCreator.DROP_TABLE3, null);
-        }
-    }
-
-    public void testGet_tableString() throws Exception {
-        TableResult emptyTable = new TableResult();
-        //select from empty table
-        TableResult res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-        assertEquals(res.toString(), emptyTable.toString());
-        //fill table-> t
-//        DatabaseCreator.fillSimpleTable1(conn);
-//        res = db.get_table("select * from "
-//                + DatabaseCreator.SIMPLE_TABLE1);
-//        assertFalse(emptyTable.toString().equals(res.toString()));
-
-        db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1 + " VALUES(1, 10, 20)", null);
-        res = db.get_table("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-        db.exec("delete from " + DatabaseCreator.SIMPLE_TABLE1
-                + " where 1", null);
-        String row[] = (String[]) res.rows.elementAt(0);
-        assertEquals(Integer.parseInt(row[0]), 1);
-        assertEquals(Integer.parseInt(row[1]), 10);
-        assertEquals(Integer.parseInt(row[2]), 20);
-    }
-
-    public void testGet_tableStringStringArray() throws Exception {
-        String args[] = new String[1];
-        args[0] = "table";
-        String argsFail[] = new String[1];
-        try {
-            db.get_table("select name from sqlite_master where type = ", argsFail);
-            fail("Testmethod should fail");
-        } catch (Exception e) {
-        }
-
-        TableResult res = db.get_table(
-                "select name from sqlite_master where type = '%q'",
-                args);
-        String[] s = (String[]) res.rows.elementAt(0);
-        assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
-    }
-
-    public void testGet_tableStringStringArrayTableResult() throws Exception {
-        String args[] = new String[1];
-        String argsFail[] = new String[1];
-        TableResult res = new TableResult();
-        TableResult defaultTableRes = new TableResult();
-        args[0] = "table";
-
-        try {
-            db.get_table("select name from sqlite_master where type = '%q'", argsFail, res);
-            assertEquals(defaultTableRes.toString(), res.toString());
-        } catch (Exception e) {
-            db.get_table("select name from sqlite_master where type = '%q'", args, res);
-            String[] s = (String[]) res.rows.elementAt(0);
-            assertEquals(s[0], DatabaseCreator.SIMPLE_TABLE1);
-            System.out.println("DatabaseTest.testGet_tableStringStringArrayTableResult() "
-                    + Arrays.toString(res.types));
-        }
-    }
-
-    public void testComplete() {
-        assertFalse(db.complete("create"));
-        assertTrue(db.complete("create table TEST (res double);"));
-    }
-
-    public void testVersion() {
-        String version = db.version();
-        if (version != null) {
-            assertTrue(Integer.parseInt(db.version().substring(0, 1)) > 0);
-            assertEquals(db.version(), db.version());
-        } else {
-            fail("DB version info missing");
-        }
-    }
-
-    public void testDbversion() throws Exception {
-        String verNo = "";
-        try {
-            verNo = db.dbversion();
-            db.close();
-            assertEquals(db.dbversion(),"unknown");
-            db.open(dbFile.getPath(), 0);
-            assertEquals(verNo, db.dbversion());
-        } catch (Exception e) {
-            db.open(dbFile.getPath(), 0);
-        }
-
-        assertTrue(Integer.parseInt(verNo.substring(0, 1))>= 3 );
-
-    }
-
-    public void testCreate_function() throws Exception {
-        double input = 1.0;
-        db.exec("create table TEST (res double)", null);
-        db.exec("insert into TEST values (" + Double.toString(input) + ")",
-                null);
-        TableResult res = new TableResult();
-        Function sinFunc = (Function) new SinFunc();
-        db.create_function("sin", 1, sinFunc);
-        db.exec("select sin(res) from TEST WHERE res = "
-                + Double.toString(input), res);
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-        double sinusVal = Double.parseDouble(val);
-        double funcVal = Math.sin(input);
-
-        assertTrue(Math.round(funcVal) == Math.round(sinusVal));
-    }
-
-    /**
-     * Aggregation function not called.
-     */
-    public void testCreate_aggregate() throws Exception {
-        TestTrace t = new TestTrace();
-        MockFunction aggFunction = new MockFunction();
-        db.exec("create table TEST(id integer, firstname text, lastname text)", null);
-        db.exec("insert into TEST values(3, 'James', 'Bond'); ", null);
-        db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null);
-        db.trace((Trace) t);
-        db.create_aggregate("myaggfunc", 1, aggFunction);
-        db.function_type("myaggfunc", Constants.SQLITE3_TEXT);
-        db.exec("PRAGMA show_datatypes = on", null);
-
-        assertFalse(aggFunction.functionCalled);
-        assertFalse(aggFunction.stepCalled);
-        assertFalse(aggFunction.lastStepCalled);
-        db.exec("select myaggfunc(TEST.firstname) from TEST", t);
-        assertTrue(aggFunction.stepCalled);
-        assertTrue(aggFunction.lastStepCalled);
-        assertTrue(aggFunction.functionCalled);
-
-        assertEquals("James Fiona ",aggFunction.getAggValue());
-        db.exec("drop table TEST", null);
-
-        try {
-            db.create_aggregate("myaggfunc", 0, null);
-        } catch (Throwable e) {
-            assertEquals("null SQLite.Function not allowed",e.getMessage());
-        }
-
-          try {
-            db.create_aggregate("myaggfunc", 0, aggFunction);
-        } catch (Throwable e) {
-            assertEquals("wrong number of arguments to function myaggfunc()",e.getMessage());
-        }
-    }
-
-    public void testFunction_type() throws Exception {
-        double input = 1.0;
-        TableResult res = new TableResult();
-        Function sinFunc = (Function) new SinFunc();
-
-        db.exec("PRAGMA show_datatypes = on", null);
-        db.exec("create table TEST (res double)", null);
-        db.exec("insert into TEST values (" + Double.toString(input) + ")",
-                null);
-
-        db.create_function("sin", 1, sinFunc);
-        db.function_type("sin", Constants.SQLITE_FLOAT);
-        res = db.get_table("select sin(res) from TEST WHERE res = "
-                + Double.toString(input));
-
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-        assertTrue("double".equalsIgnoreCase(res.types[0]));
-        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
-
-        // function determines return type: test that Double type is returned.
-        db.function_type("sin", Constants.SQLITE_BLOB);
-        Stmt s = db.prepare("select sin(res) from TEST WHERE res = ?");
-        s.bind(1, input);
-        s.step();
-
-        res = db.get_table("select sin(res) from TEST WHERE res = "
-                + Double.toString(input));
-        assertTrue("double".equalsIgnoreCase(res.types[0]));
-        row = (String[]) res.rows.elementAt(0);
-        val = row[0];
-        assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
-    }
-
-    public void testLast_error() {
-        assertEquals(db.last_error(), Constants.SQLITE_OK);
-        try {
-            db.exec("create table TEST (res double)",null);
-            db.exec("create table TEST (res double)",null);
-            fail("Error should have happened");
-        } catch (Exception e) {
-            assertEquals(db.last_error(),db.last_error());
-            assertEquals(db.last_error(),Constants.SQLITE_ERROR);
-        }
-    }
-
-    public void testSet_last_error() {
-       assertEquals(db.last_error(), Constants.SQLITE_OK);
-       try {
-           db.exec("sel from test;", null);
-       } catch (Exception e) {
-           assertEquals(Constants.SQLITE_ERROR,db.last_error());
-       }
-    }
-
-    public void testError_message() {
-        String statement = "create table TEST (res double)";
-        try {
-            db.exec(statement,null);
-            db.exec(statement,null);
-            fail("DB Error expected");
-        } catch (Exception e) {
-            String dbError = db.error_message();
-            assertTrue(e.getMessage().equals(dbError));
-
-        }
-    }
-
-    public void testError_string() {
-        TestTrace t = new TestTrace();
-        assertEquals(db.last_error(), Constants.SQLITE_OK);
-        String errorString = db.error_string(Constants.SQLITE_ERROR);
-        try {
-            db.trace((Trace) t);
-            db.exec("create table TEST (res double)", t);
-            db.exec("create table TEST (res double)", t);
-        } catch (Exception e) {
-            assertEquals(db.last_error(), Constants.SQLITE_ERROR);
-            if (db.is3()) {
-                assertEquals("Unsupported Method (sqlite 3): error_string", db
-                        .error_string(db.last_error()), errorString);
-            }
-        }
-    }
-
-    /**
-     * ASCII encoding does not work: a UTF encoded val is returned. Spec is not
-     * sufficient. Might be that test impl is wrong or String constructor for
-     * the ASCII encoding.
-     */
-    public void testSet_encoding() throws UnsupportedEncodingException, Exception {
-        String input = "\u00bfMa\u00f1ana\u003f"; // ?Manana?
-        TableResult res = new TableResult();
-        String refOutput = null;
-        Stmt stat = null;
-
-        // DB setup
-        db.exec("create table encodingTest (encoded text DEFAULT NULL);",
-                null);
-        stat = db
-                .prepare("insert into encodingTest(encoded) values(:one);");
-        stat.bind(1, input);
-        stat.step();
-        // stat.close();
-        db.exec("select * from encodingTest;", res);
-        String[] encInput = (String[]) res.rows.elementAt(0);
-        String output = encInput[0];
-        assertEquals(input, output);
-        // db.exec("delete from encodingTest where 1", null);
-
-     // tests for different encoding schemes
-        String[] charsetNames = {"UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE"};
-        for (int i = 0; i < charsetNames.length; i++) {
-            byte[] encInputBytes = input.getBytes(charsetNames[i]);
-            db.set_encoding(charsetNames[i]);
-            db.exec("select * from encodingTest;", res);
-            String[] encOutput = (String[]) res.rows.elementAt(0);
-            String inputAsString = new String(encInputBytes,charsetNames[i]);
-            assertEquals(inputAsString, encOutput[0]);
-        }
-
-        // Default tests
-        db.set_encoding("UTF-16");
-        db.exec("select * from encodingTest;", res);
-        String[] encOutput1 = (String[]) res.rows.elementAt(0);
-        assertEquals("Got "+encOutput1[0]+" as UTF-16",input,encOutput1[0]);
-
-        db.set_encoding("US-ASCII");
-        db.exec("select * from encodingTest;", res);
-        String[] encOutput2 = (String[]) res.rows.elementAt(0);
-        assertEquals(new String(input.getBytes(),"US-ASCII"),encOutput2[0]);
-
-        // DB teardown
-        stat.close();
-        db.exec("delete from encodingTest", null);
-
-        // Default tests
-        try {
-            db.set_encoding("");
-            fail("invalid input should fail");
-        } catch (Exception e) {
-            //ok
-        }
-    }
-
-    /**
-     * Callback never made for authorization. Results of private table are
-     * returned withouth furhter checks.
-     *
-     * Test fails -> implemented correctly?
-     */
-    public void testSet_authorizer() throws Exception {
-        TableResult resPriv = null;
-        TableResult resPub = null;
-        TableResult emptyTable = new TableResult();
-        String insertPublic = "insert into public_table values(1,2)";
-        String insertPrivate = "insert into private_table values(1,2)";
-        // prepare, authorizer is not activated yet
-        db.exec("create table public_table(c1 integer, c2 integer);", null);
-        db.exec("create table private_table(c1 integer, c2 integer);", null);
-        // inserts
-        db.exec(insertPublic, null);
-        db.exec(insertPrivate, null);
-        // selects
-        resPriv = db.get_table("select * from private_table");
-        resPub = db.get_table("select * from public_table");
-
-//        db.exec("delete from public_table where 1", null);
-//        TableResult emptyPubTable = db.exec("select * from public");
-
-        // set Authorizer (positive case): denies private table
-        AuthorizerCallback cb = new AuthorizerCallback();
-        db.set_authorizer(cb);
-        //select
-
-        db.exec("select * from private_table", cb);
-        assertTrue(cb.wasCalled());
-
-       /*
-        TableResult res = db.get_table("select * from private_table");
-        assertEquals(emptyTable.toString(),res.toString());
-        assertFalse(emptyTable.equals(resPriv));
-
-        res = db.get_table("select * from public_table");
-        assertEquals(resPub,res);
-        */
-
-        // Try insert
-        try {
-            db.exec(insertPublic, null);
-            fail("authorization failed");
-        } catch (Exception e) {
-        }
-
-        try {
-            db.exec(insertPrivate, null);
-            fail("authorization failed");
-        } catch (Exception e1) {
-            // ok
-        }
-    }
-
-    public void testTrace() throws Exception {
-        String stmt = "create table TEST (res double);";
-        TestTrace t = new TestTrace();
-        assertFalse(t.traceCalled);
-        assertEquals(db.last_error(),Constants.SQLITE_OK);
-        db.trace((Trace) t);
-        db.exec(stmt,t);
-        assertTrue(t.traceCalled);
-        assertEquals(t.getTrace(),stmt);
-
-        try {
-            db.close();
-            db.exec(stmt,t);
-            fail("Exception Expected");
-        } catch (Exception e) {
-            //ok
-        }
-    }
-
-    public void testCompileString() throws Exception {
-        db.compile("select name from sqlite_master;");
-        try {
-            db.compile("test");
-            fail("Compiling of inaccurate statement does not fail.");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testCompileStringStringArray() throws Exception {
-        String args[] = new String[1];
-        args[0] = "table";
-        db.compile("select name from sqlite_master where type = '%q';",args);
-
-        try {
-            db.compile("test",null);
-            fail("Compiling of inaccurate statement does not fail.");
-        } catch (Exception e) {
-        }
-    }
-
-    public void testPrepare() throws Exception {
-        Stmt st = null;
-        Stmt st2 = null;
-        // test empty statement
-        try {
-            st = db.prepare("");
-            assertEquals(0, st.bind_parameter_count());
-            st.step();
-            fail("stmt should not be prepared");
-        } catch (Exception e) {
-            assertEquals("stmt already closed", e.getMessage());
-        }
-
-        // test statement with unbound arguments
-        try {
-            st2 = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values (:one,:two,:three)");
-            assertEquals(3, st2.bind_parameter_count());
-            assertEquals(3, st2.bind_parameter_index(":three"));
-            assertEquals(":two", st2.bind_parameter_name(2));
-        } finally {
-            st2.close();
-        }
-
-        try {
-            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values(:one,:two,:three,:four);");
-        } catch (Exception e) {
-            assertEquals("table " + DatabaseCreator.SIMPLE_TABLE1
-                    + " has 3 columns but 4 values were supplied", e
-                    .getMessage());
-        }
-
-        try {
-            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values(5, '10, 20);");
-        } catch (Exception e) {
-            assertEquals("unrecognized token: \"'10, 20);\"", e.getMessage());
-        }
-
-        try {
-            db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values(5, 10 20);");
-        } catch (Exception e) {
-            assertEquals("near \"20\": syntax error", e.getMessage());
-        }
-
-    }
-
-    /**
-     * Not supported.
-     */
-    public void testOpen_blob() throws Exception, java.lang.Exception {
-        Stmt statement2;
-        Blob blobInput = new Blob();
-
-        // Create test input Blob
-        InputStream inStream = null;
-        byte[] in = {(byte) 1, (byte) 2, (byte) 3, (byte) 4};
-
-        // setup test input
-        db.exec("create table TEST (res blob)",null);
-        inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
-        assertNotNull(inStream);
-
-        // insert byte array in db
-        statement2 = db.prepare("insert into TEST(res) values (?)");
-        statement2.bind(1, in);
-        statement2.step();
-        statement2.close();
-
-        // read from db
-        Blob blob = db.open_blob(dbFile.getPath(), "TEST", "res", 1, true);
-        if (blob == null) {
-            fail("Blob could not be retrieved");
-        }
-        //read from blob and compare values (positive case)
-        InputStream is = blob.getInputStream();
-
-        int i = 0;
-        int outByte = 0;
-        byte[] out = new byte[4];
-        while ((outByte = is.read()) > -1) {
-            out[i] = (byte) outByte;
-            i++;
-        }
-        is.close();
-
-        blob.close();
-
-        assertTrue(Arrays.equals(in, out));
-
-        //read from blob and compare values (default blob)
-        db.exec("insert into TEST values(zeroblob(128))", null);
-        Blob blob2 = db.open_blob(dbFile.getPath(), "TEST", "res", 2, true);
-        is = blob2.getInputStream();
-        for (i = 0; i < 128; i++)  {
-           assertEquals(0, is.read());
-        }
-        is.close();
-    }
-
-    public void testIs3() {
-        int ver = Integer.parseInt(db.version().substring(0,1));
-        if (db.is3()) {
-            assertTrue( ver == 3);
-        } else {
-            assertTrue(ver != 3);
-        }
-    }
-
-    public void testProgress_handler() throws Exception {
-        int inputVal = 3;
-        TestProgressHandler prog = new TestProgressHandler();
-        db.exec("create table TEST5(id integer, firstname text, lastname text)",null);
-        Vm vm = db.compile("select * from TEST5; "
-                + "insert into TEST5 values(3, 'James', 'Bond'); "
-                + "delete from TEST5 where id = 3; "
-                + "select * from TEST5");
-        int stmt = 0;
-        do {
-            ++stmt;
-            if (stmt > inputVal) {
-                db.progress_handler(inputVal, prog);
-            } else {
-                assertEquals(0, prog.getCounts());
-            }
-            while (vm.step(prog)) {
-            }
-        } while (vm.compile());
-        assertEquals(inputVal,prog.getCounts());
-
-        // Boundary value test
-        inputVal = 0;
-        TestProgressHandler progBoundary = new TestProgressHandler();
-        db.progress_handler(inputVal, progBoundary);
-        Vm vm2 = db.compile("select * from TEST5; "
-                + "insert into TEST5 values(3, 'James', 'Bond'); "
-                + "delete from TEST5 where id = 3; "
-                + "select * from TEST5");
-        do {
-            vm2.step(progBoundary);
-        } while (vm2.compile());
-        assertEquals(inputVal, progBoundary.getCounts());
-
-        try {
-            db.exec("drop table TEST5",null);
-        } catch (Exception e) {
-            System.out.println(e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    class SinFunc implements Function {
-        public void function(FunctionContext fc, String args[]) {
-            Double d = new Double(args[0]);
-            fc.set_result(Math.sin(d.doubleValue()));
-        }
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestTrace implements Trace,Callback {
-
-        private StringBuffer buf = new StringBuffer();
-
-        public boolean traceCalled = false;
-
-        public String getTrace() {
-            return buf.toString();
-        }
-
-        public void trace(String stmt) {
-            traceCalled = true;
-            buf.append(stmt);
-        }
-
-        public void columns(String[] coldata) {}
-
-        public boolean newrow(String[] rowdata) {
-            return false;
-        }
-
-        public void types(String[] types) {}
-    }
-
-    class AuthorizerCallback implements Authorizer, Callback {
-
-        private boolean isAuthorizing = false;
-
-        public boolean wasCalled() {
-            return isAuthorizing;
-        }
-
-        public int authorize(int action, String arg1, String arg2, String arg3,
-                String arg4) {
-            Logger.global.info("DB authorization callback " + action + " " + arg1 + " " + arg2 + " "
-                    + arg3 + " " + arg4 + " ");
-            this.isAuthorizing = true;
-            if (action != Constants.SQLITE_SELECT || arg1.contains("private_table")) {
-                return Constants.SQLITE_DENY;
-            } else {
-                return Constants.SQLITE_OK;
-            }
-        }
-
-        public void columns(String[] coldata) {}
-
-        public boolean newrow(String[] rowdata) {
-            return false;
-        }
-
-        public void types(String[] types) {}
-
-    }
-
-    class TestBusyHandler implements BusyHandler, Callback {
-
-        public boolean busy(String table, int count) {
-            return true;
-        }
-
-        public void columns(String[] coldata) {}
-
-        public boolean newrow(String[] rowdata) {
-            return false;
-        }
-
-        public void types(String[] types) {}
-    }
-
-    class TestProgressHandler implements ProgressHandler, Callback {
-
-        private boolean progressed = false;
-
-        private int counter = 0;
-
-        public int getCounts() {
-            return counter;
-        }
-
-        public boolean progress() {
-            this.progressed = true;
-            counter++;
-            return true;
-        }
-
-        public void columns(String[] coldata) {}
-
-        public boolean newrow(String[] rowdata) {
-            return false;
-        }
-
-        public void types(String[] types) {}
-    }
-
-    /**
-     * This method creates a Runnable that executes insert operation for the first table
-     */
-    private static Runnable createTask2Interrupt(final int id,
-            final String dbName, final ErrorTracker errorTracker) {
-        return new Runnable() {
-            public void run() {
-                Database db = new Database();
-                try {
-                    String value = DatabaseCreator.defaultString + id;
-
-                    db.open(dbName, 0);
-                    String insertQuery = "INSERT INTO "
-                            + DatabaseCreator.TEST_TABLE1
-                            + " (id, field1, field2, field3) VALUES(" + id
-                            + ", '" + value + "', " + id + ", " + id + ")";
-                    db.exec(insertQuery, null);
-                } catch (Exception e) {
-                    errorTracker.registerException(this, e);
-                    try {
-                        db.interrupt();
-                        db.exec("DELETE FROM " + DatabaseCreator.SIMPLE_TABLE1
-                                + " WHERE id=" + id, null);
-                    } catch (Exception e1) {
-                        errorTracker.registerException(this, e1);
-                    }
-                }
-            }
-        };
-    }
-
-    /**
-     * This method creates a Runnable that executes delete operation for the first table
-     */
-    private static Runnable createTask1(final int id, final String dbName,
-            final ErrorTracker errorTracker) {
-        return new Runnable() {
-            public void run() {
-                try {
-                    Database db = new Database();
-                    db.open(dbName, 0);
-                    db.exec("DELETE FROM "
-                            + DatabaseCreator.SIMPLE_TABLE1 + " WHERE id=" + id, null);
-                } catch (Exception e) {
-                    errorTracker.registerException(this, e);
-                }
-            }
-        };
-    }
-
-    /**
-     * This method creates a Runnable that executes insert operation for the first table
-     */
-    private static Runnable createTask2(final int id, final String dbName,
-            final ErrorTracker errorTracker) {
-        return new Runnable() {
-            public void run() {
-                try {
-                    String value = DatabaseCreator.defaultString + id;
-                    Database db = new Database();
-                    db.open(dbName, 0);
-                    String insertQuery = "INSERT INTO "
-                            + DatabaseCreator.TEST_TABLE1
-                            + " (id, field1, field2, field3) VALUES(" + id
-                            + ", '" + value + "', " + id + ", " + id + ")";
-                    db.exec(insertQuery, null);
-                } catch (Exception e) {
-                    errorTracker.registerException(this, e);
-
-                }
-            }
-        };
-    }
-
-    /**
-     * This method creates a Runnable that executes update operation for the one record of the first
-     * table
-     */
-    private static Runnable createTask3(final int oldID, final String dbName,
-            final int newID, final ErrorTracker errorTracker) {
-        return new Runnable() {
-            public void run() {
-                Database db = new Database();
-                try {
-                    db.open(dbName, 0);
-                    String value = DatabaseCreator.defaultString + newID;
-                    String updateQuery = "UPDATE "
-                            + DatabaseCreator.TEST_TABLE1 + " SET id=" + newID
-                            + ", field1='" + value + "', field2=" + newID
-                            + ", field3=" + newID + " WHERE id=" + oldID;
-                    db.exec(updateQuery, null);
-                } catch (Exception e) {
-                    errorTracker.registerException(this, e);
-                }
-            }
-        };
-    }
-
-    private class ErrorTracker {
-
-        private List<String> errors = new ArrayList<String>();
-
-        public void registerException(Runnable runnable, Exception e) {
-            System.out.println("Registered: " + e.getMessage());
-            errors.add(e.getMessage());
-        }
-
-        public List<String> getErrors() {
-            return errors;
-        }
-
-        public void reset() {
-            errors.clear();
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldExceptionTest.java b/luni/src/test/java/libcore/sqlite/OldExceptionTest.java
deleted file mode 100644
index dddfd6b..0000000
--- a/luni/src/test/java/libcore/sqlite/OldExceptionTest.java
+++ /dev/null
@@ -1,39 +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 libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Exception;
-
-public final class OldExceptionTest extends OldSQLiteTest {
-
-    private Database db = null;
-
-    @Override public void setUp() throws java.lang.Exception {
-        super.setUp();
-        db = new Database();
-    }
-
-    public void testException() {
-        try {
-            db.open(dbFile.getName(), 0);
-        } catch (Exception e) {
-            assertNotNull(e);
-            assertNotNull(e.getMessage());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java b/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java
deleted file mode 100644
index 0924317..0000000
--- a/luni/src/test/java/libcore/sqlite/OldFunctionContextTest.java
+++ /dev/null
@@ -1,314 +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 libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Exception;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import java.io.UnsupportedEncodingException;
-import java.sql.SQLException;
-import java.sql.Statement;
-import tests.support.DatabaseCreator;
-
-public final class OldFunctionContextTest extends OldSQLiteTest {
-
-    private Database db = null;
-
-    @Override public void setUp() throws java.lang.Exception {
-        super.setUp();
-        db = new Database();
-        db.open(dbFile.getPath(), 0);
-        Statement st = conn.createStatement();
-        st.execute(DatabaseCreator.CREATE_TABLE2);
-        st.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
-        st.close();
-    }
-
-    public void testSet_resultString() throws Exception {
-        TestFCString testString = new TestFCString();
-        db.exec("insert into " + DatabaseCreator.TEST_TABLE2
-                + " (ftext) values ('TestInput')", null);
-        db.create_function("test", 1, testString);
-        TableResult res = db.get_table("select test(ftext) from "
-                + DatabaseCreator.TEST_TABLE2);
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertEquals("TestInput", val);
-    }
-
-    public void testSet_resultInt() throws Exception {
-        TestFCInt testInt = new TestFCInt();
-        db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + "  values (1,'" + testInt.intVal + "',3)", null);
-        db.create_function("testInt", 1, testInt);
-        TableResult res = db.get_table("select testInt(speed) from "
-                + DatabaseCreator.SIMPLE_TABLE1);
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertEquals(testInt.intVal, Integer.parseInt(val));
-    }
-
-    public void testSet_resultDouble() throws Exception {
-        SinFunc testD = new SinFunc();
-        db.exec("insert into " + DatabaseCreator.TEST_TABLE2
-                + " (fdouble)  values (" + testD.testDouble + ")", null);
-        db.create_function("testDouble", 1, testD);
-        TableResult res = db.get_table("select testDouble(fdouble) from "
-                + DatabaseCreator.TEST_TABLE2);
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertEquals(testD.testDouble, Double.parseDouble(val));
-
-        assertTrue(testD.functionCalled);
-    }
-
-    public void testSet_error() throws Exception {
-        TestFCError testError = new TestFCError();
-        SinFunc testD = new SinFunc();
-        db.exec("insert into " + DatabaseCreator.TEST_TABLE2
-                + " (fdouble)  values (" + testD.testDouble + ")", null);
-        db.create_function("testError", 1, testError);
-
-        try {
-        TableResult res = db.get_table("select testError(fdouble) from "
-                + DatabaseCreator.TEST_TABLE2);
-        fail("Should get Exception");
-        } catch (Exception e) {
-            assertEquals("error in step", e.getMessage());
-        }
-
-        assertFalse(testD.functionCalled);
-    }
-
-    public void testSet_resultByteArray() throws Exception, UnsupportedEncodingException {
-        Stmt st = null;
-        TestFCByteArray testBinArrayFnc = new TestFCByteArray();
-        String expected = "";
-        expected = "X'" + getHexString(testBinArrayFnc.byteVal) + "'";
-
-        // setup
-        db.exec("create table testBinaryData (binVal BINARY) ;", null);
-
-        try {
-        st = db.prepare("insert into testBinaryData values (?)");
-        st.bind(1, testBinArrayFnc.byteVal);
-        st.step();
-
-
-        db.create_function("testBinArray", 1, testBinArrayFnc);
-        TableResult res = db
-                .get_table("select testBinArray(binVal) from testBinaryData");
-
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertTrue(expected.equalsIgnoreCase(val));
-
-        assertTrue(testBinArrayFnc.functionCalled);
-
-        } finally {
-            //teardown
-            db.exec("drop table testBinaryData;", null);
-        }
-    }
-
-    /**
-     * ZeroBlob not supported
-     */
-    public void testSet_result_zeroblob() throws Exception,
-            UnsupportedEncodingException {
-        Stmt st = null;
-        TestFCZeroBlob testZeroBlobFnc = new TestFCZeroBlob();
-        byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3};
-
-
-        // setup
-        db.exec("create table testBinaryData (binVal BINARY) ;", null);
-
-        try {
-        st = db.prepare("insert into testBinaryData values (?)");
-        st.bind(1, byteVal);
-        st.step();
-
-
-        db.create_function("testZeroBlob", 0, testZeroBlobFnc);
-        TableResult res = db
-                .get_table("select testZeroBlob() from testBinaryData");
-        TableResult res2 = db.get_table("select zeroblob("
-                + testZeroBlobFnc.numBytes + ") from testBinaryData");
-
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertNotNull(val);
-
-        assertEquals(((String[]) res2.rows.elementAt(0))[0], val);
-        assertTrue(testZeroBlobFnc.functionCalled);
-
-        } finally  {
-         // teardown
-            db.exec("drop table if exists testBinaryData;", null);
-        }
-    }
-
-    /**
-     * Test Method results in a segmentation fault
-     */
-    public void testCount() throws SQLException, Exception {
-        TestFCCount countTest = new TestFCCount();
-        int inputCount = 10;
-
-        assertFalse(countTest.functionCalled);
-
-        DatabaseCreator.fillTestTable2(conn, inputCount);
-        db.create_function("testCount", 0, countTest);
-        // the invokation of testCount leads to a Segmentation fault
-        /*
-        TableResult res = db
-                .get_table("select testCount() from "+DatabaseCreator.TEST_TABLE2);
-
-        String row[] = (String[]) res.rows.elementAt(0);
-        String val = row[0];
-
-        assertTrue(countTest.functionCalled);
-        assertEquals(inputCount,Integer.parseInt(val));
-        */
-
-    }
-
-    class TestFCError implements Function {
-        public boolean functionCalled = false;
-        public String errorMsg = "FunctionError";
-
-        public void function(FunctionContext fc, String args[]) {
-            functionCalled = true;
-            fc.set_error(errorMsg);
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestFCCount implements Function {
-        public boolean functionCalled = false;
-        public int noOfRows = 0;
-
-        public void function(FunctionContext fc, String args[]) {
-            functionCalled = true;
-            noOfRows = fc.count();
-            fc.set_result(noOfRows);
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestFCZeroBlob implements Function {
-        public int numBytes = 16;
-        public boolean functionCalled = false;
-
-        public void function(FunctionContext fc, String args[]) {
-            functionCalled = true;
-            fc.set_result_zeroblob(numBytes);
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestFCString implements Function {
-        public String testString = "TestString";
-        public boolean functionCalled;
-
-        public void function(FunctionContext fc, String args[]) {
-            assertNotNull(args);
-            functionCalled = true;
-            fc.set_result(args[0]);
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestFCInt implements Function {
-        public int intVal = Integer.MAX_VALUE;
-        public boolean functionCalled;
-
-        public void function(FunctionContext fc, String args[]) {
-            assertNotNull(args);
-            functionCalled = true;
-            fc.set_result(Integer.parseInt(args[0]));
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class TestFCByteArray implements Function {
-        public byte[] byteVal = {(byte)  1, (byte) 2, (byte) 3};
-        public boolean functionCalled;
-
-        public void function(FunctionContext fc, String args[]) {
-            assertNotNull(args);
-            functionCalled = true;
-            fc.set_result(args[0].getBytes());
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    class SinFunc implements Function {
-        public Double testDouble = 3.0;
-        public boolean functionCalled = false;
-
-        public void function(FunctionContext fc, String args[]) {
-            Double d = new Double(args[0]);
-            functionCalled = true;
-            fc.set_result(d.doubleValue());
-        }
-
-        public void last_step(FunctionContext fc) {}
-        public void step(FunctionContext fc, String[] args) {}
-    }
-
-    static final byte[] HEX_CHAR_TABLE = {
-            (byte)'0', (byte)'1', (byte)'2', (byte)'3',
-            (byte)'4', (byte)'5', (byte)'6', (byte)'7',
-            (byte)'8', (byte)'9', (byte)'a', (byte)'b',
-            (byte)'c', (byte)'d', (byte)'e', (byte)'f'
-          };
-
-    public static String getHexString(byte[] raw)
-            throws UnsupportedEncodingException {
-        byte[] hex = new byte[2 * raw.length];
-        int index = 0;
-
-        for (byte b : raw) {
-            int v = b & 0xFF;
-            hex[index++] = HEX_CHAR_TABLE[v >>> 4];
-            hex[index++] = HEX_CHAR_TABLE[v & 0xF];
-        }
-        return new String(hex, "ASCII");
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java b/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java
deleted file mode 100644
index 48eeab1..0000000
--- a/luni/src/test/java/libcore/sqlite/OldJDBCDriverFunctionalTest.java
+++ /dev/null
@@ -1,64 +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 libcore.sqlite;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Tests the SQLite.JDBCDriver.
- */
-public class OldJDBCDriverFunctionalTest extends AbstractSqlTest {
-    private  File dbFile = null;
-    private String connectionURL = "empty";
-
-    @Override protected void tearDown() throws SQLException {
-        super.tearDown();
-        dbFile.delete();
-    }
-
-    @Override protected String getConnectionURL() {
-        if (connectionURL.equals("empty")) {
-            String tmp = System.getProperty("java.io.tmpdir");
-            File tmpDir = new File(tmp);
-            if (tmpDir.isDirectory()) {
-                try {
-                    dbFile = File.createTempFile("JDBCDriverFunctionalTest", ".db", tmpDir);
-                } catch (IOException e) {
-                    System.err.println("error creating temporary DB file.");
-                }
-                dbFile.deleteOnExit();
-            } else {
-                System.err.println("java.io.tmpdir does not exist");
-            }
-
-            connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
-        }
-
-        return connectionURL;
-    }
-
-    @Override protected String getDriverClassName() {
-        return "SQLite.JDBCDriver";
-    }
-
-    @Override protected int getTransactionIsolation() {
-        return Connection.TRANSACTION_SERIALIZABLE;
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java b/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java
deleted file mode 100644
index ae06dc6..0000000
--- a/luni/src/test/java/libcore/sqlite/OldJDBCDriverTest.java
+++ /dev/null
@@ -1,113 +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 libcore.sqlite;
-
-import SQLite.JDBCDriver;
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.sql.SQLException;
-
-
-public final class OldJDBCDriverTest extends OldJDBCDriverFunctionalTest {
-
-    /**
-     * The SQLite db file.
-     */
-    private JDBCDriver jDriver;
-
-    private Driver returnedDriver;
-
-    @Override public void setUp() throws java.lang.Exception {
-        super.setUp();
-        returnedDriver = DriverManager.getDriver(getConnectionURL());
-        if (returnedDriver instanceof JDBCDriver) {
-            this.jDriver = (JDBCDriver) returnedDriver;
-        }
-    }
-
-    public void testJDBCDriver() {
-        assertTrue(returnedDriver instanceof JDBCDriver);
-    }
-
-    public void testAcceptsURL() {
-        try {
-            if (this.jDriver != null) {
-                assertTrue(jDriver.acceptsURL(getConnectionURL()));
-            } else {
-                fail("no Driver available");
-            }
-        } catch (SQLException e) {
-            fail("Driver does not accept URL");
-            e.printStackTrace();
-        }
-    }
-
-    public void testConnect() {
-        try {
-            if (this.jDriver != null) {
-                Connection c = jDriver.connect(getConnectionURL(), null);
-                assertFalse(c.isClosed());
-                DriverManager.getConnection(getConnectionURL());
-            } else {
-                fail("no Driver available");
-            }
-        } catch (SQLException e) {
-            fail("Driver does not connect");
-            e.printStackTrace();
-        }
-    }
-
-    public void testGetMajorVersion() {
-        if (this.jDriver != null) {
-            assertTrue(jDriver.getMajorVersion() > 0);
-        } else {
-            fail("no Driver available");
-        }
-    }
-
-   public void testGetMinorVersion() {
-        if (this.jDriver != null) {
-            assertTrue(jDriver.getMinorVersion() > 0);
-        } else {
-            fail("no version information available");
-        }
-    }
-
-   public void testGetPropertyInfo() throws SQLException {
-        DriverPropertyInfo[] info = null;
-       if (this.jDriver != null) {
-           info = jDriver.getPropertyInfo(getConnectionURL(), null);
-           assertNotNull(info);
-           assertTrue(info.length > 0);
-       } else {
-           fail("no Driver available");
-       }
-
-        assertNotNull(info);
-
-    }
-
-    public void testJdbcCompliant() {
-        if (this.jDriver != null) {
-            assertFalse(jDriver.jdbcCompliant());
-        } else {
-            fail("no version information available");
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java b/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java
deleted file mode 100644
index e6b7f22..0000000
--- a/luni/src/test/java/libcore/sqlite/OldSQLiteTest.java
+++ /dev/null
@@ -1,62 +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 libcore.sqlite;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.logging.Logger;
-import junit.framework.TestCase;
-
-public abstract class OldSQLiteTest extends TestCase {
-
-    public static Connection conn;
-
-    public static File dbFile = null;
-
-    @Override public void setUp() throws Exception {
-        String tmp = System.getProperty("java.io.tmpdir");
-        File tmpDir = new File(tmp);
-        try {
-            if (tmpDir.isDirectory()) {
-                dbFile = File.createTempFile("sqliteTest", ".db", tmpDir);
-                dbFile.deleteOnExit();
-            } else {
-                System.out.println("ctsdir does not exist");
-            }
-
-            Class.forName("SQLite.JDBCDriver").newInstance();
-
-            if (!dbFile.exists()) {
-                Logger.global.severe("DB file could not be created. Tests can not be executed.");
-            } else {
-                conn = DriverManager.getConnection("jdbc:sqlite:/" + dbFile.getPath());
-            }
-            assertNotNull("Error creating connection", conn);
-        } catch (IOException e) {
-            System.out.println("Problem creating test file in " + tmp);
-        }
-    }
-
-    @Override public void tearDown() throws java.lang.Exception {
-        if (!conn.isClosed()) {
-            conn.close();
-        }
-        super.tearDown();
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/OldStmtTest.java b/luni/src/test/java/libcore/sqlite/OldStmtTest.java
deleted file mode 100644
index 4d379ed..0000000
--- a/luni/src/test/java/libcore/sqlite/OldStmtTest.java
+++ /dev/null
@@ -1,823 +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 libcore.sqlite;
-
-import SQLite.Constants;
-import SQLite.Database;
-import SQLite.Stmt;
-import SQLite.TableResult;
-import java.sql.Connection;
-import tests.support.DatabaseCreator;
-import tests.support.Support_SQL;
-
-public class OldStmtTest extends OldSQLiteTest {
-
-    private Database db;
-    private Stmt st;
-
-    private static final String CREATE_ALL_TYPES = "create table type ("
-            + " BoolVal BOOLEAN,"
-            + " IntVal INT,"
-            + " LongVal LONG,"
-            + " Bint BIGINT,"
-            + " Tint TINYINT,"
-            + " Sint SMALLINT,"
-            + " Mint MEDIUMINT,"
-            + " IntegerVal INTEGER,"
-            + " RealVal REAL,"
-            + " DoubleVal DOUBLE,"
-            + " FloatVal FLOAT,"
-            + " DecVal DECIMAL,"
-            + " NumVal NUMERIC,"
-            + " charStr CHAR(20),"
-            + " dateVal DATE,"
-            + " timeVal TIME,"
-            + " TS TIMESTAMP,"
-            + " DT DATETIME,"
-            + " TBlob TINYBLOB,"
-            + " BlobVal BLOB,"
-            + " MBlob MEDIUMBLOB,"
-            + " LBlob LONGBLOB,"
-            + " TText TINYTEXT,"
-            + " TextVal TEXT,"
-            + " MText MEDIUMTEXT,"
-            + " LText LONGTEXT,"
-            + " MaxLongVal BIGINT,"
-            + " MinLongVal BIGINT,"
-            + " validURL URL,"
-            + " invalidURL URL);";
-
-    static final String INSERT_ALL_TYPES = "insert into type ("
-            + "BoolVal, IntVal, LongVal, Bint, Tint, Sint, Mint,IntegerVal, RealVal, DoubleVal, "
-            + "FloatVal, DecVal,NumVal, charStr, dateVal, timeVal, TS,DT, TBlob, BlobVal, MBlob, "
-            + "LBlob,TText, TextVal, MText, LText, MaxLongVal, MinLongVal, validURL, invalidURL) "
-            + "values (1, -1, 22, 2, 33,3, 1, 2, 3.9, 23.2, 33.3, 44,5, 'test string', '1799-05-26',"
-            + "'12:35:45', '2007-10-09 14:28:02.0','1221-09-22 10:11:55', 1, 2, 3, 4,"
-            + "'Test text message tiny', 'Test text', 'Test text message medium',"
-            + "'Test text message long', " + Long.MAX_VALUE + ", " + Long.MIN_VALUE + ","
-            + "null, null);";
-
-    static final String ALL_TYPES_TABLE = "type";
-
-    @Override public void setUp() throws Exception {
-        super.setUp();
-        Support_SQL.loadDriver();
-        db = new Database();
-        db.open(dbFile.getPath(), 0);
-        db.exec(DatabaseCreator.CREATE_TABLE_SIMPLE1, null);
-        DatabaseCreator.fillSimpleTable1(conn);
-
-        st = new Stmt();
-    }
-
-    @Override public void tearDown() throws Exception {
-        if (st != null) {
-            try {
-                st.close();
-            } catch (Exception e) {
-            }
-        }
-        db.close();
-        Connection con = Support_SQL.getConnection();
-        con.close();
-        super.tearDown();
-    }
-
-    public void testStmt() throws Exception {
-        db.prepare("");
-
-        try {
-            st.step();
-            fail("Cannot execute non prepared Stmt");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testPrepare() throws Exception {
-        try {
-            st = db.prepare("");
-            st.prepare();
-            fail("statement is closed");
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-
-        st = new Stmt();
-        st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-        assertFalse(st.prepare());
-        st = new Stmt();
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        assertFalse(st.prepare());
-        st = new Stmt();
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        st.bind(1, 1);
-        st.bind(2, 10);
-        st.bind(3, 30);
-        assertFalse(st.prepare());
-        st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1
-                + "; " + "delete from " + DatabaseCreator.SIMPLE_TABLE1
-                + " where id = 5; " + "insert into "
-                + DatabaseCreator.SIMPLE_TABLE1 + " values(5, 10, 20); "
-                + "select * from " + DatabaseCreator.SIMPLE_TABLE1 + ";");
-        assertTrue(st.prepare());
-        assertTrue(st.prepare());
-        assertTrue(st.prepare());
-        assertFalse(st.prepare());
-    }
-
-    public void testStep() throws Exception {
-        try {
-            st.step();
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-
-        st = new Stmt();
-        st = db.prepare("select name from sqlite_master where type = 'table'");
-        st.step();
-    }
-
-    public void testClose() throws Exception {
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        st.close();
-
-        try {
-            st.step();
-            fail("Test fails");
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-    }
-
-    public void testReset() throws Exception {
-        db.exec("create table TEST (res integer not null)", null);
-
-        st = db.prepare("insert into TEST values (:one);");
-        st.bind(1, 1);
-        st.step();
-
-        // verify that parameter is still bound
-        st.reset();
-        assertEquals(1,st.bind_parameter_count());
-        st.step();
-
-        TableResult count = db.get_table("select count(*) from TEST where res=1", null);
-
-        String[] row0 = (String[]) count.rows.elementAt(0);
-        assertEquals(2, Integer.parseInt(row0[0]));
-    }
-
-    public void testClear_bindings() {
-        try {
-            st.clear_bindings();
-        } catch (SQLite.Exception expected) {
-            assertEquals("unsupported", expected.getMessage());
-        }
-    }
-
-    public void testBindIntInt() throws Exception {
-        int input = 0;
-        int maxVal = Integer.MAX_VALUE;
-        int minVal = Integer.MIN_VALUE;
-
-        db.exec("create table TEST (res integer)", null);
-        st = db.prepare("insert into TEST values (:one);");
-        st.bind(1, input);
-        st.step();
-
-        st.reset();
-        st.bind(1,maxVal);
-        st.step();
-
-        st.reset();
-        st.bind(1,minVal);
-        st.step();
-
-        TableResult r = db.get_table("select * from TEST");
-
-        String[] row0 = (String[]) r.rows.elementAt(0);
-        assertEquals(input,Integer.parseInt(row0[0]));
-
-        String[] row1 = (String[]) r.rows.elementAt(1);
-        assertEquals(maxVal,Integer.parseInt(row1[0]));
-
-        String[] row2 = (String[]) r.rows.elementAt(2);
-        assertEquals(minVal,Integer.parseInt(row2[0]));
-
-        try {
-            st.close();
-            st.bind(1,Integer.MIN_VALUE);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testBindIntLong() throws Exception {
-        long input = 0;
-        long maxVal = Long.MAX_VALUE;
-        long minVal = Long.MIN_VALUE;
-
-        db.exec("create table TEST (res long)", null);
-        st = db.prepare("insert into TEST values (:one);");
-        st.bind(1, input);
-        st.step();
-
-        st.reset();
-        st.bind(1,maxVal);
-        st.step();
-
-        st.reset();
-        st.bind(1,minVal);
-        st.step();
-
-        TableResult r = db.get_table("select * from TEST");
-
-        String[] row0 = (String[]) r.rows.elementAt(0);
-        assertEquals(input,Long.parseLong(row0[0]));
-
-        String[] row1 = (String[]) r.rows.elementAt(1);
-        assertEquals(maxVal,Long.parseLong(row1[0]));
-
-        String[] row2 = (String[]) r.rows.elementAt(2);
-        assertEquals(minVal,Long.parseLong(row2[0]));
-
-        try {
-            st.close();
-            st.bind(1,Long.MIN_VALUE);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testBindIntDouble() throws Exception {
-        double input = 0.0;
-        double maxVal = Double.MAX_VALUE;
-        double minVal = Double.MIN_VALUE;
-        double negInf = Double.NEGATIVE_INFINITY;
-        double posInf = Double.POSITIVE_INFINITY;
-        double nan = Double.NaN;
-
-        db.exec("create table TEST (res double)", null);
-        st = db.prepare("insert into TEST values (:one);");
-        st.bind(1, input);
-        st.step();
-
-        st.reset();
-        st.bind(1, maxVal);
-        st.step();
-
-        st.reset();
-        st.bind(1, minVal);
-        st.step();
-
-        st.reset();
-        st.bind(1, negInf);
-        st.step();
-
-        st.reset();
-        st.bind(1, posInf);
-        st.step();
-
-        st.reset();
-        st.bind(1, nan);
-        st.step();
-
-
-        TableResult r = db.get_table("select * from TEST");
-
-        String[] row0 = (String[]) r.rows.elementAt(0);
-        assertTrue(Double.compare(input, Double.parseDouble(row0[0])) == 0);
-
-        String[] row1 = (String[]) r.rows.elementAt(1);
-        assertFalse(Double.compare(maxVal, Double.parseDouble(row1[0])) == 0);
-        assertTrue(Double.compare(maxVal, Double.parseDouble(row1[0])) < 0);
-        assertTrue(Double.isInfinite(Double.parseDouble(row1[0])));
-
-        String[] row2 = (String[]) r.rows.elementAt(2);
-        assertTrue(Double.compare(minVal, Double.parseDouble(row2[0])) == 0);
-
-        String[] row3 = (String[]) r.rows.elementAt(3);
-        assertEquals("Double.NEGATIVE_INFINITY SQLite representation",
-                "-Inf", row3[0]);
-
-        String[] row4 = (String[]) r.rows.elementAt(4);
-        assertEquals("Double.POSITIVE_INFINITY SQLite representation",
-                "Inf", row4[0]);
-
-        String[] row5 = (String[]) r.rows.elementAt(4);
-        assertEquals("Double.Nan SQLite representation", "Inf", row5[0]);
-
-        try {
-            st.close();
-            st.bind(1,0.0);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testBindIntByteArray() throws Exception {
-        String name = "Hello World";
-        byte[] b = name.getBytes();
-        String stringInHex = "";
-
-        db.exec(DatabaseCreator.CREATE_TABLE_PARENT, null);
-        st = db.prepare("insert into " + DatabaseCreator.PARENT_TABLE
-                + " values (:one, :two);");
-        st.bind(1, 2);
-        st.bind(2, b);
-        st.step();
-
-        //compare what was stored with input based on Hex representation
-        // since type of column is CHAR
-        TableResult r = db.get_table("select * from "
-                + DatabaseCreator.PARENT_TABLE);
-        String[] row = (String[]) r.rows.elementAt(0);
-
-        for (byte aByte : b) {
-            stringInHex += Integer.toHexString(aByte);
-        }
-        stringInHex = "X'" + stringInHex + "'";
-        assertTrue(stringInHex.equalsIgnoreCase(row[1]));
-
-        try {
-            st.close();
-            st.bind(1,name.getBytes());
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testBindIntString() throws Exception {
-        String name = "Hello World";
-        db.exec(DatabaseCreator.CREATE_TABLE_PARENT, null);
-        st = db.prepare("insert into " + DatabaseCreator.PARENT_TABLE
-                + " values (:one, :two);");
-        st.bind(1, 2);
-        st.bind(2, name);
-        st.step();
-
-        TableResult r = db.get_table("select * from "
-                + DatabaseCreator.PARENT_TABLE);
-        String[] row = (String[]) r.rows.elementAt(0);
-        assertEquals(name,row[1]);
-
-        try {
-            st.close();
-            st.bind(1,name);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-    }
-
-    public void testBindInt() throws Exception {
-        try {
-            st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values (:one,:two,:three)");
-            st.bind(4);
-            st.bind(1, 4);
-            st.bind(2, 10);
-            st.bind(3, 30);
-            st.step();
-            fail();
-        } catch (SQLite.Exception expected) {
-            // What happens if null is bound to non existing variable position
-            assertEquals("parameter position out of bounds", expected.getMessage());
-        }
-
-        // functional tests
-
-        try {
-            st.reset();
-            st.bind(1);
-            st.bind(2, 10);
-            st.bind(3, 30);
-            st.step();
-            fail();
-        } catch (SQLite.Exception expected) {
-            // What happens if null is bound to NON NULL field
-            assertEquals("SQL logic error or missing database", expected.getMessage());
-        }
-
-        st.reset();
-        st.bind(1, 3);
-        st.bind(2);
-        st.bind(3, 30);
-        st.step();
-    }
-
-    public void testBind_zeroblob() {
-        try {
-            st.bind_zeroblob(1, 128);
-            fail();
-        } catch (SQLite.Exception expected) {
-            assertEquals("unsupported", expected.getMessage());
-        }
-    }
-
-    public void testBind_parameter_count() throws Exception {
-        try {
-            st.bind_parameter_count();
-            fail();
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        assertEquals(3, st.bind_parameter_count());
-
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (?, ?, ?)");
-        assertEquals(3, st.bind_parameter_count());
-
-        st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-        assertEquals(0, st.bind_parameter_count());
-
-        try {
-            st.close();
-            st.bind_parameter_count();
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-        }
-
-    }
-
-    public void testBind_parameter_name() {
-        try {
-            st.bind_parameter_name(1);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-
-        try {
-            st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values (:one,:two,:three)");
-            assertEquals(":one", st.bind_parameter_name(1));
-            assertEquals(":two", st.bind_parameter_name(2));
-            assertEquals(":three", st.bind_parameter_name(3));
-            st.bind_parameter_name(4);
-            fail();
-        } catch (SQLite.Exception expected) {
-            assertEquals("parameter position out of bounds", expected.getMessage());
-        }
-    }
-
-    public void testBind_parameter_index() throws Exception {
-        try {
-            st.bind_parameter_index("");
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("stmt already closed", expected.getMessage());
-        }
-
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        assertEquals(3, st.bind_parameter_index(":three"));
-
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (:one,:two,:three)");
-        assertEquals(0, st.bind_parameter_index(":t"));
-
-        st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                + " values (?, ?, ?)");
-        assertEquals(0, st.bind_parameter_index("?"));
-    }
-
-    public void testColumn_int() throws Exception {
-        db.exec(CREATE_ALL_TYPES, null);
-        db.exec(INSERT_ALL_TYPES, null);
-
-        Object columnObject;
-        int intColumn;
-        String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        // select 'speed' value
-        columnObject = st.column(1);
-        intColumn = st.column_int(1);
-        assertNotNull(intColumn);
-
-        assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
-        int stSpeed = Integer.parseInt(columnObject.toString());
-        assertNotNull(stSpeed);
-        assertEquals( intColumn, stSpeed);
-        assertEquals(10,stSpeed);
-
-        selectStmt = "select TextVal from "+ ALL_TYPES_TABLE;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        st.column_int(0);
-    }
-
-    public void testColumn_long() throws Exception {
-        Object columnObject;
-        long longColumn;
-        String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
-        st = db.prepare(selectStmt);
-        st.step();
-        columnObject = st.column(1);
-        longColumn = st.column_long(1);
-        assertNotNull(longColumn);
-        // column declared as integer
-        assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
-        int stSpeed = Integer.parseInt(columnObject.toString());
-        assertNotNull(stSpeed);
-        assertEquals( longColumn, stSpeed);
-
-        try {
-            st.column_long(4);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("column out of bounds", expected.getMessage());
-        }
-
-        try {
-            st.column_long(-1);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("column out of bounds", expected.getMessage());
-        }
-    }
-
-    public void testColumn_double() throws Exception {
-        db.exec(CREATE_ALL_TYPES, null);
-        db.exec(INSERT_ALL_TYPES, null);
-
-        double doubleColumn;
-        double actualVal = 23.2;
-        String selectStmt = "select DoubleVal from "+ ALL_TYPES_TABLE;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        // select double value
-        doubleColumn = st.column_double(0);
-        assertNotNull(doubleColumn);
-
-        assertTrue("DOUBLE".equalsIgnoreCase(st.column_decltype(0)));
-        assertNotNull(doubleColumn);
-        assertEquals( actualVal, doubleColumn);
-
-        // Exception test
-        selectStmt = "select dateVal from "+ ALL_TYPES_TABLE;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        // select double value
-        st.column_double(0);
-    }
-
-    public void testColumn_bytes() throws Exception {
-        db.exec("create table B(id integer primary key, val blob)",null);
-        db.exec("insert into B values(1, zeroblob(128))", null);
-        st = db.prepare("select val from B where id = 1");
-        assertTrue(st.step());
-        st.column_bytes(0);
-    }
-
-    public void testColumn_string() throws Exception {
-        db.exec(CREATE_ALL_TYPES, null);
-        db.exec(INSERT_ALL_TYPES, null);
-
-        String stringColumn;
-        String actualVal = "test string";
-        String selectStmt = "select charStr from "+ ALL_TYPES_TABLE;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        // select string value
-        stringColumn = st.column_string(0);
-        assertNotNull(stringColumn);
-
-        assertTrue("CHAR(20)".equalsIgnoreCase(st.column_decltype(0)));
-        assertNotNull(stringColumn);
-        assertEquals( actualVal, stringColumn);
-
-        // Exception test
-        selectStmt = "select DoubleVal from "+ ALL_TYPES_TABLE;
-
-        st = db.prepare(selectStmt);
-        st.step();
-        st.column_string(0);
-    }
-
-    public void testColumn_type() throws Exception {
-        db.exec(CREATE_ALL_TYPES, null);
-        db.exec(INSERT_ALL_TYPES, null);
-        st = db.prepare("select * from " + ALL_TYPES_TABLE);
-        st.step();
-
-        // Exception test
-        try {
-            st.column_type(100);
-            fail();
-        } catch (SQLite.Exception expected) {
-        }
-
-        /*
-        Dictionary
-
-        public static final int SQLITE_INTEGER = 1;
-        public static final int SQLITE_FLOAT = 2;
-        public static final int SQLITE_BLOB = 4;
-        public static final int SQLITE_NULL = 5;
-        public static final int SQLITE3_TEXT = 3;
-        public static final int SQLITE_NUMERIC = -1;
-        */
-
-        assertEquals(Constants.SQLITE3_TEXT, st.column_type(23)); // ok TEXT
-        assertEquals(Constants.SQLITE3_TEXT, st.column_type(13)); // CHAR(20)
-
-        assertEquals(Constants.SQLITE_FLOAT, st.column_type(8));
-        assertEquals(Constants.SQLITE_FLOAT, st.column_type(9));
-        assertEquals(Constants.SQLITE_FLOAT, st.column_type(10)); // FLOAT
-
-        for (int i = 0; i < 8; i++) {
-            assertEquals("Expected Integer at position " + i,
-                    Constants.SQLITE_INTEGER, st.column_type(i));
-        }
-
-        assertEquals(Constants.SQLITE_NULL, st.column_type(28));
-        assertEquals(Constants.SQLITE_NULL, st.column_type(29));
-
-        // Failing tests
-        assertTrue("INTEGER".equalsIgnoreCase(st.column_decltype(12)));
-        assertEquals(Constants.SQLITE_INTEGER, st.column_type(12));
-
-        assertTrue("FLOAT".equalsIgnoreCase(st.column_decltype(11)));
-        assertEquals(Constants.SQLITE_FLOAT, st.column_type(11)); // FLOAT ->
-                                                                  // got INTEGER
-        assertTrue("BLOB".equalsIgnoreCase(st.column_decltype(19)));
-        assertEquals(Constants.SQLITE_BLOB, st.column_type(19)); // Blob got
-                                                                 // INTEGER
-
-    }
-
-    /**
-     * Wrong value is returned in case of a prepared statement to which a '*' bound
-     */
-    public void testColumn_count() throws Exception {
-        String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
-        st = db.prepare(selectStmt);
-
-        assertEquals(3, st.column_count());
-
-        st.step();
-        int columnCount = st.column_count();
-        assertNotNull(columnCount);
-        assertEquals( 3, columnCount);
-
-        // actual prepared statement
-        selectStmt = "select ? from "+DatabaseCreator.SIMPLE_TABLE1;
-        st = db.prepare(selectStmt);
-
-        assertEquals(3, st.column_count());
-
-        st.bind(1, "*");
-        st.step();
-        columnCount = st.column_count();
-        assertNotNull(columnCount);
-        assertEquals( 3, columnCount);
-    }
-
-    public void testColumn() throws Exception {
-        Object columnObject;
-        int intColumn;
-        String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
-        db.get_table(selectStmt);
-        st = db.prepare(selectStmt);
-        st.step();
-        columnObject = st.column(1);
-        intColumn = st.column_int(1);
-        assertNotNull(intColumn);
-        assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
-        int stSpeed = Integer.parseInt(columnObject.toString());
-        assertNotNull(stSpeed);
-        assertEquals( intColumn, stSpeed);
-
-        try {
-            assertNotNull(columnObject);
-            ((Integer) columnObject).intValue();
-            fail("Cast to Integer should fail");
-        } catch (ClassCastException expected) {
-        }
-
-        try {
-            st.column(4);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("column out of bounds", expected.getMessage());
-        }
-
-        try {
-            st.column(-1);
-            fail("Exception expected");
-        } catch (SQLite.Exception expected) {
-            assertEquals("column out of bounds", expected.getMessage());
-        }
-    }
-
-    public void testColumn_table_name() {
-        try {
-            st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-            st.column_table_name(1);
-            fail("Function is now supported.");
-        } catch (SQLite.Exception expected) {
-            assertEquals("unsupported", expected.getMessage());
-        }
-    }
-
-    public void testColumn_database_name() {
-        try {
-            st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
-                    + " values (:one,:two,:three)");
-            st.column_database_name(1);
-            fail("Function is now supported.");
-        } catch (SQLite.Exception expected) {
-            assertEquals("unsupported", expected.getMessage());
-        }
-    }
-
-    public void testColumn_decltype() throws Exception {
-        db.exec(CREATE_ALL_TYPES, null);
-        db.exec(INSERT_ALL_TYPES, null);
-        st = db.prepare("select * from " + ALL_TYPES_TABLE);
-        st.step();
-
-        // Exception test
-        try {
-            st.column_decltype(100);
-            fail();
-        } catch (SQLite.Exception expected) {
-        }
-
-        assertTrue(st.column_decltype(0), "BOOLEAN".equalsIgnoreCase(st
-                .column_decltype(0)));
-        assertTrue(st.column_decltype(1), "INT".equalsIgnoreCase(st
-                .column_decltype(1)));
-        assertTrue(st.column_decltype(2), "LONG".equalsIgnoreCase(st
-                .column_decltype(2)));
-        assertTrue(st.column_decltype(3), "BIGINT".equalsIgnoreCase(st
-                .column_decltype(3)));
-        assertTrue(st.column_decltype(4), "TINYINT".equalsIgnoreCase(st
-                .column_decltype(4)));
-        assertTrue(st.column_decltype(5), "SMALLINT".equalsIgnoreCase(st
-                .column_decltype(5)));
-        assertTrue(st.column_decltype(6), "MEDIUMINT".equalsIgnoreCase(st
-                .column_decltype(6)));
-        assertTrue(st.column_decltype(7), "INTEGER".equalsIgnoreCase(st
-                .column_decltype(7)));
-        assertTrue(st.column_decltype(8), "REAL".equalsIgnoreCase(st
-                .column_decltype(8)));
-        assertTrue(st.column_decltype(9), "DOUBLE".equalsIgnoreCase(st
-                .column_decltype(9)));
-        assertTrue(st.column_decltype(10), "FLOAT".equalsIgnoreCase(st
-                .column_decltype(10)));
-        assertTrue(st.column_decltype(11), "DECIMAL".equalsIgnoreCase(st
-                .column_decltype(11)));
-        assertTrue(st.column_decltype(12), "NUMERIC".equalsIgnoreCase(st
-                .column_decltype(12)));
-        assertTrue(st.column_decltype(13), "CHAR(20)".equalsIgnoreCase(st
-                .column_decltype(13)));
-
-        assertTrue(st.column_decltype(19), "BLOB".equalsIgnoreCase(st
-                .column_decltype(19)));
-
-        assertTrue(st.column_decltype(23), "TEXT".equalsIgnoreCase(st
-                .column_decltype(23)));
-        assertTrue(st.column_decltype(28), "URL".equalsIgnoreCase(st
-                .column_decltype(28)));
-        assertTrue(st.column_decltype(29), "URL".equalsIgnoreCase(st
-                .column_decltype(29)));
-    }
-
-    public void testColumn_origin_name() {
-        try {
-            st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
-            st.column_origin_name(1);
-            fail("Function is now supported.");
-        } catch (SQLite.Exception expected) {
-            assertEquals("unsupported", expected.getMessage());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java b/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java
deleted file mode 100644
index 8febfff..0000000
--- a/luni/src/test/java/libcore/sqlite/QueryTimeoutTest.java
+++ /dev/null
@@ -1,165 +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 libcore.sqlite;
-
-import SQLite.Database;
-import SQLite.Function;
-import SQLite.FunctionContext;
-import SQLite.JDBC2z.JDBCConnection;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import junit.framework.TestCase;
-import tests.support.Support_SQL;
-
-
-/**
- * Test that statements honor their timeout.
- */
-public final class QueryTimeoutTest extends TestCase {
-
-    private static final String EXEC_QUERY
-            = "insert into t_copy select a from t_orig where DELAY(2,1)=1";
-
-    private static final String FETCH_QUERY = "select a from t_orig where DELAY(2,1)=1";
-
-    private Connection connection;
-
-    @Override public void setUp() throws Exception {
-        Support_SQL.loadDriver();
-        connection = Support_SQL.getConnection();
-
-        exec("drop table if exists t_orig;");
-        exec("drop table if exists t_copy;");
-        exec("create table t_orig (a int)");
-        exec("create table t_copy (a int)");
-
-        for (int i = 0; i < 7; i++) {
-            exec("insert into t_orig values (" + i + ");");
-        }
-
-        Database database = ((JDBCConnection) connection).getSQLiteDatabase();
-        database.create_function("DELAY", 2, new Function() {
-            @Override public void function(FunctionContext functionContext, String[] args) {
-                try {
-                    int seconds = Integer.parseInt(args[0]);
-                    Thread.sleep(seconds * 1000);
-                } catch (InterruptedException ignored) {
-                }
-                functionContext.set_result(Integer.parseInt(args[1]));
-            }
-            @Override public void last_step(FunctionContext functionContext) {
-            }
-            @Override public void step(FunctionContext functionContext, String[] args) {
-            }
-        });
-
-        connection.setAutoCommit(true);
-    }
-
-    @Override public void tearDown() throws Exception {
-        connection.close();
-    }
-
-    private void exec(String queryString) throws Exception {
-        System.out.println("Executing " + queryString);
-        Statement statement = null;
-        try {
-            statement = connection.createStatement();
-            statement.execute(queryString);
-        } finally {
-            if (statement != null) {
-                statement.close();
-            }
-        }
-    }
-
-    public void testPreparedStatementFetch() throws Exception {
-        PreparedStatement statement = connection.prepareStatement(FETCH_QUERY);
-        statement.setQueryTimeout(1);
-        ResultSet resultSet = null;
-        try {
-            resultSet = statement.executeQuery();
-            while (resultSet.next()) {
-            }
-            fail();
-        } catch (SQLException expected) {
-        } finally {
-            statement.close();
-            if (resultSet != null) {
-                resultSet.close();
-            }
-        }
-    }
-
-    public void testPreparedStatementUpdate() throws Exception {
-        PreparedStatement statement = connection.prepareStatement(EXEC_QUERY);
-        try {
-            statement.setQueryTimeout(1);
-            statement.execute();
-            fail();
-        } catch (SQLException expected) {
-        } finally {
-            statement.close();
-        }
-    }
-
-    public void testInvalidTimeout() throws Exception {
-        connection.setAutoCommit(true);
-        PreparedStatement statement = connection.prepareStatement("select 'hello'");
-
-        try {
-            statement.setQueryTimeout(-1);
-            fail();
-        } catch (SQLException expected) {
-        }
-
-        ResultSet resultSet = statement.executeQuery();
-        resultSet.close();
-        statement.close();
-    }
-
-    public void testExecuteUpdate() throws Exception {
-        Statement statement = connection.createStatement();
-        try {
-            statement.setQueryTimeout(1);
-            statement.executeUpdate(EXEC_QUERY);
-            fail();
-        } catch (SQLException expected) {
-        } finally {
-            statement.close();
-        }
-    }
-
-    public void testTimeoutAndStatementReuse() throws Exception {
-        Statement statement = connection.createStatement();
-        statement.setQueryTimeout(1);
-        for (int i = 0; i < 3; i++) {
-            try {
-                ResultSet resultSet = statement.executeQuery(FETCH_QUERY);
-                while (resultSet.next()) {
-                }
-                fail();
-            } catch (SQLException expected) {
-            }
-        }
-        statement.close();
-    }
-}
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
index 7886e3e..ad084e1 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
@@ -68,7 +68,17 @@
      * java.security.Signature#clone()
      */
     public void test_clone() throws Exception {
+        // A Signature may be cloneable according to the API, in practice the implementation isn't
+        // once it has been initialized. Checking for runtime exceptions rather than useful
+        // behavior.
         Signature s = Signature.getInstance("DSA");
+        Signature clone = (Signature) s.clone();
+        assertNotNull(clone);
+        assertEquals(s.getAlgorithm(), clone.getAlgorithm());
+        assertEquals(s.getProvider(), clone.getProvider());
+
+        KeyPair keyPair = getDsaKeys();
+        s.initSign(keyPair.getPrivate());
         try {
             s.clone();
             fail();
