am 00a8f245: resolved conflicts for merge of 5af4cc5a to klp-dev-plus-aosp

* commit '00a8f245f5c91b1a61bf5ca3ca690c52496c8731':
  Fix getGenericSuperclass.
diff --git a/Android.mk b/Android.mk
index f854172..0a9a0b8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,7 +28,6 @@
 
 include $(LOCAL_PATH)/JavaLibrary.mk
 
-
 #
 # Include the definitions to build the native code.
 #
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 8252954..0fbc9fb 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -173,12 +173,11 @@
     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 $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(libart_core_src_files)
@@ -186,27 +185,24 @@
     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)
+    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 
     # Make the core-tests library.
     ifeq ($(LIBCORE_SKIP_TESTS),)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(test_src_files)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-hostdex core-junit-hostdex core-tests-support-hostdex okhttp-hostdex
+    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex okhttp-hostdex
     LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-hostdex
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-    LOCAL_BUILD_HOST_DEX := true
-    include $(BUILD_HOST_JAVA_LIBRARY)
+    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
     endif
 
     # Make the core-tests-support library.
@@ -214,14 +210,12 @@
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
-    LOCAL_NO_STANDARD_LIBRARIES := true
-    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-hostdex core-junit-hostdex
+    LOCAL_JAVA_LIBRARIES := bouncycastle-hostdex core-junit-hostdex
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-support-hostdex
     LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-    LOCAL_BUILD_HOST_DEX := true
-    include $(BUILD_HOST_JAVA_LIBRARY)
+    include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
     endif
 endif
 
diff --git a/NativeCode.mk b/NativeCode.mk
index c85e22f..f8312ae 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -70,6 +70,7 @@
 core_cppflags += -std=gnu++11
 
 core_test_files := \
+  luni/src/test/native/dalvik_system_JniTest.cpp \
   luni/src/test/native/test_openssl_engine.cpp \
 
 #
diff --git a/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
new file mode 100644
index 0000000..c22e819
--- /dev/null
+++ b/benchmarks/src/benchmarks/SystemArrayCopyBenchmark.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class SystemArrayCopyBenchmark extends SimpleBenchmark {
+  @Param({"2", "4", "8", "16", "32", "64", "128", "256", "512", "1024",
+          "2048", "4096", "8192", "16384", "32768", "65536", "131072", "262144"})
+  int arrayLength;
+
+  // This copies a char array indirectly via String.getChars() as the
+  // System.arraycopy() call site optimization currently works within
+  // the core libraries only. Add direct System.arraycopy() benchmarks
+  // (including ones for other primitive types) later once this
+  // limitation goes away.
+  public void timeStringCharArrayCopy(int reps) {
+    final int len = arrayLength;
+    char[] dst = new char[len];
+    String str = new String(new char[len]);
+    for (int rep = 0; rep < reps; ++rep) {
+      str.getChars(0, len, dst, 0);
+    }
+  }
+}
diff --git a/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java b/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
index 1209b2e..349fbed 100644
--- a/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
+++ b/dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java
@@ -39,8 +39,6 @@
      * <p><b>Note:</b>: This is constant in any given VM incarnation,
      * but it is subject to change over time, so it is not appropriate
      * to represent as a compile-time constant value.</p>
-     *
-     * @see dalvik.system.VMDebug.getInstructionCount()
      */
     public static final int MAXIMUM_PACKED_VALUE;
 
@@ -60,22 +58,17 @@
     }
 
     /**
+     * Backwards compatibility stub for obsolete interpreter functionality.
+     * @hide
+     */
+    public static boolean isInvoke(int packedOpcode) {
+        return false;
+    }
+
+    /**
      * This class is not instantiable.
      */
     private OpcodeInfo() {
         // This space intentionally left blank.
     }
-
-    /**
-     * Returns whether the given packed opcode value represents a
-     * method invocation operation. This includes most things that
-     * look like method invocation at the source level, but it notably
-     * excludes methods that are implemented directly in the VM as
-     * well as ones the VM knows to have empty implementations.
-     *
-     * @hide Unclear if this is useful enough to publish as supported API.
-     *
-     * @param opcode one of the values defined in {@link Opcodes}
-     */
-    public static native boolean isInvoke(int packedOpcode);
 }
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 22a80bd..c605f40 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -23,6 +23,11 @@
   bug: 10133206
 },
 {
+  description: "Method.getExceptionTypes() broken on proxy-generated classes",
+  name: "libcore.java.lang.reflect.AnnotationsTest#testProxyMethodGetExceptions",
+  bug: 5392273
+},
+{
   description: "Package.getPackages(), ClassLoader.getPackages() both omit results",
   name: "libcore.java.lang.PackageTest#testGetPackages",
   bug: 5171136
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java
index adff3bc..d5ce8c2 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/FieldTest.java
@@ -162,13 +162,13 @@
         TestField x = new TestField();
         Field f = null;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
         } catch (Exception e) {
             fail("Exception during getType test : " + e.getMessage());
         }
         try {
             assertTrue("Same Field returned false", f.equals(f));
-            assertTrue("Inherited Field returned false", f.equals(x.getClass()
+            assertTrue("Inherited Field returned false", f.equals(TestField.class
                     .getDeclaredField("shortField")));
             assertTrue("Identical Field from different class returned true", !f
                     .equals(A.class.getDeclaredField("shortField")));
@@ -184,29 +184,16 @@
         // Test for method java.lang.Object
         // java.lang.reflect.Field.get(java.lang.Object)
         TestField x = new TestField();
-        Field f = x.getClass().getDeclaredField("doubleField");
+        Field f = TestField.class.getDeclaredField("doubleField");
         Double val = (Double) f.get(x);
 
         assertTrue("Returned incorrect double field value",
                 val.doubleValue() == Double.MAX_VALUE);
         // Test getting a static field;
-        f = x.getClass().getDeclaredField("doubleSField");
+        f = TestField.class.getDeclaredField("doubleSField");
         f.set(x, new Double(1.0));
         val = (Double) f.get(x);
-        assertEquals("Returned incorrect double field value", 1.0, val
-                .doubleValue());
-
-        // Try a get on a private field
-        boolean thrown = false;
-        try {
-            f = TestAccess.class.getDeclaredField("xxx");
-            assertNotNull(f);
-            f.get(null);
-            fail("No expected IllegalAccessException");
-        } catch (IllegalAccessException ok) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
+        assertEquals("Returned incorrect double field value", 1.0, val.doubleValue());
 
         // Try a get on a private field in nested member
         // temporarily commented because it breaks J9 VM
@@ -215,9 +202,9 @@
         //assertEquals(x.privfield1, f.get(x));
 
         // Try a get using an invalid class.
-        thrown = false;
+        boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.get(new String());
             fail("No expected IllegalArgumentException");
         } catch (IllegalArgumentException exc) {
@@ -252,7 +239,7 @@
     class SupportSubClass extends Support_Field {
 
         Object getField(char primitiveType, Object o, Field f,
-                Class expectedException) {
+                Class expected) {
             Object res = null;
             try {
                 primitiveType = Character.toUpperCase(primitiveType);
@@ -284,23 +271,23 @@
                 default:
                     res = f.get(o);
                 }
-                if (expectedException != null) {
-                    fail("expected exception " + expectedException.getName());
-                }
+                // Since 2011, members are always accessible and throwing is optional
+                assertTrue("expected " + expected + " for " + f.getName(),
+                        expected == null || expected == IllegalAccessException.class);
             } catch (Exception e) {
-                if (expectedException == null) {
+                if (expected == null) {
                     fail("unexpected exception " + e);
                 } else {
                     assertTrue("expected exception "
-                            + expectedException.getName() + " and got " + e, e
-                            .getClass().equals(expectedException));
+                            + expected.getName() + " and got " + e, e
+                            .getClass().equals(expected));
                 }
             }
             return res;
         }
 
         void setField(char primitiveType, Object o, Field f,
-                Class expectedException, Object value) {
+                Class expected, Object value) {
             try {
                 primitiveType = Character.toUpperCase(primitiveType);
                 switch (primitiveType) {
@@ -331,19 +318,19 @@
                 default:
                     f.set(o, value);
                 }
-                if (expectedException != null) {
-                    fail("expected exception " + expectedException.getName()
-                            + " for field " + f.getName() + ", value " + value);
-                }
+                // Since 2011, members are always accessible and throwing is optional
+                assertTrue("expected " + expected + " for " + f.getName() + " = " + value,
+                        expected == null || expected == IllegalAccessException.class);
             } catch (Exception e) {
-                if (expectedException == null) {
+                if (expected == null) {
+                    e.printStackTrace();
                     fail("unexpected exception " + e + " for field "
                             + f.getName() + ", value " + value);
                 } else {
                     assertTrue("expected exception "
-                            + expectedException.getName() + " and got " + e
+                            + expected.getName() + " and got " + e
                             + " for field " + f.getName() + ", value " + value,
-                            e.getClass().equals(expectedException));
+                            e.getClass().equals(expected));
                 }
             }
         }
@@ -370,7 +357,7 @@
      * java.lang.reflect.Field#setChar(java.lang.Object, char)
      */
     public void testProtectedFieldAccess() {
-        Class fieldClass = new Support_Field().getClass();
+        Class fieldClass = Support_Field.class;
         String fieldName = null;
         Field objectField = null;
         Field booleanField = null;
@@ -420,10 +407,8 @@
         SupportSubClass otherSubclass = new SupportSubClass();
         Object plainObject = new Object();
 
-        Class illegalAccessExceptionClass = new IllegalAccessException()
-                .getClass();
-        Class illegalArgumentExceptionClass = new IllegalArgumentException()
-                .getClass();
+        Class illegalAccessExceptionClass = IllegalAccessException.class;
+        Class illegalArgumentExceptionClass = IllegalArgumentException.class;
 
         // The test will attempt to use pass an object to set for object, byte,
         // short, ..., float and double fields
@@ -469,8 +454,7 @@
                     subclass.setField(type, parentClass, field,
                             illegalAccessExceptionClass, value);
                     subclass.setField(type, plainObject, field,
-                            // Failed on JDK.
-                            illegalAccessExceptionClass, value);
+                            illegalArgumentExceptionClass, value);
                 }
             }
             for (int j = 0; j < i; j++) {
@@ -489,8 +473,7 @@
         subclass.setField('Z', parentClass, booleanField,
                 illegalAccessExceptionClass, booleanValue);
         subclass.setField('Z', plainObject, booleanField,
-                // Failed on JDK
-                illegalAccessExceptionClass, booleanValue);
+                illegalArgumentExceptionClass, booleanValue);
         for (int j = 0; j < fields.length; j++) {
             Field listedField = fields[j];
             fieldName = listedField.getName();
@@ -505,7 +488,7 @@
                     illegalArgumentExceptionClass, value);
         }
 
-        // We perform the analagous test on the get methods.
+        // We perform the analogous test on the get methods.
 
         // ordered by widening conversion, except for 'L' at the end (which
         // stands for Object), to which all primitives can be converted by
