diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 797dfee..01f0bf4 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -50,18 +50,21 @@
 endef
 
 # The Java files and their associated resources.
-core_src_files := $(call all-main-java-files-under,dalvik dex dom json luni support xml)
-core_src_files += $(call all-main-java-files-under,libdvm)
+common_core_src_files := $(call all-main-java-files-under,dalvik dex dom json luni support xml)
+
 core_resource_dirs := $(call all-core-resource-dirs,main)
 test_resource_dirs := $(call all-core-resource-dirs,test)
 
 ifeq ($(EMMA_INSTRUMENT),true)
 ifneq ($(EMMA_INSTRUMENT_STATIC),true)
-    core_src_files += $(call all-java-files-under, ../external/emma/core ../external/emma/pregenerated)
+    common_core_src_files += $(call all-java-files-under, ../external/emma/core ../external/emma/pregenerated)
     core_resource_dirs += ../external/emma/core/res ../external/emma/pregenerated/res
 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
 #local_javac_flags+=-Xlint:all -Xlint:-serial,-deprecation,-unchecked
 local_javac_flags+=-Xmaxwarns 9999999
@@ -73,23 +76,28 @@
 # Definitions to make the core library.
 
 include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(core_src_files)
+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)
 
-core-intermediates := ${intermediates}
-
+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
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
+LOCAL_REQUIRED_MODULES := tzdata
+include $(BUILD_JAVA_LIBRARY)
 
 # Create the conscrypt library
 include $(CLEAR_VARS)
@@ -171,23 +179,30 @@
 ifeq ($(WITH_HOST_DALVIK),true)
 
     # Definitions to make the core library.
-
     include $(CLEAR_VARS)
-
-    LOCAL_SRC_FILES := $(core_src_files)
+    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_BUILD_HOST_DEX := true
-
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-hostdex
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     LOCAL_REQUIRED_MODULES := tzdata-host
+    include $(BUILD_HOST_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_BUILD_HOST_DEX := true
+    LOCAL_MODULE_TAGS := optional
+    LOCAL_MODULE := core-libart-hostdex
+    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
+    LOCAL_REQUIRED_MODULES := tzdata-host
     include $(BUILD_HOST_JAVA_LIBRARY)
 
     # Make the conscrypt-hostdex library
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
index 9b066b5..7c5d78f 100644
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
+++ b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
@@ -740,7 +740,7 @@
             } catch (IOException e) {
                 // return an invalid session with
                 // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
-                return SSLSessionImpl.NULL_SESSION;
+                return SSLSessionImpl.getNullSession();
             }
         }
         return sslSession;
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java b/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
index 0be367d..3ed9980 100644
--- a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
+++ b/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
@@ -369,7 +369,7 @@
         if (session != null) {
             return session;
         }
-        return SSLSessionImpl.NULL_SESSION;
+        return SSLSessionImpl.getNullSession();
     }
 
     /**
diff --git a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java b/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
index 4014a28..9631b1e 100644
--- a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
+++ b/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
@@ -33,8 +33,13 @@
 
 public final class SSLSessionImpl implements SSLSession, Cloneable  {
 
-    /** Session object reporting an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" */
-    public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null);
+    /*
+     * Holds default instances so class preloading doesn't create an instance of
+     * it.
+     */
+    private static class DefaultHolder {
+        public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null);
+    }
 
     private long creationTime;
     private boolean isValid = true;
@@ -54,6 +59,10 @@
     byte[] serverRandom;
     final boolean isServer;
 
+    public static SSLSessionImpl getNullSession() {
+        return DefaultHolder.NULL_SESSION;
+    }
+
     public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom secureRandom) {
         creationTime = System.currentTimeMillis();
         lastAccessedTime = creationTime;
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
index b727873..138a143 100644
--- a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
+++ b/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
@@ -391,7 +391,7 @@
             } catch (IOException e) {
                 // return an invalid session with
                 // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
-                return SSLSessionImpl.NULL_SESSION;
+                return SSLSessionImpl.getNullSession();
             }
         }
         return session;
diff --git a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
index 5dc6037..1ca74f9 100644
--- a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
@@ -4537,6 +4537,8 @@
     return reinterpret_cast<uintptr_t>(revoked->revocationDate);
 }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wwrite-strings"
 static void NativeCrypto_X509_REVOKED_print(JNIEnv* env, jclass, jlong bioRef, jlong x509RevokedRef) {
     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
@@ -4554,16 +4556,14 @@
         return;
     }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wwrite-strings"
     BIO_printf(bio, "Serial Number: ");
     i2a_ASN1_INTEGER(bio, revoked->serialNumber);
     BIO_printf(bio, "\nRevocation Date: ");
     ASN1_TIME_print(bio, revoked->revocationDate);
     BIO_printf(bio, "\n");
     X509V3_extensions_print(bio, "CRL entry extensions", revoked->extensions, 0, 0);
-#pragma GCC diagnostic pop
 }
+#pragma GCC diagnostic pop
 
 static jbyteArray NativeCrypto_get_X509_CRL_crl_enc(JNIEnv* env, jclass, jlong x509CrlRef) {
     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
index 29cd30e..bf24998 100644
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ b/dex/src/main/java/com/android/dex/Dex.java
@@ -53,7 +53,9 @@
     private static final int CHECKSUM_SIZE = 4;
     private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;
     private static final int SIGNATURE_SIZE = 20;
-
+    // Provided as a convenience to avoid a memory allocation to benefit Dalvik.
+    // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.
+    static final short[] EMPTY_SHORT_ARRAY = new short[0];
     private ByteBuffer data;
     private final TableOfContents tableOfContents = new TableOfContents();
     private int nextSectionStart = 0;
@@ -450,6 +452,9 @@
         }
 
         public short[] readShortArray(int length) {
+            if (length == 0) {
+                return EMPTY_SHORT_ARRAY;
+            }
             short[] result = new short[length];
             for (int i = 0; i < length; i++) {
                 result[i] = readShort();
@@ -475,10 +480,7 @@
 
         public TypeList readTypeList() {
             int size = readInt();
-            short[] types = new short[size];
-            for (int i = 0; i < size; i++) {
-                types[i] = readShort();
-            }
+            short[] types = readShortArray(size);
             alignToFourBytes();
             return new TypeList(Dex.this, types);
         }
@@ -552,71 +554,71 @@
             Try[] tries;
             CatchHandler[] catchHandlers;
             if (triesSize > 0) {
-              if (instructions.length % 2 == 1) {
-                  readShort(); // padding
-              }
+                if (instructions.length % 2 == 1) {
+                    readShort(); // padding
+                }
 
-              /*
-               * We can't read the tries until we've read the catch handlers.
-               * Unfortunately they're in the opposite order in the dex file
-               * so we need to read them out-of-order.
-               */
-              Section triesSection = open(data.position());
-              skip(triesSize * SizeOf.TRY_ITEM);
-              catchHandlers = readCatchHandlers();
-              tries = triesSection.readTries(triesSize, catchHandlers);
-          } else {
-              tries = new Try[0];
-              catchHandlers = new CatchHandler[0];
-          }
-          return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
-                  tries, catchHandlers);
+                /*
+                 * We can't read the tries until we've read the catch handlers.
+                 * Unfortunately they're in the opposite order in the dex file
+                 * so we need to read them out-of-order.
+                 */
+                Section triesSection = open(data.position());
+                skip(triesSize * SizeOf.TRY_ITEM);
+                catchHandlers = readCatchHandlers();
+                tries = triesSection.readTries(triesSize, catchHandlers);
+            } else {
+                tries = new Try[0];
+                catchHandlers = new CatchHandler[0];
+            }
+            return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
+                            tries, catchHandlers);
         }
 
         private CatchHandler[] readCatchHandlers() {
-          int baseOffset = data.position();
-          int catchHandlersSize = readUleb128();
-          CatchHandler[] result = new CatchHandler[catchHandlersSize];
-          for (int i = 0; i < catchHandlersSize; i++) {
-            int offset = data.position() - baseOffset;
-            result[i] = readCatchHandler(offset);
-          }
-          return result;
+            int baseOffset = data.position();
+            int catchHandlersSize = readUleb128();
+            CatchHandler[] result = new CatchHandler[catchHandlersSize];
+            for (int i = 0; i < catchHandlersSize; i++) {
+                int offset = data.position() - baseOffset;
+                result[i] = readCatchHandler(offset);
+            }
+            return result;
         }
 
         private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
-          Try[] result = new Try[triesSize];
-          for (int i = 0; i < triesSize; i++) {
-            int startAddress = readInt();
-            int instructionCount = readUnsignedShort();
-            int handlerOffset = readUnsignedShort();
-            int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
-            result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
-          }
-          return result;
+            Try[] result = new Try[triesSize];
+            for (int i = 0; i < triesSize; i++) {
+                int startAddress = readInt();
+                int instructionCount = readUnsignedShort();
+                int handlerOffset = readUnsignedShort();
+                int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
+                result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
+            }
+            return result;
         }
 
         private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
-          for (int i = 0; i < catchHandlers.length; i++) {
-            CatchHandler catchHandler = catchHandlers[i];
-            if (catchHandler.getOffset() == offset) {
-              return i;
+            for (int i = 0; i < catchHandlers.length; i++) {
+                CatchHandler catchHandler = catchHandlers[i];
+                if (catchHandler.getOffset() == offset) {
+                    return i;
+                }
             }
-          }
-          throw new IllegalArgumentException();
+            throw new IllegalArgumentException();
         }
 
         private CatchHandler readCatchHandler(int offset) {
-          int size = readSleb128();
-          int handlersCount = Math.abs(size);
-          int[] typeIndexes = new int[handlersCount];
-          int[] addresses = new int[handlersCount];
-          for (int i = 0; i < handlersCount; i++) {
-            typeIndexes[i] = readUleb128();
-            addresses[i] = readUleb128();
-          }
-          int catchAllAddress = size <= 0 ? readUleb128() : -1;
-          return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
+            int size = readSleb128();
+            int handlersCount = Math.abs(size);
+            int[] typeIndexes = new int[handlersCount];
+            int[] addresses = new int[handlersCount];
+            for (int i = 0; i < handlersCount; i++) {
+                typeIndexes[i] = readUleb128();
+                addresses[i] = readUleb128();
+            }
+            int catchAllAddress = size <= 0 ? readUleb128() : -1;
+            return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
         }
 
         private ClassData readClassData() {
@@ -680,11 +682,11 @@
         }
 
         public void skip(int count) {
-          if (count < 0) {
-              throw new IllegalArgumentException();
-          }
-          data.position(data.position() + count);
-      }
+            if (count < 0) {
+                throw new IllegalArgumentException();
+            }
+            data.position(data.position() + count);
+        }
 
         /**
          * Skips bytes until the position is aligned to a multiple of 4.
@@ -788,4 +790,85 @@
             return data.position() - initialPosition;
         }
     }
+
+    /**
+     * Look up a field id name index from a field index. Equivalent to:
+     * {@code fieldIds().get(fieldDexIndex).getNameIndex();}
+     */
+    public int nameIndexFromFieldIndex(int fieldIndex) {
+        checkBounds(fieldIndex, tableOfContents.fieldIds.size);
+        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);
+        position += SizeOf.USHORT;  // declaringClassIndex
+        position += SizeOf.USHORT;  // typeIndex
+        return data.getInt(position);  // nameIndex
+    }
+
+    /**
+     * Look up a field id type index from a field index. Equivalent to:
+     * {@code fieldIds().get(fieldDexIndex).getTypeIndex();}
+     */
+    public int typeIndexFromFieldIndex(int fieldIndex) {
+        checkBounds(fieldIndex, tableOfContents.fieldIds.size);
+        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);
+        position += SizeOf.USHORT;  // declaringClassIndex
+        return data.getShort(position) & 0xFFFF;  // typeIndex
+    }
+
+    /**
+     * Look up a method id name index from a method index. Equivalent to:
+     * {@code methodIds().get(methodIndex).getNameIndex();}
+     */
+    public int nameIndexFromMethodIndex(int methodIndex) {
+        checkBounds(methodIndex, tableOfContents.methodIds.size);
+        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
+        position += SizeOf.USHORT;  // declaringClassIndex
+        position += SizeOf.USHORT;  // protoIndex
+        return data.getInt(position);  // nameIndex
+    }
+
+    /**
+     * Lookup a parameter type ids from a method index. Equivalent to:
+     * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();}
+     */
+    public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) {
+        checkBounds(methodIndex, tableOfContents.methodIds.size);
+        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
+        position += SizeOf.USHORT;  // declaringClassIndex
+        int protoIndex = data.getShort(position) & 0xFFFF;
+        checkBounds(protoIndex, tableOfContents.protoIds.size);
+        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
+        position += SizeOf.UINT;  // shortyIndex
+        position += SizeOf.UINT;  // returnTypeIndex
+        int parametersOffset = data.getInt(position);
+        if (parametersOffset == 0) {
+            return EMPTY_SHORT_ARRAY;
+        }
+        position = parametersOffset;
+        int size = data.getInt(position);
+        if (size <= 0) {
+            throw new AssertionError("Unexpected parameter type list size: " + size);
+        }
+        position += SizeOf.UINT;
+        short[] types = new short[size];
+        for (int i = 0; i < size; i++) {
+            types[i] = data.getShort(position);
+            position += SizeOf.USHORT;
+        }
+        return types;
+    }
+
+    /**
+     * Look up a method id return type index from a method index. Equivalent to:
+     * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();}
+     */
+    public int returnTypeIndexFromMethodIndex(int methodIndex) {
+        checkBounds(methodIndex, tableOfContents.methodIds.size);
+        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
+        position += SizeOf.USHORT;  // declaringClassIndex
+        int protoIndex = data.getShort(position) & 0xFFFF;
+        checkBounds(protoIndex, tableOfContents.protoIds.size);
+        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
+        position += SizeOf.UINT;  // shortyIndex
+        return data.getInt(position);  // returnTypeIndex
+    }
 }
diff --git a/dex/src/main/java/com/android/dex/TypeList.java b/dex/src/main/java/com/android/dex/TypeList.java
index 6e321fb..123e82c 100644
--- a/dex/src/main/java/com/android/dex/TypeList.java
+++ b/dex/src/main/java/com/android/dex/TypeList.java
@@ -20,7 +20,7 @@
 
 public final class TypeList implements Comparable<TypeList> {
 
-    public static final TypeList EMPTY = new TypeList(null, new short[0]);
+    public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);
 
     private final Dex dex;
     private final short[] types;
diff --git a/libart/src/main/java/dalvik/system/VMDebug.java b/libart/src/main/java/dalvik/system/VMDebug.java
new file mode 100644
index 0000000..055e747
--- /dev/null
+++ b/libart/src/main/java/dalvik/system/VMDebug.java
@@ -0,0 +1,395 @@
+/*
+ * 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.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Provides access to some VM-specific debug features. Though this class and
+ * many of its members are public, this class is meant to be wrapped in a more
+ * friendly way for use by application developers. On the Android platform, the
+ * recommended way to access this functionality is through the class
+ * <code>android.os.Debug</code>.
+ *
+ * @hide
+ */
+public final class VMDebug {
+    /**
+     * Specifies the default method trace data file name.
+     *
+     * @deprecated only used in one place, which is unused and deprecated
+     */
+    @Deprecated
+    static public final String DEFAULT_METHOD_TRACE_FILE_NAME = "/sdcard/dmtrace.trace";
+
+    /**
+     * flag for startMethodTracing(), which adds the results from
+     * startAllocCounting to the trace key file.
+     */
+    public static final int TRACE_COUNT_ALLOCS = 1;
+
+    /* constants for getAllocCount */
+    private static final int KIND_ALLOCATED_OBJECTS     = 1<<0;
+    private static final int KIND_ALLOCATED_BYTES       = 1<<1;
+    private static final int KIND_FREED_OBJECTS         = 1<<2;
+    private static final int KIND_FREED_BYTES           = 1<<3;
+    private static final int KIND_GC_INVOCATIONS        = 1<<4;
+    private static final int KIND_CLASS_INIT_COUNT      = 1<<5;
+    private static final int KIND_CLASS_INIT_TIME       = 1<<6;
+    private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12;
+    private static final int KIND_EXT_ALLOCATED_BYTES   = 1<<13;
+    private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
+    private static final int KIND_EXT_FREED_BYTES       = 1<<15;
+
+    public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
+        KIND_ALLOCATED_OBJECTS;
+    public static final int KIND_GLOBAL_ALLOCATED_BYTES =
+        KIND_ALLOCATED_BYTES;
+    public static final int KIND_GLOBAL_FREED_OBJECTS =
+        KIND_FREED_OBJECTS;
+    public static final int KIND_GLOBAL_FREED_BYTES =
+        KIND_FREED_BYTES;
+    public static final int KIND_GLOBAL_GC_INVOCATIONS =
+        KIND_GC_INVOCATIONS;
+    public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
+        KIND_CLASS_INIT_COUNT;
+    public static final int KIND_GLOBAL_CLASS_INIT_TIME =
+        KIND_CLASS_INIT_TIME;
+    public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS =
+        KIND_EXT_ALLOCATED_OBJECTS;
+    public static final int KIND_GLOBAL_EXT_ALLOCATED_BYTES =
+        KIND_EXT_ALLOCATED_BYTES;
+    public static final int KIND_GLOBAL_EXT_FREED_OBJECTS =
+        KIND_EXT_FREED_OBJECTS;
+    public static final int KIND_GLOBAL_EXT_FREED_BYTES =
+        KIND_EXT_FREED_BYTES;
+
+    public static final int KIND_THREAD_ALLOCATED_OBJECTS =
+        KIND_ALLOCATED_OBJECTS << 16;
+    public static final int KIND_THREAD_ALLOCATED_BYTES =
+        KIND_ALLOCATED_BYTES << 16;
+    public static final int KIND_THREAD_FREED_OBJECTS =
+        KIND_FREED_OBJECTS << 16;
+    public static final int KIND_THREAD_FREED_BYTES =
+        KIND_FREED_BYTES << 16;
+    public static final int KIND_THREAD_GC_INVOCATIONS =
+        KIND_GC_INVOCATIONS << 16;
+    public static final int KIND_THREAD_CLASS_INIT_COUNT =
+        KIND_CLASS_INIT_COUNT << 16;
+    public static final int KIND_THREAD_CLASS_INIT_TIME =
+        KIND_CLASS_INIT_TIME << 16;
+    public static final int KIND_THREAD_EXT_ALLOCATED_OBJECTS =
+        KIND_EXT_ALLOCATED_OBJECTS << 16;
+    public static final int KIND_THREAD_EXT_ALLOCATED_BYTES =
+        KIND_EXT_ALLOCATED_BYTES << 16;
+    public static final int KIND_THREAD_EXT_FREED_OBJECTS =
+        KIND_EXT_FREED_OBJECTS << 16;
+    public static final int KIND_THREAD_EXT_FREED_BYTES =
+        KIND_EXT_FREED_BYTES << 16;
+
+    public static final int KIND_ALL_COUNTS = 0xffffffff;
+
+    /* all methods are static */
+    private VMDebug() {}
+
+    /**
+     * Returns the time since the last known debugger activity.
+     *
+     * @return the time in milliseconds, or -1 if the debugger is not connected
+     */
+    public static native long lastDebuggerActivity();
+
+    /**
+     * Determines if debugging is enabled in this VM.  If debugging is not
+     * enabled, a debugger cannot be attached.
+     *
+     * @return true if debugging is enabled
+     */
+    public static native boolean isDebuggingEnabled();
+
+    /**
+     * Determines if a debugger is currently attached.
+     *
+     * @return true if (and only if) a debugger is connected
+     */
+    public static native boolean isDebuggerConnected();
+
+    /**
+     * Returns an array of strings that identify VM features.  This is
+     * used by DDMS to determine what sorts of operations the VM can
+     * perform.
+     */
+    public static native String[] getVmFeatureList();
+
+    /**
+     * Start method tracing with default name, size, and with <code>0</code>
+     * flags.
+     *
+     * @deprecated not used, not needed
+     */
+    @Deprecated
+    public static void startMethodTracing() {
+        startMethodTracing(DEFAULT_METHOD_TRACE_FILE_NAME, 0, 0);
+    }
+
+    /**
+     * Start method tracing, specifying a file name as well as a default
+     * buffer size. See <a
+     * href="{@docRoot}guide/developing/tools/traceview.html"> Running the
+     * Traceview Debugging Program</a> for information about reading
+     * trace files.
+     *
+     * <p>You can use either a fully qualified path and
+     * name, or just a name. If only a name is specified, the file will
+     * be created under the /sdcard/ directory. If a name is not given,
+     * the default is /sdcard/dmtrace.trace.</p>
+     *
+     * @param traceFileName name to give the trace file
+     * @param bufferSize the maximum size of both files combined. If passed
+     * as <code>0</code>, it defaults to 8MB.
+     * @param flags flags to control method tracing. The only one that
+     * is currently defined is {@link #TRACE_COUNT_ALLOCS}.
+     */
+    public static void startMethodTracing(String traceFileName, int bufferSize, int flags) {
+        startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags);
+    }
+
+    /**
+     * Like startMethodTracing(String, int, int), but taking an already-opened
+     * FileDescriptor in which the trace is written.  The file name is also
+     * supplied simply for logging.  Makes a dup of the file descriptor.
+     */
+    public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags) {
+        if (fd == null) {
+            throw new NullPointerException("fd == null");
+        }
+        startMethodTracingFd(traceFileName, fd, checkBufferSize(bufferSize), flags);
+    }
+
+    /**
+     * Starts method tracing without a backing file.  When stopMethodTracing
+     * is called, the result is sent directly to DDMS.  (If DDMS is not
+     * attached when tracing ends, the profiling data will be discarded.)
+     */
+    public static void startMethodTracingDdms(int bufferSize, int flags) {
+        startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags);
+    }
+
+    private static int checkBufferSize(int bufferSize) {
+        if (bufferSize == 0) {
+            // Default to 8MB per the documentation.
+            bufferSize = 8 * 1024 * 1024;
+        }
+        if (bufferSize < 1024) {
+            throw new IllegalArgumentException("buffer size < 1024: " + bufferSize);
+        }
+        return bufferSize;
+    }
+
+    private static native void startMethodTracingDdmsImpl(int bufferSize, int flags);
+    private static native void startMethodTracingFd(String traceFileName, FileDescriptor fd, int bufferSize, int flags);
+    private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags);
+
+    /**
+     * Determine whether method tracing is currently active.
+     */
+    public static native boolean isMethodTracingActive();
+
+    /**
+     * Stops method tracing.
+     */
+    public static native void stopMethodTracing();
+
+    /**
+     * Starts sending Dalvik method trace info to the emulator.
+     */
+    public static native void startEmulatorTracing();
+
+    /**
+     * Stops sending Dalvik method trace info to the emulator.
+     */
+    public static native void stopEmulatorTracing();
+
+    /**
+     * Get an indication of thread CPU usage. The value returned indicates the
+     * amount of time that the current thread has spent executing code or
+     * waiting for certain types of I/O.
+     * <p>
+     * The time is expressed in nanoseconds, and is only meaningful when
+     * compared to the result from an earlier call. Note that nanosecond
+     * resolution does not imply nanosecond accuracy.
+     *
+     * @return the CPU usage. A value of -1 means the system does not support
+     *         this feature.
+     */
+    public static native long threadCpuTimeNanos();
+
+    /**
+     * Count the number and aggregate size of memory allocations between
+     * two points.
+     */
+    public static native void startAllocCounting();
+    public static native void stopAllocCounting();
+    public static native int getAllocCount(int kind);
+    public static native void resetAllocCount(int kinds);
+
+    /**
+     * This method exists for binary compatibility.  It was part of
+     * the allocation limits API which was removed in Honeycomb.
+     */
+    @Deprecated
+    public static int setAllocationLimit(int limit) {
+        return -1;
+    }
+
+    /**
+     * This method exists for binary compatibility.  It was part of
+     * the allocation limits API which was removed in Honeycomb.
+     */
+    @Deprecated
+    public static int setGlobalAllocationLimit(int limit) {
+        return -1;
+    }
+
+    /**
+     * Count the number of instructions executed between two points.
+     */
+    public static native void startInstructionCounting();
+    public static native void stopInstructionCounting();
+    public static native void getInstructionCount(int[] counts);
+    public static native void resetInstructionCount();
+
+    /**
+     * Dumps a list of loaded class to the log file.
+     */
+    public static native void printLoadedClasses(int flags);
+
+    /**
+     * Gets the number of loaded classes.
+     *
+     * @return the number of loaded classes
+     */
+    public static native int getLoadedClassCount();
+
+    /**
+     * Dumps "hprof" data to the specified file.  This may cause a GC.
+     *
+     * The VM may create a temporary file in the same directory.
+     *
+     * @param filename Full pathname of output file (e.g. "/sdcard/dump.hprof").
+     * @throws UnsupportedOperationException if the VM was built without
+     *         HPROF support.
+     * @throws IOException if an error occurs while opening or writing files.
+     */
+    public static void dumpHprofData(String filename) throws IOException {
+        if (filename == null) {
+            throw new NullPointerException("filename == null");
+        }
+        dumpHprofData(filename, null);
+    }
+
+    /**
+     * Collects "hprof" heap data and sends it to DDMS.  This may cause a GC.
+     *
+     * @throws UnsupportedOperationException if the VM was built without
+     *         HPROF support.
+     */
+    public static native void dumpHprofDataDdms();
+
+    /**
+     * Dumps "hprof" heap data to a file, by name or descriptor.
+     *
+     * @param fileName Name of output file.  If fd is non-null, the
+     *        file name is only used in log messages (and may be null).
+     * @param fd Descriptor of open file that will receive the output.
+     *        If this is null, the fileName is used instead.
+     */
+    public static native void dumpHprofData(String fileName, FileDescriptor fd)
+            throws IOException;
+
+    /**
+     * Primes the register map cache.
+     */
+    public static native boolean cacheRegisterMap(String classAndMethodDesc);
+
+    /**
+     * Dumps the contents of the VM reference tables (e.g. JNI locals and
+     * globals) to the log file.
+     */
+    public static native void dumpReferenceTables();
+
+    /**
+     * Crashes the VM.  Seriously.  Dumps the interpreter stack trace for
+     * the current thread and then aborts the VM so you can see the native
+     * stack trace.  Useful for figuring out how you got somewhere when
+     * lots of native code is involved.
+     */
+    public static native void crash();
+
+    /**
+     * Together with gdb, provide a handy way to stop the VM at user-tagged
+     * locations.
+     */
+    public static native void infopoint(int id);
+
+    /*
+     * Fake method, inserted into dmtrace output when the garbage collector
+     * runs.  Not actually called.
+     */
+    private static void startGC() {}
+
+    /*
+     * Fake method, inserted into dmtrace output during class preparation
+     * (loading and linking, but not verification or initialization).  Not
+     * actually called.
+     */
+    private static void startClassPrep() {}
+
+    /**
+     * Counts the instances of a class.
+     *
+     * @param klass the class to be counted.
+     * @param assignable if false, direct instances of klass are
+     *                   counted.  If true, instances that are
+     *                   assignable to klass, as defined by
+     *                   {@link Class#isAssignableFrom} are counted.
+     * @return the number of matching instances.
+     */
+    public static native long countInstancesOfClass(Class klass, boolean assignable);
+
+    /**
+     * Export the heap per-space stats for dumpsys meminfo.
+     *
+     * The content of the array is:
+     *
+     * <pre>
+     *   data[0] : the application heap space size
+     *   data[1] : the application heap space allocated bytes
+     *   data[2] : the application heap space free bytes
+     *   data[3] : the zygote heap space size
+     *   data[4] : the zygote heap space allocated size
+     *   data[5] : the zygote heap space free size
+     *   data[6] : the large object space size
+     *   data[7] : the large object space allocated bytes
+     *   data[8] : the large object space free bytes
+     * </pre>
+     *
+     * @param data the array into which the stats are written.
+     */
+    public static native void getHeapSpaceStats(long[] data);
+}
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
new file mode 100644
index 0000000..d322c16
--- /dev/null
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -0,0 +1,243 @@
+/*
+ * 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 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();
+
+    /**
+     * 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();
+
+    /**
+     * 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).
+     */
+    public native void setTargetSdkVersion(int targetSdkVersion);
+
+    /**
+     * This method exists for binary compatibility.  It was part of a
+     * heap sizing API which was removed in 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 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 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 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 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 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);
+
+    public native void trimHeap();
+    public native void concurrentGC();
+}
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
new file mode 100644
index 0000000..ee0a0db
--- /dev/null
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+     *
+     * @return the requested class, or {@code null}.
+     */
+    public static Class<?> getStackClass1() {
+        return getStackClass2();
+    }
+
+    /**
+     * Returns the class of the caller's caller's caller.
+     *
+     * @return the requested class, or {@code null}.
+     */
+    native public static Class<?> getStackClass2();
+
+    /**
+     * Returns the first ClassLoader on the call stack that isn't either of
+     * the passed-in ClassLoaders.
+     */
+    public native static ClassLoader getClosestUserClassLoader(ClassLoader bootstrap,
+                                                               ClassLoader system);
+
+    /**
+     * 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/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
new file mode 100644
index 0000000..cb504ca
--- /dev/null
+++ b/libart/src/main/java/java/lang/Class.java
@@ -0,0 +1,1676 @@
+/*
+ * 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.reflect.AbstractMethod;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.ArtField;
+import java.lang.reflect.ArtMethod;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.InvocationTargetException;
+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.List;
+import libcore.reflect.AnnotationAccess;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.InternalNames;
+import libcore.reflect.Types;
+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>descriptor</em>, which is the letter "L", followed by the
+ * class name and a semicolon (";"). The descriptor 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 descriptors 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 descriptor of the class representing the leaf component type,
+ * which can be either an object type or a primitive type. The descriptor of a
+ * {@code Class} representing an array type is the same as its name. Examples
+ * of array class descriptors 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;
+
+    /** defining class loader, or NULL for the "bootstrap" system loader. */
+    private transient ClassLoader classLoader;
+
+    /**
+     * For array classes, the component class object for instanceof/checkcast (for String[][][],
+     * this will be String[][]). NULL for non-array classes.
+     */
+    private transient Class<?> componentType;
+    /**
+     * DexCache of resolved constant pool entries. Will be null for certain VM-generated classes
+     * e.g. arrays and primitive classes.
+     */
+    private transient DexCache dexCache;
+
+    /** static, private, and &lt;init&gt; methods. */
+    private transient ArtMethod[] directMethods;
+
+    /**
+     * Instance fields. These describe the layout of the contents of an Object. Note that only the
+     * fields directly declared by this class are listed in iFields; fields declared by a
+     * superclass are listed in the superclass's Class.iFields.
+     *
+     * All instance fields that refer to objects are guaranteed to be at the beginning of the field
+     * list.  {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
+     */
+    private transient ArtField[] iFields;
+
+    /**
+     * The interface table (iftable_) contains pairs of a interface class and an array of the
+     * interface methods. There is one pair per interface supported by this class.  That
+     * means one pair for each interface we support directly, indirectly via superclass, or
+     * indirectly via a superinterface.  This will be null if neither we nor our superclass
+     * implement any interfaces.
+     *
+     * Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
+     * Invoke faceObj.blah(), where "blah" is part of the Face interface.  We can't easily use a
+     * single vtable.
+     *
+     * For every interface a concrete class implements, we create an array of the concrete vtable_
+     * methods for the methods in the interface.
+     */
+    private transient Object[] ifTable;
+
+    /** Lazily computed name of this class; always prefer calling getName(). */
+    private transient String name;
+
+    /** Static fields */
+    private transient ArtField[] sFields;
+
+    /** The superclass, or NULL if this is java.lang.Object, an interface or primitive type. */
+    private transient Class<? super T> superClass;
+
+    /** If class verify fails, we must return same error on subsequent tries. */
+    private transient Class<?> verifyErrorClass;
+
+    /** Virtual methods defined in this class; invoked through vtable. */
+    private transient ArtMethod[] virtualMethods;
+
+    /**
+     * Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass
+     * is copied in, and virtual methods from our class either replace those from the super or are
+     * appended. For abstract classes, methods may be created in the vtable that aren't in
+     * virtual_ methods_ for miranda methods.
+     */
+    private transient ArtMethod[] vtable;
+
+    /** access flags; low 16 bits are defined by VM spec */
+    private transient int accessFlags;
+
+    /**
+     * Total size of the Class instance; used when allocating storage on GC heap.
+     * See also {@link Class#objectSize}.
+     */
+    private transient int classSize;
+
+    /**
+     * tid used to check for recursive static initializer invocation.
+     */
+    private transient int clinitThreadId;
+
+    /**
+     * Type index from dex file.
+     * TODO: really 16bits
+     */
+    private transient int dexTypeIndex;
+
+    /** Number of instance fields that are object references. */
+    private transient int numReferenceInstanceFields;
+
+    /** Number of static fields that are object references. */
+    private transient int numReferenceStaticFields;
+
+    /**
+     * Total object size; used when allocating storage on GC heap. For interfaces and abstract
+     * classes this will be zero. See also {@link Class#classSize}.
+     */
+    private transient int objectSize;
+
+    /** Primitive type value, or 0 if not a primitive type; set for generated primitive classes. */
+    private transient int primitiveType;
+
+    /** Bitmap of offsets of iFields. */
+    private transient int referenceInstanceOffsets;
+
+    /** Bitmap of offsets of sFields. */
+    private transient int referenceStaticOffsets;
+
+    /** State of class initialization */
+    private transient int status;
+
+    private Class() {
+        // Prevent this class to be instantiated, instance should be created by JVM only
+    }
+
+    /**
+     * 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 cannot 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 cannot 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 LinkageError) {
+                throw (LinkageError) cause;
+            }
+            throw e;
+        }
+        return result;
+    }
+
+    static native Class<?> classForName(String className, boolean shouldInitialize,
+            ClassLoader classLoader) throws ClassNotFoundException;
+
+    /**
+     * Returns an array containing {@code Class} objects for all
+     * public classes, interfaces, enums and annotations that are
+     * members of this class and its superclasses. This does not
+     * include classes of implemented 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() {
+        List<Class<?>> result = new ArrayList<Class<?>>();
+        for (Class<?> c = this; c != null; c = c.superClass) {
+            for (Class<?> member : c.getDeclaredClasses()) {
+                if (Modifier.isPublic(member.getModifiers())) {
+                    result.add(member);
+                }
+            }
+        }
+        return result.toArray(new Class[result.size()]);
+    }
+
+    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        return AnnotationAccess.getAnnotation(this, annotationType);
+    }
+
+    /**
+     * Returns an array containing all the annotations of this class. If there are no annotations
+     * then an empty array is returned.
+     *
+     * @see #getDeclaredAnnotations()
+     */
+    @Override public Annotation[] getAnnotations() {
+        return AnnotationAccess.getAnnotations(this);
+    }
+
+    /**
+     * 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 = classLoader;
+        return loader == null ? BootClassLoader.getInstance() : loader;
+    }
+
+    /**
+     * 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 Class<?> getComponentType() {
+      return componentType;
+    }
+
+    /**
+     * Returns the dex file from which this class was loaded.
+     *
+     * @hide
+     */
+    public native Dex getDex();
+
+    /**
+     * Returns a string from the dex cache, computing the string from the dex file if necessary
+     *
+     * @hide
+     */
+    public String getDexCacheString(Dex dex, int dexStringIndex) {
+        String[] dexCacheStrings = dexCache.strings;
+        String s = dexCacheStrings[dexStringIndex];
+        if (s == null) {
+            s = dex.strings().get(dexStringIndex);
+            dexCacheStrings[dexStringIndex] = s;
+        }
+        return s;
+    }
+
+    /**
+     * Returns a resolved type from the dex cache, computing the string from the dex file if
+     * necessary
+     *
+     * @hide
+     */
+    public Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
+        Class<?>[] dexCacheResolvedTypes = dexCache.resolvedTypes;
+        Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
+        if (resolvedType == null) {
+            int descriptorIndex = dex.typeIds().get(dexTypeIndex);
+            String descriptor = getDexCacheString(dex, descriptorIndex);
+            resolvedType = InternalNames.getClass(getClassLoader(), descriptor);
+            dexCacheResolvedTypes[dexTypeIndex] = resolvedType;
+        }
+        return resolvedType;
+    }
+
+    /**
+     * Returns a {@code Constructor} object which represents the public
+     * constructor matching the given parameter types.
+     * {@code (Class[]) null} is equivalent to the empty array.
+     *
+     * @throws NoSuchMethodException
+     *             if the constructor cannot be found.
+     * @see #getDeclaredConstructor(Class[])
+     */
+    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException {
+        return getConstructor(parameterTypes, true);
+    }
+
+    /**
+     * Returns a {@code Constructor} object which represents the constructor
+     * matching the specified parameter types that is declared by the class
+     * represented by this {@code Class}.
+     * {@code (Class[]) null} is equivalent to the empty array.
+     *
+     * @throws NoSuchMethodException
+     *             if the requested constructor cannot be found.
+     * @see #getConstructor(Class[])
+     */
+    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
+            throws NoSuchMethodException {
+        return getConstructor(parameterTypes, false);
+    }
+
+    /**
+     * Returns a constructor with the given parameters.
+     *
+     * @param publicOnly true to only return public constructores.
+     * @param parameterTypes argument types to match the constructor's.
+     */
+    private Constructor<T> getConstructor(Class<?>[] parameterTypes, boolean publicOnly)
+            throws NoSuchMethodException {
+        if (parameterTypes == null) {
+            parameterTypes = EmptyArray.CLASS;
+        }
+        for (Class<?> c : parameterTypes) {
+            if (c == null) {
+                throw new NoSuchMethodException("parameter type is null");
+            }
+        }
+        Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
+        if (result == null || publicOnly && !Modifier.isPublic(result.getAccessFlags())) {
+            throw new NoSuchMethodException("<init> " + Arrays.toString(parameterTypes));
+        }
+        return result;
+    }
+
+    /**
+     * Returns the constructor with the given parameters if it is defined by this class; null
+     * otherwise. This may return a non-public member.
+     *
+     * @param args the types of the parameters to the constructor.
+     */
+    private Constructor<T> getDeclaredConstructorInternal(Class<?>[] args) {
+        if (directMethods != null) {
+            for (ArtMethod m : directMethods) {
+                int modifiers = m.getAccessFlags();
+                if (Modifier.isStatic(modifiers)) {
+                    // skip <clinit> which is a static constructor
+                    continue;
+                }
+                if (!Modifier.isConstructor(modifiers)) {
+                    continue;
+                }
+                if (!ArtMethod.equalConstructorParameters(m, args)) {
+                    continue;
+                }
+                return new Constructor<T>(m);
+            }
+        }
+        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() {
+        ArrayList<Constructor<T>> constructors = new ArrayList();
+        getDeclaredConstructors(true, constructors);
+        return constructors.toArray(new Constructor[constructors.size()]);
+    }
+
+    /**
+     * 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() {
+        ArrayList<Constructor<T>> constructors = new ArrayList();
+        getDeclaredConstructors(false, constructors);
+        return constructors.toArray(new Constructor[constructors.size()]);
+    }
+
+    private void getDeclaredConstructors(boolean publicOnly, List<Constructor<T>> constructors) {
+        if (directMethods != null) {
+            for (ArtMethod m : directMethods) {
+                int modifiers = m.getAccessFlags();
+                if (!publicOnly || Modifier.isPublic(modifiers)) {
+                    if (Modifier.isStatic(modifiers)) {
+                        // skip <clinit> which is a static constructor
+                        continue;
+                    }
+                    if (Modifier.isConstructor(modifiers)) {
+                        constructors.add(new Constructor<T>(m));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code Method} object which represents the method matching the
+     * specified name and parameter types that is declared by the class
+     * represented by this {@code Class}.
+     *
+     * @param name
+     *            the requested method's name.
+     * @param parameterTypes
+     *            the parameter types of the requested method.
+     *            {@code (Class[]) null} is equivalent to the empty array.
+     * @return the method described by {@code name} and {@code parameterTypes}.
+     * @throws NoSuchMethodException
+     *             if the requested constructor cannot be found.
+     * @throws NullPointerException
+     *             if {@code name} is {@code null}.
+     * @see #getMethod(String, Class[])
+     */
+    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
+            throws NoSuchMethodException {
+        return getMethod(name, parameterTypes, false);
+    }
+
+    /**
+     * Returns a {@code Method} object which represents the public method with
+     * the specified name and parameter types.
+     * {@code (Class[]) null} is equivalent to the empty array.
+     * 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 finally the superclasses of C
+     * for a method with matching name.
+     *
+     * @throws NoSuchMethodException
+     *             if the method cannot be found.
+     * @see #getDeclaredMethod(String, Class[])
+     */
+    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException {
+        return getMethod(name, parameterTypes, true);
+    }
+
+    private Method getMethod(String name, Class<?>[] parameterTypes, boolean recursivePublicMethods)
+            throws NoSuchMethodException {
+        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");
+            }
+        }
+        Method result = recursivePublicMethods ? getPublicMethodRecursive(name, parameterTypes)
+                                               : getDeclaredMethodInternal(name, parameterTypes);
+        // Fail if we didn't find the method or it was expected to be public.
+        if (result == null ||
+            (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
+            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
+        }
+        return result;
+    }
+
+    private Method getPublicMethodRecursive(String name, Class<?>[] parameterTypes) {
+        // search superclasses
+        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
+            Method result = c.getDeclaredMethodInternal(name, parameterTypes);
+            if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+                return result;
+            }
+        }
+        // search iftable which has a flattened and uniqued list of interfaces
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            for (int i = 0; i < iftable.length; i += 2) {
+                Class<?> ifc = (Class<?>) iftable[i];
+                Method result = ifc.getPublicMethodRecursive(name, parameterTypes);
+                if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the method if it is defined by this class; null otherwise. This may return a
+     * non-public member.
+     *
+     * @param name the method name
+     * @param args the method's parameter types
+     */
+    private Method getDeclaredMethodInternal(String name, Class<?>[] args) {
+        // Covariant return types permit the class to define multiple
+        // methods with the same name and parameter types. Prefer to
+        // return a non-synthetic method in such situations. We may
+        // still return a synthetic method to handle situations like
+        // escalated visibility. We never return miranda methods that
+        // were synthesized by the VM.
+        int skipModifiers = Modifier.MIRANDA | Modifier.SYNTHETIC;
+        ArtMethod artMethodResult = null;
+        if (virtualMethods != null) {
+            for (ArtMethod m : virtualMethods) {
+                String methodName = ArtMethod.getMethodName(m);
+                if (!name.equals(methodName)) {
+                    continue;
+                }
+                if (!ArtMethod.equalMethodParameters(m, args)) {
+                    continue;
+                }
+                int modifiers = m.getAccessFlags();
+                if ((modifiers & skipModifiers) == 0) {
+                    return new Method(m);
+                }
+                if ((modifiers & Modifier.MIRANDA) == 0) {
+                    // Remember as potential result if it's not a miranda method.
+                    artMethodResult = m;
+                }
+            }
+        }
+        if (artMethodResult == null) {
+            if (directMethods != null) {
+                for (ArtMethod m : directMethods) {
+                    int modifiers = m.getAccessFlags();
+                    if (Modifier.isConstructor(modifiers)) {
+                        continue;
+                    }
+                    String methodName = ArtMethod.getMethodName(m);
+                    if (!name.equals(methodName)) {
+                        continue;
+                    }
+                    if (!ArtMethod.equalMethodParameters(m, args)) {
+                        continue;
+                    }
+                    if ((modifiers & skipModifiers) == 0) {
+                        return new Method(m);
+                    }
+                    // Direct methods cannot be miranda methods,
+                    // so this potential result must be synthetic.
+                    artMethodResult = m;
+                }
+            }
+        }
+        if (artMethodResult == null) {
+            return null;
+        }
+        return new Method(artMethodResult);
+    }
+
+    /**
+     * 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() {
+        int initial_size = virtualMethods == null ? 0 : virtualMethods.length;
+        initial_size += directMethods == null ? 0 : directMethods.length;
+        ArrayList<Method> methods = new ArrayList<Method>(initial_size);
+        getDeclaredMethods(false, methods);
+        Method[] result = methods.toArray(new Method[methods.size()]);
+        for (Method m : result) {
+            // Throw NoClassDefFoundError if types cannot be resolved.
+            m.getReturnType();
+            m.getParameterTypes();
+        }
+        return result;
+
+    }
+
+    /**
+     * Returns the list of methods without performing any security checks
+     * first. If no methods exist, an empty array is returned.
+     */
+    private void getDeclaredMethods(boolean publicOnly, List<Method> methods) {
+        if (virtualMethods != null) {
+            for (ArtMethod m : virtualMethods) {
+                int modifiers = m.getAccessFlags();
+                if (!publicOnly || Modifier.isPublic(modifiers)) {
+                    // Add non-miranda virtual methods.
+                    if ((modifiers & Modifier.MIRANDA) == 0) {
+                        methods.add(new Method(m));
+                    }
+                }
+            }
+        }
+        if (directMethods != null) {
+            for (ArtMethod m : directMethods) {
+                int modifiers = m.getAccessFlags();
+                if (!publicOnly || Modifier.isPublic(modifiers)) {
+                    // Add non-constructor direct/static methods.
+                    if (!Modifier.isConstructor(modifiers)) {
+                        methods.add(new Method(m));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 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>();
+        getPublicMethodsInternal(methods);
+        /*
+         * Remove duplicate methods defined by superclasses and
+         * interfaces, 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 getPublicMethodsInternal(List<Method> result) {
+        getDeclaredMethods(true, result);
+        if (!isInterface()) {
+            // Search superclasses, for interfaces don't search java.lang.Object.
+            for (Class<?> c = superClass; c != null; c = c.superClass) {
+                c.getDeclaredMethods(true, result);
+            }
+        }
+        // Search iftable which has a flattened and uniqued list of interfaces.
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            for (int i = 0; i < iftable.length; i += 2) {
+                Class<?> ifc = (Class<?>) iftable[i];
+                ifc.getDeclaredMethods(true, result);
+            }
+        }
+    }
+
+    /**
+     * 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()
+     */
+    @Override public Annotation[] getDeclaredAnnotations() {
+        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
+        return result.toArray(new Annotation[result.size()]);
+    }
+
+    /**
+     * Returns an array containing {@code Class} objects for all classes,
+     * interfaces, enums and annotations that are members of this class.
+     */
+    public Class<?>[] getDeclaredClasses() {
+        return AnnotationAccess.getMemberClasses(this);
+    }
+
+    /**
+     * 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 = getDeclaredFieldInternal(name);
+        if (result == null) {
+            throw new NoSuchFieldException(name);
+        } else {
+            result.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
+        }
+        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() {
+        int initial_size = sFields == null ? 0 : sFields.length;
+        initial_size += iFields == null ? 0 : iFields.length;
+        ArrayList<Field> fields = new ArrayList(initial_size);
+        getDeclaredFields(false, fields);
+        Field[] result = fields.toArray(new Field[fields.size()]);
+        for (Field f : result) {
+            f.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
+        }
+        return result;
+    }
+
+    private void getDeclaredFields(boolean publicOnly, List<Field> fields) {
+        if (iFields != null) {
+            for (ArtField f : iFields) {
+                if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) {
+                    fields.add(new Field(f));
+                }
+            }
+        }
+        if (sFields != null) {
+            for (ArtField f : sFields) {
+                if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) {
+                    fields.add(new Field(f));
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the field if it is defined by this class; null otherwise. This
+     * may return a non-public member.
+     */
+    private Field getDeclaredFieldInternal(String name) {
+        if (iFields != null) {
+            for (ArtField f : iFields) {
+                if (f.getName().equals(name)) {
+                    return new Field(f);
+                }
+            }
+        }
+        if (sFields != null) {
+            for (ArtField f : sFields) {
+                if (f.getName().equals(name)) {
+                    return new Field(f);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the class that this class is a member of, or {@code null} if this
+     * class is a top-level class, a primitive, an array, or defined within a
+     * method or constructor.
+     */
+    public Class<?> getDeclaringClass() {
+        return AnnotationAccess.getDeclaringClass(this);
+    }
+
+    /**
+     * Returns the class enclosing this class. For most classes this is the same
+     * as the {@link #getDeclaringClass() declaring class}. For classes defined
+     * within a method or constructor (typically anonymous inner classes), this
+     * is the declaring class of that member.
+     */
+    public Class<?> getEnclosingClass() {
+        Class<?> declaringClass = getDeclaringClass();
+        if (declaringClass != null) {
+            return declaringClass;
+        }
+        AccessibleObject member = AnnotationAccess.getEnclosingMethodOrConstructor(this);
+        return member != null
+                ? ((Member) member).getDeclaringClass()
+                : null;
+    }
+
+    /**
+     * Returns the enclosing {@code Constructor} of this {@code Class}, if it is an
+     * anonymous or local/automatic class; otherwise {@code null}.
+     */
+    public Constructor<?> getEnclosingConstructor() {
+        if (classNameImpliesTopLevel()) {
+            return null;
+        }
+        AccessibleObject result = AnnotationAccess.getEnclosingMethodOrConstructor(this);
+        return result instanceof Constructor ? (Constructor<?>) result : null;
+    }
+
+    /**
+     * Returns the enclosing {@code Method} of this {@code Class}, if it is an
+     * anonymous or local/automatic class; otherwise {@code null}.
+     */
+    public Method getEnclosingMethod() {
+        if (classNameImpliesTopLevel()) {
+            return null;
+        }
+        AccessibleObject result = AnnotationAccess.getEnclosingMethodOrConstructor(this);
+        return result instanceof Method ? (Method) result : null;
+    }
+
+    /**
+     * Returns true if this class is definitely a top level class, or false if
+     * a more expensive check like {@link #getEnclosingClass()} is necessary.
+     *
+     * <p>This is a hack that exploits an implementation detail of all Java
+     * language compilers: generated names always contain "$". As it is possible
+     * for a top level class to be named with a "$", a false result <strong>does
+     * not</strong> indicate that this isn't a top-level class.
+     */
+    private boolean classNameImpliesTopLevel() {
+        return !getName().contains("$");
+    }
+
+    /**
+     * 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 cannot 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);
+        } else {
+            result.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
+        }
+        return result;
+    }
+
+    private Field getPublicFieldRecursive(String name) {
+        // search superclasses
+        for (Class<?> c = this; c != null; c = c.superClass) {
+            Field result = c.getDeclaredFieldInternal(name);
+            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
+                return result;
+            }
+        }
+
+        // search iftable which has a flattened and uniqued list of interfaces
+        if (ifTable != null) {
+            for (int i = 0; i < ifTable.length; i += 2) {
+                Class<?> ifc = (Class<?>) ifTable[i];
+                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);
+        Field[] result = fields.toArray(new Field[fields.size()]);
+        for (Field f : result) {
+            f.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
+        }
+        return result;
+    }
+
+    /**
+     * 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.superClass) {
+            c.getDeclaredFields(true, result);
+        }
+
+        // search iftable which has a flattened and uniqued list of interfaces
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            for (int i = 0; i < iftable.length; i += 2) {
+                Class<?> ifc = (Class<?>) iftable[i];
+                ifc.getDeclaredFields(true, 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() {
+        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+        parser.parseForClass(this, AnnotationAccess.getSignature(this));
+        return Types.getClonedTypeArray(parser.interfaceTypes);
+    }
+
+    /**
+     * Returns the {@code Type} that represents the superclass of this {@code
+     * class}.
+     */
+    public Type getGenericSuperclass() {
+        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+        parser.parseForClass(this, AnnotationAccess.getSignature(this));
+        return Types.getType(parser.superclassType);
+    }
+
+    /**
+     * 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.
+     *
+     * <p>This method only returns directly-implemented interfaces, and does not
+     * include interfaces implemented by superclasses or superinterfaces of any
+     * implemented interfaces.
+     */
+    public Class<?>[] getInterfaces() {
+        if (isArray()) {
+            return new Class<?>[] { Cloneable.class, Serializable.class };
+        } else if (isProxy()) {
+            return getProxyInterfaces();
+        } else {
+            return AnnotationAccess.typeIndexToInterfaces(this, getDex(), getTypeIndex());
+        }
+    }
+
+    // Returns the interfaces that this proxy class directly implements.
+    private native Class<?>[] getProxyInterfaces();
+
+    /**
+     * 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() {
+        // Array classes inherit modifiers from their component types, but in the case of arrays
+        // of an inner class, the class file may contain "fake" access flags because it's not valid
+        // for a top-level class to private, say. The real access flags are stored in the InnerClass
+        // attribute, so we need to make sure we drill down to the inner class: the accessFlags
+        // field is not the value we want to return, and the synthesized array class does not itself
+        // have an InnerClass attribute. https://code.google.com/p/android/issues/detail?id=56267
+        if (isArray()) {
+            int componentModifiers = getComponentType().getModifiers();
+            if ((componentModifiers & Modifier.INTERFACE) != 0) {
+                componentModifiers &= ~(Modifier.INTERFACE | Modifier.STATIC);
+            }
+            return Modifier.ABSTRACT | Modifier.FINAL | componentModifiers;
+        }
+        int JAVA_FLAGS_MASK = 0xffff;
+        int modifiers = AnnotationAccess.getInnerClassFlags(this, accessFlags & JAVA_FLAGS_MASK);
+        return modifiers & JAVA_FLAGS_MASK;
+    }
+
+    /**
+     * 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() + "[]";
+        }
+
+        if (isAnonymousClass()) {
+            return "";
+        }
+
+        if (isMemberClass() || isLocalClass()) {
+            return getInnerClassName();
+        }
+
+        String name = getName();
+        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 String getInnerClassName() {
+        return AnnotationAccess.getInnerClassName(this);
+    }
+
+    /**
+     * 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 Class<? super T> getSuperclass() {
+      // For interfaces superClass is Object (which agrees with the JNI spec)
+      // but not with the expected behavior here.
+      if (isInterface()) {
+        return null;
+      } else {
+        return superClass;
+      }
+    }
+
+    /**
+     * 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")
+    @Override public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
+        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+        parser.parseForClass(this, AnnotationAccess.getSignature(this));
+        return parser.formalTypeParameters.clone();
+    }
+
+    /**
+     * Tests whether this {@code Class} represents an annotation class.
+     */
+    public boolean isAnnotation() {
+        final int ACC_ANNOTATION = 0x2000;  // not public in reflect.Modifier
+        return (accessFlags & ACC_ANNOTATION) != 0;
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        return AnnotationAccess.isAnnotationPresent(this, annotationType);
+    }
+
+    /**
+     * Tests whether the class represented by this {@code Class} is
+     * anonymous.
+     */
+    public boolean isAnonymousClass() {
+        return AnnotationAccess.isAnonymousClass(this);
+    }
+
+    /**
+     * Tests whether the class represented by this {@code Class} is an array class.
+     */
+    public boolean isArray() {
+        return getComponentType() != null;
+    }
+
+    /**
+     * Is this a runtime created proxy class?
+     *
+     * @hide
+     */
+    public boolean isProxy() {
+        return (accessFlags & 0x00040000) != 0;
+    }
+
+    /**
+     * Can {@code c}  be assigned to this class? For example, String can be assigned to Object
+     * (by an upcast), however, an Object cannot be assigned to a String as a potentially exception
+     * throwing downcast would be necessary. Similarly for interfaces, a class that implements (or
+     * an interface that extends) another can be assigned to its parent, but not vice-versa. All
+     * Classes may assign to themselves. Classes for primitive types may not assign to each other.
+     *
+     * @param c the class to check.
+     * @return {@code true} if {@code c} can be assigned to the class
+     *         represented by this {@code Class}; {@code false} otherwise.
+     * @throws NullPointerException if {@code c} is {@code null}.
+     */
+    public boolean isAssignableFrom(Class<?> c) {
+        if (this == c) {
+            return true;  // Can always assign to things of the same type.
+        } else if (this == Object.class) {
+            return !c.isPrimitive();  // Can assign any reference to java.lang.Object.
+        } else if (isArray()) {
+            return c.isArray() && componentType.isAssignableFrom(c.componentType);
+        } else if (isInterface()) {
+            // Search iftable which has a flattened and uniqued list of interfaces.
+            Object[] iftable = c.ifTable;
+            if (iftable != null) {
+                for (int i = 0; i < iftable.length; i += 2) {
+                    Class<?> ifc = (Class<?>) iftable[i];
+                    if (ifc == this) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } else {
+            if (!c.isInterface()) {
+                for (c = c.superClass; c != null; c = c.superClass) {
+                    if (c == this) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether the class represented by this {@code Class} is an
+     * {@code enum}.
+     */
+    public boolean isEnum() {
+        return ((getModifiers() & 0x4000) != 0) && (getSuperclass() == Enum.class);
+    }
+
+    /**
+     * 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 boolean isInstance(Object object) {
+        if (object == null) {
+            return false;
+        }
+        return isAssignableFrom(object.getClass());
+    }
+
+    /**
+     * Tests whether this {@code Class} represents an interface.
+     */
+    public boolean isInterface() {
+      return (accessFlags & Modifier.INTERFACE) != 0;
+    }
+
+    /**
+     * Tests whether the class represented by this {@code Class} is defined
+     * locally.
+     */
+    public boolean isLocalClass() {
+        return !classNameImpliesTopLevel()
+                && AnnotationAccess.getEnclosingMethodOrConstructor(this) != null
+                && !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 boolean isPrimitive() {
+      return primitiveType != 0;
+    }
+
+    /**
+     * Tests whether this {@code Class} represents a synthetic type.
+     */
+    public boolean isSynthetic() {
+        final int ACC_SYNTHETIC = 0x1000;   // not public in reflect.Modifier
+        return (accessFlags & ACC_SYNTHETIC) != 0;
+    }
+
+    /**
+     * Indicates whether this {@code Class} or its parents override finalize.
+     *
+     * @hide
+     */
+    public boolean isFinalizable() {
+      final int ACC_CLASS_IS_FINALIZABLE = 0x80000000;  // not public in reflect.Modifier
+      return (accessFlags & ACC_CLASS_IS_FINALIZABLE) != 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 cannot be created.
+     */
+    public T newInstance() throws InstantiationException, IllegalAccessException {
+        if (isPrimitive() || isInterface() || isArray() || Modifier.isAbstract(accessFlags)) {
+            throw new InstantiationException(this + " cannot be instantiated");
+        }
+        Class<?> caller = VMStack.getStackClass1();
+        if (!caller.canAccess(this)) {
+            throw new IllegalAccessException(this + " is not accessible from " + caller);
+        }
+        Constructor<T> init;
+        try {
+            init = getDeclaredConstructor();
+        } catch (NoSuchMethodException e) {
+            InstantiationException t =
+                new InstantiationException(this + " has no zero argument constructor");
+            t.initCause(e);
+            throw t;
+        }
+        if (!caller.canAccessMember(this, init.getAccessFlags())) {
+            throw new IllegalAccessException(init + " is not accessible from " + caller);
+        }
+        try {
+            return init.newInstance();
+        } catch (InvocationTargetException e) {
+            InstantiationException t = new InstantiationException(this);
+            t.initCause(e);
+            throw t;
+        }
+    }
+
+    private boolean canAccess(Class<?> c) {
+        if(Modifier.isPublic(c.accessFlags)) {
+            return true;
+        }
+        return inSamePackage(c);
+    }
+
+    private boolean canAccessMember(Class<?> memberClass, int memberModifiers) {
+        if (memberClass == this || Modifier.isPublic(memberModifiers)) {
+            return true;
+        }
+        if (Modifier.isPrivate(memberModifiers)) {
+            return false;
+        }
+        if (Modifier.isProtected(memberModifiers)) {
+            for (Class<?> parent = this.superClass; parent != null; parent = parent.superClass) {
+                if (parent == memberClass) {
+                    return true;
+                }
+            }
+        }
+        return inSamePackage(memberClass);
+    }
+
+    private boolean inSamePackage(Class<?> c) {
+        if (classLoader != c.classLoader) {
+            return false;
+        }
+        String packageName1 = getPackageName$();
+        String packageName2 = c.getPackageName$();
+        if (packageName1 == null) {
+            return packageName2 == null;
+        } else if (packageName2 == null) {
+            return false;
+        } else {
+            return packageName1.equals(packageName2);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (isPrimitive()) {
+            return getSimpleName();
+        } else {
+            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 packageName = getPackageName$();
+            return packageName != null ? loader.getPackage(packageName) : null;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the package name of this class. This returns null for classes in
+     * the default package.
+     *
+     * @hide
+     */
+    public String getPackageName$() {
+        String name = getName();
+        int last = name.lastIndexOf('.');
+        return last == -1 ? null : name.substring(0, last);
+    }
+
+    /**
+     * 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 boolean desiredAssertionStatus() {
+      return false;
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * The type index of this class in its own Dex, or 0 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.
+     *
+     * TODO: 0 is a valid index; this should be -1 if it is unknown
+     *
+     * @hide
+     */
+    public int getTypeIndex() {
+        int result = dexTypeIndex;
+        if (result == 0) {  // uncomputed => Dalvik
+            result = AnnotationAccess.computeTypeIndex(getDex(), this);
+            dexTypeIndex = result;
+        }
+        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 native int getAnnotationDirectoryOffset();
+    // TODO: Use native code rather than:
+    //   return AnnotationAccess.typeIndexToAnnotationDirectoryOffset(getDex(), getTypeIndex());
+    // as native code has access to fast maps between type indices and class
+    // defs. Move fast maps to managed code.
+}
diff --git a/libart/src/main/java/java/lang/ClassLoader.java b/libart/src/main/java/java/lang/ClassLoader.java
new file mode 100644
index 0000000..fb2eb8f
--- /dev/null
+++ b/libart/src/main/java/java/lang/ClassLoader.java
@@ -0,0 +1,856 @@
+/*
+ * 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 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;
+import java.util.Set;
+
+/**
+ * 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>();
+
+    /**
+     * To avoid unloading individual classes, {@link java.lang.reflect.Proxy}
+     * only generates one class for each set of interfaces. This maps sets of
+     * interfaces to the proxy class that implements all of them. It is declared
+     * here so that these generated classes can be unloaded with their class
+     * loader.
+     *
+     * @hide
+     */
+    public final Map<Set<Class<?>>, Class<?>> proxyCache
+            = Collections.synchronizedMap(new HashMap<Set<Class<?>>, Class<?>>());
+
+    /**
+     * 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)}
+     */
+    @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<URL> first = parent.getResources(resName);
+        Enumeration<URL> 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) {
+            ClassNotFoundException suppressed = null;
+            try {
+                clazz = parent.loadClass(className, false);
+            } catch (ClassNotFoundException e) {
+                suppressed = e;
+            }
+
+            if (clazz == null) {
+                try {
+                    clazz = findClass(className);
+                } catch (ClassNotFoundException e) {
+                    e.addSuppressed(suppressed);
+                    throw e;
+                }
+            }
+        }
+
+        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 final Enumeration<URL> first;
+
+    private final Enumeration<URL> second;
+
+    public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) {
+        this.first = first;
+        this.second = second;
+    }
+
+    @Override
+    public boolean hasMoreElements() {
+        return first.hasMoreElements() || second.hasMoreElements();
+    }
+
+    @Override
+    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 Class.classForName(name, false, null);
+    }
+
+    @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/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
new file mode 100644
index 0000000..1422c13
--- /dev/null
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -0,0 +1,340 @@
+/*
+ * 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();
+        HeapTrimmerDaemon.INSTANCE.start();
+        GCDaemon.INSTANCE.start();
+    }
+
+    public static void stop() {
+        ReferenceQueueDaemon.INSTANCE.stop();
+        FinalizerDaemon.INSTANCE.stop();
+        FinalizerWatchdogDaemon.INSTANCE.stop();
+        HeapTrimmerDaemon.INSTANCE.stop();
+        GCDaemon.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.systemThreadGroup, 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);
+        }
+    }
+
+    // Invoked by the GC to request that the HeapTrimmerDaemon thread attempt to trim the heap.
+    public static void requestHeapTrim() {
+        synchronized (HeapTrimmerDaemon.INSTANCE) {
+            HeapTrimmerDaemon.INSTANCE.notify();
+        }
+    }
+
+    private static class HeapTrimmerDaemon extends Daemon {
+        private static final HeapTrimmerDaemon INSTANCE = new HeapTrimmerDaemon();
+
+        @Override public void run() {
+            while (isRunning()) {
+                try {
+                    synchronized (this) {
+                        wait();
+                    }
+                    VMRuntime.getRuntime().trimHeap();
+                } catch (InterruptedException ignored) {
+                }
+            }
+        }
+    }
+
+    // Invoked by the GC to request that the HeapTrimmerDaemon thread attempt to trim the heap.
+    public static void requestGC() {
+        GCDaemon.INSTANCE.requestGC();
+    }
+
+    private static class GCDaemon extends Daemon {
+        private static final GCDaemon INSTANCE = new GCDaemon();
+        private int count = 0;
+
+        public void requestGC() {
+            synchronized (this) {
+                ++count;
+                notify();
+            }
+        }
+
+        @Override public void run() {
+            while (isRunning()) {
+                try {
+                    synchronized (this) {
+                        // Wait until a request comes in, unless we have a pending request.
+                        while (count == 0) {
+                            wait();
+                        }
+                        --count;
+                    }
+                    VMRuntime.getRuntime().concurrentGC();
+                } catch (InterruptedException ignored) {
+                }
+            }
+        }
+    }
+}
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
new file mode 100644
index 0000000..5cb6792
--- /dev/null
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -0,0 +1,39 @@
+/*
+ *  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.reflect.ArtField;
+import java.lang.reflect.ArtMethod;
+
+/**
+ * A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
+ */
+final class DexCache {
+    // Only created by the VM.
+    private DexCache() {}
+
+    Object[] initializedStaticStorage;
+    String location;
+    ArtField[] resolvedFields;
+    ArtMethod[] resolvedMethods;
+    Class[] resolvedTypes;
+    String[] strings;
+
+    // Holds pointer to dexFile.
+    private int dexFile;
+}
+
diff --git a/libart/src/main/java/java/lang/Enum.java b/libart/src/main/java/java/lang/Enum.java
new file mode 100644
index 0000000..f98554a
--- /dev/null
+++ b/libart/src/main/java/java/lang/Enum.java
@@ -0,0 +1,222 @@
+/* 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;
+            }
+            try {
+                Method method = enumType.getDeclaredMethod("values", EmptyArray.CLASS);
+                return (Object[]) method.invoke((Object[]) null);
+            } catch (NoSuchMethodException impossible) {
+                throw new AssertionError("impossible", impossible);
+            } catch (IllegalAccessException impossible) {
+                throw new AssertionError("impossible", impossible);
+            } catch (InvocationTargetException impossible) {
+                throw new AssertionError("impossible", impossible);
+            }
+        }
+    };
+
+    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/libart/src/main/java/java/lang/Object.java b/libart/src/main/java/java/lang/Object.java
new file mode 100644
index 0000000..9c59870
--- /dev/null
+++ b/libart/src/main/java/java/lang/Object.java
@@ -0,0 +1,452 @@
+/*
+ * 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 {
+
+    private transient Class<?> shadow$_klass_;
+    private transient int shadow$_monitor_;
+
+    /**
+     * Constructs a new instance of {@code Object}.
+     */
+    public Object() {
+      if (shadow$_klass_.isFinalizable()) {
+        java.lang.ref.FinalizerReference.add(this);
+      }
+    }
+
+    /**
+     * 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 " + getClass().getName() +
+                                                 " doesn't implement Cloneable");
+        }
+
+        return internalClone();
+    }
+
+    /*
+     * Native helper method for cloning.
+     */
+    private native Object internalClone();
+
+    /**
+     * 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 Class<?> getClass() {
+      return shadow$_klass_;
+    }
+
+    /**
+     * 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 int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    /**
+     * 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
+     * </p>
+     * <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
+     * </p>
+     * <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>
+     * <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>
+     *
+     * @throws IllegalMonitorStateException
+     *             if the thread calling this method is not the owner of this
+     *             object's monitor.
+     * @throws InterruptedException
+     *             if another thread interrupts this thread while it is waiting.
+     * @see #notify
+     * @see #notifyAll
+     * @see #wait(long)
+     * @see #wait(long,int)
+     * @see java.lang.Thread
+     */
+    public final native void wait() throws InterruptedException;
+
+    /**
+     * 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>
+     * <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>
+     *
+     * @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 another thread interrupts this thread while it is waiting.
+     * @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>
+     * <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>
+     *
+     * @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 another thread interrupts this thread while it is waiting.
+     * @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/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
new file mode 100644
index 0000000..385f549
--- /dev/null
+++ b/libart/src/main/java/java/lang/String.java
@@ -0,0 +1,2011 @@
+/*
+ *  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
+         *
+         * @exception 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;
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * Returns the character at the specified offset in this string.
+     *
+     * @param index
+     *            the zero-based index in this string.
+     * @return the character at the 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)}
+     */
+    @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/libart/src/main/java/java/lang/Thread.java b/libart/src/main/java/java/lang/Thread.java
new file mode 100644
index 0000000..5c81e36
--- /dev/null
+++ b/libart/src/main/java/java/lang/Thread.java
@@ -0,0 +1,1267 @@
+/*
+ * 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 */
+    private volatile int nativePeer;
+    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's join/sleep/park operations.
+     */
+    private final Object lock = new Object();
+
+    /** Looked up reflectively and used by java.util.concurrent.locks.LockSupport. */
+    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 == null");
+        }
+
+        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.
+     */
+    public static native Thread 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.systemThreadGroup.activeCount();
+        Thread[] threads = new Thread[count + count / 2];
+
+        // Enumerate the threads and collect the stacktraces.
+        count = ThreadGroup.systemThreadGroup.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() {
+        return State.values()[nativeGetStatus(hasBeenStarted)];
+    }
+
+    private native int nativeGetStatus(boolean hasBeenStarted);
+
+    /**
+     * 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.
+        nativeInterrupt();
+
+        synchronized (interruptActions) {
+            for (int i = interruptActions.size() - 1; i >= 0; i--) {
+                interruptActions.get(i).run();
+            }
+        }
+    }
+
+    private native void nativeInterrupt();
+
+    /**
+     * 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 native boolean 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 (nativePeer != 0);
+    }
+
+    /**
+     * 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 native boolean isInterrupted();
+
+    /**
+     * Blocks the current Thread (<code>Thread.currentThread()</code>) until
+     * the receiver finishes its execution and dies.
+     *
+     * @throws InterruptedException if <code>interrupt()</code> was called for
+     *         the receiver while it was in the <code>join()</code> call
+     * @see Object#notifyAll
+     * @see java.lang.ThreadDeath
+     */
+    public final void join() throws InterruptedException {
+        synchronized (lock) {
+            while (isAlive()) {
+                lock.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.
+     *
+     * @param millis The maximum time to wait (in milliseconds).
+     * @throws InterruptedException if <code>interrupt()</code> was called for
+     *         the receiver while it was in the <code>join()</code> call
+     * @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.
+     *
+     * @param millis The maximum time to wait (in milliseconds).
+     * @param nanos Extra nanosecond precision
+     * @throws InterruptedException if <code>interrupt()</code> was called for
+     *         the receiver while it was in the <code>join()</code> call
+     * @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;
+        }
+
+        synchronized (lock) {
+            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) {
+                lock.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 (nativePeer == 0) {
+            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");
+        }
+        // The lock is taken to ensure no race occurs between starting the
+        // the thread and setting its name (and the name of its native peer).
+        synchronized (this) {
+            this.name = threadName;
+
+            if (isAlive()) {
+                nativeSetName(threadName);
+            }
+        }
+    }
+
+    /**
+     * Tell the VM that the thread's name has changed.  This is useful for
+     * DDMS, which would otherwise be oblivious to Thread.setName calls.
+     */
+    private native void nativeSetName(String newName);
+
+    /**
+     * 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();
+        }
+
+        // The lock is taken to ensure no race occurs between starting the
+        // the thread and setting its priority (and the priority of its native peer).
+        synchronized (this) {
+            this.priority = priority;
+
+            if (isAlive()) {
+                nativeSetPriority(priority);
+            }
+        }
+    }
+
+    private native void nativeSetPriority(int newPriority);
+
+    /**
+     * <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 <code>interrupt()</code> was called for this Thread while
+     *             it was sleeping
+     * @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 <code>interrupt()</code> was called for this Thread while
+     *             it was sleeping
+     * @see Thread#interrupt()
+     */
+    public static void sleep(long millis, int nanos) throws InterruptedException {
+        // The JLS 3rd edition, section 17.9 says: "...sleep for zero
+        // time...need not have observable effects."
+        if (millis == 0 && nanos == 0) {
+            return;
+        }
+
+        long start = System.nanoTime();
+        long duration = (millis * NANOS_PER_MILLI) + nanos;
+
+        Object lock = currentThread().lock;
+
+        // Wait may return early, so loop until sleep duration passes.
+        synchronized (lock) {
+            while (true) {
+                sleep(lock, millis, nanos);
+
+                long now = System.nanoTime();
+                long elapsed = now - start;
+
+                if (elapsed >= duration) {
+                    break;
+                }
+
+                duration -= elapsed;
+                start = now;
+                millis = duration / NANOS_PER_MILLI;
+                nanos = (int) (duration % NANOS_PER_MILLI);
+            }
+        }
+    }
+
+    private static native void sleep(Object lock, long millis, int 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;
+
+        nativeCreate(this, stackSize, daemon);
+    }
+
+    private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
+
+    /**
+     * 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 because 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 because 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 native void 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().nativeHoldsLock(object);
+    }
+
+    private native boolean nativeHoldsLock(Object 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() {
+        synchronized (lock) {
+            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;
+                    lock.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) {
+        synchronized (lock) {
+            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 {
+                        lock.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("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) {
+        synchronized (lock) {
+            /*
+             * 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/libart/src/main/java/java/lang/ThreadGroup.java b/libart/src/main/java/java/lang/ThreadGroup.java
new file mode 100644
index 0000000..51b2137
--- /dev/null
+++ b/libart/src/main/java/java/lang/ThreadGroup.java
@@ -0,0 +1,726 @@
+/*
+ * 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 systemThreadGroup = new ThreadGroup();
+    static final ThreadGroup mainThreadGroup = new ThreadGroup(systemThreadGroup, "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 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 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 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 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/libart/src/main/java/java/lang/VMClassLoader.java b/libart/src/main/java/java/lang/VMClassLoader.java
new file mode 100644
index 0000000..d180a4d
--- /dev/null
+++ b/libart/src/main/java/java/lang/VMClassLoader.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+    }
+
+    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/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
new file mode 100644
index 0000000..cacf057
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
@@ -0,0 +1,294 @@
+/*
+ * 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) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.reflect;
+
+import com.android.dex.Dex;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import libcore.reflect.AnnotationAccess;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.ListOfTypes;
+import libcore.reflect.Types;
+
+/**
+ * This class represents an abstract method. Abstract methods are either methods or constructors.
+ * @hide
+ */
+public abstract class AbstractMethod extends AccessibleObject {
+
+    protected final ArtMethod artMethod;
+
+    protected AbstractMethod(ArtMethod artMethod) {
+        if (artMethod == null) {
+            throw new NullPointerException("artMethod == null");
+        }
+        this.artMethod = artMethod;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return super.getAnnotation(annotationClass);
+    }
+
+    /**
+     * We insert native method stubs for abstract methods so we don't have to
+     * check the access flags at the time of the method call.  This results in
+     * "native abstract" methods, which can't exist.  If we see the "abstract"
+     * flag set, clear the "native" flag.
+     *
+     * We also move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED
+     * position, because the callers of this function are trying to convey
+     * the "traditional" meaning of the flags to their callers.
+     */
+    private static int fixMethodFlags(int flags) {
+        if ((flags & Modifier.ABSTRACT) != 0) {
+            flags &= ~Modifier.NATIVE;
+        }
+        flags &= ~Modifier.SYNCHRONIZED;
+        int ACC_DECLARED_SYNCHRONIZED = 0x00020000;
+        if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {
+            flags |= Modifier.SYNCHRONIZED;
+        }
+        return flags & 0xffff;  // mask out bits not used by Java
+    }
+
+    int getModifiers() {
+        return fixMethodFlags(artMethod.getAccessFlags());
+    }
+
+    boolean isVarArgs() {
+        return (artMethod.getAccessFlags() & Modifier.VARARGS) != 0;
+    }
+
+    boolean isBridge() {
+        return (artMethod.getAccessFlags() & Modifier.BRIDGE) != 0;
+    }
+
+    boolean isSynthetic() {
+        return (artMethod.getAccessFlags() & Modifier.SYNTHETIC) != 0;
+    }
+
+    /**
+     * @hide
+     */
+    public final int getAccessFlags() {
+        return artMethod.getAccessFlags();
+    }
+
+    /**
+     * Returns the class that declares this constructor or method.
+     */
+    Class<?> getDeclaringClass() {
+        return artMethod.getDeclaringClass();
+    }
+
+    /**
+     * Returns the index of this method's ID in its dex file.
+     *
+     * @hide
+     */
+    public final int getDexMethodIndex() {
+        return artMethod.getDexMethodIndex();
+    }
+
+    /**
+     * Returns the name of the method or constructor represented by this
+     * instance.
+     *
+     * @return the name of this method
+     */
+    abstract public String getName();
+
+    /**
+     * Returns an array of {@code Class} objects associated with the parameter types of this
+     * abstract method. If the method was declared with no parameters, an
+     * empty array will be returned.
+     *
+     * @return the parameter types
+     */
+    public Class<?>[] getParameterTypes() {
+        return artMethod.getParameterTypes();
+    }
+
+    /**
+     * Returns true if {@code other} has the same declaring class, name,
+     * parameters and return type as this method.
+     */
+    @Override public boolean equals(Object other) {
+        if (!(other instanceof AbstractMethod)) {
+            return false;
+        }
+        // exactly one instance of each member in this runtime
+        return this.artMethod == ((AbstractMethod) other).artMethod;
+    }
+
+    String toGenericString() {
+        return toGenericStringHelper();
+    }
+
+    Type[] getGenericParameterTypes() {
+        return Types.getClonedTypeArray(getMethodOrConstructorGenericInfo().genericParameterTypes);
+    }
+
+    Type[] getGenericExceptionTypes() {
+        return Types.getClonedTypeArray(getMethodOrConstructorGenericInfo().genericExceptionTypes);
+    }
+
+    @Override public Annotation[] getDeclaredAnnotations() {
+        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
+        return result.toArray(new Annotation[result.size()]);
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.isDeclaredAnnotationPresent(this, annotationType);
+    }
+
+    public Annotation[] getAnnotations() {
+        return super.getAnnotations();
+    }
+
+    /**
+     * 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 abstract Annotation[][] getParameterAnnotations();
+
+    /**
+     * 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")
+    abstract String getSignature();
+
+    static final class GenericInfo {
+        final ListOfTypes genericExceptionTypes;
+        final ListOfTypes genericParameterTypes;
+        final Type genericReturnType;
+        final TypeVariable<?>[] formalTypeParameters;
+
+        GenericInfo(ListOfTypes exceptions, ListOfTypes parameters, Type ret,
+                    TypeVariable<?>[] formal) {
+            genericExceptionTypes = exceptions;
+            genericParameterTypes = parameters;
+            genericReturnType = ret;
+            formalTypeParameters = formal;
+        }
+    }
+
+    /**
+     * Returns generic information associated with this method/constructor member.
+     */
+    final GenericInfo getMethodOrConstructorGenericInfo() {
+        String signatureAttribute = AnnotationAccess.getSignature(this);
+        Member member;
+        Class<?>[] exceptionTypes;
+        boolean method = this instanceof Method;
+        if (method) {
+            Method m = (Method) this;
+            member = m;
+            exceptionTypes = m.getExceptionTypes();
+        } else {
+            Constructor<?> c = (Constructor<?>) this;
+            member = c;
+            exceptionTypes = c.getExceptionTypes();
+        }
+        GenericSignatureParser parser =
+            new GenericSignatureParser(member.getDeclaringClass().getClassLoader());
+        if (method) {
+            parser.parseForMethod((GenericDeclaration) this, signatureAttribute, exceptionTypes);
+        } else {
+            parser.parseForConstructor((GenericDeclaration) this,
+                                       signatureAttribute,
+                                       exceptionTypes);
+        }
+        return new GenericInfo(parser.exceptionTypes, parser.parameterTypes,
+                               parser.returnType, parser.formalTypeParameters);
+    }
+
+    /**
+     * Helper for Method and Constructor for toGenericString
+     */
+    final String toGenericStringHelper() {
+        StringBuilder sb = new StringBuilder(80);
+        GenericInfo info =  getMethodOrConstructorGenericInfo();
+        int modifiers = ((Member)this).getModifiers();
+        // append modifiers if any
+        if (modifiers != 0) {
+            sb.append(Modifier.toString(modifiers & ~Modifier.VARARGS)).append(' ');
+        }
+        // append type parameters
+        if (info.formalTypeParameters != null && info.formalTypeParameters.length > 0) {
+            sb.append('<');
+            for (int i = 0; i < info.formalTypeParameters.length; i++) {
+                Types.appendGenericType(sb, info.formalTypeParameters[i]);
+                if (i < info.formalTypeParameters.length - 1) {
+                    sb.append(",");
+                }
+            }
+            sb.append("> ");
+        }
+        Class<?> declaringClass = ((Member) this).getDeclaringClass();
+        if (this instanceof Constructor) {
+            // append constructor name
+            Types.appendTypeName(sb, declaringClass);
+        } else {
+            // append return type
+            Types.appendGenericType(sb, Types.getType(info.genericReturnType));
+            sb.append(' ');
+            // append method name
+            Types.appendTypeName(sb, declaringClass);
+            sb.append(".").append(((Method) this).getName());
+        }
+        // append parameters
+        sb.append('(');
+        Types.appendArrayGenericType(sb, info.genericParameterTypes.getResolvedTypes());
+        sb.append(')');
+        // append exceptions if any
+        Type[] genericExceptionTypeArray =
+                Types.getClonedTypeArray(info.genericExceptionTypes);
+        if (genericExceptionTypeArray.length > 0) {
+            sb.append(" throws ");
+            Types.appendArrayGenericType(sb, genericExceptionTypeArray);
+        }
+        return sb.toString();
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/AccessibleObject.java b/libart/src/main/java/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 0000000..dd57a12
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+/**
+ * {@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 {
+    protected AccessibleObject() {
+    }
+
+    /**
+     * If true, object is accessible, bypassing normal access checks
+     */
+    private boolean flag = false;
+
+    /**
+     * Returns true if this object is accessible without access checks.
+     */
+    public boolean isAccessible() {
+        return flag;
+    }
+
+    /**
+     * Attempts to set the accessible flag. Setting this to true prevents {@code
+     * IllegalAccessExceptions}.
+     */
+    public void setAccessible(boolean flag) {
+        this.flag = flag;
+     }
+
+    /**
+     * Attempts to set the accessible flag for all objects in {@code objects}.
+     * Setting this to true prevents {@code IllegalAccessExceptions}.
+     */
+    public static void setAccessible(AccessibleObject[] objects, boolean flag) {
+        for (AccessibleObject object : objects) {
+            object.flag = flag;
+        }
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override public Annotation[] getDeclaredAnnotations() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override public Annotation[] getAnnotations() {
+        // for all but Class, getAnnotations == getDeclaredAnnotations
+        return getDeclaredAnnotations();
+    }
+
+    @Override public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/ArtField.java b/libart/src/main/java/java/lang/reflect/ArtField.java
new file mode 100644
index 0000000..6fdcdb2
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/ArtField.java
@@ -0,0 +1,96 @@
+/*
+ * 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 com.android.dex.Dex;
+
+/**
+ * @hide
+ */
+public final class ArtField {
+
+    private Class<?> declaringClass;
+    /** Field access flags (modifiers) */
+    private int accessFlags;
+    /** Index into DexFile's field ids */
+    private int fieldDexIndex;
+    /** Offset of field in object or class */
+    private int offset;
+
+    /**
+     * Only created by art directly.
+     */
+    private ArtField() {}
+
+    public int getAccessFlags() {
+        return accessFlags;
+    }
+
+    int getDexFieldIndex() {
+        return fieldDexIndex;
+    }
+
+    int getOffset() {
+        return offset;
+    }
+
+    public String getName() {
+        if (fieldDexIndex == -1) {
+            // Proxy classes have 1 synthesized static field with no valid dex index
+            if (!declaringClass.isProxy()) {
+                throw new AssertionError();
+            }
+            return "throws";
+        }
+        Dex dex = declaringClass.getDex();
+        int nameIndex = dex.nameIndexFromFieldIndex(fieldDexIndex);
+        return declaringClass.getDexCacheString(dex, nameIndex);
+    }
+
+    Class<?> getDeclaringClass() {
+        return declaringClass;
+    }
+
+    Class<?> getType() {
+        if (fieldDexIndex == -1) {
+            // The type of the synthesized field in a Proxy class is Class[][]
+            if (!declaringClass.isProxy()) {
+                throw new AssertionError();
+            }
+            return Class[][].class;
+        }
+        Dex dex = declaringClass.getDex();
+        int typeIndex = dex.typeIndexFromFieldIndex(fieldDexIndex);
+        return declaringClass.getDexCacheType(dex, typeIndex);
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java
new file mode 100644
index 0000000..5e56d87
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java
@@ -0,0 +1,223 @@
+/*
+ * 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) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.reflect;
+
+import com.android.dex.Dex;
+import java.lang.annotation.Annotation;
+import libcore.reflect.AnnotationAccess;
+import libcore.reflect.InternalNames;
+import libcore.util.EmptyArray;
+
+/**
+ * This class represents methods and constructors.
+ * @hide
+ */
+public final class ArtMethod {
+
+    /** Method's declaring class */
+    private Class<?> declaringClass;
+    /** Method access flags (modifiers) */
+    private int accessFlags;
+    /** DexFile index */
+    private int methodDexIndex;
+    /** Dispatch table entry */
+    private int methodIndex;
+    /** DexFile offset of CodeItem for this Method */
+    private int codeItemOffset;
+    /* ART compiler meta-data */
+    private int frameSizeInBytes;
+    private int coreSpillMask;
+    private int fpSpillMask;
+    private int mappingTable;
+    private int gcMap;
+    private int vmapTable;
+    /** ART: compiled managed code associated with this Method */
+    private int entryPointFromCompiledCode;
+    /** ART: entry point from interpreter associated with this Method */
+    private int entryPointFromInterpreter;
+    /** ART: if this is a native method, the native code that will be invoked */
+    private int nativeMethod;
+    /* ART: dex cache fast access */
+    private String[] dexCacheStrings;
+    Class<?>[] dexCacheResolvedTypes;
+    private ArtMethod[] dexCacheResolvedMethods;
+    private Object[] dexCacheInitializedStaticStorage;
+
+    /**
+     * Only created by art directly.
+     */
+    private ArtMethod() {}
+
+    Class getDeclaringClass() {
+        return declaringClass;
+    }
+
+    public int getAccessFlags() {
+        return accessFlags;
+    }
+
+    int getDexMethodIndex() {
+        return methodDexIndex;
+    }
+
+    public static String getMethodName(ArtMethod artMethod) {
+        artMethod = artMethod.findOverriddenMethodIfProxy();
+        Dex dex = artMethod.getDeclaringClass().getDex();
+        int nameIndex = dex.nameIndexFromMethodIndex(artMethod.getDexMethodIndex());
+        // Note, in the case of a Proxy the dex cache strings are equal.
+        return artMethod.getDexCacheString(dex, nameIndex);
+    }
+
+    /**
+     * Returns true if the given parameters match those of the method in the given order.
+     *
+     * @hide
+     */
+    public static boolean equalConstructorParameters(ArtMethod artMethod, Class<?>[] params) {
+        Dex dex = artMethod.getDeclaringClass().getDex();
+        short[] types = dex.parameterTypeIndicesFromMethodIndex(artMethod.getDexMethodIndex());
+        if (types.length != params.length) {
+            return false;
+        }
+        for (int i = 0; i < types.length; i++) {
+            if (artMethod.getDexCacheType(dex, types[i]) != params[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the given parameters match those of this method in the given order.
+     *
+     * @hide
+     */
+    public static boolean equalMethodParameters(ArtMethod artMethod, Class<?>[] params) {
+        return equalConstructorParameters(artMethod.findOverriddenMethodIfProxy(), params);
+    }
+
+    Class<?>[] getParameterTypes() {
+        Dex dex = getDeclaringClass().getDex();
+        short[] types = dex.parameterTypeIndicesFromMethodIndex(methodDexIndex);
+        if (types.length == 0) {
+            return EmptyArray.CLASS;
+        }
+        Class<?>[] parametersArray = new Class[types.length];
+        for (int i = 0; i < types.length; i++) {
+            // Note, in the case of a Proxy the dex cache types are equal.
+            parametersArray[i] = getDexCacheType(dex, types[i]);
+        }
+        return parametersArray;
+    }
+
+    Class<?> getReturnType() {
+        Dex dex = declaringClass.getDex();
+        int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(methodDexIndex);
+        // Note, in the case of a Proxy the dex cache types are equal.
+        return getDexCacheType(dex, returnTypeIndex);
+    }
+
+    /**
+     * Performs a comparison of the parameters to this method with the given parameters.
+     *
+     * @hide
+     */
+    int compareParameters(Class<?>[] params) {
+        Dex dex = getDeclaringClass().getDex();
+        short[] types = dex.parameterTypeIndicesFromMethodIndex(methodDexIndex);
+        int length = Math.min(types.length, params.length);
+        for (int i = 0; i < length; i++) {
+            Class<?> aType = getDexCacheType(dex, types[i]);
+            Class<?> bType = params[i];
+            if (aType != bType) {
+                int comparison = aType.getName().compareTo(bType.getName());
+                if (comparison != 0) {
+                    return comparison;
+                }
+            }
+        }
+        return types.length - params.length;
+    }
+
+    Annotation[][] getParameterAnnotations() {
+        return AnnotationAccess.getParameterAnnotations(declaringClass, methodDexIndex);
+    }
+
+    /**
+     * Returns a string from the dex cache, computing the string from the dex file if necessary.
+     * Note this method replicates {@link java.lang.Class#getDexCacheString(Dex, int)}, but in
+     * Method we can avoid one indirection.
+     */
+    private String getDexCacheString(Dex dex, int dexStringIndex) {
+        String s = (String) dexCacheStrings[dexStringIndex];
+        if (s == null) {
+            s = dex.strings().get(dexStringIndex);
+            dexCacheStrings[dexStringIndex] = s;
+        }
+        return s;
+    }
+
+    /**
+     * Returns a resolved type from the dex cache, computing the string from the dex file if
+     * necessary. Note this method replicates {@link java.lang.Class#getDexCacheType(Dex, int)},
+     * but in Method we can avoid one indirection.
+     */
+    private Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
+        Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
+        if (resolvedType == null) {
+            int descriptorIndex = dex.typeIds().get(dexTypeIndex);
+            String descriptor = getDexCacheString(dex, descriptorIndex);
+            resolvedType = InternalNames.getClass(declaringClass.getClassLoader(),
+                                                  descriptor);
+            dexCacheResolvedTypes[dexTypeIndex] = resolvedType;
+        }
+        return resolvedType;
+    }
+
+    /**
+     * Returns the {@code ArtMethod} that this method overrides for
+     * proxy methods, otherwise returns this method. Used to determine
+     * the interface method overridden by a proxy method (as the proxy
+     * method doesn't directly support operations such as {@link
+     * Method#getName}).
+     */
+    ArtMethod findOverriddenMethodIfProxy() {
+        if (declaringClass.isProxy()) {
+            // Proxy method's declaring class' dex cache refers to that of Proxy. The local cache in
+            // Method refers to the original interface's dex cache and is ensured to be resolved by
+            // proxy generation.
+            return dexCacheResolvedMethods[methodDexIndex];
+        }
+        return this;
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java
new file mode 100644
index 0000000..62dfdfd
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/Constructor.java
@@ -0,0 +1,326 @@
+/*
+ * 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 com.android.dex.Dex;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+import java.util.List;
+import libcore.reflect.AnnotationAccess;
+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 AbstractMethod implements GenericDeclaration, Member {
+
+    private static final Comparator<Method> ORDER_BY_SIGNATURE = null; // Unused; must match Method.
+
+    /**
+     * @hide
+     */
+    public Constructor(ArtMethod artMethod) {
+        super(artMethod);
+    }
+
+    public Annotation[] getAnnotations() {
+        return super.getAnnotations();
+    }
+
+    /**
+     * Returns the modifiers for this constructor. The {@link Modifier} class
+     * should be used to decode the result.
+     */
+    @Override public int getModifiers() {
+        return super.getModifiers();
+    }
+
+    /**
+     * Returns true if this constructor takes a variable number of arguments.
+     */
+    public boolean isVarArgs() {
+        return super.isVarArgs();
+    }
+
+    /**
+     * Returns true if this constructor is synthetic (artificially introduced by the compiler).
+     */
+    @Override public boolean isSynthetic() {
+        return super.isSynthetic();
+    }
+
+    /**
+     * Returns the name of this constructor.
+     */
+    @Override public String getName() {
+        return getDeclaringClass().getName();
+    }
+
+    /**
+     * Returns the class that declares this constructor.
+     */
+    @Override public Class<T> getDeclaringClass() {
+        return (Class<T>) super.getDeclaringClass();
+    }
+
+    /**
+     * Returns the exception types as an array of {@code Class} instances. If
+     * this constructor has no declared exceptions, an empty array will be
+     * returned.
+     */
+    public Class<?>[] getExceptionTypes() {
+        // TODO: use dex cache to speed looking up class
+        return AnnotationAccess.getExceptions(this);
+    }
+
+    /**
+     * 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.
+     */
+    public Class<?>[] getParameterTypes() {
+        return super.getParameterTypes();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>Equivalent to {@code getDeclaringClass().getName().hashCode()}.
+     */
+    @Override public int hashCode() {
+        return getDeclaringClass().getName().hashCode();
+    }
+
+    /**
+     * Returns true if {@code other} has the same declaring class and parameters
+     * as this constructor.
+     */
+    @Override public boolean equals(Object other) {
+        return super.equals(other);
+    }
+
+    @Override public TypeVariable<Constructor<T>>[] getTypeParameters() {
+        GenericInfo info = getMethodOrConstructorGenericInfo();
+        return (TypeVariable<Constructor<T>>[]) info.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() {
+        return super.toGenericString();
+    }
+
+    /**
+     * 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() {
+        return super.getGenericParameterTypes();
+    }
+
+    /**
+     * 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() {
+        return super.getGenericExceptionTypes();
+    }
+
+    @Override public Annotation[] getDeclaredAnnotations() {
+        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
+        return result.toArray(new Annotation[result.size()]);
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.isDeclaredAnnotationPresent(this, annotationType);
+    }
+
+    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.getDeclaredAnnotation(this, 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() {
+        return artMethod.getParameterAnnotations();
+    }
+
+    /**
+     * 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")
+    String getSignature() {
+        StringBuilder result = new StringBuilder();
+
+        result.append('(');
+        Class<?>[] parameterTypes = getParameterTypes();
+        for (Class<?> parameterType : parameterTypes) {
+            result.append(Types.getSignature(parameterType));
+        }
+        result.append(")V");
+
+        return result.toString();
+    }
+
+    /**
+     * 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
+     *
+     * @exception InstantiationException
+     *                if the class cannot be instantiated
+     * @exception IllegalAccessException
+     *                if this constructor is not accessible
+     * @exception IllegalArgumentException
+     *                if an incorrect number of arguments are passed, or an
+     *                argument could not be converted by a widening conversion
+     * @exception InvocationTargetException
+     *                if an exception was thrown by the invoked constructor
+     *
+     * @see AccessibleObject
+     */
+    public native T newInstance(Object... args) throws InstantiationException,
+        IllegalAccessException, IllegalArgumentException, 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(getDeclaringClass().getName());
+        result.append("(");
+        Class<?>[] parameterTypes = getParameterTypes();
+        result.append(Types.toString(parameterTypes));
+        result.append(")");
+        Class<?>[] exceptionTypes = getExceptionTypes();
+        if (exceptionTypes.length > 0) {
+            result.append(" throws ");
+            result.append(Types.toString(exceptionTypes));
+        }
+
+        return result.toString();
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/Field.java b/libart/src/main/java/java/lang/reflect/Field.java
new file mode 100644
index 0000000..4e982c7
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/Field.java
@@ -0,0 +1,792 @@
+/*
+ * 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 com.android.dex.Dex;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+import java.util.List;
+import libcore.reflect.AnnotationAccess;
+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) {
+            if (a == b) {
+                return 0;
+            }
+            int comparison = a.getName().compareTo(b.getName());
+            if (comparison != 0) {
+                return comparison;
+            }
+            Class<?> aType = a.getDeclaringClass();
+            Class<?> bType = b.getDeclaringClass();
+            if (aType == bType) {
+                return 0;
+            } else {
+                return aType.getName().compareTo(bType.getName());
+            }
+        }
+    };
+
+    private final ArtField artField;
+
+    /**
+     * @hide
+     */
+    public Field(ArtField artField) {
+        if (artField == null) {
+            throw new NullPointerException("artField == null");
+        }
+        this.artField = artField;
+    }
+
+    /**
+     * 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
+     */
+    @Override public int getModifiers() {
+        return artField.getAccessFlags() & 0xffff;  // mask out bits not used by Java
+    }
+
+    /**
+     * 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() {
+        return (artField.getAccessFlags() & Modifier.ENUM) != 0;
+    }
+
+    /**
+     * Indicates whether or not this field is synthetic.
+     *
+     * @return {@code true} if this field is synthetic, {@code false} otherwise
+     */
+    @Override public boolean isSynthetic() {
+        return (artField.getAccessFlags() & Modifier.SYNTHETIC) != 0;
+    }
+
+    /**
+     * Returns the name of this field.
+     *
+     * @return the name of this field
+     */
+    @Override public String getName() {
+        return artField.getName();
+    }
+
+    @Override public Class<?> getDeclaringClass() {
+        return artField.getDeclaringClass();
+    }
+
+    /**
+     * Return the {@link Class} associated with the type of this field.
+     *
+     * @return the type of this field
+     */
+    public Class<?> getType() {
+        return artField.getType();
+    }
+
+    /**
+     * Returns the index of this field's ID in its dex file.
+     *
+     * @hide
+     */
+    public int getDexFieldIndex() {
+        return artField.getDexFieldIndex();
+    }
+
+    /**
+     * Returns the offset of the field within an instance, or for static fields, the class.
+     *
+     * @hide
+     */
+    public int getOffset() {
+        return artField.getOffset();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>Equivalent to {@code getDeclaringClass().getName().hashCode() ^ getName().hashCode()}.
+     */
+    @Override public int hashCode() {
+        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+    }
+
+    /**
+     * Returns true if {@code other} has the same declaring class, name and type
+     * as this field.
+     */
+    @Override public boolean equals(Object other) {
+        if (!(other instanceof Field)) {
+            return false;
+        }
+        // exactly one instance of each member in this runtime
+        return this.artField == ((Field) other).artField;
+    }
+
+    /**
+     * 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
+        Types.appendGenericType(sb, getGenericType());
+        sb.append(' ');
+        // append full field name
+        sb.append(getDeclaringClass().getName()).append('.').append(getName());
+        return sb.toString();
+    }
+
+    /**
+     * 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() {
+        String signatureAttribute = AnnotationAccess.getSignature(this);
+        Class<?> declaringClass = getDeclaringClass();
+        ClassLoader cl = declaringClass.getClassLoader();
+        GenericSignatureParser parser = new GenericSignatureParser(cl);
+        parser.parseForField(declaringClass, signatureAttribute);
+        Type genericType = parser.fieldType;
+        if (genericType == null) {
+            genericType = getType();
+        }
+        return genericType;
+    }
+
+    /**
+     * 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
+     */
+    @SuppressWarnings("unused")
+    private String getSignature() {
+        return Types.getSignature(getType());
+    }
+
+    @Override public Annotation[] getDeclaredAnnotations() {
+        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
+        return result.toArray(new Annotation[result.size()]);
+    }
+
+    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.getDeclaredAnnotation(this, annotationType);
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.isDeclaredAnnotationPresent(this, annotationType);
+    }
+
+    /**
+     * 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 native Object get(Object object) throws IllegalAccessException, IllegalArgumentException;
+
+    /**
+     * 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 native boolean getBoolean(Object object) throws IllegalAccessException,
+                                                           IllegalArgumentException;
+
+    /**
+     * 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 native byte getByte(Object object) throws IllegalAccessException,
+                                                     IllegalArgumentException;
+
+    /**
+     * 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 native char getChar(Object object) throws IllegalAccessException,
+                                                     IllegalArgumentException;
+
+    /**
+     * 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 native double getDouble(Object object) throws IllegalAccessException,
+                                                         IllegalArgumentException;
+
+    /**
+     * 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 native float getFloat(Object object) throws IllegalAccessException,
+                                                       IllegalArgumentException;
+
+    /**
+     * 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 native int getInt(Object object) throws IllegalAccessException,
+                                                   IllegalArgumentException;
+
+    /**
+     * 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 native long getLong(Object object) throws IllegalAccessException,
+                                                     IllegalArgumentException;
+
+    /**
+     * 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 native short getShort(Object object) throws IllegalAccessException,
+                                                       IllegalArgumentException;
+
+    /**
+     * 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 native void set(Object object, Object value) throws IllegalAccessException,
+                                                               IllegalArgumentException;
+
+    /**
+     * 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 native void setBoolean(Object object, boolean value) throws IllegalAccessException,
+                                                                       IllegalArgumentException;
+
+    /**
+     * 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 native void setByte(Object object, byte value) throws IllegalAccessException,
+                                                                 IllegalArgumentException;
+
+    /**
+     * 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 native void setChar(Object object, char value) throws IllegalAccessException,
+                                                                 IllegalArgumentException;
+
+    /**
+     * 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 native void setDouble(Object object, double value) throws IllegalAccessException,
+                                                                     IllegalArgumentException;
+
+    /**
+     * 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 native void setFloat(Object object, float value) throws IllegalAccessException,
+                                                                   IllegalArgumentException;
+
+    /**
+     * 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 native void setInt(Object object, int value) throws IllegalAccessException,
+                                                               IllegalArgumentException;
+
+    /**
+     * 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 native void setLong(Object object, long value) throws IllegalAccessException,
+                                                                 IllegalArgumentException;
+
+    /**
+     * 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 native void setShort(Object object, short value) throws IllegalAccessException,
+                                                                   IllegalArgumentException;
+
+    /**
+     * 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(' ');
+        }
+        Types.appendTypeName(result, getType());
+        result.append(' ');
+        result.append(getDeclaringClass().getName());
+        result.append('.');
+        result.append(getName());
+        return result.toString();
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/Method.java b/libart/src/main/java/java/lang/reflect/Method.java
new file mode 100644
index 0000000..1a0d5c5
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/Method.java
@@ -0,0 +1,439 @@
+/*
+ * 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 com.android.dex.Dex;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+import java.util.List;
+import libcore.reflect.AnnotationAccess;
+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 AbstractMethod implements GenericDeclaration, Member {
+
+    /**
+     * Orders methods by their name, parameters and return type.
+     *
+     * @hide
+     */
+    public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
+        @Override public int compare(Method a, Method b) {
+            if (a == b) {
+                return 0;
+            }
+            int comparison = a.getName().compareTo(b.getName());
+            if (comparison == 0) {
+                comparison = a.artMethod.findOverriddenMethodIfProxy().compareParameters(
+                        b.getParameterTypes());
+                if (comparison == 0) {
+                    // This is necessary for methods that have covariant return types.
+                    Class<?> aReturnType = a.getReturnType();
+                    Class<?> bReturnType = b.getReturnType();
+                    if (aReturnType == bReturnType) {
+                        comparison = 0;
+                    } else {
+                        comparison = aReturnType.getName().compareTo(bReturnType.getName());
+                    }
+                }
+            }
+            return comparison;
+        }
+    };
+
+    /**
+     * @hide
+     */
+    public Method(ArtMethod artMethod) {
+        super(artMethod);
+    }
+
+    ArtMethod getArtMethod() {
+        return artMethod;
+    }
+
+    public Annotation[] getAnnotations() {
+        return super.getAnnotations();
+    }
+
+    /**
+     * 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
+     */
+    @Override public int getModifiers() {
+        return super.getModifiers();
+    }
+
+    /**
+     * 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() {
+        return super.isVarArgs();
+    }
+
+    /**
+     * Indicates whether or not this method is a bridge.
+     *
+     * @return {@code true} if this method is a bridge, {@code false} otherwise
+     */
+    public boolean isBridge() {
+        return super.isBridge();
+
+    }
+
+    /**
+     * Indicates whether or not this method is synthetic.
+     *
+     * @return {@code true} if this method is synthetic, {@code false} otherwise
+     */
+    @Override public boolean isSynthetic() {
+        return super.isSynthetic();
+    }
+
+    /**
+     * Returns the name of the method represented by this {@code Method}
+     * instance.
+     *
+     * @return the name of this method
+     */
+    @Override public String getName() {
+        return ArtMethod.getMethodName(artMethod);
+    }
+
+    /**
+     * Returns the class that declares this method.
+     */
+    @Override public Class<?> getDeclaringClass() {
+        return super.getDeclaringClass();
+    }
+
+    /**
+     * 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 (getDeclaringClass().isProxy()) {
+            return getExceptionTypesNative();
+        } else {
+            // TODO: use dex cache to speed looking up class
+            return AnnotationAccess.getExceptions(this);
+        }
+    }
+
+    private native Class<?>[] getExceptionTypesNative();
+
+    /**
+     * 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
+     */
+    @Override public Class<?>[] getParameterTypes() {
+        return artMethod.findOverriddenMethodIfProxy().getParameterTypes();
+    }
+
+    /**
+     * Returns the {@code Class} associated with the return type of this
+     * method.
+     *
+     * @return the return type
+     */
+    public Class<?> getReturnType() {
+        return artMethod.findOverriddenMethodIfProxy().getReturnType();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>Equivalent to {@code getDeclaringClass().getName().hashCode() ^ getName().hashCode()}.
+     */
+    @Override public int hashCode() {
+        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+    }
+
+    /**
+     * Returns true if {@code other} has the same declaring class, name,
+     * parameters and return type as this method.
+     */
+    @Override public boolean equals(Object other) {
+        return super.equals(other);
+    }
+
+    /**
+     * Returns true if this and {@code method} have the same name and the same
+     * parameters in the same order. Such methods can share implementation if
+     * one method's return types is assignable to the other.
+     *
+     * @hide needed by Proxy
+     */
+    boolean equalNameAndParameters(Method m) {
+        return getName().equals(m.getName()) &&
+                ArtMethod.equalMethodParameters(artMethod,m.getParameterTypes());
+    }
+
+    /**
+     * Returns the string representation of the method's declaration, including
+     * the type parameters.
+     *
+     * @return the string representation of this method
+     */
+    public String toGenericString() {
+        return super.toGenericString();
+    }
+
+    @Override public TypeVariable<Method>[] getTypeParameters() {
+        GenericInfo info = getMethodOrConstructorGenericInfo();
+        return (TypeVariable<Method>[]) info.formalTypeParameters.clone();
+    }
+
+    /**
+     * 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() {
+        return Types.getClonedTypeArray(getMethodOrConstructorGenericInfo().genericParameterTypes);
+    }
+
+    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.isDeclaredAnnotationPresent(this, annotationType);
+    }
+
+    /**
+     * 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() {
+        return Types.getClonedTypeArray(getMethodOrConstructorGenericInfo().genericExceptionTypes);
+    }
+
+    /**
+     * 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() {
+        return Types.getType(getMethodOrConstructorGenericInfo().genericReturnType);
+    }
+
+    @Override public Annotation[] getDeclaredAnnotations() {
+        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
+        return result.toArray(new Annotation[result.size()]);
+    }
+
+    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return AnnotationAccess.getDeclaredAnnotation(this, annotationType);
+    }
+
+    /**
+     * 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() {
+        return artMethod.findOverriddenMethodIfProxy().getParameterAnnotations();
+    }
+
+    /**
+     * 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 AnnotationAccess.getDefaultValue(this);
+    }
+
+    /**
+     * 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 native Object invoke(Object receiver, Object... args)
+        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(getReturnType().getName());
+        result.append(' ');
+        result.append(getDeclaringClass().getName());
+        result.append('.');
+        result.append(getName());
+        result.append("(");
+        Class<?>[] parameterTypes = getParameterTypes();
+        result.append(Types.toString(parameterTypes));
+        result.append(")");
+        Class<?>[] exceptionTypes = getExceptionTypes();
+        if (exceptionTypes.length != 0) {
+            result.append(" throws ");
+            result.append(Types.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")
+    String getSignature() {
+        StringBuilder result = new StringBuilder();
+
+        result.append('(');
+        Class<?>[] parameterTypes = getParameterTypes();
+        for (Class<?> parameterType : parameterTypes) {
+            result.append(Types.getSignature(parameterType));
+        }
+        result.append(')');
+        result.append(Types.getSignature(getReturnType()));
+
+        return result.toString();
+    }
+}
diff --git a/libart/src/main/java/java/lang/reflect/Proxy.java b/libart/src/main/java/java/lang/reflect/Proxy.java
new file mode 100644
index 0000000..51b3ad5
--- /dev/null
+++ b/libart/src/main/java/java/lang/reflect/Proxy.java
@@ -0,0 +1,381 @@
+/*
+ *  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.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import libcore.util.EmptyArray;
+
+/**
+ * {@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;
+
+    private static int NextClassNameIndex = 0;
+
+    /**
+     * Orders methods by their name, parameters, return type and inheritance relationship.
+     *
+     * @hide
+     */
+    private static final Comparator<Method> ORDER_BY_SIGNATURE_AND_SUBTYPE = new Comparator<Method>() {
+        @Override public int compare(Method a, Method b) {
+            int comparison = Method.ORDER_BY_SIGNATURE.compare(a, b);
+            if (comparison != 0) {
+                return comparison;
+            }
+            Class<?> aClass = a.getDeclaringClass();
+            Class<?> bClass = b.getDeclaringClass();
+            if (aClass == bClass) {
+                return 0;
+            } else if (aClass.isAssignableFrom(bClass)) {
+                return 1;
+            } else if (bClass.isAssignableFrom(aClass)) {
+                return -1;
+            } else {
+                return 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 {
+        if (loader == null) {
+            loader = ClassLoader.getSystemClassLoader();
+        }
+
+        if (interfaces == null) {
+            throw new NullPointerException("interfaces == null");
+        }
+
+        Set<Class<?>> interfacesSet = new CopyOnWriteArraySet<Class<?>>(Arrays.asList(interfaces));
+
+        Class<?> proxy = loader.proxyCache.get(interfacesSet);
+        if (proxy != null) {
+            return proxy;
+        }
+
+        if (interfacesSet.size() != interfaces.length) {
+            throw new IllegalArgumentException(
+                    "interfaces has duplicates: " + Arrays.toString(interfaces));
+        }
+        String commonPackageName = null;
+        for (Class<?> c : interfaces) {
+            if (c == null) {
+                throw new NullPointerException("interfaces contained a null element");
+            }
+            if (!c.isInterface()) {
+                throw new IllegalArgumentException(c + " is not an interface");
+            }
+            if (!isVisibleToClassLoader(loader, c)) {
+                throw new IllegalArgumentException(c + " is not visible from class loader");
+            }
+            if (!Modifier.isPublic(c.getModifiers())) {
+                String packageName = c.getPackageName$();
+                if (packageName == null) {
+                    packageName = "";
+                }
+                if (commonPackageName != null && !commonPackageName.equals(packageName)) {
+                    throw new IllegalArgumentException(
+                            "non-public interfaces must be in the same package");
+                }
+                commonPackageName = packageName;
+            }
+        }
+
+        String baseName = commonPackageName != null && !commonPackageName.isEmpty()
+                ? commonPackageName + ".$Proxy"
+                : "$Proxy";
+        String name = baseName + NextClassNameIndex++;
+
+        List<Method> methods = getMethods(interfaces);
+        Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
+        validateReturnTypes(methods);
+        List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
+
+        ArtMethod[] methodsArray = new ArtMethod[methods.size()];
+        for (int i = 0; i < methodsArray.length; i++) {
+            methodsArray[i] = methods.get(i).getArtMethod();
+        }
+        Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
+        Class<?> result = generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);
+        loader.proxyCache.put(interfacesSet, result);
+        return result;
+    }
+
+    private static boolean isVisibleToClassLoader(ClassLoader loader, Class<?> c) {
+        try {
+            return loader == c.getClassLoader() || c == Class.forName(c.getName(), false, loader);
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+
+    /**
+     * 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 invocationHandler
+     *            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 invocationHandler)
+            throws IllegalArgumentException {
+
+        if (invocationHandler == null) {
+            throw new NullPointerException("invocationHandler == null");
+        }
+        Exception cause;
+        try {
+            return getProxyClass(loader, interfaces)
+                    .getConstructor(InvocationHandler.class)
+                    .newInstance(invocationHandler);
+        } catch (NoSuchMethodException e) {
+            cause = e;
+        } catch (IllegalAccessException e) {
+            cause = e;
+        } catch (InstantiationException e) {
+            cause = e;
+        } catch (InvocationTargetException e) {
+            cause = e;
+        }
+        AssertionError error = new AssertionError();
+        error.initCause(cause);
+        throw error;
+    }
+
+    /**
+     * 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) {
+        return cl.isProxy();
+    }
+
+    /**
+     * 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 {
+        // TODO: return false for subclasses of Proxy not created by generateProxy()
+        if (!(proxy instanceof Proxy)) {
+            throw new IllegalArgumentException("not a proxy instance");
+        }
+        return ((Proxy) proxy).h;
+    }
+
+    private static List<Method> getMethods(Class<?>[] interfaces) {
+        List<Method> result = new ArrayList<Method>();
+        try {
+            result.add(Object.class.getMethod("equals", Object.class));
+            result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
+            result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
+        } catch (NoSuchMethodException e) {
+            throw new AssertionError();
+        }
+
+        getMethodsRecursive(interfaces, result);
+        return result;
+    }
+
+    /**
+     * Fills {@code proxiedMethods} with the methods of {@code interfaces} and
+     * the interfaces they extend. May contain duplicates.
+     */
+    private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
+        for (Class<?> i : interfaces) {
+            getMethodsRecursive(i.getInterfaces(), methods);
+            Collections.addAll(methods, i.getDeclaredMethods());
+        }
+    }
+
+    /**
+     * Throws if any two methods in {@code methods} have the same name and
+     * parameters but incompatible return types.
+     *
+     * @param methods the methods to find exceptions for, ordered by name and
+     *     signature.
+     */
+    private static void validateReturnTypes(List<Method> methods) {
+        Method vs = null;
+        for (Method method : methods) {
+            if (vs == null || !vs.equalNameAndParameters(method)) {
+                vs = method; // this has a different name or parameters
+                continue;
+            }
+            Class<?> returnType = method.getReturnType();
+            Class<?> vsReturnType = vs.getReturnType();
+            if (returnType.isInterface() && vsReturnType.isInterface()) {
+                // all interfaces are mutually compatible
+            } else if (vsReturnType.isAssignableFrom(returnType)) {
+                vs = method; // the new return type is a subtype; use it instead
+            } else if (!returnType.isAssignableFrom(vsReturnType)) {
+                throw new IllegalArgumentException("proxied interface methods have incompatible "
+                        + "return types:\n  " + vs + "\n  " + method);
+            }
+        }
+    }
+
+    /**
+     * Remove methods that have the same name, parameters and return type. This
+     * computes the exceptions of each method; this is the intersection of the
+     * exceptions of equivalent methods.
+     *
+     * @param methods the methods to find exceptions for, ordered by name and
+     *     signature.
+     */
+    private static List<Class<?>[]> deduplicateAndGetExceptions(List<Method> methods) {
+        List<Class<?>[]> exceptions = new ArrayList<Class<?>[]>(methods.size());
+
+        for (int i = 0; i < methods.size(); ) {
+            Method method = methods.get(i);
+            Class<?>[] exceptionTypes = method.getExceptionTypes();
+
+            if (i > 0 && Method.ORDER_BY_SIGNATURE.compare(method, methods.get(i - 1)) == 0) {
+                exceptions.set(i - 1, intersectExceptions(exceptions.get(i - 1), exceptionTypes));
+                methods.remove(i);
+            } else {
+                exceptions.add(exceptionTypes);
+                i++;
+            }
+        }
+        return exceptions;
+    }
+
+    /**
+     * Returns the exceptions that are declared in both {@code aExceptions} and
+     * {@code bExceptions}. If an exception type in one array is a subtype of an
+     * exception from the other, the subtype is included in the intersection.
+     */
+    private static Class<?>[] intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions) {
+        if (aExceptions.length == 0 || bExceptions.length == 0) {
+            return EmptyArray.CLASS;
+        }
+        if (Arrays.equals(aExceptions, bExceptions)) {
+            return aExceptions;
+        }
+        Set<Class<?>> intersection = new HashSet<Class<?>>();
+        for (Class<?> a : aExceptions) {
+            for (Class<?> b : bExceptions) {
+                if (a.isAssignableFrom(b)) {
+                    intersection.add(b);
+                } else if (b.isAssignableFrom(a)) {
+                    intersection.add(a);
+                }
+            }
+        }
+        return intersection.toArray(new Class<?>[intersection.size()]);
+    }
+
+    private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
+                                                 ClassLoader loader, ArtMethod[] methods,
+                                                 Class<?>[][] exceptions);
+
+    /*
+     * The VM clones this method's descriptor when generating a proxy class.
+     * There is no implementation.
+     */
+    private static native void constructorPrototype(InvocationHandler h);
+
+    static Object invoke(Proxy proxy, ArtMethod method, Object[] args) throws Throwable {
+        InvocationHandler h = proxy.h;
+        return h.invoke(proxy, new Method(method), args);
+    }
+}
diff --git a/libart/src/main/java/sun/misc/Unsafe.java b/libart/src/main/java/sun/misc/Unsafe.java
new file mode 100644
index 0000000..aa7b6de
--- /dev/null
+++ b/libart/src/main/java/sun/misc/Unsafe.java
@@ -0,0 +1,338 @@
+/*
+ * 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 field.getOffset();
+    }
+
+    /**
+     * 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) {
+        Class<?> component = clazz.getComponentType();
+        if (component == null) {
+            throw new IllegalArgumentException("Valid for array classes only: " + clazz);
+        }
+        // TODO: make the following not specific to the object model.
+        int offset = 12;
+        if (component == long.class || component == double.class) {
+            offset += 4;  // 4 bytes of padding.
+        }
+        return offset;
+    }
+
+    /**
+     * 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) {
+      Class<?> component = clazz.getComponentType();
+      if (component == null) {
+          throw new IllegalArgumentException("Valid for array classes only: " + clazz);
+      }
+      // TODO: make the following not specific to the object model.
+      if (!clazz.isPrimitive()) {
+          return 4;
+      } else  if (component == long.class || component == double.class) {
+          return 8;
+      } else if (component == int.class || component == float.class) {
+          return 4;
+      } else if (component == char.class || component == short.class) {
+          return 2;
+      } else {
+          // component == byte.class || component == boolean.class.
+          return 1;
+      }
+    }
+
+    /**
+     * 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/libdvm/src/main/java/dalvik/system/VMDebug.java b/libdvm/src/main/java/dalvik/system/VMDebug.java
index a80cfcc..9966d5e 100644
--- a/libdvm/src/main/java/dalvik/system/VMDebug.java
+++ b/libdvm/src/main/java/dalvik/system/VMDebug.java
@@ -373,4 +373,25 @@
      * @return the number of matching instances.
      */
     public static native long countInstancesOfClass(Class klass, boolean assignable);
+
+    /**
+     * Export the heap per-space stats for dumpsys meminfo.
+     *
+     * The content of the array is:
+     *
+     * <pre>
+     *   data[0] : the application heap space size
+     *   data[1] : the application heap space allocated bytes
+     *   data[2] : the application heap space free bytes
+     *   data[3] : the zygote heap space size
+     *   data[4] : the zygote heap space allocated size
+     *   data[5] : the zygote heap space free size
+     *   data[6] : the large object space size
+     *   data[7] : the large object space allocated bytes
+     *   data[8] : the large object space free bytes
+     * </pre>
+     *
+     * @param data the array into which the stats are written.
+     */
+    public static native void getHeapSpaceStats(long[] data);
 }
diff --git a/libdvm/src/main/java/dalvik/system/VMRuntime.java b/libdvm/src/main/java/dalvik/system/VMRuntime.java
index 71098be..8ee607c 100644
--- a/libdvm/src/main/java/dalvik/system/VMRuntime.java
+++ b/libdvm/src/main/java/dalvik/system/VMRuntime.java
@@ -68,6 +68,11 @@
     public native String vmVersion();
 
     /**
+     * Returns the name of the shared library providing the VM implementation.
+     */
+    public native String vmLibrary();
+
+    /**
      * 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
@@ -217,4 +222,19 @@
      * 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);
 }
diff --git a/luni/src/main/files/cacerts/3c9a4d3b.0 b/luni/src/main/files/cacerts/3c9a4d3b.0
new file mode 100644
index 0000000..c6e312c
--- /dev/null
+++ b/luni/src/main/files/cacerts/3c9a4d3b.0
@@ -0,0 +1,152 @@
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 6828503384748696800 (0x5ec3b7a6437fa4e0)
+    Signature Algorithm: sha1WithRSAEncryption
+        Issuer: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
+        Validity
+            Not Before: May  5 09:37:37 2011 GMT
+            Not After : Dec 31 09:37:37 2030 GMT
+        Subject: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:9b:a9:ab:bf:61:4a:97:af:2f:97:66:9a:74:5f:
+                    d0:d9:96:fd:cf:e2:e4:66:ef:1f:1f:47:33:c2:44:
+                    a3:df:9a:de:1f:b5:54:dd:15:7c:69:35:11:6f:bb:
+                    c8:0c:8e:6a:18:1e:d8:8f:d9:16:bc:10:48:36:5c:
+                    f0:63:b3:90:5a:5c:24:37:d7:a3:d6:cb:09:71:b9:
+                    f1:01:72:84:b0:7d:db:4d:80:cd:fc:d3:6f:c9:f8:
+                    da:b6:0e:82:d2:45:85:a8:1b:68:a8:3d:e8:f4:44:
+                    6c:bd:a1:c2:cb:03:be:8c:3e:13:00:84:df:4a:48:
+                    c0:e3:22:0a:e8:e9:37:a7:18:4c:b1:09:0d:23:56:
+                    7f:04:4d:d9:17:84:18:a5:c8:da:40:94:73:eb:ce:
+                    0e:57:3c:03:81:3a:9d:0a:a1:57:43:69:ac:57:6d:
+                    79:90:78:e5:b5:b4:3b:d8:bc:4c:8d:28:a1:a7:a3:
+                    a7:ba:02:4e:25:d1:2a:ae:ed:ae:03:22:b8:6b:20:
+                    0f:30:28:54:95:7f:e0:ee:ce:0a:66:9d:d1:40:2d:
+                    6e:22:af:9d:1a:c1:05:19:d2:6f:c0:f2:9f:f8:7b:
+                    b3:02:42:fb:50:a9:1d:2d:93:0f:23:ab:c6:c1:0f:
+                    92:ff:d0:a2:15:f5:53:09:71:1c:ff:45:13:84:e6:
+                    26:5e:f8:e0:88:1c:0a:fc:16:b6:a8:73:06:b8:f0:
+                    63:84:02:a0:c6:5a:ec:e7:74:df:70:ae:a3:83:25:
+                    ea:d6:c7:97:87:93:a7:c6:8a:8a:33:97:60:37:10:
+                    3e:97:3e:6e:29:15:d6:a1:0f:d1:88:2c:12:9f:6f:
+                    aa:a4:c6:42:eb:41:a2:e3:95:43:d3:01:85:6d:8e:
+                    bb:3b:f3:23:36:c7:fe:3b:e0:a1:25:07:48:ab:c9:
+                    89:74:ff:08:8f:80:bf:c0:96:65:f3:ee:ec:4b:68:
+                    bd:9d:88:c3:31:b3:40:f1:e8:cf:f6:38:bb:9c:e4:
+                    d1:7f:d4:e5:58:9b:7c:fa:d4:f3:0e:9b:75:91:e4:
+                    ba:52:2e:19:7e:d1:f5:cd:5a:19:fc:ba:06:f6:fb:
+                    52:a8:4b:99:04:dd:f8:f9:b4:8b:50:a3:4e:62:89:
+                    f0:87:24:fa:83:42:c1:87:fa:d5:2d:29:2a:5a:71:
+                    7a:64:6a:d7:27:60:63:0d:db:ce:49:f5:8d:1f:90:
+                    89:32:17:f8:73:43:b8:d2:5a:93:86:61:d6:e1:75:
+                    0a:ea:79:66:76:88:4f:71:eb:04:25:d6:0a:5a:7a:
+                    93:e5:b9:4b:17:40:0f:b1:b6:b9:f5:de:4f:dc:e0:
+                    b3:ac:3b:11:70:60:84:4a:43:6e:99:20:c0:29:71:
+                    0a:c0:65
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            Authority Information Access: 
+                CA Issuers - URI:http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1.crt
+                OCSP - URI:http://ocsp.accv.es
+
+            X509v3 Subject Key Identifier: 
+                D2:87:B4:E3:DF:37:27:93:55:F6:56:EA:81:E5:36:CC:8C:1E:3F:BD
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Authority Key Identifier: 
+                keyid:D2:87:B4:E3:DF:37:27:93:55:F6:56:EA:81:E5:36:CC:8C:1E:3F:BD
+
+            X509v3 Certificate Policies: 
+                Policy: X509v3 Any Policy
+                  User Notice:
+                    Explicit Text: 
+                  CPS: http://www.accv.es/legislacion_c.htm
+
+            X509v3 CRL Distribution Points: 
+
+                Full Name:
+                  URI:http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1_der.crl
+
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Subject Alternative Name: 
+                email:accv@accv.es
+    Signature Algorithm: sha1WithRSAEncryption
+         97:31:02:9f:e7:fd:43:67:48:44:14:e4:29:87:ed:4c:28:66:
+         d0:8f:35:da:4d:61:b7:4a:97:4d:b5:db:90:e0:05:2e:0e:c6:
+         79:d0:f2:97:69:0f:bd:04:47:d9:be:db:b5:29:da:9b:d9:ae:
+         a9:99:d5:d3:3c:30:93:f5:8d:a1:a8:fc:06:8d:44:f4:ca:16:
+         95:7c:33:dc:62:8b:a8:37:f8:27:d8:09:2d:1b:ef:c8:14:27:
+         20:a9:64:44:ff:2e:d6:75:aa:6c:4d:60:40:19:49:43:54:63:
+         da:e2:cc:ba:66:e5:4f:44:7a:5b:d9:6a:81:2b:40:d5:7f:f9:
+         01:27:58:2c:c8:ed:48:91:7c:3f:a6:00:cf:c4:29:73:11:36:
+         de:86:19:3e:9d:ee:19:8a:1b:d5:b0:ed:8e:3d:9c:2a:c0:0d:
+         d8:3d:66:e3:3c:0d:bd:d5:94:5c:e2:e2:a7:35:1b:04:00:f6:
+         3f:5a:8d:ea:43:bd:5f:89:1d:a9:c1:b0:cc:99:e2:4d:00:0a:
+         da:c9:27:5b:e7:13:90:5c:e4:f5:33:a2:55:6d:dc:e0:09:4d:
+         2f:b1:26:5b:27:75:00:09:c4:62:77:29:08:5f:9e:59:ac:b6:
+         7e:ad:9f:54:30:22:03:c1:1e:71:64:fe:f9:38:0a:96:18:dd:
+         02:14:ac:23:cb:06:1c:1e:a4:7d:8d:0d:de:27:41:e8:ad:da:
+         15:b7:b0:23:dd:2b:a8:d3:da:25:87:ed:e8:55:44:4d:88:f4:
+         36:7e:84:9a:78:ac:f7:0e:56:49:0e:d6:33:25:d6:84:50:42:
+         6c:20:12:1d:2a:d5:be:bc:f2:70:81:a4:70:60:be:05:b5:9b:
+         9e:04:44:be:61:23:ac:e9:a5:24:8c:11:80:94:5a:a2:a2:b9:
+         49:d2:c1:dc:d1:a7:ed:31:11:2c:9e:19:a6:ee:e1:55:e1:c0:
+         ea:cf:0d:84:e4:17:b7:a2:7c:a5:de:55:25:06:ee:cc:c0:87:
+         5c:40:da:cc:95:3f:55:e0:35:c7:b8:84:be:b4:5d:cd:7a:83:
+         01:72:ee:87:e6:5f:1d:ae:b5:85:c6:26:df:e6:c1:9a:e9:1e:
+         02:47:9f:2a:a8:6d:a9:5b:cf:ec:45:77:7f:98:27:9a:32:5d:
+         2a:e3:84:ee:c5:98:66:2f:96:20:1d:dd:d8:c3:27:d7:b0:f9:
+         fe:d9:7d:cd:d0:9f:8f:0b:14:58:51:9f:2f:8b:c3:38:2d:de:
+         e8:8f:d6:8d:87:a4:f5:56:43:16:99:2c:f4:a4:56:b4:34:b8:
+         61:37:c9:c2:58:80:1b:a0:97:a1:fc:59:8d:e9:11:f6:d1:0f:
+         4b:55:34:46:2a:8b:86:3b
+SHA1 Fingerprint=93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17
diff --git a/luni/src/main/files/cacerts/40dc992e.0 b/luni/src/main/files/cacerts/40dc992e.0
new file mode 100644
index 0000000..847cec6
--- /dev/null
+++ b/luni/src/main/files/cacerts/40dc992e.0
@@ -0,0 +1,93 @@
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
+RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
+YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
+NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
+EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
+cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
+dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
+fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
+bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
+75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
+FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
+HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
+5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
+b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
+A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
+6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
+dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
+Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
+l7WdmplNsDz4SgCbZN2fOUvRJ9e4
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 0 (0x0)
+    Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011
+        Validity
+            Not Before: Dec  6 13:49:52 2011 GMT
+            Not After : Dec  1 13:49:52 2031 GMT
+        Subject: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a9:53:00:e3:2e:a6:f6:8e:fa:60:d8:2d:95:3e:
+                    f8:2c:2a:54:4e:cd:b9:84:61:94:58:4f:8f:3d:8b:
+                    e4:43:f3:75:89:8d:51:e4:c3:37:d2:8a:88:4d:79:
+                    1e:b7:12:dd:43:78:4a:8a:92:e6:d7:48:d5:0f:a4:
+                    3a:29:44:35:b8:07:f6:68:1d:55:cd:38:51:f0:8c:
+                    24:31:85:af:83:c9:7d:e9:77:af:ed:1a:7b:9d:17:
+                    f9:b3:9d:38:50:0f:a6:5a:79:91:80:af:37:ae:a6:
+                    d3:31:fb:b5:26:09:9d:3c:5a:ef:51:c5:2b:df:96:
+                    5d:eb:32:1e:02:da:70:49:ec:6e:0c:c8:9a:37:8d:
+                    f7:f1:36:60:4b:26:2c:82:9e:d0:78:f3:0d:0f:63:
+                    a4:51:30:e1:f9:2b:27:12:07:d8:ea:bd:18:62:98:
+                    b0:59:37:7d:be:ee:f3:20:51:42:5a:83:ef:93:ba:
+                    69:15:f1:62:9d:9f:99:39:82:a1:b7:74:2e:8b:d4:
+                    c5:0b:7b:2f:f0:c8:0a:da:3d:79:0a:9a:93:1c:a5:
+                    28:72:73:91:43:9a:a7:d1:4d:85:84:b9:a9:74:8f:
+                    14:40:c7:dc:de:ac:41:64:6c:b4:19:9b:02:63:6d:
+                    24:64:8f:44:b2:25:ea:ce:5d:74:0c:63:32:5c:8d:
+                    87:e5
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: 
+                Certificate Sign, CRL Sign
+            X509v3 Subject Key Identifier: 
+                A6:91:42:FD:13:61:4A:23:9E:08:A4:29:E5:D8:13:04:23:EE:41:25
+            X509v3 Name Constraints: 
+                Permitted:
+                  DNS:.gr
+                  DNS:.eu
+                  DNS:.edu
+                  DNS:.org
+                  email:.gr
+                  email:.eu
+                  email:.edu
+                  email:.org
+
+    Signature Algorithm: sha1WithRSAEncryption
+         1f:ef:79:41:e1:7b:6e:3f:b2:8c:86:37:42:4a:4e:1c:37:1e:
+         8d:66:ba:24:81:c9:4f:12:0f:21:c0:03:97:86:25:6d:5d:d3:
+         22:29:a8:6c:a2:0d:a9:eb:3d:06:5b:99:3a:c7:cc:c3:9a:34:
+         7f:ab:0e:c8:4e:1c:e1:fa:e4:dc:cd:0d:be:bf:24:fe:6c:e7:
+         6b:c2:0d:c8:06:9e:4e:8d:61:28:a6:6a:fd:e5:f6:62:ea:18:
+         3c:4e:a0:53:9d:b2:3a:9c:eb:a5:9c:91:16:b6:4d:82:e0:0c:
+         05:48:a9:6c:f5:cc:f8:cb:9d:49:b4:f0:02:a5:fd:70:03:ed:
+         8a:21:a5:ae:13:86:49:c3:33:73:be:87:3b:74:8b:17:45:26:
+         4c:16:91:83:fe:67:7d:cd:4d:63:67:fa:f3:03:12:96:78:06:
+         8d:b1:67:ed:8e:3f:be:9f:4f:02:f5:b3:09:2f:f3:4c:87:df:
+         2a:cb:95:7c:01:cc:ac:36:7a:bf:a2:73:7a:f7:8f:c1:b5:9a:
+         a1:14:b2:8f:33:9f:0d:ef:22:dc:66:7b:84:bd:45:17:06:3d:
+         3c:ca:b9:77:34:8f:ca:ea:cf:3f:31:3e:e3:88:e3:80:49:25:
+         c8:97:b5:9d:9a:99:4d:b0:3c:f8:4a:00:9b:64:dd:9f:39:4b:
+         d1:27:d7:b8
+SHA1 Fingerprint=FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D
diff --git a/luni/src/main/files/cacerts/b3fb433b.0 b/luni/src/main/files/cacerts/b3fb433b.0
new file mode 100644
index 0000000..de880c1
--- /dev/null
+++ b/luni/src/main/files/cacerts/b3fb433b.0
@@ -0,0 +1,56 @@
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            a6:8b:79:29:00:00:00:00:50:d0:91:f9
+    Signature Algorithm: ecdsa-with-SHA384
+        Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1
+        Validity
+            Not Before: Dec 18 15:25:36 2012 GMT
+            Not After : Dec 18 15:55:36 2037 GMT
+        Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub: 
+                    04:84:13:c9:d0:ba:6d:41:7b:e2:6c:d0:eb:55:5f:
+                    66:02:1a:24:f4:5b:89:69:47:e3:b8:c2:7d:f1:f2:
+                    02:c5:9f:a0:f6:5b:d5:8b:06:19:86:4f:53:10:6d:
+                    07:24:27:a1:a0:f8:d5:47:19:61:4c:7d:ca:93:27:
+                    ea:74:0c:ef:6f:96:09:fe:63:ec:70:5d:36:ad:67:
+                    77:ae:c9:9d:7c:55:44:3a:a2:63:51:1f:f5:e3:62:
+                    d4:a9:47:07:3e:cc:20
+                ASN1 OID: secp384r1
+        X509v3 extensions:
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Subject Key Identifier: 
+                B7:63:E7:1A:DD:8D:E9:08:A6:55:83:A4:E0:6A:50:41:65:11:42:49
+    Signature Algorithm: ecdsa-with-SHA384
+         30:64:02:30:61:79:d8:e5:42:47:df:1c:ae:53:99:17:b6:6f:
+         1c:7d:e1:bf:11:94:d1:03:88:75:e4:8d:89:a4:8a:77:46:de:
+         6d:61:ef:02:f5:fb:b5:df:cc:fe:4e:ff:fe:a9:e6:a7:02:30:
+         5b:99:d7:85:37:06:b5:7b:08:fd:eb:27:8b:4a:94:f9:e1:fa:
+         a7:8e:26:08:e8:7c:92:68:6d:73:d8:6f:26:ac:21:02:b8:99:
+         b7:26:41:5b:25:60:ae:d0:48:1a:ee:06
+SHA1 Fingerprint=20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47
diff --git a/luni/src/main/files/cacerts/ee90b008.0 b/luni/src/main/files/cacerts/ee90b008.0
new file mode 100644
index 0000000..f017edc
--- /dev/null
+++ b/luni/src/main/files/cacerts/ee90b008.0
@@ -0,0 +1,119 @@
+-----BEGIN CERTIFICATE-----
+MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
+OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
+A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
+JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
+vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
+D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
+Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
+RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
+HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
+nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
+0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
+UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
+Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
+TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
+BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
+2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
+UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
+6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
+9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
+HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
+wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
+XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
+IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
+hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
+so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 59 (0x3b)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=IL, O=StartCom Ltd., CN=StartCom Certification Authority G2
+        Validity
+            Not Before: Jan  1 01:00:01 2010 GMT
+            Not After : Dec 31 23:59:01 2039 GMT
+        Subject: C=IL, O=StartCom Ltd., CN=StartCom Certification Authority G2
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:b6:89:36:5b:07:b7:20:36:bd:82:bb:e1:16:20:
+                    03:95:7a:af:0e:a3:55:c9:25:99:4a:c5:d0:56:41:
+                    87:90:4d:21:60:a4:14:87:3b:cd:fd:b2:3e:b4:67:
+                    03:6a:ed:e1:0f:4b:c0:91:85:70:45:e0:42:9e:de:
+                    29:23:d4:01:0d:a0:10:79:b8:db:03:bd:f3:a9:2f:
+                    d1:c6:e0:0f:cb:9e:8a:14:0a:b8:bd:f6:56:62:f1:
+                    c5:72:b6:32:25:d9:b2:f3:bd:65:c5:0d:2c:6e:d5:
+                    92:6f:18:8b:00:41:14:82:6f:40:20:26:7a:28:0f:
+                    f5:1e:7f:27:f7:94:b1:37:3d:b7:c7:91:f7:e2:01:
+                    ec:fd:94:89:e1:cc:6e:d3:36:d6:0a:19:79:ae:d7:
+                    34:82:65:ff:7c:42:bb:b6:dd:0b:a6:34:af:4b:60:
+                    fe:7f:43:49:06:8b:8c:43:b8:56:f2:d9:7f:21:43:
+                    17:ea:a7:48:95:01:75:75:ea:2b:a5:43:95:ea:15:
+                    84:9d:08:8d:26:6e:55:9b:ab:dc:d2:39:d2:31:1d:
+                    60:e2:ac:cc:56:45:24:f5:1c:54:ab:ee:86:dd:96:
+                    32:85:f8:4c:4f:e8:95:76:b6:05:dd:36:23:67:bc:
+                    ff:15:e2:ca:3b:e6:a6:ec:3b:ec:26:11:34:48:8d:
+                    f6:80:2b:1a:23:02:eb:8a:1c:3a:76:2a:7b:56:16:
+                    1c:72:2a:b3:aa:e3:60:a5:00:9f:04:9b:e2:6f:1e:
+                    14:58:5b:a5:6c:8b:58:3c:c3:ba:4e:3a:5c:f7:e1:
+                    96:2b:3e:ef:07:bc:a4:e5:5d:cc:4d:9f:0d:e1:dc:
+                    aa:bb:e1:6e:1a:ec:8f:e1:b6:4c:4d:79:72:5d:17:
+                    35:0b:1d:d7:c1:47:da:96:24:e0:d0:72:a8:5a:5f:
+                    66:2d:10:dc:2f:2a:13:ae:26:fe:0a:1c:19:cc:d0:
+                    3e:0b:9c:c8:09:2e:f9:5b:96:7a:47:9c:e9:7a:f3:
+                    05:50:74:95:73:9e:30:09:f3:97:82:5e:e6:8f:39:
+                    08:1e:59:e5:35:14:42:13:ff:00:9c:f7:be:aa:50:
+                    cf:e2:51:48:d7:b8:6f:af:f8:4e:7e:33:98:92:14:
+                    62:3a:75:63:cf:7b:fa:de:82:3b:a9:bb:39:e2:c4:
+                    bd:2c:00:0e:c8:17:ac:13:ef:4d:25:8e:d8:b3:90:
+                    2f:a9:da:29:7d:1d:af:74:3a:b2:27:c0:c1:1e:3e:
+                    75:a3:16:a9:af:7a:22:5d:9f:13:1a:cf:a7:a0:eb:
+                    e3:86:0a:d3:fd:e6:96:95:d7:23:c8:37:dd:c4:7c:
+                    aa:36:ac:98:1a:12:b1:e0:4e:e8:b1:3b:f5:d6:6f:
+                    f1:30:d7
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Subject Key Identifier: 
+                4B:C5:B4:40:6B:AD:1C:B3:A5:1C:65:6E:46:36:89:87:05:0C:0E:B6
+    Signature Algorithm: sha256WithRSAEncryption
+         73:57:3f:2c:d5:95:32:7e:37:db:96:92:eb:19:5e:7e:53:e7:
+         41:ec:11:b6:47:ef:b5:de:ed:74:5c:c5:f1:8e:49:e0:fc:6e:
+         99:13:cd:9f:8a:da:cd:3a:0a:d8:3a:5a:09:3f:5f:34:d0:2f:
+         03:d2:66:1d:1a:bd:9c:90:37:c8:0c:8e:07:5a:94:45:46:2a:
+         e6:be:7a:da:a1:a9:a4:69:12:92:b0:7d:36:d4:44:87:d7:51:
+         f1:29:63:d6:75:cd:16:e4:27:89:1d:f8:c2:32:48:fd:db:99:
+         d0:8f:5f:54:74:cc:ac:67:34:11:62:d9:0c:0a:37:87:d1:a3:
+         17:48:8e:d2:17:1d:f6:d7:fd:db:65:eb:fd:a8:d4:f5:d6:4f:
+         a4:5b:75:e8:c5:d2:60:b2:db:09:7e:25:8b:7b:ba:52:92:9e:
+         3e:e8:c5:77:a1:3c:e0:4a:73:6b:61:cf:86:dc:43:ff:ff:21:
+         fe:23:5d:24:4a:f5:d3:6d:0f:62:04:05:57:82:da:6e:a4:33:
+         25:79:4b:2e:54:19:8b:cc:2c:3d:30:e9:d1:06:ff:e8:32:46:
+         be:b5:33:76:77:a8:01:5d:96:c1:c1:d5:be:ae:25:c0:c9:1e:
+         0a:09:20:88:a1:0e:c9:f3:6f:4d:82:54:00:20:a7:d2:8f:e4:
+         39:54:17:2e:8d:1e:b8:1b:bb:1b:bd:9a:4e:3b:10:34:dc:9c:
+         88:53:ef:a2:31:5b:58:4f:91:62:c8:c2:9a:9a:cd:15:5d:38:
+         a9:d6:be:f8:13:b5:9f:12:69:f2:50:62:ac:fb:17:37:f4:ee:
+         b8:75:67:60:10:fb:83:50:f9:44:b5:75:9c:40:17:b2:fe:fd:
+         79:5d:6e:58:58:5f:30:fc:00:ae:af:33:c1:0e:4e:6c:ba:a7:
+         a6:a1:7f:32:db:38:e0:b1:72:17:0a:2b:91:ec:6a:63:26:ed:
+         89:d4:78:cc:74:1e:05:f8:6b:fe:8c:6a:76:39:29:ae:65:23:
+         12:95:08:22:1c:97:ce:5b:06:ee:0c:e2:bb:bc:1f:44:93:f6:
+         d8:38:45:05:21:ed:e4:ad:ab:12:b6:03:a4:42:2e:2d:c4:09:
+         3a:03:67:69:84:9a:e1:59:90:8a:28:85:d5:5d:74:b1:d1:0e:
+         20:58:9b:13:a5:b0:63:a6:ed:7b:47:fd:45:55:30:a4:ee:9a:
+         d4:e6:e2:87:ef:98:c9:32:82:11:29:22:bc:00:0a:31:5e:2d:
+         0f:c0:8e:e9:6b:b2:8f:2e:06:d8:d1:91:c7:c6:12:f4:4c:fd:
+         30:17:c3:c1:da:38:5b:e3:a9:ea:e6:a1:ba:79:ef:73:d8:b6:
+         53:57:2d:f6:d0:e1:d7:48
+SHA1 Fingerprint=31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17
diff --git a/luni/src/main/java/java/lang/reflect/Modifier.java b/luni/src/main/java/java/lang/reflect/Modifier.java
index fdbe3bb..5f973d5 100644
--- a/luni/src/main/java/java/lang/reflect/Modifier.java
+++ b/luni/src/main/java/java/lang/reflect/Modifier.java
@@ -109,6 +109,13 @@
     public static final int MIRANDA = 0x8000;
 
     /**
+     * Dex addition to mark instance constructors and static class
+     * initializer methods.
+     * @hide
+     */
+    public static final int CONSTRUCTOR = 0x10000;
+
+    /**
      * Constructs a new {@code Modifier} instance.
      */
     public Modifier() {
@@ -239,6 +246,14 @@
     }
 
     /**
+     * Returns true if the given modifiers contain {@link Modifier#CONSTRUCTOR}.
+     * @hide
+     */
+    public static boolean isConstructor(int modifiers) {
+        return ((modifiers & Modifier.CONSTRUCTOR) != 0);
+    }
+
+    /**
      * Returns a string containing the string representation of all modifiers
      * present in the specified modifiers. Modifiers appear in the order
      * specified by the Java Language Specification.
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 23db9dc..fcb821d 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -71,7 +71,8 @@
  * <tr><td>Gingerbread/Honeycomb</td><td>ICU 4.4</td> <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-8">CLDR 1.8</a></td>   <td><a href="http://www.unicode.org/versions/Unicode5.2.0/">Unicode 5.2</a></td></tr>
  * <tr><td>Ice Cream Sandwich</td>   <td>ICU 4.6</td> <td><a href="http://cldr.unicode.org/index/downloads/cldr-1-9">CLDR 1.9</a></td>   <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
  * <tr><td>Jelly Bean</td>           <td>ICU 4.8</td> <td><a href="http://cldr.unicode.org/index/downloads/cldr-2-0">CLDR 2.0</a></td>   <td><a href="http://www.unicode.org/versions/Unicode6.0.0/">Unicode 6.0</a></td></tr>
- * <tr><td>Jelly Bean MR2</td>       <td>ICU 50</td>  <td><a href="http://cldr.unicode.org/index/downloads/cldr-21-1">CLDR 22.1</a></td> <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
+ * <tr><td>Jelly Bean MR2</td>       <td>ICU 50</td>  <td><a href="http://cldr.unicode.org/index/downloads/cldr-22-1">CLDR 22.1</a></td> <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
+ * <tr><td>Key Lime Pie</td>         <td>ICU 51</td>  <td><a href="http://cldr.unicode.org/index/downloads/cldr-23">CLDR 23</a></td>     <td><a href="http://www.unicode.org/versions/Unicode6.2.0/">Unicode 6.2</a></td></tr>
  * </table>
  *
  * <a name="default_locale"><h3>Be wary of the default locale</h3></a>
diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java
index e4146bd..76bbe26 100644
--- a/luni/src/main/java/java/util/zip/ZipEntry.java
+++ b/luni/src/main/java/java/util/zip/ZipEntry.java
@@ -21,6 +21,7 @@
 import java.io.InputStream;
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
@@ -383,6 +384,9 @@
 
         byte[] nameBytes = new byte[nameLength];
         Streams.readFully(in, nameBytes, 0, nameBytes.length);
+        if (containsNulByte(nameBytes)) {
+            throw new ZipException("Filename contains NUL byte: " + Arrays.toString(nameBytes));
+        }
         name = new String(nameBytes, 0, nameBytes.length, StandardCharsets.UTF_8);
 
         if (extraLength > 0) {
@@ -398,4 +402,13 @@
             comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);
         }
     }
+
+    private static boolean containsNulByte(byte[] bytes) {
+        for (byte b : bytes) {
+            if (b == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/luni/src/main/java/java/util/zip/ZipFile.java b/luni/src/main/java/java/util/zip/ZipFile.java
index 2f9e3b0..8f5b37e 100644
--- a/luni/src/main/java/java/util/zip/ZipFile.java
+++ b/luni/src/main/java/java/util/zip/ZipFile.java
@@ -284,19 +284,22 @@
                 throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf);
             }
 
-            // At position 28 we find the length of the extra data. In some cases
-            // this length differs from the one coming in the central header.
-            is.skipBytes(20);
-            int localExtraLenOrWhatever = Short.reverseBytes(is.readShort()) & 0xffff;
+            // Offset 26 has the file name length, and offset 28 has the extra field length.
+            // These lengths can differ from the ones in the central header.
+            is.skipBytes(18);
+            int fileNameLength = Short.reverseBytes(is.readShort()) & 0xffff;
+            int extraFieldLength = Short.reverseBytes(is.readShort()) & 0xffff;
             is.close();
 
-            // Skip the name and this "extra" data or whatever it is:
-            rafStream.skip(entry.nameLength + localExtraLenOrWhatever);
-            rafStream.length = rafStream.offset + entry.compressedSize;
+            // Skip the variable-size file name and extra field data.
+            rafStream.skip(fileNameLength + extraFieldLength);
+
             if (entry.compressionMethod == ZipEntry.DEFLATED) {
-                int bufSize = Math.max(1024, (int)Math.min(entry.getSize(), 65535L));
+                rafStream.length = rafStream.offset + entry.compressedSize;
+                int bufSize = Math.max(1024, (int) Math.min(entry.getSize(), 65535L));
                 return new ZipInflaterInputStream(rafStream, new Inflater(true), bufSize, entry);
             } else {
+                rafStream.length = rafStream.offset + entry.size;
                 return rafStream;
             }
         }
diff --git a/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index 9803f3d..ab86a9b 100644
--- a/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -104,11 +104,16 @@
  * connection will be retried with SSLv3 only.
  */
 public abstract class HttpsURLConnection extends HttpURLConnection {
+    /*
+     * Holds default instances so class preloading doesn't create an instance of
+     * it.
+     */
+    private static class NoPreloadHolder {
+        public static HostnameVerifier defaultHostnameVerifier = new DefaultHostnameVerifier();
 
-    private static HostnameVerifier defaultHostnameVerifier = new DefaultHostnameVerifier();
-
-    private static SSLSocketFactory defaultSSLSocketFactory = (SSLSocketFactory) SSLSocketFactory
-            .getDefault();
+        public static SSLSocketFactory defaultSSLSocketFactory = (SSLSocketFactory) SSLSocketFactory
+                .getDefault();
+    }
 
     /**
      * Sets the default hostname verifier to be used by new instances.
@@ -122,7 +127,7 @@
         if (v == null) {
             throw new IllegalArgumentException("HostnameVerifier is null");
         }
-        defaultHostnameVerifier = v;
+        NoPreloadHolder.defaultHostnameVerifier = v;
     }
 
     /**
@@ -131,7 +136,7 @@
      * @return the default hostname verifier.
      */
     public static HostnameVerifier getDefaultHostnameVerifier() {
-        return defaultHostnameVerifier;
+        return NoPreloadHolder.defaultHostnameVerifier;
     }
 
     /**
@@ -146,7 +151,7 @@
         if (sf == null) {
             throw new IllegalArgumentException("SSLSocketFactory is null");
         }
-        defaultSSLSocketFactory = sf;
+        NoPreloadHolder.defaultSSLSocketFactory = sf;
     }
 
     /**
@@ -155,7 +160,7 @@
      * @return the default SSL socket factory for new instances.
      */
     public static SSLSocketFactory getDefaultSSLSocketFactory() {
-        return defaultSSLSocketFactory;
+        return NoPreloadHolder.defaultSSLSocketFactory;
     }
 
     /**
@@ -176,8 +181,8 @@
      */
     protected HttpsURLConnection(URL url) {
         super(url);
-        hostnameVerifier = defaultHostnameVerifier;
-        sslSocketFactory = defaultSSLSocketFactory;
+        hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
+        sslSocketFactory = NoPreloadHolder.defaultSSLSocketFactory;
     }
 
     /**
diff --git a/luni/src/main/java/libcore/reflect/AnnotationAccess.java b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
index fe740de..3c24b08 100644
--- a/luni/src/main/java/libcore/reflect/AnnotationAccess.java
+++ b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
@@ -271,15 +271,9 @@
     /**
      * Returns the parameter annotations on {@code member}.
      */
-    public static Annotation[][] getParameterAnnotations(Member member) {
-        Class<?> declaringClass = member.getDeclaringClass();
+    public static Annotation[][] getParameterAnnotations(Class<?> declaringClass,
+                                                         int methodDexIndex) {
         Dex dex = declaringClass.getDex();
-        int methodDexIndex;
-        if (member instanceof Method) {
-            methodDexIndex = ((Method) member).getDexMethodIndex();
-        } else {
-            methodDexIndex = ((Constructor<?>) member).getDexMethodIndex();
-        }
         int protoIndex = dex.methodIds().get(methodDexIndex).getProtoIndex();
         ProtoId proto = dex.protoIds().get(protoIndex);
         TypeList parametersList = dex.readTypeList(proto.getParametersOffset());
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
index 5760906..5c0e328 100644
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
+++ b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
@@ -300,6 +300,11 @@
             updateSeed(getRandomBytes(DIGEST_LENGTH));
             nextBIndex = HASHBYTES_TO_USE;
 
+            // updateSeed(...) updates where the last word of the seed is, so we
+            // have to read it again.
+            lastWord = seed[BYTES_OFFSET] == 0 ? 0
+                    : (seed[BYTES_OFFSET] + extrabytes) >> 3 - 1;
+
         } else if (state == SET_SEED) {
 
             System.arraycopy(seed, HASH_OFFSET, copies, HASHCOPY_OFFSET,
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index dec074e..60af4d0 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -33,7 +33,6 @@
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 import junit.framework.TestCase;
-import libcore.io.IoUtils;
 
 public final class ZipFileTest extends TestCase {
     /**
@@ -119,6 +118,51 @@
         }
     }
 
+    /**
+     * Make sure the size used for stored zip entires is the uncompressed size.
+     * b/10227498
+     */
+    public void testStoredEntrySize() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream out = new ZipOutputStream(baos);
+
+        // Set up a single stored entry.
+        String name = "test_file";
+        int expectedLength = 5;
+        ZipEntry outEntry = new ZipEntry(name);
+        byte[] buffer = new byte[expectedLength];
+        outEntry.setMethod(ZipEntry.STORED);
+        CRC32 crc = new CRC32();
+        crc.update(buffer);
+        outEntry.setCrc(crc.getValue());
+        outEntry.setSize(buffer.length);
+
+        out.putNextEntry(outEntry);
+        out.write(buffer);
+        out.closeEntry();
+        out.close();
+
+        // Write the result to a file.
+        byte[] outBuffer = baos.toByteArray();
+        File zipFile = createTemporaryZipFile();
+        writeBytes(zipFile, outBuffer);
+
+        ZipFile zip = new ZipFile(zipFile);
+        // Set up the zip entry to have different compressed/uncompressed sizes.
+        ZipEntry ze = zip.getEntry(name);
+        ze.setCompressedSize(expectedLength - 1);
+        // Read the contents of the stream and verify uncompressed size was used.
+        InputStream stream = zip.getInputStream(ze);
+        int count = 0;
+        int read;
+        while ((read = stream.read(buffer)) != -1) {
+            count += read;
+        }
+
+        assertEquals(expectedLength, count);
+
+    }
+
     public void testInflatingStreamsRequiringZipRefill() throws IOException {
         int originalSize = 1024 * 1024;
         byte[] readBuffer = new byte[8192];
@@ -379,33 +423,24 @@
         assertEquals(null, zipFile.getComment());
     }
 
-    public void testNameLengthChecks() throws IOException {
-        // Is entry name length checking done on bytes or characters?
-        // Really it should be bytes, but the RI only checks characters at construction time.
-        // Android does the same, because it's cheap...
-        try {
-            new ZipEntry((String) null);
-            fail();
-        } catch (NullPointerException expected) {
-        }
-        new ZipEntry(makeString(0xffff, "a"));
-        try {
-            new ZipEntry(makeString(0xffff + 1, "a"));
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
+    // https://code.google.com/p/android/issues/detail?id=58465
+    public void test_NUL_in_filename() throws Exception {
+        File file = createTemporaryZipFile();
 
-        // ...but Android won't let you create a zip file with a truncated name.
-        ZipOutputStream out = createZipOutputStream(createTemporaryZipFile());
-        ZipEntry ze = new ZipEntry(makeString(0xffff, "\u0666"));
-        try {
-            out.putNextEntry(ze);
-            fail(); // The RI fails this test; it just checks the character count at construction time.
-        } catch (IllegalArgumentException expected) {
-        }
-        out.closeEntry();
-        out.putNextEntry(new ZipEntry("okay")); // ZipOutputStream.close throws if you add nothing!
+        // We allow creation of a ZipEntry whose name contains a NUL byte,
+        // mainly because it's not likely to happen by accident and it's useful for testing.
+        ZipOutputStream out = createZipOutputStream(file);
+        out.putNextEntry(new ZipEntry("hello"));
+        out.putNextEntry(new ZipEntry("hello\u0000"));
         out.close();
+
+        // But you can't open a ZIP file containing such an entry, because we reject it
+        // when we find it in the central directory.
+        try {
+            ZipFile zipFile = new ZipFile(file);
+            fail();
+        } catch (ZipException expected) {
+        }
     }
 
     public void testCrc() throws IOException {
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java b/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java
index ffdbe92..0db5ee1 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.harmony.security.tests.provider.crypto;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.SecureRandom;
@@ -400,4 +402,31 @@
             assertFalse("sequences are equal i=" + i, b);
         }
     }
+
+    public void testSeedIsFullLength() throws Exception {
+        Class<?> srClass = Class.forName(
+                "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
+        Field seedField = srClass.getDeclaredField("seed");
+        seedField.setAccessible(true);
+
+        Method nextBytesMethod = srClass.getDeclaredMethod("engineNextBytes", byte[].class);
+        nextBytesMethod.setAccessible(true);
+
+        byte[] bytes = new byte[1];
+
+        // Iterate 8 times to make sure the probability of a false positive is
+        // extremely rare.
+        for (int i = 0; i < 8; i++) {
+            Object sr = srClass.newInstance();
+            nextBytesMethod.invoke(sr, bytes);
+            int[] seed = (int[]) seedField.get(sr);
+
+            // If the first integer is not zero, it is fixed.
+            if (seed[0] != 0) {
+                return; // Success
+            }
+        }
+
+        fail("Fallback SHA1PRNG_SecureRandomImpl should not clobber seed internally");
+    }
 }