@@ -534,7 +517,7 @@
                     subclass.getField(type, parentClass, field,
                             illegalAccessExceptionClass);
                     subclass.getField(type, plainObject, field,
-                            illegalAccessExceptionClass);
+                            illegalArgumentExceptionClass);
                 }
             }
             for (int j = i + 1; j < fields.length; j++) {
@@ -551,7 +534,7 @@
         subclass.getField('Z', parentClass, booleanField,
                 illegalAccessExceptionClass);
         subclass.getField('Z', plainObject, booleanField,
-                illegalAccessExceptionClass);
+                illegalArgumentExceptionClass);
         for (int j = 0; j < fields.length; j++) {
             Field listedField = fields[j];
             fieldName = listedField.getName();
@@ -576,7 +559,7 @@
         Field f = null;
         boolean val = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             val = f.getBoolean(x);
         } catch (Exception e) {
             fail("Exception during getBoolean test: " + e.toString());
@@ -585,7 +568,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.getBoolean(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -595,23 +578,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("booleanPFField");
-            f.getBoolean(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getBoolean(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -624,7 +594,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanSField");
+            f = TestField.class.getDeclaredField("booleanSField");
             boolean staticValue = f.getBoolean(null);
             assertTrue("Wrong value returned", staticValue);
         }  catch (Exception ex) {
@@ -643,7 +613,7 @@
         Field f = null;
         byte val = 0;
         try {
-            f = x.getClass().getDeclaredField("byteField");
+            f = TestField.class.getDeclaredField("byteField");
             val = f.getByte(x);
         } catch (Exception e) {
             fail("Exception during getbyte test : " + e.getMessage());
@@ -652,7 +622,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.getByte(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -662,23 +632,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("bytePFField");
-            f.getByte(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("byteField");
+            f = TestField.class.getDeclaredField("byteField");
             f.getByte(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -691,7 +648,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("byteSField");
+            f = TestField.class.getDeclaredField("byteSField");
             byte staticValue = f.getByte(null);
             assertEquals("Wrong value returned", Byte.MAX_VALUE, staticValue);
         }  catch (Exception ex) {
@@ -709,7 +666,7 @@
         Field f = null;
         char val = 0;
         try {
-            f = x.getClass().getDeclaredField("charField");
+            f = TestField.class.getDeclaredField("charField");
             val = f.getChar(x);
         } catch (Exception e) {
             fail("Exception during getCharacter test: " + e.toString());
@@ -718,7 +675,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.getChar(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -728,23 +685,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("charPFField");
-            f.getChar(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("charField");
+            f = TestField.class.getDeclaredField("charField");
             f.getChar(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -757,7 +701,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("charSField");
+            f = TestField.class.getDeclaredField("charSField");
             char staticValue = f.getChar(null);
             assertEquals("Wrong value returned", 'T', staticValue);
         }  catch (Exception ex) {
@@ -774,15 +718,15 @@
         Field[] fields;
 
         try {
-            fields = new TestField().getClass().getFields();
+            fields = TestField.class.getFields();
             assertTrue("Returned incorrect declaring class", fields[0]
-                    .getDeclaringClass().equals(new TestField().getClass()));
+                    .getDeclaringClass().equals(TestField.class));
 
             // Check the case where the field is inherited to be sure the parent
-            // is returned as the declarator
-            fields = new TestFieldSub1().getClass().getFields();
+            // is returned as the declarer
+            fields = TestFieldSub1.class.getFields();
             assertTrue("Returned incorrect declaring class", fields[0]
-                    .getDeclaringClass().equals(new TestField().getClass()));
+                    .getDeclaringClass().equals(TestField.class));
         } catch (Exception e) {
             fail("Exception : " + e.getMessage());
         }
@@ -798,7 +742,7 @@
         Field f = null;
         double val = 0.0;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             val = f.getDouble(x);
         } catch (Exception e) {
             fail("Exception during getDouble test: " + e.toString());
@@ -808,7 +752,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getDouble(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -819,23 +763,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("doublePFField");
-            f.getDouble(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.getDouble(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -848,7 +779,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleSFField");
+            f = TestField.class.getDeclaredField("doubleSFField");
             double staticValue = f.getDouble(null);
             assertEquals("Wrong value returned", Double.MAX_VALUE, staticValue);
         }  catch (Exception ex) {
@@ -866,7 +797,7 @@
         Field f = null;
         float val = 0;
         try {
-            f = x.getClass().getDeclaredField("floatField");
+            f = TestField.class.getDeclaredField("floatField");
             val = f.getFloat(x);
         } catch (Exception e) {
             fail("Exception during getFloat test : " + e.getMessage());
@@ -876,7 +807,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getFloat(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -887,23 +818,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("floatPFField");
-            f.getFloat(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("floatField");
+            f = TestField.class.getDeclaredField("floatField");
             f.getFloat(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -916,7 +834,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("floatSField");
+            f = TestField.class.getDeclaredField("floatSField");
             float staticValue = f.getFloat(null);
             assertEquals("Wrong value returned", Float.MAX_VALUE, staticValue);
         }  catch (Exception ex) {
@@ -933,7 +851,7 @@
         Field f = null;
         int val = 0;
         try {
-            f = x.getClass().getDeclaredField("intField");
+            f = TestField.class.getDeclaredField("intField");
             val = f.getInt(x);
         } catch (Exception e) {
             fail("Exception during getInt test : " + e.getMessage());
@@ -943,7 +861,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getInt(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -954,23 +872,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("intPFField");
-            f.getInt(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("intField");
+            f = TestField.class.getDeclaredField("intField");
             f.getInt(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -983,7 +888,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("intSField");
+            f = TestField.class.getDeclaredField("intSField");
             int staticValue = f.getInt(null);
             assertEquals("Wrong value returned", Integer.MAX_VALUE, staticValue);
         } catch (Exception ex) {
@@ -1002,7 +907,7 @@
         Field f = null;
         long val = 0;
         try {
-            f = x.getClass().getDeclaredField("longField");
+            f = TestField.class.getDeclaredField("longField");
             val = f.getLong(x);
         } catch (Exception e) {
             fail("Exception during getLong test : " + e.getMessage());
@@ -1010,7 +915,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getLong(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -1021,23 +926,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("longPFField");
-            f.getLong(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("longField");
+            f = TestField.class.getDeclaredField("longField");
             f.getLong(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1050,7 +942,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("longSField");
+            f = TestField.class.getDeclaredField("longSField");
             long staticValue = f.getLong(null);
             assertEquals("Wrong value returned", Long.MAX_VALUE, staticValue);
         }  catch (Exception ex) {
@@ -1066,7 +958,7 @@
         TestField x = new TestField();
         Field f = null;
         try {
-            f = x.getClass().getDeclaredField("prsttrvol");
+            f = TestField.class.getDeclaredField("prsttrvol");
         } catch (Exception e) {
             fail("Exception during getModifiers test: " + e.toString());
         }
@@ -1086,7 +978,7 @@
         TestField x = new TestField();
         Field f = null;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
         } catch (Exception e) {
             fail("Exception during getType test : " + e.getMessage());
         }
@@ -1105,7 +997,7 @@
         short val = 0;
         ;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
             val = f.getShort(x);
         } catch (Exception e) {
             fail("Exception during getShort test : " + e.getMessage());
@@ -1115,7 +1007,7 @@
 
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.getShort(x);
             fail("IllegalArgumentException expected but not thrown");
         } catch (IllegalArgumentException ex) {
@@ -1126,23 +1018,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("shortPFField");
-            f.getShort(x);
-            fail("IllegalAccessException expected but not thrown");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        } catch (Exception ex) {
-            fail("IllegalAccessException expected but not thrown"
-                    + ex.getMessage());
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
             f.getShort(null);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1155,7 +1034,7 @@
         //Test no NPE on static field
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("shortSField");
+            f = TestField.class.getDeclaredField("shortSField");
             short staticValue = f.getShort(null);
             assertEquals("Wrong value returned", Short.MAX_VALUE, staticValue);
         }  catch (Exception ex) {
@@ -1171,7 +1050,7 @@
         TestField x = new TestField();
         Field f = null;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
         } catch (Exception e) {
             fail("Exception during getType test : " + e.getMessage());
         }
@@ -1189,7 +1068,7 @@
         Field f = null;
         double val = 0.0;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.set(x, new Double(1.0));
             val = f.getDouble(x);
         } catch (Exception e) {
@@ -1200,7 +1079,7 @@
         //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.set(x, new Double(1.0));
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1208,22 +1087,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("doubleFField");
-            assertFalse(f.isAccessible());
-            f.set(x, new Double(1.0));
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.set(null, true);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1234,7 +1101,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("doubleSField");
+        f = TestField.class.getDeclaredField("doubleSField");
         f.set(null, new Double(1.0));
         val = f.getDouble(x);
         assertEquals("Returned incorrect double field value", 1.0, val);
@@ -1250,7 +1117,7 @@
         Field f = null;
         boolean val = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setBoolean(x, false);
             val = f.getBoolean(x);
         } catch (Exception e) {
@@ -1261,7 +1128,7 @@
       //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.setBoolean(x, false);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1269,22 +1136,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("booleanPFField");
-            assertFalse(f.isAccessible());
-            f.setBoolean(x, true);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setBoolean(null, true);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1295,7 +1150,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("booleanSField");
+        f = TestField.class.getDeclaredField("booleanSField");
         f.setBoolean(null, false);
         val = f.getBoolean(x);
         assertFalse("Returned incorrect boolean field value", val);
@@ -1311,7 +1166,7 @@
         Field f = null;
         byte val = 0;
         try {
-            f = x.getClass().getDeclaredField("byteField");
+            f = TestField.class.getDeclaredField("byteField");
             f.setByte(x, (byte) 1);
             val = f.getByte(x);
         } catch (Exception e) {
@@ -1322,7 +1177,7 @@
         //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setByte(x, Byte.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1330,22 +1185,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("bytePFField");
-            assertFalse(f.isAccessible());
-            f.setByte(x, Byte.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("byteField");
+            f = TestField.class.getDeclaredField("byteField");
             f.setByte(null, Byte.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1356,7 +1199,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("byteSField");
+        f = TestField.class.getDeclaredField("byteSField");
         f.setByte(null, Byte.MIN_VALUE);
         val = f.getByte(x);
         assertEquals("Returned incorrect byte field value", Byte.MIN_VALUE,
@@ -1373,7 +1216,7 @@
         Field f = null;
         char val = 0;
         try {
-            f = x.getClass().getDeclaredField("charField");
+            f = TestField.class.getDeclaredField("charField");
             f.setChar(x, (char) 1);
             val = f.getChar(x);
         } catch (Exception e) {
@@ -1384,7 +1227,7 @@
       //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setChar(x, Character.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1392,22 +1235,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("charPFField");
-            assertFalse(f.isAccessible());
-            f.setChar(x, Character.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("charField");
+            f = TestField.class.getDeclaredField("charField");
             f.setChar(null, Character.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1418,7 +1249,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("charSField");
+        f = TestField.class.getDeclaredField("charSField");
         f.setChar(null, Character.MIN_VALUE);
         val = f.getChar(x);
         assertEquals("Returned incorrect char field value",
@@ -1435,7 +1266,7 @@
         Field f = null;
         double val = 0.0;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.setDouble(x, Double.MIN_VALUE);
             val = f.getDouble(x);
         } catch (Exception e) {
@@ -1447,7 +1278,7 @@
       //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setDouble(x, Double.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1455,22 +1286,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("doublePFField");
-            assertFalse(f.isAccessible());
-            f.setDouble(x, Double.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("doubleField");
+            f = TestField.class.getDeclaredField("doubleField");
             f.setDouble(null, Double.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1481,7 +1300,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("doubleSField");
+        f = TestField.class.getDeclaredField("doubleSField");
         f.setDouble(null, Double.MIN_VALUE);
         val = f.getDouble(x);
         assertEquals("Returned incorrect double field value",
@@ -1498,7 +1317,7 @@
         Field f = null;
         float val = 0.0F;
         try {
-            f = x.getClass().getDeclaredField("floatField");
+            f = TestField.class.getDeclaredField("floatField");
             f.setFloat(x, Float.MIN_VALUE);
             val = f.getFloat(x);
         } catch (Exception e) {
@@ -1510,7 +1329,7 @@
         //test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setFloat(x, Float.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1518,22 +1337,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        //test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("floatPFField");
-            assertFalse(f.isAccessible());
-            f.setFloat(x, Float.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
       //Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("floatField");
+            f = TestField.class.getDeclaredField("floatField");
             f.setFloat(null, Float.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1544,7 +1351,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("floatSField");
+        f = TestField.class.getDeclaredField("floatSField");
         f.setFloat(null, Float.MIN_VALUE);
         val = f.getFloat(x);
         assertEquals("Returned incorrect float field value",
@@ -1561,7 +1368,7 @@
         Field f = null;
         int val = 0;
         try {
-            f = x.getClass().getDeclaredField("intField");
+            f = TestField.class.getDeclaredField("intField");
             f.setInt(x, Integer.MIN_VALUE);
             val = f.getInt(x);
         } catch (Exception e) {
@@ -1573,7 +1380,7 @@
         // test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setInt(x, Integer.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1581,22 +1388,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        // test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("intPFField");
-            assertFalse(f.isAccessible());
-            f.setInt(x, Integer.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         // Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("intField");
+            f = TestField.class.getDeclaredField("intField");
             f.setInt(null, Integer.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1607,7 +1402,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("intSField");
+        f = TestField.class.getDeclaredField("intSField");
         f.setInt(null, Integer.MIN_VALUE);
         val = f.getInt(x);
         assertEquals("Returned incorrect int field value",
@@ -1624,7 +1419,7 @@
         Field f = null;
         long val = 0L;
         try {
-            f = x.getClass().getDeclaredField("longField");
+            f = TestField.class.getDeclaredField("longField");
             f.setLong(x, Long.MIN_VALUE);
             val = f.getLong(x);
         } catch (Exception e) {
@@ -1635,7 +1430,7 @@
         // test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setLong(x, Long.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1643,22 +1438,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        // test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("longPFField");
-            assertFalse(f.isAccessible());
-            f.setLong(x, Long.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         // Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("longField");
+            f = TestField.class.getDeclaredField("longField");
             f.setLong(null, Long.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1669,7 +1452,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("longSField");
+        f = TestField.class.getDeclaredField("longSField");
         f.setLong(null, Long.MIN_VALUE);
         val = f.getLong(x);
         assertEquals("Returned incorrect long field value",
@@ -1686,7 +1469,7 @@
         Field f = null;
         short val = 0;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
             f.setShort(x, Short.MIN_VALUE);
             val = f.getShort(x);
         } catch (Exception e) {
@@ -1698,7 +1481,7 @@
         // test wrong type
         boolean thrown = false;
         try {
-            f = x.getClass().getDeclaredField("booleanField");
+            f = TestField.class.getDeclaredField("booleanField");
             f.setShort(x, Short.MIN_VALUE);
             fail("Accessed field of invalid type");
         } catch (IllegalArgumentException ex) {
@@ -1706,22 +1489,10 @@
         }
         assertTrue("IllegalArgumentException expected but not thrown", thrown);
 
-        // test not accessible
-        thrown = false;
-        try {
-            f = x.getClass().getDeclaredField("shortPFField");
-            assertFalse(f.isAccessible());
-            f.setShort(x, Short.MIN_VALUE);
-            fail("Accessed inaccessible field");
-        } catch (IllegalAccessException ex) {
-            thrown = true;
-        }
-        assertTrue("IllegalAccessException expected but not thrown", thrown);
-
         // Test NPE
         thrown = false;
         try {
-            f = x.getClass().getDeclaredField("shortField");
+            f = TestField.class.getDeclaredField("shortField");
             f.setShort(null, Short.MIN_VALUE);
             fail("NullPointerException expected but not thrown");
         } catch (NullPointerException ex) {
@@ -1732,7 +1503,7 @@
         assertTrue("NullPointerException expected but not thrown", thrown);
 
         // Test setting a static field;
-        f = x.getClass().getDeclaredField("shortSField");
+        f = TestField.class.getDeclaredField("shortSField");
         f.setShort(null, Short.MIN_VALUE);
         val = f.getShort(x);
         assertEquals("Returned incorrect short field value",
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 8f19e3a..063a988 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -30,6 +30,8 @@
      */
     private static final VMRuntime THE_ONE = new VMRuntime();
 
+    private int targetSdkVersion;
+
     /**
      * Prevents this class from being instantiated.
      */
@@ -116,9 +118,23 @@
      * 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).
+     * allocated version numbers start at 1), and 10000 to mean
+     * CUR_DEVELOPMENT.
      */
-    public native void setTargetSdkVersion(int targetSdkVersion);
+    public synchronized void setTargetSdkVersion(int targetSdkVersion) {
+        this.targetSdkVersion = targetSdkVersion;
+        setTargetSdkVersionNative(this.targetSdkVersion);
+    }
+
+    /**
+     * Gets the target SDK version. See {@link #setTargetSdkVersion} for
+     * special values.
+     */
+    public synchronized int getTargetSdkVersion() {
+        return targetSdkVersion;
+    }
+
+    private native void setTargetSdkVersionNative(int targetSdkVersion);
 
     /**
      * This method exists for binary compatibility.  It was part of a
@@ -241,7 +257,9 @@
     public native void trimHeap();
     public native void concurrentGC();
 
-    public void preloadDexCaches() {
-        // Do nothing with ART, image generation already does this.
-    }
+    /**
+     * Fill in dex caches with classes, fields, and methods that are
+     * already loaded. Typically used after Zygote preloading.
+     */
+    public native void preloadDexCaches();
 }
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index d1b9a18..eda2b5c 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -166,6 +166,9 @@
      */
     private transient Object[] ifTable;
 
+    /** Interface method table (imt), for quick "invoke-interface". */
+    private transient ArtMethod[] imTable;
+
     /** Lazily computed name of this class; always prefer calling getName(). */
     private transient String name;
 
@@ -952,7 +955,10 @@
      * method or constructor.
      */
     public Class<?> getDeclaringClass() {
-        return AnnotationAccess.getDeclaringClass(this);
+        if (AnnotationAccess.isAnonymousClass(this)) {
+            return null;
+        }
+        return AnnotationAccess.getEnclosingClass(this);
     }
 
     /**
@@ -967,9 +973,10 @@
             return declaringClass;
         }
         AccessibleObject member = AnnotationAccess.getEnclosingMethodOrConstructor(this);
-        return member != null
-                ? ((Member) member).getDeclaringClass()
-                : null;
+        if (member != null)  {
+            return ((Member) member).getDeclaringClass();
+        }
+        return AnnotationAccess.getEnclosingClass(this);
     }
 
     /**
diff --git a/libart/src/main/java/java/lang/Enum.java b/libart/src/main/java/java/lang/Enum.java
index f98554a..43ac113 100644
--- a/libart/src/main/java/java/lang/Enum.java
+++ b/libart/src/main/java/java/lang/Enum.java
@@ -148,7 +148,7 @@
      * @see java.lang.Comparable
      */
     public final int compareTo(E o) {
-        return ordinal - o.ordinal;
+        return ordinal - o.ordinal();
     }
 
     /**
diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
index 385f549..ab36752 100644
--- a/libart/src/main/java/java/lang/String.java
+++ b/libart/src/main/java/java/lang/String.java
@@ -496,13 +496,8 @@
     }
 
     /**
-     * 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()}.
+     * Returns the character at {@code index}.
+     * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}.
      */
     public char charAt(int index) {
         if (index < 0 || index >= count) {
diff --git a/libdvm/src/main/java/dalvik/system/VMRuntime.java b/libdvm/src/main/java/dalvik/system/VMRuntime.java
index f26ca54..9ae3f67 100644
--- a/libdvm/src/main/java/dalvik/system/VMRuntime.java
+++ b/libdvm/src/main/java/dalvik/system/VMRuntime.java
@@ -255,7 +255,8 @@
     public native void registerNativeFree(int bytes);
 
     /**
-     * Fill in dex caches with classes, fields, and methods that are already loaded.
+     * Fill in dex caches with classes, fields, and methods that are
+     * already loaded. Typically used after Zygote preloading.
      */
     public native void preloadDexCaches();
 }
diff --git a/libdvm/src/main/java/java/lang/String.java b/libdvm/src/main/java/java/lang/String.java
index 353765b..10a6301 100644
--- a/libdvm/src/main/java/java/lang/String.java
+++ b/libdvm/src/main/java/java/lang/String.java
@@ -736,13 +736,47 @@
      * equal. The object must be an instance of string with the same characters
      * in the same order.
      *
-     * @param object
+     * @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 native boolean equals(Object object);
+    @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
diff --git a/luni/src/main/java/java/lang/Double.java b/luni/src/main/java/java/lang/Double.java
index 456529b..cb8c301 100644
--- a/luni/src/main/java/java/lang/Double.java
+++ b/luni/src/main/java/java/lang/Double.java
@@ -171,7 +171,13 @@
      * {@code value}. All <em>Not-a-Number (NaN)</em> values are converted to a single NaN
      * representation ({@code 0x7ff8000000000000L}) (compare to {@link #doubleToRawLongBits}).
      */
-    public static native long doubleToLongBits(double value);
+    public static long doubleToLongBits(double value) {
+        if (value != value) {
+            return 0x7ff8000000000000L;  // NaN.
+        } else {
+            return doubleToRawLongBits(value);
+        }
+    }
 
     /**
      * Returns an integer corresponding to the bits of the given
diff --git a/luni/src/main/java/java/lang/Float.java b/luni/src/main/java/java/lang/Float.java
index 900b2a0..5f316f1 100644
--- a/luni/src/main/java/java/lang/Float.java
+++ b/luni/src/main/java/java/lang/Float.java
@@ -199,7 +199,13 @@
      * float {@code value}. All <em>Not-a-Number (NaN)</em> values are converted to a single NaN
      * representation ({@code 0x7fc00000}) (compare to {@link #floatToRawIntBits}).
      */
-    public static native int floatToIntBits(float value);
+    public static int floatToIntBits(float value) {
+        if (value != value) {
+            return 0x7fc00000;  // NaN.
+        } else {
+            return floatToRawIntBits(value);
+        }
+    }
 
     /**
      * Returns an integer corresponding to the bits of the given
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 68ca506..605b863 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -156,6 +156,59 @@
     public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
 
     /**
+     * The char array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 64;
+
+    /**
+     * The char[] specialized version of arraycopy().
+     *
+     * @hide internal use only
+     */
+    public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
+            // Copy char by char for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The char[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    private static native void arraycopyCharUnchecked(char[] src, int srcPos,
+        char[] dst, int dstPos, int length);
+
+    /**
      * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC.
      *
      * <p>This method always returns UTC times, regardless of the system's time zone.
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 80fbd0c..b6fe646 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -297,12 +297,7 @@
             return e == null ? null : e.value;
         }
 
-        // Doug Lea's supplemental secondaryHash function (inlined).
-        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
-        int hash = key.hashCode();
-        hash ^= (hash >>> 20) ^ (hash >>> 12);
-        hash ^= (hash >>> 7) ^ (hash >>> 4);
-
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {
@@ -327,12 +322,7 @@
             return entryForNullKey != null;
         }
 
-        // Doug Lea's supplemental secondaryHash function (inlined).
-        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
-        int hash = key.hashCode();
-        hash ^= (hash >>> 20) ^ (hash >>> 12);
-        hash ^= (hash >>> 7) ^ (hash >>> 4);
-
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {
@@ -344,15 +334,6 @@
         return false;
     }
 
-    // Doug Lea's supplemental secondaryHash function (non-inlined).
-    // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
-    static int secondaryHash(Object key) {
-        int hash = key.hashCode();
-        hash ^= (hash >>> 20) ^ (hash >>> 12);
-        hash ^= (hash >>> 7) ^ (hash >>> 4);
-        return hash;
-    }
-
     /**
      * Returns whether this map contains the specified value.
      *
@@ -401,7 +382,7 @@
             return putValueForNullKey(value);
         }
 
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
@@ -464,7 +445,7 @@
             return;
         }
 
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         HashMapEntry<K, V> first = tab[index];
@@ -632,7 +613,7 @@
         if (key == null) {
             return removeNullKey();
         }
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index], prev = null;
@@ -852,7 +833,7 @@
             return e != null && Objects.equal(value, e.value);
         }
 
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
@@ -880,7 +861,7 @@
             return true;
         }
 
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index], prev = null;
diff --git a/luni/src/main/java/java/util/LinkedHashMap.java b/luni/src/main/java/java/util/LinkedHashMap.java
index 2ace9db..3d6e6c3 100644
--- a/luni/src/main/java/java/util/LinkedHashMap.java
+++ b/luni/src/main/java/java/util/LinkedHashMap.java
@@ -247,8 +247,7 @@
             return e.value;
         }
 
-        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
-        int hash = secondaryHash(key);
+        int hash = Collections.secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {
diff --git a/luni/src/main/java/libcore/io/Memory.java b/luni/src/main/java/libcore/io/Memory.java
index 5743949..e148457 100644
--- a/luni/src/main/java/libcore/io/Memory.java
+++ b/luni/src/main/java/libcore/io/Memory.java
@@ -151,9 +151,33 @@
     public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount);
 
     public static native byte peekByte(long address);
-    public static native int peekInt(long address, boolean swap);
-    public static native long peekLong(long address, boolean swap);
-    public static native short peekShort(long address, boolean swap);
+
+    public static int peekInt(long address, boolean swap) {
+        int result = peekIntNative(address);
+        if (swap) {
+            result = Integer.reverseBytes(result);
+        }
+        return result;
+    }
+    private static native int peekIntNative(long address);
+
+    public static long peekLong(long address, boolean swap) {
+        long result = peekLongNative(address);
+        if (swap) {
+            result = Long.reverseBytes(result);
+        }
+        return result;
+    }
+    private static native long peekLongNative(long address);
+
+    public static short peekShort(long address, boolean swap) {
+        short result = peekShortNative(address);
+        if (swap) {
+            result = Short.reverseBytes(result);
+        }
+        return result;
+    }
+    private static native short peekShortNative(long address);
 
     public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount);
     public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap);
@@ -164,9 +188,30 @@
     public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap);
 
     public static native void pokeByte(long address, byte value);
-    public static native void pokeInt(long address, int value, boolean swap);
-    public static native void pokeLong(long address, long value, boolean swap);
-    public static native void pokeShort(long address, short value, boolean swap);
+
+    public static void pokeInt(long address, int value, boolean swap) {
+        if (swap) {
+            value = Integer.reverseBytes(value);
+        }
+        pokeIntNative(address, value);
+    }
+    private static native void pokeIntNative(long address, int value);
+
+    public static void pokeLong(long address, long value, boolean swap) {
+        if (swap) {
+            value = Long.reverseBytes(value);
+        }
+        pokeLongNative(address, value);
+    }
+    private static native void pokeLongNative(long address, long value);
+
+    public static void pokeShort(long address, short value, boolean swap) {
+        if (swap) {
+            value = Short.reverseBytes(value);
+        }
+        pokeShortNative(address, value);
+    }
+    private static native void pokeShortNative(long address, short value);
 
     public static native void pokeByteArray(long address, byte[] src, int offset, int count);
     public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap);
diff --git a/luni/src/main/java/libcore/reflect/AnnotationAccess.java b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
index 064151e..c2b54ce 100644
--- a/luni/src/main/java/libcore/reflect/AnnotationAccess.java
+++ b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
@@ -384,7 +384,7 @@
      * Returns the class of which {@code c} is a direct member. If {@code c} is
      * defined in a method or constructor, this is not transitive.
      */
-    public static Class<?> getDeclaringClass(Class<?> c) {
+    public static Class<?> getEnclosingClass(Class<?> c) {
         /*
          * public class Bar {
          *   @EnclosingClass(value=Bar)
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index b1cef1f..15f6953 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 
 // DalvikVM calls this on startup, so we can statically register all our native methods.
-int JNI_OnLoad(JavaVM* vm, void*) {
+jint JNI_OnLoad(JavaVM* vm, void*) {
     JNIEnv* env;
     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
         ALOGE("JavaVM::GetEnv() failed");
@@ -75,5 +75,6 @@
     REGISTER(register_org_apache_harmony_xml_ExpatParser);
     REGISTER(register_sun_misc_Unsafe);
 #undef REGISTER
+
     return JNI_VERSION_1_6;
 }
diff --git a/luni/src/main/native/java_lang_Double.cpp b/luni/src/main/native/java_lang_Double.cpp
index 259be30..186bd26 100644
--- a/luni/src/main/native/java_lang_Double.cpp
+++ b/luni/src/main/native/java_lang_Double.cpp
@@ -29,15 +29,6 @@
     double d;
 };
 
-static const jlong NaN = 0x7ff8000000000000ULL;
-
-static jlong Double_doubleToLongBits(JNIEnv*, jclass, jdouble val) {
-    Double d;
-    d.d = val;
-    //  For this method all values in the NaN range are normalized to the canonical NaN value.
-    return isnan(d.d) ? NaN : d.bits;
-}
-
 static jlong Double_doubleToRawLongBits(JNIEnv*, jclass, jdouble val) {
     Double d;
     d.d = val;
@@ -51,10 +42,9 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Double, doubleToLongBits, "(D)J"),
     NATIVE_METHOD(Double, doubleToRawLongBits, "(D)J"),
     NATIVE_METHOD(Double, longBitsToDouble, "(J)D"),
 };
-int register_java_lang_Double(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/lang/Double", gMethods, NELEM(gMethods));
+void register_java_lang_Double(JNIEnv* env) {
+    jniRegisterNativeMethods(env, "java/lang/Double", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_lang_Float.cpp b/luni/src/main/native/java_lang_Float.cpp
index 59544db..3852516 100644
--- a/luni/src/main/native/java_lang_Float.cpp
+++ b/luni/src/main/native/java_lang_Float.cpp
@@ -18,6 +18,7 @@
 
 #include "JNIHelp.h"
 #include "JniConstants.h"
+#include "Portability.h"
 
 #include <math.h>
 #include <stdlib.h>
@@ -28,15 +29,6 @@
     float f;
 };
 
-static const jint NaN = 0x7fc00000;
-
-static jint Float_floatToIntBits(JNIEnv*, jclass, jfloat val) {
-    Float f;
-    f.f = val;
-    //  For this method all values in the NaN range are normalized to the canonical NaN value.
-    return isnanf(f.f) ? NaN : f.bits;
-}
-
 jint Float_floatToRawIntBits(JNIEnv*, jclass, jfloat val) {
     Float f;
     f.f = val;
@@ -50,10 +42,9 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Float, floatToIntBits, "(F)I"),
     NATIVE_METHOD(Float, floatToRawIntBits, "(F)I"),
     NATIVE_METHOD(Float, intBitsToFloat, "(I)F"),
 };
-int register_java_lang_Float(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/lang/Float", gMethods, NELEM(gMethods));
+void register_java_lang_Float(JNIEnv* env) {
+    jniRegisterNativeMethods(env, "java/lang/Float", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_lang_Math.cpp b/luni/src/main/native/java_lang_Math.cpp
index 784b84d..83c39bd 100644
--- a/luni/src/main/native/java_lang_Math.cpp
+++ b/luni/src/main/native/java_lang_Math.cpp
@@ -145,7 +145,6 @@
     NATIVE_METHOD(Math, tan, "!(D)D"),
     NATIVE_METHOD(Math, tanh, "!(D)D"),
 };
-
 void register_java_lang_Math(JNIEnv* env) {
     jniRegisterNativeMethods(env, "java/lang/Math", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_lang_System.cpp b/luni/src/main/native/java_lang_System.cpp
index 0686310..f8b98b1 100644
--- a/luni/src/main/native/java_lang_System.cpp
+++ b/luni/src/main/native/java_lang_System.cpp
@@ -93,9 +93,15 @@
 }
 
 static jlong System_nanoTime(JNIEnv*, jclass) {
+#if defined(HAVE_POSIX_CLOCKS)
     timespec now;
     clock_gettime(CLOCK_MONOTONIC, &now);
     return now.tv_sec * 1000000000LL + now.tv_nsec;
+#else
+    timeval now;
+    gettimeofday(&now, NULL);
+    return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL;
+#endif
 }
 
 static jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) {
@@ -111,10 +117,10 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(System, currentTimeMillis, "()J"),
+    NATIVE_METHOD(System, currentTimeMillis, "!()J"),
     NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
     NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(System, nanoTime, "()J"),
+    NATIVE_METHOD(System, nanoTime, "!()J"),
     NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"),
     NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
 };
diff --git a/luni/src/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp
index 77aef5b..2cef410 100644
--- a/luni/src/main/native/libcore_io_Memory.cpp
+++ b/luni/src/main/native/libcore_io_Memory.cpp
@@ -259,37 +259,23 @@
     POKER(jshort, Short, jshort, swapShorts);
 }
 
-static jshort Memory_peekShort(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
-    jshort result = *cast<const jshort*>(srcAddress);
-    if (swap) {
-        result = bswap_16(result);
-    }
-    return result;
+static jshort Memory_peekShortNative(JNIEnv*, jclass, jlong srcAddress) {
+    return *cast<const jshort*>(srcAddress);
 }
 
-static void Memory_pokeShort(JNIEnv*, jclass, jlong dstAddress, jshort value, jboolean swap) {
-    if (swap) {
-        value = bswap_16(value);
-    }
+static void Memory_pokeShortNative(JNIEnv*, jclass, jlong dstAddress, jshort value) {
     *cast<jshort*>(dstAddress) = value;
 }
 
-static jint Memory_peekInt(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
-    jint result = *cast<const jint*>(srcAddress);
-    if (swap) {
-        result = bswap_32(result);
-    }
-    return result;
+static jint Memory_peekIntNative(JNIEnv*, jclass, jlong srcAddress) {
+    return *cast<const jint*>(srcAddress);
 }
 
-static void Memory_pokeInt(JNIEnv*, jclass, jlong dstAddress, jint value, jboolean swap) {
-    if (swap) {
-        value = bswap_32(value);
-    }
+static void Memory_pokeIntNative(JNIEnv*, jclass, jlong dstAddress, jint value) {
     *cast<jint*>(dstAddress) = value;
 }
 
-static jlong Memory_peekLong(JNIEnv*, jclass, jlong srcAddress, jboolean swap) {
+static jlong Memory_peekLongNative(JNIEnv*, jclass, jlong srcAddress) {
     jlong result;
     const jlong* src = cast<const jlong*>(srcAddress);
     if ((srcAddress & LONG_ALIGNMENT_MASK) == 0) {
@@ -297,17 +283,11 @@
     } else {
         result = get_unaligned<jlong>(src);
     }
-    if (swap) {
-        result = bswap_64(result);
-    }
     return result;
 }
 
-static void Memory_pokeLong(JNIEnv*, jclass, jlong dstAddress, jlong value, jboolean swap) {
+static void Memory_pokeLongNative(JNIEnv*, jclass, jlong dstAddress, jlong value) {
     jlong* dst = cast<jlong*>(dstAddress);
-    if (swap) {
-        value = bswap_64(value);
-    }
     if ((dstAddress & LONG_ALIGNMENT_MASK) == 0) {
         *dst = value;
     } else {
@@ -378,22 +358,22 @@
     NATIVE_METHOD(Memory, peekCharArray, "(J[CIIZ)V"),
     NATIVE_METHOD(Memory, peekDoubleArray, "(J[DIIZ)V"),
     NATIVE_METHOD(Memory, peekFloatArray, "(J[FIIZ)V"),
-    NATIVE_METHOD(Memory, peekInt, "!(JZ)I"),
+    NATIVE_METHOD(Memory, peekIntNative, "!(J)I"),
     NATIVE_METHOD(Memory, peekIntArray, "(J[IIIZ)V"),
-    NATIVE_METHOD(Memory, peekLong, "!(JZ)J"),
+    NATIVE_METHOD(Memory, peekLongNative, "!(J)J"),
     NATIVE_METHOD(Memory, peekLongArray, "(J[JIIZ)V"),
-    NATIVE_METHOD(Memory, peekShort, "!(JZ)S"),
+    NATIVE_METHOD(Memory, peekShortNative, "!(J)S"),
     NATIVE_METHOD(Memory, peekShortArray, "(J[SIIZ)V"),
     NATIVE_METHOD(Memory, pokeByte, "!(JB)V"),
     NATIVE_METHOD(Memory, pokeByteArray, "(J[BII)V"),
     NATIVE_METHOD(Memory, pokeCharArray, "(J[CIIZ)V"),
     NATIVE_METHOD(Memory, pokeDoubleArray, "(J[DIIZ)V"),
     NATIVE_METHOD(Memory, pokeFloatArray, "(J[FIIZ)V"),
-    NATIVE_METHOD(Memory, pokeInt, "!(JIZ)V"),
+    NATIVE_METHOD(Memory, pokeIntNative, "!(JI)V"),
     NATIVE_METHOD(Memory, pokeIntArray, "(J[IIIZ)V"),
-    NATIVE_METHOD(Memory, pokeLong, "!(JJZ)V"),
+    NATIVE_METHOD(Memory, pokeLongNative, "!(JJ)V"),
     NATIVE_METHOD(Memory, pokeLongArray, "(J[JIIZ)V"),
-    NATIVE_METHOD(Memory, pokeShort, "!(JSZ)V"),
+    NATIVE_METHOD(Memory, pokeShortNative, "!(JS)V"),
     NATIVE_METHOD(Memory, pokeShortArray, "(J[SIIZ)V"),
     NATIVE_METHOD(Memory, unsafeBulkGet, "(Ljava/lang/Object;II[BIIZ)V"),
     NATIVE_METHOD(Memory, unsafeBulkPut, "([BIILjava/lang/Object;IIZ)V"),
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 64dbc8c..9e1a05b 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -62,9 +62,9 @@
 	external/openssl/include \
 	external/zlib
 
+LOCAL_STATIC_LIBRARIES += \
+	libfdlibm
+
 LOCAL_SHARED_LIBRARIES += \
 	liblog \
 	libnativehelper
-
-LOCAL_STATIC_LIBRARIES += \
-	libfdlibm
diff --git a/luni/src/test/java/dalvik/system/DexClassLoaderTest.java b/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
index 5133ea0..4735c15 100644
--- a/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
+++ b/luni/src/test/java/dalvik/system/DexClassLoaderTest.java
@@ -29,8 +29,19 @@
  * Tests for the class {@link DexClassLoader}.
  */
 public class DexClassLoaderTest extends TestCase {
-    private static final File TMP_DIR =
-        new File(System.getProperty("java.io.tmpdir"), "loading-test");
+    // Use /data not /sdcard because optimized cannot be noexec mounted
+    private static final File WORKING_DIR;
+    static {
+      // First try to use the test runner directory for cts, fall back to
+      // shell-writable directory for vogar
+      File runner_dir = new File("/data/data/android.core.tests.runner");
+      if (runner_dir.exists()) {
+        WORKING_DIR = runner_dir;
+      } else {
+        WORKING_DIR = new File("/data/local/tmp");
+      }
+    }
+    private static final File TMP_DIR = new File(WORKING_DIR, "loading-test");
     private static final String PACKAGE_PATH = "dalvik/system/";
     private static final String JAR_NAME = "loading-test.jar";
     private static final String DEX_NAME = "loading-test.dex";
@@ -62,7 +73,7 @@
         }
     }
 
-    protected void setUp() throws IOException {
+    protected void setUp() throws Exception {
         TMP_DIR.mkdirs();
 
         ClassLoader cl = DexClassLoaderTest.class.getClassLoader();
diff --git a/luni/src/test/java/dalvik/system/JniTest.java b/luni/src/test/java/dalvik/system/JniTest.java
new file mode 100644
index 0000000..37e687d
--- /dev/null
+++ b/luni/src/test/java/dalvik/system/JniTest.java
@@ -0,0 +1,368 @@
+/*
+ * 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 dalvik.system;
+
+import junit.framework.TestCase;
+
+/**
+ * Test JNI behavior
+ */
+public final class JniTest extends TestCase {
+
+    static {
+        System.loadLibrary("javacoretests");
+    }
+
+    /** @return this argument of method */
+    private native JniTest returnThis();
+    /** @return class argument of method */
+    private static native Class<JniTest> returnClass();
+
+    private native Object returnObjectArgFrom16(int arg_no,
+                                                Object o1,  Object o2,  Object o3,  Object o4,  Object o5,
+                                                Object o6,  Object o7,  Object o8,  Object o9,  Object o10,
+                                                Object o11, Object o12, Object o13, Object o14, Object o15,
+                                                Object o16);
+    private native boolean returnBooleanArgFrom16(int arg_no,
+                                                  boolean o1,  boolean o2,  boolean o3,  boolean o4,  boolean o5,
+                                                  boolean o6,  boolean o7,  boolean o8,  boolean o9,  boolean o10,
+                                                  boolean o11, boolean o12, boolean o13, boolean o14, boolean o15,
+                                                  boolean o16);
+    private native char returnCharArgFrom16(int arg_no,
+                                            char o1,  char o2,  char o3,  char o4,  char o5,
+                                            char o6,  char o7,  char o8,  char o9,  char o10,
+                                            char o11, char o12, char o13, char o14, char o15,
+                                            char o16);
+    private native byte returnByteArgFrom16(int arg_no,
+                                            byte o1,  byte o2,  byte o3,  byte o4,  byte o5,
+                                            byte o6,  byte o7,  byte o8,  byte o9,  byte o10,
+                                            byte o11, byte o12, byte o13, byte o14, byte o15,
+                                            byte o16);
+    private native short returnShortArgFrom16(int arg_no,
+                                              short o1,  short o2,  short o3,  short o4,  short o5,
+                                              short o6,  short o7,  short o8,  short o9,  short o10,
+                                              short o11, short o12, short o13, short o14, short o15,
+                                              short o16);
+    private native int returnIntArgFrom16(int arg_no,
+                                          int o1,  int o2,  int o3,  int o4,  int o5,
+                                          int o6,  int o7,  int o8,  int o9,  int o10,
+                                          int o11, int o12, int o13, int o14, int o15,
+                                          int o16);
+    private native long returnLongArgFrom16(int arg_no,
+                                            long o1,  long o2,  long o3,  long o4,  long o5,
+                                            long o6,  long o7,  long o8,  long o9,  long o10,
+                                            long o11, long o12, long o13, long o14, long o15,
+                                            long o16);
+    private native float returnFloatArgFrom16(int arg_no,
+                                              float o1,  float o2,  float o3,  float o4,  float o5,
+                                              float o6,  float o7,  float o8,  float o9,  float o10,
+                                              float o11, float o12, float o13, float o14, float o15,
+                                              float o16);
+    private native double returnDoubleArgFrom16(int arg_no,
+                                                double o1,  double o2,  double o3,  double o4,  double o5,
+                                                double o6,  double o7,  double o8,  double o9,  double o10,
+                                                double o11, double o12, double o13, double o14, double o15,
+                                                double o16);
+
+    /** Test cases for implicit this argument */
+    public void testPassingThis() {
+        assertEquals(this, returnThis());
+    }
+
+    /** Test cases for implicit class argument */
+    public void testPassingClass() {
+        assertEquals(JniTest.class, returnClass());
+    }
+
+    /** Test passing object references as arguments to a native method */
+    public void testPassingObjectReferences() {
+        final Object[] literals = {"Bradshaw", "Isherwood", "Oldknow", "Mallet",
+                                   JniTest.class, null, Integer.valueOf(0)};
+        final Object[] a  = new Object[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(Object literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnObjectArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                         a[5], a[6], a[7], a[8], a[9], a[10],
+                                                         a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnObjectArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                         a[5], a[6], a[7], a[8], a[9], a[10],
+                                                         a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing booleans as arguments to a native method */
+    public void testPassingBooleans() {
+        final boolean[] literals = {true, false, false, true};
+        final boolean[] a  = new boolean[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(boolean literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnBooleanArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                          a[5], a[6], a[7], a[8], a[9], a[10],
+                                                          a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnBooleanArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                          a[5], a[6], a[7], a[8], a[9], a[10],
+                                                          a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing characters as arguments to a native method */
+    public void testPassingChars() {
+        final char[] literals = {Character.MAX_VALUE, Character.MIN_VALUE,
+                                 Character.MAX_HIGH_SURROGATE, Character.MAX_LOW_SURROGATE,
+                                 Character.MIN_HIGH_SURROGATE, Character.MIN_LOW_SURROGATE,
+                                 'a', 'z', 'A', 'Z', '0', '9'};
+        final char[] a  = new char[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(char literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnCharArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnCharArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing bytes as arguments to a native method */
+    public void testPassingBytes() {
+        final byte[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, 0, -1};
+        final byte[] a  = new byte[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(byte literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnByteArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnByteArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing shorts as arguments to a native method */
+    public void testPassingShorts() {
+        final short[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE, 0, -1};
+        final short[] a  = new short[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(short literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnShortArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                        a[5], a[6], a[7], a[8], a[9], a[10],
+                                                        a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnShortArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                        a[5], a[6], a[7], a[8], a[9], a[10],
+                                                        a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing ints as arguments to a native method */
+    public void testPassingInts() {
+        final int[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+                                Integer.MAX_VALUE, Integer.MIN_VALUE, 0, -1};
+        final int[] a  = new int[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(int literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnIntArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                      a[5], a[6], a[7], a[8], a[9], a[10],
+                                                      a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnIntArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                      a[5], a[6], a[7], a[8], a[9], a[10],
+                                                      a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing longs as arguments to a native method */
+    public void testPassingLongs() {
+        final long[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+                                 Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE, 0, -1};
+        final long[] a  = new long[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(long literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnLongArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnLongArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                       a[5], a[6], a[7], a[8], a[9], a[10],
+                                                       a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing floats as arguments to a native method */
+    public void testPassingFloats() {
+        final float[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+                                  Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE,
+                                  Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_NORMAL, Float.NaN,
+                                  Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, (float)Math.E, (float)Math.PI, 0, -1};
+        final float[] a  = new float[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(float literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnFloatArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                        a[5], a[6], a[7], a[8], a[9], a[10],
+                                                        a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnFloatArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                        a[5], a[6], a[7], a[8], a[9], a[10],
+                                                        a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    /** Test passing doubles as arguments to a native method */
+    public void testPassingDoubles() {
+        final double[] literals = {Byte.MAX_VALUE, Byte.MIN_VALUE, Short.MAX_VALUE, Short.MIN_VALUE,
+                                   Integer.MAX_VALUE, Integer.MIN_VALUE, Long.MAX_VALUE, Long.MIN_VALUE,
+                                   Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_NORMAL, Float.NaN,
+                                   Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY,
+                                   Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_NORMAL, Double.NaN,
+                                   Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                                   Math.E, Math.PI, 0, -1};
+        final double[] a  = new double[16];
+        // test selection from a list of object literals where the literals are all the same
+        for(double literal : literals) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literal;
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnDoubleArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                         a[5], a[6], a[7], a[8], a[9], a[10],
+                                                         a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+        // test selection from a list of object literals where the literals are shuffled
+        for(int j = 0; j < literals.length; j++) {
+            for(int i = 0; i < 16; i++) {
+                a[i] = literals[(i + j) % literals.length];
+            }
+            for(int i = 0; i < 16; i++) {
+                assertEquals(a[i], returnDoubleArgFrom16(i, a[0], a[1], a[2], a[3], a[4],
+                                                         a[5], a[6], a[7], a[8], a[9], a[10],
+                                                         a[11], a[12], a[13], a[14], a[15]));
+            }
+        }
+    }
+
+    private static native Class<?> envGetSuperclass(Class<?> clazz);
+
+    public void testGetSuperclass() {
+        assertEquals(Object.class, envGetSuperclass(String.class));
+        assertEquals(null, envGetSuperclass(Object.class));
+        assertEquals(null, envGetSuperclass(int.class));
+
+        // incorrect! the spec says this should be null. http://b/5652725
+        assertEquals(Object.class, envGetSuperclass(Runnable.class));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
deleted file mode 100644
index 98e497d..0000000
--- a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase {
-    public void testAput() throws Exception {
-        byte[] bs = new byte[1];
-        try {
-            bs[2] = 0;
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-
-    public void testAget() throws Exception {
-        byte[] bs = new byte[1];
-        try {
-            byte b = bs[2];
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-
-    public void testAputWide() throws Exception {
-        double[] ds = new double[1];
-        try {
-            ds[2] = 0.0;
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-
-    public void testAgetWide() throws Exception {
-        double[] ds = new double[1];
-        try {
-            double d = ds[2];
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-
-    public void testAputObject() throws Exception {
-        Object[] os = new Object[1];
-        try {
-            os[2] = null;
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-
-    public void testAgetObject() throws Exception {
-        Object[] os = new Object[1];
-        try {
-            Object o = os[2];
-            fail();
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            assertEquals("length=1; index=2", ex.getMessage());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java
deleted file mode 100644
index c25245f..0000000
--- a/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ArrayStoreExceptionTest extends TestCase {
-    public void testArrayStoreException_store1() throws Exception {
-        Object[] array = new String[10];
-        Object o = new Exception();
-        try {
-            array[0] = o;
-            fail();
-        } catch (ArrayStoreException ex) {
-            ex.printStackTrace();
-            assertEquals("java.lang.Exception cannot be stored in an array of type "
-                    + "java.lang.String[]",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_store2() throws Exception {
-        Object[] array = new Nonce[10][];
-        Object o = new Integer(5);
-        try {
-            array[0] = o;
-            fail();
-        } catch (ArrayStoreException ex) {
-            assertEquals("java.lang.Integer cannot be stored in an array of type "
-                    + "libcore.java.lang.ArrayStoreExceptionTest$Nonce[][]",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_store3() throws Exception {
-        Object[] array = new Float[10][];
-        Object o = new Nonce[1];
-        try {
-            array[0] = o;
-            fail();
-        } catch (ArrayStoreException ex) {
-            assertEquals("libcore.java.lang.ArrayStoreExceptionTest$Nonce[] cannot be stored "
-                    + "in an array of type java.lang.Float[][]",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy1() throws Exception {
-        String[] src = new String[] { null, null, null, null, "hello", "goodbye" };
-        Integer[] dest = new Integer[10];
-        try {
-            System.arraycopy(src, 1, dest, 0, 5);
-        } catch (ArrayStoreException ex) {
-            ex.printStackTrace();
-            assertEquals("source[4] of type java.lang.String cannot be stored in destination "
-                    + "array of type java.lang.Integer[]",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy2() throws Exception {
-        String[] src = new String[1];
-        int[] dest = new int[1];
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("java.lang.String[] and int[] are incompatible array types",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy3() throws Exception {
-        float[] src = new float[1];
-        Runnable[] dest = new Runnable[1];
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("float[] and java.lang.Runnable[] are incompatible array types",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy4() throws Exception {
-        boolean[] src = new boolean[1];
-        double[][] dest = new double[1][];
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("boolean[] and double[][] are incompatible array types",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy5() throws Exception {
-        String src = "blort";
-        Object[] dest = new Object[1];
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("source of type java.lang.String is not an array",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy6() throws Exception {
-        Object[] src = new Object[1];
-        Integer dest = new Integer(5);
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("destination of type java.lang.Integer is not an array",
-                    ex.getMessage());
-        }
-    }
-
-    public void testArrayStoreException_arraycopy7() throws Exception {
-        /*
-         * This test demonstrates that the exception message complains
-         * about the source in cases where neither source nor
-         * destination is an array.
-         */
-        Nonce src = new Nonce();
-        String dest = "blort";
-        try {
-            System.arraycopy(src, 0, dest, 0, 1);
-        } catch (ArrayStoreException ex) {
-            assertEquals("source of type libcore.java.lang.ArrayStoreExceptionTest$Nonce "
-                    + "is not an array",
-                    ex.getMessage());
-        }
-    }
-
-    /**
-     * This class is just used so that we have an example of getting a
-     * message that includes an inner class.
-     */
-    private static class Nonce {
-        // This space intentionally left blank.
-    }
-}
diff --git a/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
index ec3aa46..3c10aa8 100644
--- a/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
+++ b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java
@@ -23,16 +23,6 @@
 import junit.framework.TestCase;
 
 public final class ClassCastExceptionTest extends TestCase {
-    public void testCast() throws Exception {
-        Object o = new Exception();
-        try {
-            String s = (String) o;
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage());
-        }
-    }
-
     public void testClassCast() throws Exception {
         Object o = new Exception();
         try {
@@ -53,69 +43,6 @@
         }
     }
 
-    public void testCastOperator() throws Exception {
-        try {
-            Object o = (InputStream) makeInteger();
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("java.lang.Integer cannot be cast to java.io.InputStream",
-                    ex.getMessage());
-        }
-    }
-
-    public void testCastOperatorWithArrays() throws Exception {
-        try {
-            Object o = (E) makeArray(String.class);
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("java.lang.String[] cannot be cast to "
-                    + "libcore.java.lang.ClassCastExceptionTest$E",
-                    ex.getMessage());
-        }
-
-        try {
-            Object o = (E) makeArray(float.class);
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("float[] cannot be cast to libcore.java.lang.ClassCastExceptionTest$E",
-                    ex.getMessage());
-        }
-
-        try {
-            Object o = (E) makeArray(char[].class);
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("char[][] cannot be cast to libcore.java.lang.ClassCastExceptionTest$E",
-                    ex.getMessage());
-        }
-
-        try {
-            Object o = (Object[][][]) makeInteger();
-            fail();
-        } catch (ClassCastException ex) {
-            assertEquals("java.lang.Integer cannot be cast to java.lang.Object[][][]",
-                    ex.getMessage());
-        }
-    }
-
-    /**
-     * Helper for {@link #testCastOperator} and {@link
-     * #testCastOperatorWithArrays}, above. It's important that the
-     * return type is {@code Object}, since otherwise the compiler
-     * will just reject the code.
-     */
-    private static Object makeInteger() {
-        return new Integer(5);
-    }
-
-    /**
-     * Helper for {@link #testCastOperatorWithArrays} above. It's important that
-     * the return type is {@code Object}.
-     */
-    private static Object makeArray(Class clazz) {
-        return Array.newInstance(clazz, 1);
-    }
-
     enum E { A, B, C };
     enum F { A, B, C };
 
@@ -125,7 +52,6 @@
             m.put(F.A, "world");
             fail();
         } catch (ClassCastException ex) {
-            ex.printStackTrace();
             assertNotNull(ex.getMessage());
         }
     }
@@ -136,7 +62,6 @@
             m.add(F.A);
             fail();
         } catch (ClassCastException ex) {
-            ex.printStackTrace();
             assertNotNull(ex.getMessage());
         }
     }
@@ -148,7 +73,6 @@
             m.addAll(n);
             fail();
         } catch (ClassCastException ex) {
-            ex.printStackTrace();
             assertNotNull(ex.getMessage());
         }
     }
@@ -170,7 +94,6 @@
             m.add(HugeF.A0);
             fail();
         } catch (ClassCastException ex) {
-            ex.printStackTrace();
             assertNotNull(ex.getMessage());
         }
     }
@@ -182,7 +105,6 @@
             m.addAll(n);
             fail();
         } catch (ClassCastException ex) {
-            ex.printStackTrace();
             assertNotNull(ex.getMessage());
         }
     }
diff --git a/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java b/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java
deleted file mode 100644
index 6eb97c2..0000000
--- a/luni/src/test/java/libcore/java/lang/ClassNotFoundExceptionTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class ClassNotFoundExceptionTest extends TestCase {
-    public void testIllegalName() throws Exception {
-        try {
-            // There is no such thing as an array of void.
-            Class.forName("[V");
-            fail();
-        } catch (ClassNotFoundException ex) {
-            assertEquals("[V", ex.getMessage());
-        }
-    }
-
-    public void testValidName() throws Exception {
-        try {
-            Class.forName("blort.Zorch");
-            fail();
-        } catch (ClassNotFoundException ex) {
-            assertEquals("blort.Zorch", ex.getMessage());
-        }
-    }
-
-    public void testValidArrayName() throws Exception {
-        try {
-            Class.forName("[[Lblort.Zorch;");
-            fail();
-        } catch (ClassNotFoundException ex) {
-            assertEquals("[[Lblort.Zorch;", ex.getMessage());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/java/lang/OldObjectTest.java b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
index 3ab0327..f7a3781 100644
--- a/luni/src/test/java/libcore/java/lang/OldObjectTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
@@ -36,6 +36,16 @@
     TestThread1 thr1;
     TestThread2 thr2;
 
+    public void test_hashCode() {
+        Object o1 = new Object();
+        Object o2 = new Object();
+        int h1 = System.identityHashCode(o1);
+        int h2 = System.identityHashCode(o2);
+        assertEquals(h1, o1.hashCode());
+        assertEquals(h2, o2.hashCode());
+        assertTrue(h1 != h2);
+    }
+
     public void test_clone() {
         MockCloneableObject mco = new MockCloneableObject();
         try {
diff --git a/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java
deleted file mode 100644
index 822e37f..0000000
--- a/luni/src/test/java/libcore/java/lang/StringIndexOutOfBoundsExceptionTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.java.lang;
-
-import junit.framework.TestCase;
-
-public final class StringIndexOutOfBoundsExceptionTest extends TestCase {
-    public void testCharAt() throws Exception {
-        try {
-            "hello".charAt(-1);
-            fail();
-        } catch (StringIndexOutOfBoundsException ex) {
-            assertEquals("length=5; index=-1", ex.getMessage());
-        }
-
-        try {
-            "hello".charAt(7);
-            fail();
-        } catch (StringIndexOutOfBoundsException ex) {
-            assertEquals("length=5; index=7", ex.getMessage());
-        }
-    }
-
-    public void testSubstring() throws Exception {
-        try {
-            "hello there".substring(9,14);
-            fail();
-        } catch (StringIndexOutOfBoundsException ex) {
-            assertEquals("length=11; regionStart=9; regionLength=5",
-                    ex.getMessage());
-        }
-    }
-}
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index f995954..9fc5e8b 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -16,14 +16,14 @@
 
 package libcore.java.lang;
 
-import junit.framework.TestCase;
-
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Formatter;
+import java.util.concurrent.atomic.AtomicBoolean;
+import junit.framework.TestCase;
 
 public class SystemTest extends TestCase {
 
@@ -90,7 +90,7 @@
             System.arraycopy(new char[5], 0, new Object[5], 0, 3);
             fail();
         } catch (ArrayStoreException e) {
-            assertEquals("char[] and java.lang.Object[] are incompatible array types", e.getMessage());
+            assertEquals("Incompatible types: src=char[], dst=java.lang.Object[]", e.getMessage());
         }
     }
 
@@ -118,4 +118,37 @@
             assertEquals("dst == null", e.getMessage());
         }
     }
+
+    /**
+     * System.arraycopy() must never copy objects into arrays that can't store
+     * them. We've had bugs where type checks and copying were done separately
+     * and racy code could defeat the type checks. http://b/5247258
+     */
+    public void testArrayCopyConcurrentModification() {
+        final AtomicBoolean done = new AtomicBoolean();
+
+        final Object[] source = new Object[1024 * 1024];
+        String[] target = new String[1024 * 1024];
+
+        new Thread() {
+            @Override public void run() {
+                // the last array element alternates between being a Thread and being null. When
+                // it's a Thread it isn't safe for arrayCopy; when its null it is!
+                while (!done.get()) {
+                    source[source.length - 1] = this;
+                    source[source.length - 1] = null;
+                }
+            }
+        }.start();
+
+        for (int i = 0; i < 8192; i++) {
+            try {
+                System.arraycopy(source, 0, target, 0, source.length);
+                assertNull(target[source.length - 1]); // make sure the wrong type didn't sneak in
+            } catch (ArrayStoreException ignored) {
+            }
+        }
+
+        done.set(true);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 998afdb..68ad795 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -58,14 +58,40 @@
         assertTrue("Unstarted threads were never finalized!", finalizedThreadsCount.get() > 0);
     }
 
-    private Thread newThread(final AtomicInteger finalizedThreadsCount, final int size) {
-        return new Thread() {
-            byte[] memoryPressure = new byte[size];
-            @Override protected void finalize() throws Throwable {
-                super.finalize();
-                finalizedThreadsCount.incrementAndGet();
-            }
-        };
+    public void testThreadSleep() throws Exception {
+       int millis = 1000;
+       long start = System.currentTimeMillis();
+
+       Thread.sleep(millis);
+
+       long elapsed = System.currentTimeMillis() - start;
+       long offBy = Math.abs(elapsed - millis);
+
+       assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
+    }
+
+    public void testThreadWakeup() throws Exception {
+        WakeupTestThread t1 = new WakeupTestThread();
+        WakeupTestThread t2 = new WakeupTestThread();
+
+        t1.start();
+        t2.start();
+        assertTrue("Threads already finished", !t1.done && !t2.done);
+
+        t1.interrupt();
+        t2.interrupt();
+
+        Thread.sleep(1000);
+        assertTrue("Threads did not finish", t1.done && t2.done);
+    }
+
+    public void testContextClassLoaderIsNotNull() {
+        assertNotNull(Thread.currentThread().getContextClassLoader());
+    }
+
+    public void testContextClassLoaderIsInherited() {
+        Thread other = new Thread();
+        assertSame(Thread.currentThread().getContextClassLoader(), other.getContextClassLoader());
     }
 
     /**
@@ -109,4 +135,30 @@
         // Expect to see the traces of all threads (not just t2)
         assertTrue("Must have traces for all threads", visibleTraces.get() > 1);
     }
+
+    private Thread newThread(final AtomicInteger finalizedThreadsCount, final int size) {
+        return new Thread() {
+            long[] memoryPressure = new long[size];
+            @Override protected void finalize() throws Throwable {
+                super.finalize();
+                finalizedThreadsCount.incrementAndGet();
+            }
+        };
+    }
+
+    private class WakeupTestThread extends Thread {
+        public boolean done;
+
+        public void run() {
+            done = false;
+
+            // Sleep for a while (1 min)
+            try {
+                Thread.sleep(60000);
+            } catch (InterruptedException ignored) {
+            }
+
+            done = true;
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
index c23775e..4cc69ba 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/AnnotationsTest.java
@@ -16,6 +16,7 @@
 
 package libcore.java.lang.reflect;
 
+import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
@@ -23,7 +24,11 @@
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
@@ -56,7 +61,13 @@
 
     public void testParameterAnnotations() throws Exception {
         Method method = Type.class.getMethod("method", String.class, String.class);
-        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        Annotation[][] noParameterAnnotations = method.getParameterAnnotations();
+        assertEquals(2, noParameterAnnotations.length);
+        assertEquals(set(), annotationsToTypes(noParameterAnnotations[0]));
+        assertEquals(set(), annotationsToTypes(noParameterAnnotations[1]));
+
+        Method parameters = Type.class.getMethod("parameters", String.class, String.class);
+        Annotation[][] parameterAnnotations = parameters.getParameterAnnotations();
         assertEquals(2, parameterAnnotations.length);
         assertEquals(set(AnnotationB.class, AnnotationD.class),
                 annotationsToTypes(parameterAnnotations[0]));
@@ -64,6 +75,206 @@
                 annotationsToTypes(parameterAnnotations[1]));
     }
 
+    public void testAnnotationDefaults() throws Exception {
+        assertEquals((byte) 5, defaultValue("a"));
+        assertEquals((short) 6, defaultValue("b"));
+        assertEquals(7, defaultValue("c"));
+        assertEquals(8L, defaultValue("d"));
+        assertEquals(9.0f, defaultValue("e"));
+        assertEquals(10.0, defaultValue("f"));
+        assertEquals('k', defaultValue("g"));
+        assertEquals(true, defaultValue("h"));
+        assertEquals(Breakfast.WAFFLES, defaultValue("i"));
+        assertEquals("@" + AnnotationA.class.getName() + "()", defaultValue("j").toString());
+        assertEquals("maple", defaultValue("k"));
+        assertEquals(AnnotationB.class, defaultValue("l"));
+        assertEquals("[1, 2, 3]", Arrays.toString((int[]) defaultValue("m")));
+        assertEquals("[WAFFLES, PANCAKES]", Arrays.toString((Breakfast[]) defaultValue("n")));
+        assertEquals(null, defaultValue("o"));
+        assertEquals(null, defaultValue("p"));
+    }
+
+    private Object defaultValue(String name) throws NoSuchMethodException {
+        return HasDefaultsAnnotation.class.getMethod(name).getDefaultValue();
+    }
+
+    public void testGetEnclosingClass() {
+        assertNull(AnnotationsTest.class.getEnclosingClass());
+        assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+        assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getEnclosingClass());
+        assertEquals(HasMemberClassesInterface.class,
+                HasMemberClassesInterface.D.class.getEnclosingClass());
+        assertEquals(AnnotationsTest.class, Foo.class.getEnclosingClass());
+    }
+
+    public void testGetDeclaringClass() {
+        assertNull(AnnotationsTest.class.getDeclaringClass());
+        assertEquals(AnnotationsTest.class, Foo.class.getDeclaringClass());
+        assertEquals(AnnotationsTest.class, HasMemberClassesInterface.class.getDeclaringClass());
+        assertEquals(HasMemberClassesInterface.class,
+                HasMemberClassesInterface.D.class.getDeclaringClass());
+    }
+
+    public void testGetEnclosingClassIsTransitiveForClassesDefinedInAMethod() {
+        class C {}
+        assertEquals(AnnotationsTest.class, C.class.getEnclosingClass());
+    }
+
+    public void testGetDeclaringClassIsNotTransitiveForClassesDefinedInAMethod() {
+        class C {}
+        assertEquals(null, C.class.getDeclaringClass());
+    }
+
+    public void testGetEnclosingMethodIsNotTransitive() {
+        class C {
+            class D {}
+        }
+        assertEquals(null, C.D.class.getEnclosingMethod());
+    }
+
+    public void testStaticFieldAnonymousClass() {
+        // The class declared in the <clinit> is enclosed by the <clinit>'s class.
+        // http://b/11245138
+        assertEquals(AnnotationsTest.class, staticAnonymous.getClass().getEnclosingClass());
+        // However, because it is anonymous, it has no declaring class.
+        // https://code.google.com/p/android/issues/detail?id=61003
+        assertNull(staticAnonymous.getClass().getDeclaringClass());
+        // Because the class is declared in <clinit> which is not exposed through reflection,
+        // it has no enclosing method or constructor.
+        assertNull(staticAnonymous.getClass().getEnclosingMethod());
+        assertNull(staticAnonymous.getClass().getEnclosingConstructor());
+    }
+
+    public void testGetEnclosingMethodOfTopLevelClass() {
+        assertNull(AnnotationsTest.class.getEnclosingMethod());
+    }
+
+    public void testGetEnclosingConstructorOfTopLevelClass() {
+        assertNull(AnnotationsTest.class.getEnclosingConstructor());
+    }
+
+    public void testClassEnclosedByConstructor() throws Exception {
+        Foo foo = new Foo("string");
+        assertEquals(Foo.class, foo.c.getEnclosingClass());
+        assertEquals(Foo.class.getDeclaredConstructor(String.class),
+                foo.c.getEnclosingConstructor());
+        assertNull(foo.c.getEnclosingMethod());
+        assertNull(foo.c.getDeclaringClass());
+    }
+
+    public void testClassEnclosedByMethod() throws Exception {
+        Foo foo = new Foo();
+        foo.foo("string");
+        assertEquals(Foo.class, foo.c.getEnclosingClass());
+        assertNull(foo.c.getEnclosingConstructor());
+        assertEquals(Foo.class.getDeclaredMethod("foo", String.class),
+                foo.c.getEnclosingMethod());
+        assertNull(foo.c.getDeclaringClass());
+    }
+
+    public void testGetClasses() throws Exception {
+        // getClasses() doesn't include classes inherited from interfaces!
+        assertSetEquals(HasMemberClasses.class.getClasses(),
+                HasMemberClassesSuperclass.B.class, HasMemberClasses.H.class);
+    }
+
+    public void testGetDeclaredClasses() throws Exception {
+        assertSetEquals(HasMemberClasses.class.getDeclaredClasses(),
+                HasMemberClasses.G.class, HasMemberClasses.H.class, HasMemberClasses.I.class,
+                HasMemberClasses.J.class, HasMemberClasses.K.class, HasMemberClasses.L.class);
+    }
+
+    public void testConstructorGetExceptions() throws Exception {
+        assertSetEquals(HasThrows.class.getConstructor().getExceptionTypes(),
+                IOException.class, InvocationTargetException.class, IllegalStateException.class);
+        assertSetEquals(HasThrows.class.getConstructor(Void.class).getExceptionTypes());
+    }
+
+    public void testClassMethodGetExceptions() throws Exception {
+        assertSetEquals(HasThrows.class.getMethod("foo").getExceptionTypes(),
+                IOException.class, InvocationTargetException.class, IllegalStateException.class);
+        assertSetEquals(HasThrows.class.getMethod("foo", Void.class).getExceptionTypes());
+    }
+
+    public void testProxyMethodGetExceptions() throws Exception {
+        InvocationHandler emptyInvocationHandler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                return null;
+            }
+        };
+
+        Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
+                new Class[] { ThrowsInterface.class }, emptyInvocationHandler);
+        assertSetEquals(proxy.getClass().getMethod("foo").getExceptionTypes(),
+                IOException.class, InvocationTargetException.class, IllegalStateException.class);
+        assertSetEquals(proxy.getClass().getMethod("foo", Void.class).getExceptionTypes());
+    }
+
+    public void testClassModifiers() {
+        int modifiers = AnnotationsTest.class.getModifiers();
+        assertTrue(Modifier.isPublic(modifiers));
+        assertFalse(Modifier.isProtected(modifiers));
+        assertFalse(Modifier.isPrivate(modifiers));
+        assertFalse(Modifier.isAbstract(modifiers));
+        assertFalse(Modifier.isStatic(modifiers));
+        assertTrue(Modifier.isFinal(modifiers));
+        assertFalse(Modifier.isStrict(modifiers));
+    }
+
+    public void testInnerClassModifiers() {
+        int modifiers = Foo.class.getModifiers();
+        assertFalse(Modifier.isPublic(modifiers));
+        assertFalse(Modifier.isProtected(modifiers));
+        assertTrue(Modifier.isPrivate(modifiers));
+        assertFalse(Modifier.isAbstract(modifiers));
+        assertTrue(Modifier.isStatic(modifiers));
+        assertFalse(Modifier.isFinal(modifiers));
+        assertFalse(Modifier.isStrict(modifiers));
+    }
+
+    public void testAnonymousClassModifiers() {
+        int modifiers = staticAnonymous.getClass().getModifiers();
+        assertFalse(Modifier.isPublic(modifiers));
+        assertFalse(Modifier.isProtected(modifiers));
+        assertFalse(Modifier.isPrivate(modifiers));
+        assertFalse(Modifier.isAbstract(modifiers));
+        assertTrue(Modifier.isStatic(modifiers));
+        assertFalse(Modifier.isFinal(modifiers));
+        assertFalse(Modifier.isStrict(modifiers));
+    }
+
+    public void testInnerClassName() {
+        assertEquals("AnnotationsTest", AnnotationsTest.class.getSimpleName());
+        assertEquals("Foo", Foo.class.getSimpleName());
+        assertEquals("", staticAnonymous.getClass().getSimpleName());
+    }
+
+    public void testIsAnonymousClass() {
+        assertFalse(AnnotationsTest.class.isAnonymousClass());
+        assertFalse(Foo.class.isAnonymousClass());
+        assertTrue(staticAnonymous.getClass().isAnonymousClass());
+    }
+
+    private static final Object staticAnonymous = new Object() {};
+
+    private static class Foo {
+        Class<?> c;
+        private Foo() {
+        }
+        private Foo(String s) {
+            c = new Object() {}.getClass();
+        }
+        private Foo(int i) {
+            c = new Object() {}.getClass();
+        }
+        private void foo(String s) {
+            c = new Object() {}.getClass();
+        }
+        private void foo(int i) {
+            c = new Object() {}.getClass();
+        }
+    }
+
     @Retention(RetentionPolicy.RUNTIME)
     public @interface AnnotationA {}
 
@@ -81,12 +292,68 @@
     public static class Type {
         @AnnotationA @AnnotationC public Type() {}
         @AnnotationA @AnnotationD public String field;
-        @AnnotationB @AnnotationC public void method(@AnnotationB @AnnotationD String parameter1,
+        @AnnotationB @AnnotationC public void method(String parameter1, String parameter2) {}
+        @AnnotationB @AnnotationC public void parameters(@AnnotationB @AnnotationD String parameter1,
                 @AnnotationC @AnnotationD String parameter2) {}
     }
 
     public static class ExtendsType extends Type {}
 
+    static enum Breakfast { WAFFLES, PANCAKES }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface HasDefaultsAnnotation {
+        byte a() default 5;
+        short b() default 6;
+        int c() default 7;
+        long d() default 8;
+        float e() default 9.0f;
+        double f() default 10.0;
+        char g() default 'k';
+        boolean h() default true;
+        Breakfast i() default Breakfast.WAFFLES;
+        AnnotationA j() default @AnnotationA();
+        String k() default "maple";
+        Class l() default AnnotationB.class;
+        int[] m() default { 1, 2, 3 };
+        Breakfast[] n() default { Breakfast.WAFFLES, Breakfast.PANCAKES };
+        Breakfast o();
+        int p();
+    }
+
+    static class HasMemberClassesSuperclass {
+        class A {}
+        public class B {}
+        static class C {}
+    }
+
+    public interface HasMemberClassesInterface {
+        class D {}
+        public class E {}
+        static class F {}
+    }
+
+    public static class HasMemberClasses extends HasMemberClassesSuperclass
+            implements HasMemberClassesInterface {
+        class G {}
+        public class H {}
+        static class I {}
+        enum J {}
+        interface K {}
+        @interface L {}
+    }
+
+    public static class HasThrows {
+        public HasThrows() throws IOException, InvocationTargetException, IllegalStateException {}
+        public HasThrows(Void v) {}
+        public void foo() throws IOException, InvocationTargetException, IllegalStateException {}
+        public void foo(Void v) {}
+    }
+
+    public static interface ThrowsInterface {
+        void foo() throws IOException, InvocationTargetException, IllegalStateException;
+        void foo(Void v);
+    }
 
     private void assertAnnotatedElement(
             AnnotatedElement element, Class<? extends Annotation>... expectedAnnotations) {
@@ -134,4 +401,10 @@
     private <T> Set<T> set(T... instances) {
         return new HashSet<T>(Arrays.asList(instances));
     }
+
+    private void assertSetEquals(Object[] actual, Object... expected) {
+        Set<Object> actualSet = new HashSet<Object>(Arrays.asList(actual));
+        Set<Object> expectedSet = new HashSet<Object>(Arrays.asList(expected));
+        assertEquals(expectedSet, actualSet);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java b/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
index 2e15de2..28fd7e9 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ClassLoaderReflectionTest.java
@@ -124,6 +124,28 @@
         assertParameterizedType(types[1], List.class, aClass);
     }
 
+    public void testClassesOfDifferentClassLoadersAreNotEqual() throws Exception {
+        assertFalse(A.class.equals(aClass));
+    }
+
+    public void testConstructorsOfDifferentClassLoadersAreNotEqual() throws Exception {
+        Constructor<?> c1 = A.class.getDeclaredConstructor();
+        Constructor<?> c2 = aClass.getDeclaredConstructor();
+        assertFalse(c1.equals(c2));
+    }
+
+    public void testMethodsOfDifferentClassLoadersAreNotEqual() throws Exception {
+        Method m1 = E.class.getMethod("call");
+        Method m2 = eClass.getMethod("call");
+        assertFalse(m1.equals(m2));
+    }
+
+    public void testFieldsOfDifferentClassLoadersAreNotEqual() throws Exception {
+        Field f1 = B.class.getDeclaredField("field");
+        Field f2 = bClass.getDeclaredField("field");
+        assertFalse(f1.equals(f2));
+    }
+
     static class A {}
     static class B<T> {
         T field;
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java b/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
index ed98794..51ddfc0 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ConstructorTest.java
@@ -72,6 +72,24 @@
         assertEquals(2, constructor.getParameterTypes().length);
     }
 
+    public void testEqualConstructorEqualsAndHashCode() throws Exception {
+        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+        Constructor<?> c2 = ConstructorTestHelper.class.getConstructor();
+        assertEquals(c1, c2);
+        assertEquals(c1.hashCode(), c2.hashCode());
+    }
+
+    public void testHashCodeSpec() throws Exception {
+        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+        assertEquals(ConstructorTestHelper.class.getName().hashCode(), c1.hashCode());
+    }
+
+    public void testDifferentConstructorEqualsAndHashCode() throws Exception {
+        Constructor<?> c1 = ConstructorTestHelper.class.getConstructor();
+        Constructor<?> c2 = ConstructorTestHelper.class.getConstructor(Object.class);
+        assertFalse(c1.equals(c2));
+    }
+
     static class ConstructorTestHelper {
         public ConstructorTestHelper() throws IndexOutOfBoundsException { }
         public ConstructorTestHelper(Object o) { }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java b/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
index eb3d034..b60d984 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/FieldTest.java
@@ -27,4 +27,27 @@
         Field field = getClass().getDeclaredField("MY_LONG");
         assertEquals(5073258162644648461L, field.getLong(null));
     }
+
+    public void testEqualConstructorEqualsAndHashCode() throws Exception {
+        Field f1 = FieldTestHelper.class.getField("a");
+        Field f2 = FieldTestHelper.class.getField("a");
+        assertEquals(f1, f2);
+        assertEquals(f1.hashCode(), f2.hashCode());
+    }
+
+    public void testHashCodeSpec() throws Exception {
+        Field f1 = FieldTestHelper.class.getField("a");
+        assertEquals(FieldTestHelper.class.getName().hashCode() ^ "a".hashCode(), f1.hashCode());
+    }
+
+    public void testDifferentConstructorEqualsAndHashCode() throws Exception {
+        Field f1 = FieldTestHelper.class.getField("a");
+        Field f2 = FieldTestHelper.class.getField("b");
+        assertFalse(f1.equals(f2));
+    }
+
+    static class FieldTestHelper {
+        public String a;
+        public Object b;
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java b/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
index ef30eb8..c3a436c 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
@@ -20,42 +20,6 @@
 import junit.framework.TestCase;
 
 public final class MethodTest extends TestCase {
-    // Check that the VM gives useful detail messages.
-    public void test_invokeExceptions() throws Exception {
-        Method m = String.class.getMethod("charAt", int.class);
-        try {
-            m.invoke("hello"); // Wrong number of arguments.
-            fail();
-        } catch (IllegalArgumentException iae) {
-            assertEquals("wrong number of arguments; expected 1, got 0", iae.getMessage());
-        }
-        try {
-            m.invoke("hello", "world"); // Wrong type.
-            fail();
-        } catch (IllegalArgumentException iae) {
-            assertEquals("argument 1 should have type int, got java.lang.String", iae.getMessage());
-        }
-        try {
-            m.invoke("hello", (Object) null); // Null for a primitive argument.
-            fail();
-        } catch (IllegalArgumentException iae) {
-            assertEquals("argument 1 should have type int, got null", iae.getMessage());
-        }
-        try {
-            m.invoke(new Integer(5)); // Wrong type for 'this'.
-            fail();
-        } catch (IllegalArgumentException iae) {
-            assertEquals("expected receiver of type java.lang.String, but got java.lang.Integer", iae.getMessage());
-        }
-        try {
-            m.invoke(null); // Null for 'this'.
-            fail();
-        } catch (NullPointerException npe) {
-            assertEquals("expected receiver of type java.lang.String, but got null",
-                    npe.getMessage());
-        }
-    }
-
     public void test_getExceptionTypes() throws Exception {
         Method method = MethodTestHelper.class.getMethod("m1", new Class[0]);
         Class[] exceptions = method.getExceptionTypes();
@@ -197,6 +161,26 @@
         assertEquals(anonymous.getClass(), method.getDeclaringClass());
     }
 
+    public void testEqualMethodEqualsAndHashCode() throws Exception {
+        Method m1 = MethodTestHelper.class.getMethod("m1");
+        Method m2 = MethodTestHelper.class.getMethod("m1");
+        assertEquals(m1, m2);
+        assertEquals(m1.hashCode(), m2.hashCode());
+        assertEquals(MethodTestHelper.class.getName().hashCode() ^ "m1".hashCode(), m1.hashCode());
+    }
+
+    public void testHashCodeSpec() throws Exception {
+        Method m1 = MethodTestHelper.class.getMethod("m1");
+        assertEquals(MethodTestHelper.class.getName().hashCode() ^ "m1".hashCode(), m1.hashCode());
+    }
+
+    public void testDifferentMethodEqualsAndHashCode() throws Exception {
+        Method m1 = MethodTestHelper.class.getMethod("m1");
+        Method m2 = MethodTestHelper.class.getMethod("m2", Object.class);
+        assertFalse(m1.equals(m2));
+        assertFalse(m1.hashCode() == m2.hashCode());
+    }
+
     // http://b/1045939
     public void testMethodToString() throws Exception {
         assertEquals("public final native void java.lang.Object.notify()",
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
index 30d47fb..d9e6cba 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ProxyTest.java
@@ -16,14 +16,25 @@
 
 package libcore.java.lang.reflect;
 
+import java.io.EOFException;
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.net.SocketException;
 import junit.framework.TestCase;
 import tests.util.ClassLoaderBuilder;
 
 public final class ProxyTest extends TestCase {
+    private final ClassLoader loader = getClass().getClassLoader();
+    private final InvocationHandler returnHandler = new TestInvocationHandler();
+    private final InvocationHandler throwHandler = new InvocationHandler() {
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            throw (Throwable) args[0];
+        }
+    };
 
     /**
      * Make sure the proxy's class loader fails if it cannot see the class
@@ -36,7 +47,7 @@
 
         Class[] interfacesA = { loaderA.loadClass(prefix + "$Echo") };
         try {
-            Proxy.newProxyInstance(loaderB, interfacesA, new TestInvocationHandler());
+            Proxy.newProxyInstance(loaderB, interfacesA, returnHandler);
             fail();
         } catch (IllegalArgumentException expected) {
         }
@@ -55,10 +66,299 @@
         assertEquals("foo", proxy.getClass().getMethod("echo", String.class).invoke(proxy, "foo"));
     }
 
+    public void testIncompatibleReturnTypesPrimitiveAndPrimitive() {
+        try {
+            Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsFloat.class},
+                    returnHandler);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testIncompatibleReturnTypesPrimitiveAndWrapper() {
+        try {
+            Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsInteger.class},
+                    returnHandler);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testIncompatibleReturnTypesPrimitiveAndVoid() {
+        try {
+            Proxy.newProxyInstance(loader, new Class[] {ReturnsInt.class, ReturnsVoid.class},
+                    returnHandler);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testIncompatibleReturnTypesIncompatibleObjects() {
+        try {
+            Proxy.newProxyInstance(loader, new Class[] {ReturnsInteger.class, ReturnsString.class },
+                    returnHandler);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testCompatibleReturnTypesImplementedInterface() {
+        Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsCharSequence.class},
+                returnHandler);
+        Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+                ReturnsString.class}, returnHandler);
+        Proxy.newProxyInstance(loader, new Class[]{ReturnsObject.class, ReturnsCharSequence.class,
+                ReturnsString.class, ReturnsSerializable.class, ReturnsComparable.class},
+                returnHandler);
+    }
+
+    public void testCompatibleReturnTypesSuperclass() {
+        Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsObject.class},
+                returnHandler);
+    }
+
+    public void testDeclaredExceptionIntersectionIsSubtype() throws Exception {
+        ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+                new Class[] {ThrowsIOException.class, ThrowsEOFException.class},
+                throwHandler);
+        try {
+            instance.run(new EOFException());
+            fail();
+        } catch (EOFException expected) {
+        }
+        try {
+            instance.run(new IOException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+        try {
+            instance.run(new Exception());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+    }
+
+    public void testDeclaredExceptionIntersectionIsEmpty() throws Exception {
+        ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+                new Class[] {ThrowsSocketException.class, ThrowsEOFException.class},
+                throwHandler);
+        try {
+            instance.run(new EOFException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+        try {
+            instance.run(new SocketException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+    }
+
+    public void testDeclaredExceptionIntersectionIsSubset() throws Exception {
+        ThrowsEOFException instance = (ThrowsEOFException) Proxy.newProxyInstance(loader,
+                new Class[] {ThrowsEOFException.class, ThrowsSocketExceptionAndEOFException.class},
+                throwHandler);
+        try {
+            instance.run(new EOFException());
+            fail();
+        } catch (EOFException expected) {
+        }
+        try {
+            instance.run(new SocketException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+        try {
+            instance.run(new IOException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+    }
+
+    public void testDeclaredExceptionIntersectedByExactReturnTypes() throws Exception {
+        ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
+                new Class[] {ThrowsIOException.class, ThrowsEOFExceptionReturnsString.class},
+                throwHandler);
+        try {
+            instance.run(new EOFException());
+            fail();
+        } catch (EOFException expected) {
+        }
+        try {
+            instance.run(new IOException());
+            fail();
+        } catch (IOException expected) {
+        }
+        try {
+            ((ThrowsEOFExceptionReturnsString) instance).run(new EOFException());
+            fail();
+        } catch (EOFException expected) {
+        }
+        try {
+            ((ThrowsEOFExceptionReturnsString) instance).run(new IOException());
+            fail();
+        } catch (UndeclaredThrowableException expected) {
+        }
+    }
+
+    public void testMethodsImplementedByFarIndirectInterface() {
+        ExtendsExtendsDeclaresFiveMethods instance = (ExtendsExtendsDeclaresFiveMethods)
+                Proxy.newProxyInstance(loader, new Class[]{ExtendsExtendsDeclaresFiveMethods.class},
+                returnHandler);
+        assertEquals("foo", instance.a("foo"));
+        assertEquals(0x12345678, instance.b(0x12345678));
+        assertEquals(Double.MIN_VALUE, instance.c(Double.MIN_VALUE));
+        assertEquals(null, instance.d(null));
+        assertEquals(0x1234567890abcdefL, instance.e(0x1234567890abcdefL));
+    }
+
+    public void testEquals() {
+        InvocationHandler handler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                return args[0] == ProxyTest.class; // bogus as equals(), but good for testing
+            }
+        };
+        Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+        assertTrue(instance.equals(ProxyTest.class));
+        assertFalse(instance.equals(new Object()));
+        assertFalse(instance.equals(instance));
+        assertFalse(instance.equals(null));
+    }
+
+    public void testHashCode() {
+        InvocationHandler handler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                return 0x12345678;
+            }
+        };
+        Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+        assertEquals(0x12345678, instance.hashCode());
+    }
+
+    public void testToString() {
+        InvocationHandler handler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                return "foo";
+            }
+        };
+        Echo instance = (Echo) Proxy.newProxyInstance(loader, new Class[]{Echo.class}, handler);
+        assertEquals("foo", instance.toString());
+    }
+
+    public void testReturnTypeDoesNotSatisfyAllConstraintsWithLenientCaller() {
+        InvocationHandler handler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                assertEquals(Object.class, method.getReturnType());
+                return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+            }
+        };
+        ReturnsObject returnsObject = (ReturnsObject) Proxy.newProxyInstance(loader,
+                new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+        assertEquals(true, returnsObject.foo());
+    }
+
+    public void testReturnTypeDoesNotSatisfyAllConstraintsWithStrictCaller() {
+        InvocationHandler handler = new InvocationHandler() {
+            @Override public Object invoke(Object proxy, Method method, Object[] args) {
+                assertEquals(String.class, method.getReturnType());
+                return Boolean.TRUE; // not the right type for 'ReturnsString' callers
+            }
+        };
+        ReturnsString returnsString = (ReturnsString) Proxy.newProxyInstance(loader,
+                new Class[] {ReturnsString.class, ReturnsObject.class}, handler);
+        try {
+            returnsString.foo();
+            fail();
+        } catch (ClassCastException expected) {
+        }
+    }
+
+    public void testReturnsTypeAndInterfaceNotImplementedByThatType() {
+        try {
+            Proxy.newProxyInstance(loader, new Class[] {ReturnsString.class, ReturnsEcho.class},
+                    returnHandler);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     public interface Echo {
         String echo(String s);
     }
 
+    public interface ReturnsInt {
+        int foo();
+    }
+
+    public interface ReturnsFloat {
+        float foo();
+    }
+
+    public interface ReturnsInteger {
+        Integer foo();
+    }
+
+    public interface ReturnsString {
+        String foo();
+    }
+
+    public interface ReturnsCharSequence {
+        CharSequence foo();
+    }
+
+    public interface ReturnsSerializable {
+        CharSequence foo();
+    }
+
+    public interface ReturnsComparable {
+        CharSequence foo();
+    }
+
+    public interface ReturnsObject {
+        Object foo();
+    }
+
+    public interface ReturnsVoid {
+        void foo();
+    }
+
+    public interface ReturnsEcho {
+        Echo foo();
+    }
+
+    public interface ThrowsIOException {
+        Object run(Throwable toThrow) throws IOException;
+    }
+
+    public interface ThrowsEOFException {
+        Object run(Throwable toThrow) throws EOFException;
+    }
+
+    public interface ThrowsEOFExceptionReturnsString {
+        String run(Throwable toThrow) throws EOFException;
+    }
+
+    public interface ThrowsSocketException {
+        Object run(Throwable toThrow) throws SocketException;
+
+    }
+    public interface ThrowsSocketExceptionAndEOFException {
+        Object run(Throwable toThrow) throws SocketException, EOFException;
+
+    }
+
+    public interface DeclaresFiveMethods {
+        String a(String a);
+        int b(int b);
+        double c(double c);
+        Object d(Object d);
+        long e(long e);
+    }
+    public interface ExtendsDeclaresFiveMethods extends DeclaresFiveMethods {
+    }
+    public interface ExtendsExtendsDeclaresFiveMethods extends ExtendsDeclaresFiveMethods {
+    }
+
     public static class TestInvocationHandler implements InvocationHandler {
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
             return args[0];
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
index cdce405..1950bf3 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java
@@ -24,6 +24,8 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -37,6 +39,27 @@
     String classB = "libcore.java.lang.reflect.ReflectionTest$B";
     String classC = "libcore.java.lang.reflect.ReflectionTest$C";
 
+    public void testClassGetSuperclass() {
+        assertEquals(AbstractList.class, ArrayList.class.getSuperclass());
+        assertEquals(AbstractCollection.class, AbstractList.class.getSuperclass());
+        assertEquals(AbstractCollection.class, AbstractList.class.getSuperclass());
+        assertEquals(Object.class, AbstractCollection.class.getSuperclass());
+        assertNull(Object.class.getSuperclass());
+    }
+
+    public void testPrimitiveGetSuperclass() {
+        assertNull(boolean.class.getSuperclass());
+        assertNull(int.class.getSuperclass());
+        assertNull(double.class.getSuperclass());
+        assertNull(void.class.getSuperclass());
+    }
+
+    public void testInterfaceGetSuperclass() {
+        assertNull(Comparable.class.getSuperclass());
+        assertNull(DefinesMember.class.getSuperclass());
+        assertNull(ExtendsDefinesMember.class.getSuperclass());
+    }
+
     /**
      * http://code.google.com/p/android/issues/detail?id=6636
      */
@@ -277,6 +300,36 @@
         assertEquals(1, count(names(fields), "field"));
     }
 
+    public void testIsLocalClass() {
+        A methodLevelAnonymous = new A() {};
+        class Local {}
+        class $Local$1 {}
+        assertFalse(ReflectionTest.class.isLocalClass());
+        assertFalse(A.class.isLocalClass());
+        assertFalse($Dollar$1.class.isLocalClass());
+        assertFalse(CLASS_LEVEL_ANONYMOUS.getClass().isLocalClass());
+        assertFalse(methodLevelAnonymous.getClass().isLocalClass());
+        assertTrue(Local.class.isLocalClass());
+        assertTrue($Local$1.class.isLocalClass());
+        assertFalse(int.class.isLocalClass());
+        assertFalse(Object.class.isLocalClass());
+    }
+
+    public void testIsAnonymousClass() {
+        A methodLevelAnonymous = new A() {};
+        class Local {}
+        class $Local$1 {}
+        assertFalse(ReflectionTest.class.isAnonymousClass());
+        assertFalse(A.class.isAnonymousClass());
+        assertFalse($Dollar$1.class.isAnonymousClass());
+        assertTrue(CLASS_LEVEL_ANONYMOUS.getClass().isAnonymousClass());
+        assertTrue(methodLevelAnonymous.getClass().isAnonymousClass());
+        assertFalse(Local.class.isAnonymousClass());
+        assertFalse($Local$1.class.isAnonymousClass());
+        assertFalse(int.class.isAnonymousClass());
+        assertFalse(Object.class.isAnonymousClass());
+    }
+
     /**
      * Class.isEnum() erroneously returned true for indirect descendants of
      * Enum. http://b/1062200.
@@ -299,8 +352,10 @@
         assertNull(greenClass.getEnumConstants());
     }
 
+    static class $Dollar$1 {}
     static class A {}
     static class AList extends ArrayList<A> {}
+    static A CLASS_LEVEL_ANONYMOUS = new A() {};
 
     static class B extends Exception {}
 
diff --git a/luni/src/test/java/libcore/reflect/InternalNamesTest.java b/luni/src/test/java/libcore/reflect/InternalNamesTest.java
new file mode 100644
index 0000000..bb305ff
--- /dev/null
+++ b/luni/src/test/java/libcore/reflect/InternalNamesTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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 libcore.reflect;
+
+import junit.framework.TestCase;
+
+public final class InternalNamesTest extends TestCase {
+    private final ClassLoader loader = InternalNames.class.getClassLoader();
+
+    public void testGetClassNull() {
+        try {
+            InternalNames.getClass(loader, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testGetInternalNameNull() {
+        try {
+            InternalNames.getInternalName(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testInternalNameToPrimitive() {
+        assertEquals(byte.class, InternalNames.getClass(loader, "B"));
+        assertEquals(char.class, InternalNames.getClass(loader, "C"));
+        assertEquals(double.class, InternalNames.getClass(loader, "D"));
+        assertEquals(float.class, InternalNames.getClass(loader, "F"));
+        assertEquals(int.class, InternalNames.getClass(loader, "I"));
+        assertEquals(long.class, InternalNames.getClass(loader, "J"));
+        assertEquals(short.class, InternalNames.getClass(loader, "S"));
+        assertEquals(boolean.class, InternalNames.getClass(loader, "Z"));
+        assertEquals(void.class, InternalNames.getClass(loader, "V"));
+    }
+
+    public void testPrimitiveToInternalName() {
+        assertEquals("B", InternalNames.getInternalName(byte.class));
+        assertEquals("C", InternalNames.getInternalName(char.class));
+        assertEquals("D", InternalNames.getInternalName(double.class));
+        assertEquals("F", InternalNames.getInternalName(float.class));
+        assertEquals("I", InternalNames.getInternalName(int.class));
+        assertEquals("J", InternalNames.getInternalName(long.class));
+        assertEquals("S", InternalNames.getInternalName(short.class));
+        assertEquals("Z", InternalNames.getInternalName(boolean.class));
+        assertEquals("V", InternalNames.getInternalName(void.class));
+    }
+
+    public void testInternalNameToClass() {
+        assertEquals(String.class, InternalNames.getClass(loader, "Ljava/lang/String;"));
+    }
+
+    public void testClassToInternalName() {
+        assertEquals("Ljava/lang/String;", InternalNames.getInternalName(String.class));
+    }
+
+    public void testInternalNameToPrimitiveArray() {
+        assertEquals(int[].class, InternalNames.getClass(loader, "[I"));
+        assertEquals(int[][][][].class, InternalNames.getClass(loader, "[[[[I"));
+    }
+
+    public void testInternalNameToObjectArray() {
+        assertEquals(String[].class, InternalNames.getClass(loader, "[Ljava/lang/String;"));
+        assertEquals(String[][][][].class,
+                InternalNames.getClass(loader, "[[[[Ljava/lang/String;"));
+    }
+}
diff --git a/luni/src/test/native/dalvik_system_JniTest.cpp b/luni/src/test/native/dalvik_system_JniTest.cpp
new file mode 100644
index 0000000..df48ca9
--- /dev/null
+++ b/luni/src/test/native/dalvik_system_JniTest.cpp
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <stdlib.h> // for abort
+
+extern "C" jobject Java_dalvik_system_JniTest_returnThis(JNIEnv*, jobject obj) {
+  return obj;
+}
+
+extern "C" jclass Java_dalvik_system_JniTest_returnClass(JNIEnv*, jclass klass) {
+  return klass;
+}
+
+extern "C" jobject Java_dalvik_system_JniTest_returnObjectArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jobject o1,  jobject o2,  jobject o3,  jobject o4,  jobject o5,
+    jobject o6,  jobject o7,  jobject o8,  jobject o9,  jobject o10,
+    jobject o11, jobject o12, jobject o13, jobject o14, jobject o15,
+    jobject o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jboolean Java_dalvik_system_JniTest_returnBooleanArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jboolean o1,  jboolean o2,  jboolean o3,  jboolean o4,  jboolean o5,
+    jboolean o6,  jboolean o7,  jboolean o8,  jboolean o9,  jboolean o10,
+    jboolean o11, jboolean o12, jboolean o13, jboolean o14, jboolean o15,
+    jboolean o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jchar Java_dalvik_system_JniTest_returnCharArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jchar o1,  jchar o2,  jchar o3,  jchar o4,  jchar o5,
+    jchar o6,  jchar o7,  jchar o8,  jchar o9,  jchar o10,
+    jchar o11, jchar o12, jchar o13, jchar o14, jchar o15,
+    jchar o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jbyte Java_dalvik_system_JniTest_returnByteArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jbyte o1,  jbyte o2,  jbyte o3,  jbyte o4,  jbyte o5,
+    jbyte o6,  jbyte o7,  jbyte o8,  jbyte o9,  jbyte o10,
+    jbyte o11, jbyte o12, jbyte o13, jbyte o14, jbyte o15,
+    jbyte o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jshort Java_dalvik_system_JniTest_returnShortArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jshort o1,  jshort o2,  jshort o3,  jshort o4,  jshort o5,
+    jshort o6,  jshort o7,  jshort o8,  jshort o9,  jshort o10,
+    jshort o11, jshort o12, jshort o13, jshort o14, jshort o15,
+    jshort o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jint Java_dalvik_system_JniTest_returnIntArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jint o1,  jint o2,  jint o3,  jint o4,  jint o5,
+    jint o6,  jint o7,  jint o8,  jint o9,  jint o10,
+    jint o11, jint o12, jint o13, jint o14, jint o15,
+    jint o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jlong Java_dalvik_system_JniTest_returnLongArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jlong o1,  jlong o2,  jlong o3,  jlong o4,  jlong o5,
+    jlong o6,  jlong o7,  jlong o8,  jlong o9,  jlong o10,
+    jlong o11, jlong o12, jlong o13, jlong o14, jlong o15,
+    jlong o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jfloat Java_dalvik_system_JniTest_returnFloatArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jfloat o1,  jfloat o2,  jfloat o3,  jfloat o4,  jfloat o5,
+    jfloat o6,  jfloat o7,  jfloat o8,  jfloat o9,  jfloat o10,
+    jfloat o11, jfloat o12, jfloat o13, jfloat o14, jfloat o15,
+    jfloat o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jdouble Java_dalvik_system_JniTest_returnDoubleArgFrom16(
+    JNIEnv*, jobject, int arg_no,
+    jdouble o1,  jdouble o2,  jdouble o3,  jdouble o4,  jdouble o5,
+    jdouble o6,  jdouble o7,  jdouble o8,  jdouble o9,  jdouble o10,
+    jdouble o11, jdouble o12, jdouble o13, jdouble o14, jdouble o15,
+    jdouble o16) {
+  switch(arg_no){
+  case 0:  return o1;
+  case 1:  return o2;
+  case 2:  return o3;
+  case 3:  return o4;
+  case 4:  return o5;
+  case 5:  return o6;
+  case 6:  return o7;
+  case 7:  return o8;
+  case 8:  return o9;
+  case 9:  return o10;
+  case 10: return o11;
+  case 11: return o12;
+  case 12: return o13;
+  case 13: return o14;
+  case 14: return o15;
+  case 15: return o16;
+  default: abort();
+  }
+}
+
+extern "C" jclass Java_dalvik_system_JniTest_envGetSuperclass(
+    JNIEnv* env, jobject, jclass clazz) {
+  return env->GetSuperclass(clazz);
+}