diff --git a/luni/src/test/java/libcore/java/lang/invoke/MethodTypeTest.java b/luni/src/test/java/libcore/java/lang/invoke/MethodTypeTest.java
new file mode 100644
index 0000000..3705744
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/invoke/MethodTypeTest.java
@@ -0,0 +1,673 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.invoke;
+
+import junit.framework.TestCase;
+
+import java.lang.invoke.MethodType;
+import java.util.Arrays;
+import java.util.List;
+
+public class MethodTypeTest extends TestCase {
+    private static final Class<?>[] LARGE_PARAMETER_ARRAY;
+
+    static {
+        LARGE_PARAMETER_ARRAY = new Class<?>[254];
+        for (int i = 0; i < 254; ++i) {
+            LARGE_PARAMETER_ARRAY[i] = Object.class;
+        }
+    }
+
+    public void test_methodType_basicTestsReturnTypeAndParameterClassArray() {
+        MethodType mt = MethodType.methodType(int.class,
+                new Class<?>[] { String.class, long.class});
+
+        assertEquals(int.class, mt.returnType());
+        assertParameterTypes(mt, String.class, long.class);
+
+        try {
+            MethodType.methodType(null, new Class<?>[] { String.class });
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, (Class<?>[]) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, new Class<?>[] {void.class});
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void test_methodType_basicTestsReturnTypeAndParameterClassList() {
+        MethodType mt = MethodType.methodType(int.class, Arrays.asList(String.class, long.class));
+
+        assertEquals(int.class, mt.returnType());
+        assertParameterTypes(mt, String.class, long.class);
+
+        try {
+            MethodType.methodType(null, Arrays.asList(String.class));
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, (List<Class<?>>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, Arrays.asList(void.class));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void test_methodType_basicTestsReturnTypeAndVarargsParameters() {
+        MethodType mt = MethodType.methodType(int.class, String.class, long.class);
+
+        assertEquals(int.class, mt.returnType());
+        assertParameterTypes(mt, String.class, long.class);
+
+        try {
+            MethodType.methodType(null, String.class);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, String.class, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, void.class, String.class);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void test_methodType_basicTestsReturnTypeOnly() {
+        MethodType mt = MethodType.methodType(int.class);
+
+        assertEquals(int.class, mt.returnType());
+        assertEquals(0, mt.parameterCount());
+
+        try {
+            MethodType.methodType(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void test_methodType_basicTestsReturnTypeAndSingleParameter() {
+        MethodType mt = MethodType.methodType(int.class, long.class);
+
+        assertEquals(int.class, mt.returnType());
+        assertParameterTypes(mt, long.class);
+
+        try {
+            MethodType.methodType(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(null, String.class);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, (Class<?>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.methodType(int.class, void.class);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testGenericMethodType() {
+        MethodType mt = MethodType.genericMethodType(0);
+        assertEquals(0, mt.parameterCount());
+        assertEquals(Object.class, mt.returnType());
+
+        mt = MethodType.genericMethodType(3);
+        assertEquals(Object.class, mt.returnType());
+
+        assertEquals(3, mt.parameterCount());
+        assertParameterTypes(mt, Object.class, Object.class, Object.class);
+
+        try {
+            MethodType.genericMethodType(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.genericMethodType(256);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testGenericMethodTypeWithTrailingArray() {
+        MethodType mt = MethodType.genericMethodType(3, false /* finalArray */);
+        assertEquals(Object.class, mt.returnType());
+        assertParameterTypes(mt, Object.class, Object.class, Object.class);
+
+        mt = MethodType.genericMethodType(0, true /* finalArray */);
+        assertEquals(Object.class, mt.returnType());
+        assertParameterTypes(mt, Object[].class);
+
+        mt = MethodType.genericMethodType(2, true /* finalArray */);
+        assertEquals(Object.class, mt.returnType());
+        assertParameterTypes(mt, Object.class, Object.class, Object[].class);
+
+        try {
+            MethodType.genericMethodType(-1, true);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.genericMethodType(255, true);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testChangeParameterType() {
+        // int method(String, Object, List);
+        MethodType mt = MethodType.methodType(int.class, String.class, Object.class, List.class);
+        assertEquals(Object.class, mt.parameterType(1));
+
+        MethodType changed = mt.changeParameterType(1, String.class);
+        assertEquals(String.class, changed.parameterType(1));
+
+        // Assert that the return types and the other parameter types haven't changed.
+        assertEquals(mt.parameterCount(), changed.parameterCount());
+        assertEquals(mt.returnType(), changed.returnType());
+        assertEquals(mt.parameterType(0), changed.parameterType(0));
+        assertEquals(mt.parameterType(2), changed.parameterType(2));
+
+        try {
+            mt.changeParameterType(-1, String.class);
+            fail();
+        } catch (ArrayIndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.changeParameterType(3, String.class);
+            fail();
+        } catch (ArrayIndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.changeParameterType(1, void.class);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.changeParameterType(1, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testInsertParameterTypes_varargs() {
+        MethodType mt = MethodType.methodType(int.class, String.class, Object.class);
+
+        MethodType insert0 = mt.insertParameterTypes(0, Integer.class, Long.class);
+        assertEquals(int.class, insert0.returnType());
+        assertParameterTypes(insert0, Integer.class, Long.class, String.class, Object.class);
+
+        MethodType insert1 = mt.insertParameterTypes(1, Integer.class, Long.class);
+        assertParameterTypes(insert1, String.class, Integer.class, Long.class, Object.class);
+
+        MethodType insert2 = mt.insertParameterTypes(2, Integer.class, Long.class);
+        assertParameterTypes(insert2, String.class, Object.class, Integer.class, Long.class);
+
+        try {
+            mt.insertParameterTypes(1, LARGE_PARAMETER_ARRAY);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(1, void.class);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(1, (Class<?>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(-1, String.class);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(3, String.class);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void testInsertParameterTypes_list() {
+        MethodType mt = MethodType.methodType(int.class, String.class, Object.class);
+
+        MethodType insert0 = mt.insertParameterTypes(0, Arrays.asList(Integer.class, Long.class));
+        assertEquals(int.class, insert0.returnType());
+        assertParameterTypes(insert0, Integer.class, Long.class, String.class, Object.class);
+
+        MethodType insert1 = mt.insertParameterTypes(1, Arrays.asList(Integer.class, Long.class));
+        assertParameterTypes(insert1, String.class, Integer.class, Long.class, Object.class);
+
+        MethodType insert2 = mt.insertParameterTypes(2, Arrays.asList(Integer.class, Long.class));
+        assertParameterTypes(insert2, String.class, Object.class, Integer.class, Long.class);
+
+        try {
+            mt.insertParameterTypes(1, Arrays.asList(LARGE_PARAMETER_ARRAY));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(1, Arrays.asList(void.class));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(1, (List<Class<?>>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(1, Arrays.asList(null));
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(-1, Arrays.asList(String.class));
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.insertParameterTypes(3, Arrays.asList(String.class));
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void testAppendParameterTypes_varargs() {
+        MethodType mt = MethodType.methodType(int.class, String.class, String.class);
+
+        MethodType appended = mt.appendParameterTypes(List.class, Integer.class);
+        assertEquals(int.class, appended.returnType());
+        assertParameterTypes(appended, String.class, String.class, List.class, Integer.class);
+
+        try {
+            mt.appendParameterTypes(LARGE_PARAMETER_ARRAY);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.appendParameterTypes(void.class);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.appendParameterTypes((Class<?>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testAppendParameterTypes_list() {
+        MethodType mt = MethodType.methodType(int.class, String.class, String.class);
+
+        MethodType appended = mt.appendParameterTypes(Arrays.asList(List.class, Integer.class));
+        assertEquals(int.class, appended.returnType());
+        assertParameterTypes(appended, String.class, String.class, List.class, Integer.class);
+
+        try {
+            mt.appendParameterTypes(Arrays.asList(LARGE_PARAMETER_ARRAY));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.appendParameterTypes(Arrays.asList(void.class));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            mt.appendParameterTypes((List<Class<?>>) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            mt.appendParameterTypes(Arrays.asList(null));
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testDropParameterTypes() {
+        MethodType mt = MethodType.methodType(int.class, String.class, List.class, Object.class);
+
+        MethodType dropNone = mt.dropParameterTypes(0, 0);
+        assertEquals(int.class, dropNone.returnType());
+        assertParameterTypes(dropNone, String.class, List.class, Object.class);
+
+        MethodType dropFirst = mt.dropParameterTypes(0, 1);
+        assertEquals(int.class, dropFirst.returnType());
+        assertParameterTypes(dropFirst, List.class, Object.class);
+
+        MethodType dropAll = mt.dropParameterTypes(0, 3);
+        assertEquals(0, dropAll.parameterCount());
+        assertEquals(int.class, dropAll.returnType());
+
+        try {
+            mt.dropParameterTypes(-1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.dropParameterTypes(1, 4);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+
+        try {
+            mt.dropParameterTypes(2, 1);
+            fail();
+        } catch (IndexOutOfBoundsException expected) {
+        }
+    }
+
+    public void testChangeReturnType() {
+        MethodType mt = MethodType.methodType(int.class, String.class);
+
+        MethodType changed = mt.changeReturnType(long.class);
+        assertEquals(long.class, changed.returnType());
+        assertParameterTypes(changed, String.class);
+
+        try {
+            mt.changeReturnType(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testHasPrimitives() {
+        MethodType mt = MethodType.methodType(Integer.class, Object.class, String.class);
+        assertFalse(mt.hasPrimitives());
+
+        mt = MethodType.methodType(int.class, Object.class);
+        assertTrue(mt.hasPrimitives());
+
+        mt = MethodType.methodType(Integer.class, long.class);
+        assertTrue(mt.hasPrimitives());
+
+        mt = MethodType.methodType(Integer.class, int[].class);
+        assertFalse(mt.hasPrimitives());
+
+        mt = MethodType.methodType(void.class);
+        assertTrue(mt.hasPrimitives());
+    }
+
+    public void testHasWrappers() {
+        MethodType mt = MethodType.methodType(Integer.class);
+        assertTrue(mt.hasWrappers());
+
+        mt = MethodType.methodType(String.class, Integer.class);
+        assertTrue(mt.hasWrappers());
+
+        mt = MethodType.methodType(int.class, long.class);
+        assertFalse(mt.hasWrappers());
+    }
+
+    public void testErase() {
+        // String mt(int, String, Object) should be erased to Object mt(int, Object, Object);
+        MethodType mt = MethodType.methodType(String.class, int.class, String.class, Object.class);
+
+        MethodType erased = mt.erase();
+        assertEquals(Object.class, erased.returnType());
+        assertParameterTypes(erased, int.class, Object.class, Object.class);
+
+        // Void returns must be left alone.
+        mt = MethodType.methodType(void.class, int.class);
+        erased = mt.erase();
+        assertEquals(mt, erased);
+    }
+
+    public void testGeneric() {
+        // String mt(int, String, Object) should be generified to Object mt(Object, Object, Object).
+        // In other words, it must be equal to genericMethodType(3 /* parameterCount */);
+        MethodType mt = MethodType.methodType(String.class, int.class, String.class, Object.class);
+
+        MethodType generic = mt.generic();
+
+        assertEquals(generic, MethodType.genericMethodType(mt.parameterCount()));
+        assertEquals(generic, mt.wrap().erase());
+
+        assertEquals(Object.class, generic.returnType());
+        assertParameterTypes(generic, Object.class, Object.class, Object.class);
+
+        // Primitive return types must also become Object.
+        generic = MethodType.methodType(int.class).generic();
+        assertEquals(Object.class, generic.returnType());
+
+        // void returns get converted to object returns (the same as wrap).
+        generic = MethodType.methodType(void.class).generic();
+        assertEquals(Object.class, generic.returnType());
+    }
+
+    public void testWrap() {
+        // int mt(String, int, long, float, double, short, char, byte) should be wrapped to
+        // Integer mt(String, Integer, Long, Float, Double, Short, Character, Byte);
+        MethodType mt = MethodType.methodType(int.class, String.class, int.class, long.class,
+                float.class, double.class, short.class, char.class, byte.class);
+
+        MethodType wrapped = mt.wrap();
+        assertFalse(wrapped.hasPrimitives());
+        assertTrue(wrapped.hasWrappers());
+
+        assertEquals(Integer.class, wrapped.returnType());
+        assertParameterTypes(wrapped, String.class, Integer.class, Long.class, Float.class,
+                Double.class, Short.class, Character.class, Byte.class);
+
+        // (semi) special case - void return types get wrapped to Void.
+        wrapped = MethodType.methodType(void.class, int.class).wrap();
+        assertEquals(Void.class, wrapped.returnType());
+    }
+
+    public void testUnwrap() {
+        // Integer mt(String, Integer, Long, Float, Double, Short, Character, Byte);
+        // should be unwrapped to :
+        // int mt(String, int, long, float, double, short, char, byte).
+        MethodType mt = MethodType.methodType(Integer.class, String.class, Integer.class,
+                Long.class, Float.class, Double.class, Short.class, Character.class, Byte.class);
+
+        MethodType unwrapped = mt.unwrap();
+        assertTrue(unwrapped.hasPrimitives());
+        assertFalse(unwrapped.hasWrappers());
+
+        assertEquals(int.class, unwrapped.returnType());
+        assertParameterTypes(unwrapped, String.class, int.class, long.class, float.class,
+                double.class, short.class, char.class, byte.class);
+
+        // (semi) special case - void return types get wrapped to Void.
+        unwrapped = MethodType.methodType(Void.class, int.class).unwrap();
+        assertEquals(void.class, unwrapped.returnType());
+    }
+
+    public void testParameterListAndArray() {
+        MethodType mt = MethodType.methodType(String.class, int.class, String.class, Object.class);
+
+        List<Class<?>> paramsList = mt.parameterList();
+        Class<?>[] paramsArray = mt.parameterArray();
+
+        assertEquals(3, mt.parameterCount());
+
+        for (int i = 0; i < 3; ++i) {
+            Class<?> param = mt.parameterType(i);
+            assertEquals(param, paramsList.get(i));
+            assertEquals(param, paramsArray[i]);
+        }
+
+        mt = MethodType.methodType(int.class);
+        assertEquals(0, mt.parameterCount());
+
+        paramsList = mt.parameterList();
+        paramsArray = mt.parameterArray();
+
+        assertEquals(0, paramsList.size());
+        assertEquals(0, paramsArray.length);
+    }
+
+    public void testEquals() {
+        MethodType mt = MethodType.methodType(int.class, String.class);
+        MethodType mt2 = MethodType.methodType(int.class, String.class);
+
+        assertEquals(mt, mt2);
+        assertEquals(mt, mt);
+
+        assertFalse(mt.equals(null));
+        assertFalse(mt.equals(MethodType.methodType(Integer.class, String.class)));
+    }
+
+    public void testHashCode() {
+        MethodType mt = MethodType.methodType(int.class, String.class, Object.class);
+        int hashCode = mt.hashCode();
+
+        // The hash code should change if we change the return type or any of the parameters,
+        // or if we add or remove parameters from the list.
+        assertFalse(hashCode == mt.changeReturnType(long.class).hashCode());
+        assertFalse(hashCode == mt.changeParameterType(0, Object.class).hashCode());
+        assertFalse(hashCode == mt.appendParameterTypes(List.class).hashCode());
+        assertFalse(hashCode == mt.dropParameterTypes(0, 1).hashCode());
+    }
+
+    public void testToString() {
+        assertEquals("(String,Object)int",
+                MethodType.methodType(int.class, String.class, Object.class).toString());
+        assertEquals("()int", MethodType.methodType(int.class).toString());
+        assertEquals("()void", MethodType.methodType(void.class).toString());
+        assertEquals("()int[]", MethodType.methodType(int[].class).toString());
+    }
+
+    public void testFromMethodDescriptorString() {
+        assertEquals(
+                MethodType.methodType(int.class, String.class, Object.class),
+                MethodType.fromMethodDescriptorString("(Ljava/lang/String;Ljava/lang/Object;)I", null));
+
+        assertEquals(MethodType.fromMethodDescriptorString("()I", null),
+                MethodType.methodType(int.class));
+        assertEquals(MethodType.fromMethodDescriptorString("()[I", null),
+                MethodType.methodType(int[].class));
+        assertEquals(MethodType.fromMethodDescriptorString("([I)V", null),
+                MethodType.methodType(void.class, int[].class));
+
+        try {
+            MethodType.fromMethodDescriptorString(null, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            MethodType.fromMethodDescriptorString("(a/b/c)I", null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.fromMethodDescriptorString("(A)I", null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.fromMethodDescriptorString("(Ljava/lang/String)I", null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.fromMethodDescriptorString("(Ljava/lang/String;)", null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            MethodType.fromMethodDescriptorString("(Ljava/lang/NonExistentString;)I", null);
+            fail();
+        } catch (TypeNotPresentException expected) {
+        }
+    }
+
+    public void testToMethodDescriptorString() {
+        assertEquals("(Ljava/lang/String;Ljava/lang/Object;)I", MethodType.methodType(
+                int.class, String.class, Object.class).toMethodDescriptorString());
+
+        assertEquals("()I", MethodType.methodType(int.class).toMethodDescriptorString());
+        assertEquals("()[I", MethodType.methodType(int[].class).toMethodDescriptorString());
+
+        assertEquals("([I)V", MethodType.methodType(void.class, int[].class)
+                .toMethodDescriptorString());
+    }
+
+    private static void assertParameterTypes(MethodType type, Class<?>... params) {
+        assertEquals(params.length, type.parameterCount());
+
+        List<Class<?>> paramsList = type.parameterList();
+        for (int i = 0; i < params.length; ++i) {
+            assertEquals(params[i], type.parameterType(i));
+            assertEquals(params[i], paramsList.get(i));
+        }
+
+        assertTrue(Arrays.equals(params, type.parameterArray()));
+    }
+}
diff --git a/ojluni/src/lambda/java/java/lang/invoke/MethodType.java b/ojluni/src/lambda/java/java/lang/invoke/MethodType.java
deleted file mode 100644
index 4cb5c22..0000000
--- a/ojluni/src/lambda/java/java/lang/invoke/MethodType.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import java.util.List;
-
-public final
-class MethodType implements java.io.Serializable {
-
-    public static
-    MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
-        return null;
-    }
-
-    public static
-    MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
-        return null;
-    }
-
-    public static
-    MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) { return null; }
-
-    public static
-    MethodType methodType(Class<?> rtype) { return null; }
-
-    public static
-    MethodType methodType(Class<?> rtype, Class<?> ptype0) { return null; }
-
-    public static
-    MethodType methodType(Class<?> rtype, MethodType ptypes) { return null; }
-
-    public static
-    MethodType genericMethodType(int objectArgCount, boolean finalArray) { return null; }
-
-    public static
-    MethodType genericMethodType(int objectArgCount) { return null; }
-
-    public MethodType changeParameterType(int num, Class<?> nptype) { return null; }
-
-    public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) { return null; }
-
-    public MethodType appendParameterTypes(Class<?>... ptypesToInsert) { return null; }
-
-    public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) { return null; }
-
-    public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) { return null; }
-
-    public MethodType dropParameterTypes(int start, int end) { return null; }
-
-    public MethodType changeReturnType(Class<?> nrtype) { return null; }
-
-    public boolean hasPrimitives() { return false; }
-
-    public boolean hasWrappers() { return false; }
-
-    public MethodType erase() { return null; }
-
-    public MethodType generic() { return null; }
-
-    public MethodType wrap() { return null; }
-
-    public MethodType unwrap() { return null; }
-
-    public Class<?> parameterType(int num) { return null; }
-
-    public int parameterCount() { return 0; }
-
-    public Class<?> returnType() { return null; }
-
-    public List<Class<?>> parameterList() { return null; }
-
-    public Class<?>[] parameterArray() { return null; }
-
-    public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
-        throws IllegalArgumentException, TypeNotPresentException { return null; }
-
-    public String toMethodDescriptorString() { return null; }
-
-}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java b/ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java
new file mode 100644
index 0000000..6928c22
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
+
+/**
+ * This class consists exclusively of static names internal to the
+ * method handle implementation.
+ * Usage:  {@code import static java.lang.invoke.MethodHandleStatics.*}
+ * @author John Rose, JSR 292 EG
+ */
+/*non-public*/ class MethodHandleStatics {
+
+    private MethodHandleStatics() { }  // do not instantiate
+
+    static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+    static final boolean DEBUG_METHOD_HANDLE_NAMES;
+    static final boolean DUMP_CLASS_FILES;
+    static final boolean TRACE_INTERPRETER;
+    static final boolean TRACE_METHOD_LINKAGE;
+    static final int COMPILE_THRESHOLD;
+    static final int DONT_INLINE_THRESHOLD;
+    static final int PROFILE_LEVEL;
+    static final boolean PROFILE_GWT;
+    static final int CUSTOMIZE_THRESHOLD;
+
+    static {
+        final Object[] values = new Object[9];
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
+                    values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
+                    values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
+                    values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
+                    values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
+                    values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
+                    values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
+                    values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
+                    values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
+                    return null;
+                }
+            });
+        DEBUG_METHOD_HANDLE_NAMES = (Boolean) values[0];
+        DUMP_CLASS_FILES          = (Boolean) values[1];
+        TRACE_INTERPRETER         = (Boolean) values[2];
+        TRACE_METHOD_LINKAGE      = (Boolean) values[3];
+        COMPILE_THRESHOLD         = (Integer) values[4];
+        DONT_INLINE_THRESHOLD     = (Integer) values[5];
+        PROFILE_LEVEL             = (Integer) values[6];
+        PROFILE_GWT               = (Boolean) values[7];
+        CUSTOMIZE_THRESHOLD       = (Integer) values[8];
+
+        if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
+            throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
+        }
+    }
+
+    /** Tell if any of the debugging switches are turned on.
+     *  If this is the case, it is reasonable to perform extra checks or save extra information.
+     */
+    /*non-public*/ static boolean debugEnabled() {
+        return (DEBUG_METHOD_HANDLE_NAMES |
+                DUMP_CLASS_FILES |
+                TRACE_INTERPRETER |
+                TRACE_METHOD_LINKAGE);
+    }
+
+    // Android-changed: Temporarily hide methods that operate on MethodHandles until the
+    // MethodHandle class is imported.
+    //
+    // /*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
+    //     if (type == null)
+    //         type = target.type();
+    //     MemberName name = null;
+    //     if (target != null)
+    //         name = target.internalMemberName();
+    //     if (name == null)
+    //         return "invoke" + type;
+    //     return name.getName() + type;
+    // }
+    //
+    // /*non-public*/ static String getNameString(MethodHandle target, MethodHandle typeHolder) {
+    //     return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type());
+    // }
+    //
+    // /*non-public*/ static String getNameString(MethodHandle target) {
+    //     return getNameString(target, (MethodType) null);
+    // }
+    //
+    // /*non-public*/ static String addTypeString(Object obj, MethodHandle target) {
+    //     String str = String.valueOf(obj);
+    //     if (target == null)  return str;
+    //     int paren = str.indexOf('(');
+    //     if (paren >= 0) str = str.substring(0, paren);
+    //     return str + target.type();
+    // }
+
+    // handy shared exception makers (they simplify the common case code)
+    /*non-public*/ static InternalError newInternalError(String message) {
+        return new InternalError(message);
+    }
+    /*non-public*/ static InternalError newInternalError(String message, Throwable cause) {
+        return new InternalError(message, cause);
+    }
+    /*non-public*/ static InternalError newInternalError(Throwable cause) {
+        return new InternalError(cause);
+    }
+    /*non-public*/ static RuntimeException newIllegalStateException(String message) {
+        return new IllegalStateException(message);
+    }
+    /*non-public*/ static RuntimeException newIllegalStateException(String message, Object obj) {
+        return new IllegalStateException(message(message, obj));
+    }
+    /*non-public*/ static RuntimeException newIllegalArgumentException(String message) {
+        return new IllegalArgumentException(message);
+    }
+    /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
+        return new IllegalArgumentException(message(message, obj));
+    }
+    /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
+        return new IllegalArgumentException(message(message, obj, obj2));
+    }
+    /** Propagate unchecked exceptions and errors, but wrap anything checked and throw that instead. */
+    /*non-public*/ static Error uncaughtException(Throwable ex) {
+        if (ex instanceof Error)  throw (Error) ex;
+        if (ex instanceof RuntimeException)  throw (RuntimeException) ex;
+        throw newInternalError("uncaught exception", ex);
+    }
+    static Error NYI() {
+        throw new AssertionError("NYI");
+    }
+    private static String message(String message, Object obj) {
+        if (obj != null)  message = message + ": " + obj;
+        return message;
+    }
+    private static String message(String message, Object obj, Object obj2) {
+        if (obj != null || obj2 != null)  message = message + ": " + obj + ", " + obj2;
+        return message;
+    }
+}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodType.java b/ojluni/src/main/java/java/lang/invoke/MethodType.java
new file mode 100644
index 0000000..3cafe89
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/MethodType.java
@@ -0,0 +1,1254 @@
+/*
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.Wrapper;
+import java.lang.ref.WeakReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import sun.invoke.util.BytecodeDescriptor;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method type represents the arguments and return type accepted and
+ * returned by a method handle, or the arguments and return type passed
+ * and expected  by a method handle caller.  Method types must be properly
+ * matched between a method handle and all its callers,
+ * and the JVM's operations enforce this matching at, specifically
+ * during calls to {@code MethodHandle#invokeExact MethodHandle.invokeExact}
+ * and {@code MethodHandle#invoke MethodHandle.invoke}, and during execution
+ * of {@code invokedynamic} instructions.
+ * <p>
+ * The structure is a return type accompanied by any number of parameter types.
+ * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
+ * (For ease of exposition, we treat {@code void} as if it were a type.
+ * In fact, it denotes the absence of a return type.)
+ * <p>
+ * All instances of {@code MethodType} are immutable.
+ * Two instances are completely interchangeable if they compare equal.
+ * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
+ * <p>
+ * This type can be created only by factory methods.
+ * All factory methods may cache values, though caching is not guaranteed.
+ * Some factory methods are static, while others are virtual methods which
+ * modify precursor method types, e.g., by changing a selected parameter.
+ * <p>
+ * Factory methods which operate on groups of parameter types
+ * are systematically presented in two versions, so that both Java arrays and
+ * Java lists can be used to work with groups of parameter types.
+ * The query methods {@code parameterArray} and {@code parameterList}
+ * also provide a choice between arrays and lists.
+ * <p>
+ * {@code MethodType} objects are sometimes derived from bytecode instructions
+ * such as {@code invokedynamic}, specifically from the type descriptor strings associated
+ * with the instructions in a class file's constant pool.
+ * <p>
+ * Like classes and strings, method types can also be represented directly
+ * in a class file's constant pool as constants.
+ * A method type may be loaded by an {@code ldc} instruction which refers
+ * to a suitable {@code CONSTANT_MethodType} constant pool entry.
+ * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
+ * (For full details on method type constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
+ * <p>
+ * When the JVM materializes a {@code MethodType} from a descriptor string,
+ * all classes named in the descriptor must be accessible, and will be loaded.
+ * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
+ * This loading may occur at any time before the {@code MethodType} object is first derived.
+ * @author John Rose, JSR 292 EG
+ */
+// Android-changed, TODO(narayan): Temporarily changed links to MethodHandle API to @code.
+public final
+class MethodType implements java.io.Serializable {
+    private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
+
+    // The rtype and ptypes fields define the structural identity of the method type:
+    private final Class<?>   rtype;
+    private final Class<?>[] ptypes;
+
+    // The remaining fields are caches of various sorts:
+    private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
+    private @Stable MethodType wrapAlt;  // alternative wrapped/unwrapped version
+    // Android-changed: Remove adapter cache. We're not dynamically generating any
+    // adapters at this point.
+    // private @Stable Invokers invokers;   // cache of handy higher-order adapters
+    private @Stable String methodDescriptor;  // cache for toMethodDescriptorString
+
+    /**
+     * Check the given parameters for validity and store them into the final fields.
+     */
+    private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+        checkRtype(rtype);
+        checkPtypes(ptypes);
+        this.rtype = rtype;
+        // defensively copy the array passed in by the user
+        this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
+    }
+
+    /**
+     * Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
+     * Does not check the given parameters for validity, and must be discarded after it is used as a searching key.
+     * The parameters are reversed for this constructor, so that is is not accidentally used.
+     */
+    private MethodType(Class<?>[] ptypes, Class<?> rtype) {
+        this.rtype = rtype;
+        this.ptypes = ptypes;
+    }
+
+    /*trusted*/ MethodTypeForm form() { return form; }
+    /*trusted*/ Class<?> rtype() { return rtype; }
+    /*trusted*/ Class<?>[] ptypes() { return ptypes; }
+
+    // Android-changed: Removed method setForm. It's unused in the JDK and there's no
+    // good reason to allow the form to be set externally.
+    //
+    // void setForm(MethodTypeForm f) { form = f; }
+
+    /** This number, mandated by the JVM spec as 255,
+     *  is the maximum number of <em>slots</em>
+     *  that any Java method can receive in its argument list.
+     *  It limits both JVM signatures and method type objects.
+     *  The longest possible invocation will look like
+     *  {@code staticMethod(arg1, arg2, ..., arg255)} or
+     *  {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
+     */
+    /*non-public*/ static final int MAX_JVM_ARITY = 255;  // this is mandated by the JVM spec.
+
+    /** This number is the maximum arity of a method handle, 254.
+     *  It is derived from the absolute JVM-imposed arity by subtracting one,
+     *  which is the slot occupied by the method handle itself at the
+     *  beginning of the argument list used to invoke the method handle.
+     *  The longest possible invocation will look like
+     *  {@code mh.invoke(arg1, arg2, ..., arg254)}.
+     */
+    // Issue:  Should we allow MH.invokeWithArguments to go to the full 255?
+    /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1;  // deduct one for mh receiver
+
+    /** This number is the maximum arity of a method handle invoker, 253.
+     *  It is derived from the absolute JVM-imposed arity by subtracting two,
+     *  which are the slots occupied by invoke method handle, and the
+     *  target method handle, which are both at the beginning of the argument
+     *  list used to invoke the target method handle.
+     *  The longest possible invocation will look like
+     *  {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
+     */
+    /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1;  // deduct one more for invoker
+
+    private static void checkRtype(Class<?> rtype) {
+        Objects.requireNonNull(rtype);
+    }
+    private static void checkPtype(Class<?> ptype) {
+        Objects.requireNonNull(ptype);
+        if (ptype == void.class)
+            throw newIllegalArgumentException("parameter type cannot be void");
+    }
+    /** Return number of extra slots (count of long/double args). */
+    private static int checkPtypes(Class<?>[] ptypes) {
+        int slots = 0;
+        for (Class<?> ptype : ptypes) {
+            checkPtype(ptype);
+            if (ptype == double.class || ptype == long.class) {
+                slots++;
+            }
+        }
+        checkSlotCount(ptypes.length + slots);
+        return slots;
+    }
+    static void checkSlotCount(int count) {
+        assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
+        // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
+        if ((count & MAX_JVM_ARITY) != count)
+            throw newIllegalArgumentException("bad parameter count "+count);
+    }
+    private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
+        if (num instanceof Integer)  num = "bad index: "+num;
+        return new IndexOutOfBoundsException(num.toString());
+    }
+
+    static final ConcurrentWeakInternSet<MethodType> internTable = new ConcurrentWeakInternSet<>();
+
+    static final Class<?>[] NO_PTYPES = {};
+
+    /**
+     * Finds or creates an instance of the given method type.
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+     */
+    public static
+    MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
+        return makeImpl(rtype, ptypes, false);
+    }
+
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param rtype  the return type
+     * @param ptypes the parameter types
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+     */
+    public static
+    MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
+        boolean notrust = false;  // random List impl. could return evil ptypes array
+        return makeImpl(rtype, listToArray(ptypes), notrust);
+    }
+
+    private static Class<?>[] listToArray(List<Class<?>> ptypes) {
+        // sanity check the size before the toArray call, since size might be huge
+        checkSlotCount(ptypes.size());
+        return ptypes.toArray(NO_PTYPES);
+    }
+
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The leading parameter type is prepended to the remaining array.
+     * @param rtype  the return type
+     * @param ptype0 the first parameter type
+     * @param ptypes the remaining parameter types
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
+     * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
+     */
+    public static
+    MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
+        Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
+        ptypes1[0] = ptype0;
+        System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
+        return makeImpl(rtype, ptypes1, true);
+    }
+
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has no parameter types.
+     * @param rtype  the return type
+     * @return a method type with the given return value
+     * @throws NullPointerException if {@code rtype} is null
+     */
+    public static
+    MethodType methodType(Class<?> rtype) {
+        return makeImpl(rtype, NO_PTYPES, true);
+    }
+
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has the single given parameter type.
+     * @param rtype  the return type
+     * @param ptype0 the parameter type
+     * @return a method type with the given return value and parameter type
+     * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
+     * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
+     */
+    public static
+    MethodType methodType(Class<?> rtype, Class<?> ptype0) {
+        return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
+    }
+
+    /**
+     * Finds or creates a method type with the given components.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * The resulting method has the same parameter types as {@code ptypes},
+     * and the specified return type.
+     * @param rtype  the return type
+     * @param ptypes the method type which supplies the parameter types
+     * @return a method type with the given components
+     * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
+     */
+    public static
+    MethodType methodType(Class<?> rtype, MethodType ptypes) {
+        return makeImpl(rtype, ptypes.ptypes, true);
+    }
+
+    /**
+     * Sole factory method to find or create an interned method type.
+     * @param rtype desired return type
+     * @param ptypes desired parameter types
+     * @param trusted whether the ptypes can be used without cloning
+     * @return the unique method type of the desired structure
+     */
+    /*trusted*/ static
+    MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+        MethodType mt = internTable.get(new MethodType(ptypes, rtype));
+        if (mt != null)
+            return mt;
+        if (ptypes.length == 0) {
+            ptypes = NO_PTYPES; trusted = true;
+        }
+        mt = new MethodType(rtype, ptypes, trusted);
+        // promote the object to the Real Thing, and reprobe
+        mt.form = MethodTypeForm.findForm(mt);
+        return internTable.add(mt);
+    }
+    private static final MethodType[] objectOnlyTypes = new MethodType[20];
+
+    /**
+     * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * All parameters and the return type will be {@code Object},
+     * except the final array parameter if any, which will be {@code Object[]}.
+     * @param objectArgCount number of parameters (excluding the final array parameter if any)
+     * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
+     * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
+     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray} is true)
+     * @see #genericMethodType(int)
+     */
+    public static
+    MethodType genericMethodType(int objectArgCount, boolean finalArray) {
+        MethodType mt;
+        checkSlotCount(objectArgCount);
+        int ivarargs = (!finalArray ? 0 : 1);
+        int ootIndex = objectArgCount*2 + ivarargs;
+        if (ootIndex < objectOnlyTypes.length) {
+            mt = objectOnlyTypes[ootIndex];
+            if (mt != null)  return mt;
+        }
+        Class<?>[] ptypes = new Class<?>[objectArgCount + ivarargs];
+        Arrays.fill(ptypes, Object.class);
+        if (ivarargs != 0)  ptypes[objectArgCount] = Object[].class;
+        mt = makeImpl(Object.class, ptypes, true);
+        if (ootIndex < objectOnlyTypes.length) {
+            objectOnlyTypes[ootIndex] = mt;     // cache it here also!
+        }
+        return mt;
+    }
+
+    /**
+     * Finds or creates a method type whose components are all {@code Object}.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * All parameters and the return type will be Object.
+     * @param objectArgCount number of parameters
+     * @return a generally applicable method type, for all calls of the given argument count
+     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
+     * @see #genericMethodType(int, boolean)
+     */
+    public static
+    MethodType genericMethodType(int objectArgCount) {
+        return genericMethodType(objectArgCount, false);
+    }
+
+    /**
+     * Finds or creates a method type with a single different parameter type.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param num    the index (zero-based) of the parameter type to change
+     * @param nptype a new parameter type to replace the old one with
+     * @return the same type, except with the selected parameter changed
+     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+     * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
+     * @throws NullPointerException if {@code nptype} is null
+     */
+    public MethodType changeParameterType(int num, Class<?> nptype) {
+        if (parameterType(num) == nptype)  return this;
+        checkPtype(nptype);
+        Class<?>[] nptypes = ptypes.clone();
+        nptypes[num] = nptype;
+        return makeImpl(rtype, nptypes, true);
+    }
+
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param num    the position (zero-based) of the inserted parameter type(s)
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+     * @return the same type, except with the selected parameter(s) inserted
+     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
+        int len = ptypes.length;
+        if (num < 0 || num > len)
+            throw newIndexOutOfBoundsException(num);
+        int ins = checkPtypes(ptypesToInsert);
+        checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
+        int ilen = ptypesToInsert.length;
+        if (ilen == 0)  return this;
+        Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
+        System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
+        System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
+        return makeImpl(rtype, nptypes, true);
+    }
+
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+     * @return the same type, except with the selected parameter(s) appended
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    public MethodType appendParameterTypes(Class<?>... ptypesToInsert) {
+        return insertParameterTypes(parameterCount(), ptypesToInsert);
+    }
+
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param num    the position (zero-based) of the inserted parameter type(s)
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+     * @return the same type, except with the selected parameter(s) inserted
+     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
+        return insertParameterTypes(num, listToArray(ptypesToInsert));
+    }
+
+    /**
+     * Finds or creates a method type with additional parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+     * @return the same type, except with the selected parameter(s) appended
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) {
+        return insertParameterTypes(parameterCount(), ptypesToInsert);
+    }
+
+     /**
+     * Finds or creates a method type with modified parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param start  the position (zero-based) of the first replaced parameter type(s)
+     * @param end    the position (zero-based) after the last replaced parameter type(s)
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+     * @return the same type, except with the selected parameter(s) replaced
+     * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code end} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code start} is greater than {@code end}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    /*non-public*/ MethodType replaceParameterTypes(int start, int end, Class<?>... ptypesToInsert) {
+        if (start == end)
+            return insertParameterTypes(start, ptypesToInsert);
+        int len = ptypes.length;
+        if (!(0 <= start && start <= end && end <= len))
+            throw newIndexOutOfBoundsException("start="+start+" end="+end);
+        int ilen = ptypesToInsert.length;
+        if (ilen == 0)
+            return dropParameterTypes(start, end);
+        return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
+    }
+
+    /** Replace the last arrayLength parameter types with the component type of arrayType.
+     * @param arrayType any array type
+     * @param arrayLength the number of parameter types to change
+     * @return the resulting type
+     */
+    /*non-public*/ MethodType asSpreaderType(Class<?> arrayType, int arrayLength) {
+        assert(parameterCount() >= arrayLength);
+        int spreadPos = ptypes.length - arrayLength;
+        if (arrayLength == 0)  return this;  // nothing to change
+        if (arrayType == Object[].class) {
+            if (isGeneric())  return this;  // nothing to change
+            if (spreadPos == 0) {
+                // no leading arguments to preserve; go generic
+                MethodType res = genericMethodType(arrayLength);
+                if (rtype != Object.class) {
+                    res = res.changeReturnType(rtype);
+                }
+                return res;
+            }
+        }
+        Class<?> elemType = arrayType.getComponentType();
+        assert(elemType != null);
+        for (int i = spreadPos; i < ptypes.length; i++) {
+            if (ptypes[i] != elemType) {
+                Class<?>[] fixedPtypes = ptypes.clone();
+                Arrays.fill(fixedPtypes, i, ptypes.length, elemType);
+                return methodType(rtype, fixedPtypes);
+            }
+        }
+        return this;  // arguments check out; no change
+    }
+
+    /** Return the leading parameter type, which must exist and be a reference.
+     *  @return the leading parameter type, after error checks
+     */
+    /*non-public*/ Class<?> leadingReferenceParameter() {
+        Class<?> ptype;
+        if (ptypes.length == 0 ||
+            (ptype = ptypes[0]).isPrimitive())
+            throw newIllegalArgumentException("no leading reference parameter");
+        return ptype;
+    }
+
+    /** Delete the last parameter type and replace it with arrayLength copies of the component type of arrayType.
+     * @param arrayType any array type
+     * @param arrayLength the number of parameter types to insert
+     * @return the resulting type
+     */
+    /*non-public*/ MethodType asCollectorType(Class<?> arrayType, int arrayLength) {
+        assert(parameterCount() >= 1);
+        assert(lastParameterType().isAssignableFrom(arrayType));
+        MethodType res;
+        if (arrayType == Object[].class) {
+            res = genericMethodType(arrayLength);
+            if (rtype != Object.class) {
+                res = res.changeReturnType(rtype);
+            }
+        } else {
+            Class<?> elemType = arrayType.getComponentType();
+            assert(elemType != null);
+            res = methodType(rtype, Collections.nCopies(arrayLength, elemType));
+        }
+        if (ptypes.length == 1) {
+            return res;
+        } else {
+            return res.insertParameterTypes(0, parameterList().subList(0, ptypes.length-1));
+        }
+    }
+
+    /**
+     * Finds or creates a method type with some parameter types omitted.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param start  the index (zero-based) of the first parameter type to remove
+     * @param end    the index (greater than {@code start}) of the first parameter type after not to remove
+     * @return the same type, except with the selected parameter(s) removed
+     * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code end} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code start} is greater than {@code end}
+     */
+    public MethodType dropParameterTypes(int start, int end) {
+        int len = ptypes.length;
+        if (!(0 <= start && start <= end && end <= len))
+            throw newIndexOutOfBoundsException("start="+start+" end="+end);
+        if (start == end)  return this;
+        Class<?>[] nptypes;
+        if (start == 0) {
+            if (end == len) {
+                // drop all parameters
+                nptypes = NO_PTYPES;
+            } else {
+                // drop initial parameter(s)
+                nptypes = Arrays.copyOfRange(ptypes, end, len);
+            }
+        } else {
+            if (end == len) {
+                // drop trailing parameter(s)
+                nptypes = Arrays.copyOfRange(ptypes, 0, start);
+            } else {
+                int tail = len - end;
+                nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
+                System.arraycopy(ptypes, end, nptypes, start, tail);
+            }
+        }
+        return makeImpl(rtype, nptypes, true);
+    }
+
+    /**
+     * Finds or creates a method type with a different return type.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param nrtype a return parameter type to replace the old one with
+     * @return the same type, except with the return type change
+     * @throws NullPointerException if {@code nrtype} is null
+     */
+    public MethodType changeReturnType(Class<?> nrtype) {
+        if (returnType() == nrtype)  return this;
+        return makeImpl(nrtype, ptypes, true);
+    }
+
+    /**
+     * Reports if this type contains a primitive argument or return value.
+     * The return type {@code void} counts as a primitive.
+     * @return true if any of the types are primitives
+     */
+    public boolean hasPrimitives() {
+        return form.hasPrimitives();
+    }
+
+    /**
+     * Reports if this type contains a wrapper argument or return value.
+     * Wrappers are types which box primitive values, such as {@link Integer}.
+     * The reference type {@code java.lang.Void} counts as a wrapper,
+     * if it occurs as a return type.
+     * @return true if any of the types are wrappers
+     */
+    public boolean hasWrappers() {
+        return unwrap() != this;
+    }
+
+    /**
+     * Erases all reference types to {@code Object}.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * All primitive types (including {@code void}) will remain unchanged.
+     * @return a version of the original type with all reference types replaced
+     */
+    public MethodType erase() {
+        return form.erasedType();
+    }
+
+    /**
+     * Erases all reference types to {@code Object}, and all subword types to {@code int}.
+     * This is the reduced type polymorphism used by private methods
+     * such as {@code MethodHandle#invokeBasic invokeBasic}.
+     * @return a version of the original type with all reference and subword types replaced
+     */
+    // Android-changed, TODO(narayan): Temporarily changed links to MethodHandle API to @code.
+    /*non-public*/ MethodType basicType() {
+        return form.basicType();
+    }
+
+    /**
+     * @return a version of the original type with MethodHandle prepended as the first argument
+     */
+    /*non-public*/ MethodType invokerType() {
+        // Android-changed, TODO(narayan): Temporarily disabled until MethodHandle.class is
+        // available.
+        // return insertParameterTypes(0, MethodHandle.class);
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Converts all types, both reference and primitive, to {@code Object}.
+     * Convenience method for {@link #genericMethodType(int) genericMethodType}.
+     * The expression {@code type.wrap().erase()} produces the same value
+     * as {@code type.generic()}.
+     * @return a version of the original type with all types replaced
+     */
+    public MethodType generic() {
+        return genericMethodType(parameterCount());
+    }
+
+    /*non-public*/ boolean isGeneric() {
+        return this == erase() && !hasPrimitives();
+    }
+
+    /**
+     * Converts all primitive types to their corresponding wrapper types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * All reference types (including wrapper types) will remain unchanged.
+     * A {@code void} return type is changed to the type {@code java.lang.Void}.
+     * The expression {@code type.wrap().erase()} produces the same value
+     * as {@code type.generic()}.
+     * @return a version of the original type with all primitive types replaced
+     */
+    public MethodType wrap() {
+        return hasPrimitives() ? wrapWithPrims(this) : this;
+    }
+
+    /**
+     * Converts all wrapper types to their corresponding primitive types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * All primitive types (including {@code void}) will remain unchanged.
+     * A return type of {@code java.lang.Void} is changed to {@code void}.
+     * @return a version of the original type with all wrapper types replaced
+     */
+    public MethodType unwrap() {
+        MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
+        return unwrapWithNoPrims(noprims);
+    }
+
+    private static MethodType wrapWithPrims(MethodType pt) {
+        assert(pt.hasPrimitives());
+        MethodType wt = pt.wrapAlt;
+        if (wt == null) {
+            // fill in lazily
+            wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP);
+            assert(wt != null);
+            pt.wrapAlt = wt;
+        }
+        return wt;
+    }
+
+    private static MethodType unwrapWithNoPrims(MethodType wt) {
+        assert(!wt.hasPrimitives());
+        MethodType uwt = wt.wrapAlt;
+        if (uwt == null) {
+            // fill in lazily
+            uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP);
+            if (uwt == null)
+                uwt = wt;    // type has no wrappers or prims at all
+            wt.wrapAlt = uwt;
+        }
+        return uwt;
+    }
+
+    /**
+     * Returns the parameter type at the specified index, within this method type.
+     * @param num the index (zero-based) of the desired parameter type
+     * @return the selected parameter type
+     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+     */
+    public Class<?> parameterType(int num) {
+        return ptypes[num];
+    }
+    /**
+     * Returns the number of parameter types in this method type.
+     * @return the number of parameter types
+     */
+    public int parameterCount() {
+        return ptypes.length;
+    }
+    /**
+     * Returns the return type of this method type.
+     * @return the return type
+     */
+    public Class<?> returnType() {
+        return rtype;
+    }
+
+    /**
+     * Presents the parameter types as a list (a convenience method).
+     * The list will be immutable.
+     * @return the parameter types (as an immutable list)
+     */
+    public List<Class<?>> parameterList() {
+        return Collections.unmodifiableList(Arrays.asList(ptypes.clone()));
+    }
+
+    /*non-public*/ Class<?> lastParameterType() {
+        int len = ptypes.length;
+        return len == 0 ? void.class : ptypes[len-1];
+    }
+
+    /**
+     * Presents the parameter types as an array (a convenience method).
+     * Changes to the array will not result in changes to the type.
+     * @return the parameter types (as a fresh copy if necessary)
+     */
+    public Class<?>[] parameterArray() {
+        return ptypes.clone();
+    }
+
+    /**
+     * Compares the specified object with this type for equality.
+     * That is, it returns <tt>true</tt> if and only if the specified object
+     * is also a method type with exactly the same parameters and return type.
+     * @param x object to compare
+     * @see Object#equals(Object)
+     */
+    @Override
+    public boolean equals(Object x) {
+        return this == x || x instanceof MethodType && equals((MethodType)x);
+    }
+
+    private boolean equals(MethodType that) {
+        return this.rtype == that.rtype
+            && Arrays.equals(this.ptypes, that.ptypes);
+    }
+
+    /**
+     * Returns the hash code value for this method type.
+     * It is defined to be the same as the hashcode of a List
+     * whose elements are the return type followed by the
+     * parameter types.
+     * @return the hash code value for this method type
+     * @see Object#hashCode()
+     * @see #equals(Object)
+     * @see List#hashCode()
+     */
+    @Override
+    public int hashCode() {
+      int hashCode = 31 + rtype.hashCode();
+      for (Class<?> ptype : ptypes)
+          hashCode = 31*hashCode + ptype.hashCode();
+      return hashCode;
+    }
+
+    /**
+     * Returns a string representation of the method type,
+     * of the form {@code "(PT0,PT1...)RT"}.
+     * The string representation of a method type is a
+     * parenthesis enclosed, comma separated list of type names,
+     * followed immediately by the return type.
+     * <p>
+     * Each type is represented by its
+     * {@link java.lang.Class#getSimpleName simple name}.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("(");
+        for (int i = 0; i < ptypes.length; i++) {
+            if (i > 0)  sb.append(",");
+            sb.append(ptypes[i].getSimpleName());
+        }
+        sb.append(")");
+        sb.append(rtype.getSimpleName());
+        return sb.toString();
+    }
+
+    /** True if the old return type can always be viewed (w/o casting) under new return type,
+     *  and the new parameters can be viewed (w/o casting) under the old parameter types.
+     */
+    // Android-changed: Removed implementation details.
+    // boolean isViewableAs(MethodType newType, boolean keepInterfaces);
+    // boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces);
+    /*non-public*/
+    boolean isConvertibleTo(MethodType newType) {
+        MethodTypeForm oldForm = this.form();
+        MethodTypeForm newForm = newType.form();
+        if (oldForm == newForm)
+            // same parameter count, same primitive/object mix
+            return true;
+        if (!canConvert(returnType(), newType.returnType()))
+            return false;
+        Class<?>[] srcTypes = newType.ptypes;
+        Class<?>[] dstTypes = ptypes;
+        if (srcTypes == dstTypes)
+            return true;
+        int argc;
+        if ((argc = srcTypes.length) != dstTypes.length)
+            return false;
+        if (argc <= 1) {
+            if (argc == 1 && !canConvert(srcTypes[0], dstTypes[0]))
+                return false;
+            return true;
+        }
+        if ((oldForm.primitiveParameterCount() == 0 && oldForm.erasedType == this) ||
+            (newForm.primitiveParameterCount() == 0 && newForm.erasedType == newType)) {
+            // Somewhat complicated test to avoid a loop of 2 or more trips.
+            // If either type has only Object parameters, we know we can convert.
+            assert(canConvertParameters(srcTypes, dstTypes));
+            return true;
+        }
+        return canConvertParameters(srcTypes, dstTypes);
+    }
+
+    /** Returns true if MHs.explicitCastArguments produces the same result as MH.asType.
+     *  If the type conversion is impossible for either, the result should be false.
+     */
+    /*non-public*/
+    boolean explicitCastEquivalentToAsType(MethodType newType) {
+        if (this == newType)  return true;
+        if (!explicitCastEquivalentToAsType(rtype, newType.rtype)) {
+            return false;
+        }
+        Class<?>[] srcTypes = newType.ptypes;
+        Class<?>[] dstTypes = ptypes;
+        if (dstTypes == srcTypes) {
+            return true;
+        }
+        assert(dstTypes.length == srcTypes.length);
+        for (int i = 0; i < dstTypes.length; i++) {
+            if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
+     *  and with the same effect.
+     *  MHs.eCA has the following "upgrades" to MH.asType:
+     *  1. interfaces are unchecked (that is, treated as if aliased to Object)
+     *     Therefore, {@code Object->CharSequence} is possible in both cases but has different semantics
+     *  2. the full matrix of primitive-to-primitive conversions is supported
+     *     Narrowing like {@code long->byte} and basic-typing like {@code boolean->int}
+     *     are not supported by asType, but anything supported by asType is equivalent
+     *     with MHs.eCE.
+     *  3a. unboxing conversions can be followed by the full matrix of primitive conversions
+     *  3b. unboxing of null is permitted (creates a zero primitive value)
+     * Other than interfaces, reference-to-reference conversions are the same.
+     * Boxing primitives to references is the same for both operators.
+     */
+    private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
+        if (src == dst || dst == Object.class || dst == void.class)  return true;
+        if (src.isPrimitive()) {
+            // Could be a prim/prim conversion, where casting is a strict superset.
+            // Or a boxing conversion, which is always to an exact wrapper class.
+            return canConvert(src, dst);
+        } else if (dst.isPrimitive()) {
+            // Unboxing behavior is different between MHs.eCA & MH.asType (see 3b).
+            return false;
+        } else {
+            // R->R always works, but we have to avoid a check-cast to an interface.
+            return !dst.isInterface() || dst.isAssignableFrom(src);
+        }
+    }
+
+    private boolean canConvertParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) {
+        for (int i = 0; i < srcTypes.length; i++) {
+            if (!canConvert(srcTypes[i], dstTypes[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*non-public*/
+    static boolean canConvert(Class<?> src, Class<?> dst) {
+        // short-circuit a few cases:
+        if (src == dst || src == Object.class || dst == Object.class)  return true;
+        // the remainder of this logic is documented in MethodHandle.asType
+        if (src.isPrimitive()) {
+            // can force void to an explicit null, a la reflect.Method.invoke
+            // can also force void to a primitive zero, by analogy
+            if (src == void.class)  return true;  //or !dst.isPrimitive()?
+            Wrapper sw = Wrapper.forPrimitiveType(src);
+            if (dst.isPrimitive()) {
+                // P->P must widen
+                return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
+            } else {
+                // P->R must box and widen
+                return dst.isAssignableFrom(sw.wrapperType());
+            }
+        } else if (dst.isPrimitive()) {
+            // any value can be dropped
+            if (dst == void.class)  return true;
+            Wrapper dw = Wrapper.forPrimitiveType(dst);
+            // R->P must be able to unbox (from a dynamically chosen type) and widen
+            // For example:
+            //   Byte/Number/Comparable/Object -> dw:Byte -> byte.
+            //   Character/Comparable/Object -> dw:Character -> char
+            //   Boolean/Comparable/Object -> dw:Boolean -> boolean
+            // This means that dw must be cast-compatible with src.
+            if (src.isAssignableFrom(dw.wrapperType())) {
+                return true;
+            }
+            // The above does not work if the source reference is strongly typed
+            // to a wrapper whose primitive must be widened.  For example:
+            //   Byte -> unbox:byte -> short/int/long/float/double
+            //   Character -> unbox:char -> int/long/float/double
+            if (Wrapper.isWrapperType(src) &&
+                dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
+                // can unbox from src and then widen to dst
+                return true;
+            }
+            // We have already covered cases which arise due to runtime unboxing
+            // of a reference type which covers several wrapper types:
+            //   Object -> cast:Integer -> unbox:int -> long/float/double
+            //   Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
+            // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
+            // subclass of Number which wraps a value that can convert to char.
+            // Since there is none, we don't need an extra check here to cover char or boolean.
+            return false;
+        } else {
+            // R->R always works, since null is always valid dynamically
+            return true;
+        }
+    }
+
+    /** Reports the number of JVM stack slots required to invoke a method
+     * of this type.  Note that (for historical reasons) the JVM requires
+     * a second stack slot to pass long and double arguments.
+     * So this method returns {@link #parameterCount() parameterCount} plus the
+     * number of long and double parameters (if any).
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and invokedynamic.
+     * @return the number of JVM stack slots for this type's parameters
+     */
+    /*non-public*/ int parameterSlotCount() {
+        return form.parameterSlotCount();
+    }
+
+    /// Queries which have to do with the bytecode architecture
+
+    // Android-changed: These methods aren't needed on Android and are unused within the JDK.
+    //
+    // int parameterSlotDepth(int num);
+    // int returnSlotCount();
+    //
+    // Android-changed: Removed cache of higher order adapters.
+    //
+    // Invokers invokers();
+
+    /**
+     * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * Any class or interface name embedded in the descriptor string
+     * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
+     * on the given loader (or if it is null, on the system class loader).
+     * <p>
+     * Note that it is possible to encounter method types which cannot be
+     * constructed by this method, because their component types are
+     * not all reachable from a common class loader.
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and {@code invokedynamic}.
+     * @param descriptor a bytecode-level type descriptor string "(T...)T"
+     * @param loader the class loader in which to look up the types
+     * @return a method type matching the bytecode-level type descriptor
+     * @throws NullPointerException if the string is null
+     * @throws IllegalArgumentException if the string is not well-formed
+     * @throws TypeNotPresentException if a named type cannot be found
+     */
+    public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
+        throws IllegalArgumentException, TypeNotPresentException
+    {
+        if (!descriptor.startsWith("(") ||  // also generates NPE if needed
+            descriptor.indexOf(')') < 0 ||
+            descriptor.indexOf('.') >= 0)
+            throw newIllegalArgumentException("not a method descriptor: "+descriptor);
+        List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
+        Class<?> rtype = types.remove(types.size() - 1);
+        checkSlotCount(types.size());
+        Class<?>[] ptypes = listToArray(types);
+        return makeImpl(rtype, ptypes, true);
+    }
+
+    /**
+     * Produces a bytecode descriptor representation of the method type.
+     * <p>
+     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
+     * Two distinct classes which share a common name but have different class loaders
+     * will appear identical when viewed within descriptor strings.
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and {@code invokedynamic}.
+     * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
+     * because the latter requires a suitable class loader argument.
+     * @return the bytecode type descriptor representation
+     */
+    public String toMethodDescriptorString() {
+        String desc = methodDescriptor;
+        if (desc == null) {
+            desc = BytecodeDescriptor.unparse(this);
+            methodDescriptor = desc;
+        }
+        return desc;
+    }
+
+    /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
+        return BytecodeDescriptor.unparse(cls);
+    }
+
+    /// Serialization.
+
+    /**
+     * There are no serializable fields for {@code MethodType}.
+     */
+    private static final java.io.ObjectStreamField[] serialPersistentFields = { };
+
+    /**
+     * Save the {@code MethodType} instance to a stream.
+     *
+     * @serialData
+     * For portability, the serialized format does not refer to named fields.
+     * Instead, the return type and parameter type arrays are written directly
+     * from the {@code writeObject} method, using two calls to {@code s.writeObject}
+     * as follows:
+     * <blockquote><pre>{@code
+s.writeObject(this.returnType());
+s.writeObject(this.parameterArray());
+     * }</pre></blockquote>
+     * <p>
+     * The deserialized field values are checked as if they were
+     * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
+     * For example, null values, or {@code void} parameter types,
+     * will lead to exceptions during deserialization.
+     * @param s the stream to write the object to
+     * @throws java.io.IOException if there is a problem writing the object
+     */
+    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+        s.defaultWriteObject();  // requires serialPersistentFields to be an empty array
+        s.writeObject(returnType());
+        s.writeObject(parameterArray());
+    }
+
+    /**
+     * Reconstitute the {@code MethodType} instance from a stream (that is,
+     * deserialize it).
+     * This instance is a scratch object with bogus final fields.
+     * It provides the parameters to the factory method called by
+     * {@link #readResolve readResolve}.
+     * After that call it is discarded.
+     * @param s the stream to read the object from
+     * @throws java.io.IOException if there is a problem reading the object
+     * @throws ClassNotFoundException if one of the component classes cannot be resolved
+     * @see #MethodType()
+     * @see #readResolve
+     * @see #writeObject
+     */
+    private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();  // requires serialPersistentFields to be an empty array
+
+        Class<?>   returnType     = (Class<?>)   s.readObject();
+        Class<?>[] parameterArray = (Class<?>[]) s.readObject();
+
+        // Probably this object will never escape, but let's check
+        // the field values now, just to be sure.
+        checkRtype(returnType);
+        checkPtypes(parameterArray);
+
+        parameterArray = parameterArray.clone();  // make sure it is unshared
+        MethodType_init(returnType, parameterArray);
+    }
+
+    /**
+     * For serialization only.
+     * Sets the final fields to null, pending {@code Unsafe.putObject}.
+     */
+    private MethodType() {
+        this.rtype = null;
+        this.ptypes = null;
+    }
+    private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
+        // In order to communicate these values to readResolve, we must
+        // store them into the implementation-specific final fields.
+        checkRtype(rtype);
+        checkPtypes(ptypes);
+        UNSAFE.putObject(this, rtypeOffset, rtype);
+        UNSAFE.putObject(this, ptypesOffset, ptypes);
+    }
+
+    // Support for resetting final fields while deserializing
+    private static final long rtypeOffset, ptypesOffset;
+    static {
+        try {
+            rtypeOffset = UNSAFE.objectFieldOffset
+                (MethodType.class.getDeclaredField("rtype"));
+            ptypesOffset = UNSAFE.objectFieldOffset
+                (MethodType.class.getDeclaredField("ptypes"));
+        } catch (Exception ex) {
+            throw new Error(ex);
+        }
+    }
+
+    /**
+     * Resolves and initializes a {@code MethodType} object
+     * after serialization.
+     * @return the fully initialized {@code MethodType} object
+     */
+    private Object readResolve() {
+        // Do not use a trusted path for deserialization:
+        //return makeImpl(rtype, ptypes, true);
+        // Verify all operands, and make sure ptypes is unshared:
+        return methodType(rtype, ptypes);
+    }
+
+    /**
+     * Simple implementation of weak concurrent intern set.
+     *
+     * @param <T> interned type
+     */
+    private static class ConcurrentWeakInternSet<T> {
+
+        private final ConcurrentMap<WeakEntry<T>, WeakEntry<T>> map;
+        private final ReferenceQueue<T> stale;
+
+        public ConcurrentWeakInternSet() {
+            this.map = new ConcurrentHashMap<>();
+            this.stale = new ReferenceQueue<>();
+        }
+
+        /**
+         * Get the existing interned element.
+         * This method returns null if no element is interned.
+         *
+         * @param elem element to look up
+         * @return the interned element
+         */
+        public T get(T elem) {
+            if (elem == null) throw new NullPointerException();
+            expungeStaleElements();
+
+            WeakEntry<T> value = map.get(new WeakEntry<>(elem));
+            if (value != null) {
+                T res = value.get();
+                if (res != null) {
+                    return res;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Interns the element.
+         * Always returns non-null element, matching the one in the intern set.
+         * Under the race against another add(), it can return <i>different</i>
+         * element, if another thread beats us to interning it.
+         *
+         * @param elem element to add
+         * @return element that was actually added
+         */
+        public T add(T elem) {
+            if (elem == null) throw new NullPointerException();
+
+            // Playing double race here, and so spinloop is required.
+            // First race is with two concurrent updaters.
+            // Second race is with GC purging weak ref under our feet.
+            // Hopefully, we almost always end up with a single pass.
+            T interned;
+            WeakEntry<T> e = new WeakEntry<>(elem, stale);
+            do {
+                expungeStaleElements();
+                WeakEntry<T> exist = map.putIfAbsent(e, e);
+                interned = (exist == null) ? elem : exist.get();
+            } while (interned == null);
+            return interned;
+        }
+
+        private void expungeStaleElements() {
+            Reference<? extends T> reference;
+            while ((reference = stale.poll()) != null) {
+                map.remove(reference);
+            }
+        }
+
+        private static class WeakEntry<T> extends WeakReference<T> {
+
+            public final int hashcode;
+
+            public WeakEntry(T key, ReferenceQueue<T> queue) {
+                super(key, queue);
+                hashcode = key.hashCode();
+            }
+
+            public WeakEntry(T key) {
+                super(key);
+                hashcode = key.hashCode();
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (obj instanceof WeakEntry) {
+                    Object that = ((WeakEntry) obj).get();
+                    Object mine = get();
+                    return (that == null || mine == null) ? (this == obj) : mine.equals(that);
+                }
+                return false;
+            }
+
+            @Override
+            public int hashCode() {
+                return hashcode;
+            }
+
+        }
+    }
+
+}
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
new file mode 100644
index 0000000..d65392b
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.Wrapper;
+import java.lang.ref.SoftReference;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * Shared information for a group of method types, which differ
+ * only by reference types, and therefore share a common erasure
+ * and wrapping.
+ * <p>
+ * For an empirical discussion of the structure of method types,
+ * see <a href="http://groups.google.com/group/jvm-languages/browse_thread/thread/ac9308ae74da9b7e/">
+ * the thread "Avoiding Boxing" on jvm-languages</a>.
+ * There are approximately 2000 distinct erased method types in the JDK.
+ * There are a little over 10 times that number of unerased types.
+ * No more than half of these are likely to be loaded at once.
+ * @author John Rose
+ */
+final class MethodTypeForm {
+    final int[] argToSlotTable, slotToArgTable;
+    final long argCounts;               // packed slot & value counts
+    final long primCounts;              // packed prim & double counts
+    final MethodType erasedType;        // the canonical erasure
+    final MethodType basicType;         // the canonical erasure, with primitives simplified
+
+    // Cached adapter information:
+    //
+    // @Stable final SoftReference<MethodHandle>[] methodHandles;
+    // static final int  MH_BASIC_INV, MH_NF_INV, MH_UNINIT_CS, MH_LIMIT;
+    //
+    // Cached lambda form information, for basic types only:
+    // final @Stable SoftReference<LambdaForm>[] lambdaForms;
+    //
+    // Indexes into lambdaForms:
+    //
+    // static final int LF_INVVIRTUAL, LF_INVSTATIC, LF_INVSPECIAL, LF_NEWINVSPECIAL,
+    // LF_INVINTERFACE, LF_INVSTATIC_INIT, LF_INTERPRET, LF_REBIND, LF_DELEGATE,
+    // LF_DELEGATE_BLOCK_INLINING, LF_EX_LINKER, LF_EX_INVOKER, LF_GEN_LINKER, LF_GEN_INVOKER,
+    // LF_CS_LINKER, LF_MH_LINKER, LF_GWC, LF_GWT, LF_LIMIT;
+
+    /** Return the type corresponding uniquely (1-1) to this MT-form.
+     *  It might have any primitive returns or arguments, but will have no references except Object.
+     */
+    public MethodType erasedType() {
+        return erasedType;
+    }
+
+    /** Return the basic type derived from the erased type of this MT-form.
+     *  A basic type is erased (all references Object) and also has all primitive
+     *  types (except int, long, float, double, void) normalized to int.
+     *  Such basic types correspond to low-level JVM calling sequences.
+     */
+    public MethodType basicType() {
+        return basicType;
+    }
+
+    private boolean assertIsBasicType() {
+        // primitives must be flattened also
+        assert(erasedType == basicType)
+                : "erasedType: " + erasedType + " != basicType: " + basicType;
+        return true;
+    }
+
+    // Android-changed: Removed caches for MethodHandle adaptors / LambdaForms.
+    //
+    // public MethodHandle cachedMethodHandle(int which);
+    // synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh);
+    // public LambdaForm cachedLambdaForm(int which);
+    // synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form);
+
+    /**
+     * Build an MTF for a given type, which must have all references erased to Object.
+     * This MTF will stand for that type and all un-erased variations.
+     * Eagerly compute some basic properties of the type, common to all variations.
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected MethodTypeForm(MethodType erasedType) {
+        this.erasedType = erasedType;
+
+        Class<?>[] ptypes = erasedType.ptypes();
+        int ptypeCount = ptypes.length;
+        int pslotCount = ptypeCount;            // temp. estimate
+        int rtypeCount = 1;                     // temp. estimate
+        int rslotCount = 1;                     // temp. estimate
+
+        int[] argToSlotTab = null, slotToArgTab = null;
+
+        // Walk the argument types, looking for primitives.
+        int pac = 0, lac = 0, prc = 0, lrc = 0;
+        Class<?>[] epts = ptypes;
+        Class<?>[] bpts = epts;
+        for (int i = 0; i < epts.length; i++) {
+            Class<?> pt = epts[i];
+            if (pt != Object.class) {
+                ++pac;
+                Wrapper w = Wrapper.forPrimitiveType(pt);
+                if (w.isDoubleWord())  ++lac;
+                if (w.isSubwordOrInt() && pt != int.class) {
+                    if (bpts == epts)
+                        bpts = bpts.clone();
+                    bpts[i] = int.class;
+                }
+            }
+        }
+        pslotCount += lac;                  // #slots = #args + #longs
+        Class<?> rt = erasedType.returnType();
+        Class<?> bt = rt;
+        if (rt != Object.class) {
+            ++prc;          // even void.class counts as a prim here
+            Wrapper w = Wrapper.forPrimitiveType(rt);
+            if (w.isDoubleWord())  ++lrc;
+            if (w.isSubwordOrInt() && rt != int.class)
+                bt = int.class;
+            // adjust #slots, #args
+            if (rt == void.class)
+                rtypeCount = rslotCount = 0;
+            else
+                rslotCount += lrc;
+        }
+        if (epts == bpts && bt == rt) {
+            this.basicType = erasedType;
+        } else {
+            this.basicType = MethodType.makeImpl(bt, bpts, true);
+            // fill in rest of data from the basic type:
+            MethodTypeForm that = this.basicType.form();
+            assert(this != that);
+            this.primCounts = that.primCounts;
+            this.argCounts = that.argCounts;
+            this.argToSlotTable = that.argToSlotTable;
+            this.slotToArgTable = that.slotToArgTable;
+            // Android-changed: Removed cached adaptors / lambda forms.
+            //
+            // this.methodHandles = null;
+            // this.lambdaForms = null;
+            return;
+        }
+        if (lac != 0) {
+            int slot = ptypeCount + lac;
+            slotToArgTab = new int[slot+1];
+            argToSlotTab = new int[1+ptypeCount];
+            argToSlotTab[0] = slot;  // argument "-1" is past end of slots
+            for (int i = 0; i < epts.length; i++) {
+                Class<?> pt = epts[i];
+                Wrapper w = Wrapper.forBasicType(pt);
+                if (w.isDoubleWord())  --slot;
+                --slot;
+                slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+                argToSlotTab[1+i]  = slot;
+            }
+            assert(slot == 0);  // filled the table
+        } else if (pac != 0) {
+            // have primitives but no long primitives; share slot counts with generic
+            assert(ptypeCount == pslotCount);
+            MethodTypeForm that = MethodType.genericMethodType(ptypeCount).form();
+            assert(this != that);
+            slotToArgTab = that.slotToArgTable;
+            argToSlotTab = that.argToSlotTable;
+        } else {
+            int slot = ptypeCount; // first arg is deepest in stack
+            slotToArgTab = new int[slot+1];
+            argToSlotTab = new int[1+ptypeCount];
+            argToSlotTab[0] = slot;  // argument "-1" is past end of slots
+            for (int i = 0; i < ptypeCount; i++) {
+                --slot;
+                slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+                argToSlotTab[1+i]  = slot;
+            }
+        }
+        this.primCounts = pack(lrc, prc, lac, pac);
+        this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount);
+        this.argToSlotTable = argToSlotTab;
+        this.slotToArgTable = slotToArgTab;
+
+        if (pslotCount >= 256)  throw newIllegalArgumentException("too many arguments");
+
+        // Initialize caches, but only for basic types
+        assert(basicType == erasedType);
+        // Android-changed: Removed cached adaptors / lambda forms.
+        //
+        // this.lambdaForms   = new SoftReference[LF_LIMIT];
+        // this.methodHandles = new SoftReference[MH_LIMIT];
+    }
+
+    private static long pack(int a, int b, int c, int d) {
+        assert(((a|b|c|d) & ~0xFFFF) == 0);
+        long hw = ((a << 16) | b), lw = ((c << 16) | d);
+        return (hw << 32) | lw;
+    }
+    private static char unpack(long packed, int word) { // word==0 => return a, ==3 => return d
+        assert(word <= 3);
+        return (char)(packed >> ((3-word) * 16));
+    }
+
+    public int parameterCount() {                      // # outgoing values
+        return unpack(argCounts, 3);
+    }
+    public int parameterSlotCount() {                  // # outgoing interpreter slots
+        return unpack(argCounts, 2);
+    }
+    public int returnCount() {                         // = 0 (V), or 1
+        return unpack(argCounts, 1);
+    }
+    public int returnSlotCount() {                     // = 0 (V), 2 (J/D), or 1
+        return unpack(argCounts, 0);
+    }
+    public int primitiveParameterCount() {
+        return unpack(primCounts, 3);
+    }
+    public int longPrimitiveParameterCount() {
+        return unpack(primCounts, 2);
+    }
+    public int primitiveReturnCount() {                // = 0 (obj), or 1
+        return unpack(primCounts, 1);
+    }
+    public int longPrimitiveReturnCount() {            // = 1 (J/D), or 0
+        return unpack(primCounts, 0);
+    }
+    public boolean hasPrimitives() {
+        return primCounts != 0;
+    }
+    public boolean hasNonVoidPrimitives() {
+        if (primCounts == 0)  return false;
+        if (primitiveParameterCount() != 0)  return true;
+        return (primitiveReturnCount() != 0 && returnCount() != 0);
+    }
+    public boolean hasLongPrimitives() {
+        return (longPrimitiveParameterCount() | longPrimitiveReturnCount()) != 0;
+    }
+    public int parameterToArgSlot(int i) {
+        return argToSlotTable[1+i];
+    }
+    public int argSlotToParameter(int argSlot) {
+        // Note:  Empty slots are represented by zero in this table.
+        // Valid arguments slots contain incremented entries, so as to be non-zero.
+        // We return -1 the caller to mean an empty slot.
+        return slotToArgTable[argSlot] - 1;
+    }
+
+    static MethodTypeForm findForm(MethodType mt) {
+        MethodType erased = canonicalize(mt, ERASE, ERASE);
+        if (erased == null) {
+            // It is already erased.  Make a new MethodTypeForm.
+            return new MethodTypeForm(mt);
+        } else {
+            // Share the MethodTypeForm with the erased version.
+            return erased.form();
+        }
+    }
+
+    /** Codes for {@link #canonicalize(java.lang.Class, int)}.
+     * ERASE means change every reference to {@code Object}.
+     * WRAP means convert primitives (including {@code void} to their
+     * corresponding wrapper types.  UNWRAP means the reverse of WRAP.
+     * INTS means convert all non-void primitive types to int or long,
+     * according to size.  LONGS means convert all non-void primitives
+     * to long, regardless of size.  RAW_RETURN means convert a type
+     * (assumed to be a return type) to int if it is smaller than an int,
+     * or if it is void.
+     */
+    public static final int NO_CHANGE = 0, ERASE = 1, WRAP = 2, UNWRAP = 3, INTS = 4, LONGS = 5, RAW_RETURN = 6;
+
+    /** Canonicalize the types in the given method type.
+     * If any types change, intern the new type, and return it.
+     * Otherwise return null.
+     */
+    public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
+        Class<?>[] ptypes = mt.ptypes();
+        Class<?>[] ptc = MethodTypeForm.canonicalizeAll(ptypes, howArgs);
+        Class<?> rtype = mt.returnType();
+        Class<?> rtc = MethodTypeForm.canonicalize(rtype, howRet);
+        if (ptc == null && rtc == null) {
+            // It is already canonical.
+            return null;
+        }
+        // Find the erased version of the method type:
+        if (rtc == null)  rtc = rtype;
+        if (ptc == null)  ptc = ptypes;
+        return MethodType.makeImpl(rtc, ptc, true);
+    }
+
+    /** Canonicalize the given return or param type.
+     *  Return null if the type is already canonicalized.
+     */
+    static Class<?> canonicalize(Class<?> t, int how) {
+        Class<?> ct;
+        if (t == Object.class) {
+            // no change, ever
+        } else if (!t.isPrimitive()) {
+            switch (how) {
+                case UNWRAP:
+                    ct = Wrapper.asPrimitiveType(t);
+                    if (ct != t)  return ct;
+                    break;
+                case RAW_RETURN:
+                case ERASE:
+                    return Object.class;
+            }
+        } else if (t == void.class) {
+            // no change, usually
+            switch (how) {
+                case RAW_RETURN:
+                    return int.class;
+                case WRAP:
+                    return Void.class;
+            }
+        } else {
+            // non-void primitive
+            switch (how) {
+                case WRAP:
+                    return Wrapper.asWrapperType(t);
+                case INTS:
+                    if (t == int.class || t == long.class)
+                        return null;  // no change
+                    if (t == double.class)
+                        return long.class;
+                    return int.class;
+                case LONGS:
+                    if (t == long.class)
+                        return null;  // no change
+                    return long.class;
+                case RAW_RETURN:
+                    if (t == int.class || t == long.class ||
+                        t == float.class || t == double.class)
+                        return null;  // no change
+                    // everything else returns as an int
+                    return int.class;
+            }
+        }
+        // no change; return null to signify
+        return null;
+    }
+
+    /** Canonicalize each param type in the given array.
+     *  Return null if all types are already canonicalized.
+     */
+    static Class<?>[] canonicalizeAll(Class<?>[] ts, int how) {
+        Class<?>[] cs = null;
+        for (int imax = ts.length, i = 0; i < imax; i++) {
+            Class<?> c = canonicalize(ts[i], how);
+            if (c == void.class)
+                c = null;  // a Void parameter was unwrapped to void; ignore
+            if (c != null) {
+                if (cs == null)
+                    cs = ts.clone();
+                cs[i] = c;
+            }
+        }
+        return cs;
+    }
+
+    @Override
+    public String toString() {
+        return "Form"+erasedType;
+    }
+}
diff --git a/ojluni/src/main/java/java/lang/invoke/Stable.java b/ojluni/src/main/java/java/lang/invoke/Stable.java
new file mode 100644
index 0000000..077c546
--- /dev/null
+++ b/ojluni/src/main/java/java/lang/invoke/Stable.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import java.lang.annotation.*;
+
+/**
+ * A field may be annotated as stable if all of its component variables
+ * changes value at most once.
+ * A field's value counts as its component value.
+ * If the field is typed as an array, then all the non-null components
+ * of the array, of depth up to the rank of the field's array type,
+ * also count as component values.
+ * By extension, any variable (either array or field) which has annotated
+ * as stable is called a stable variable, and its non-null or non-zero
+ * value is called a stable value.
+ * <p>
+ * Since all fields begin with a default value of null for references
+ * (resp., zero for primitives), it follows that this annotation indicates
+ * that the first non-null (resp., non-zero) value stored in the field
+ * will never be changed.
+ * <p>
+ * If the field is not of an array type, there are no array elements,
+ * then the value indicated as stable is simply the value of the field.
+ * If the dynamic type of the field value is an array but the static type
+ * is not, the components of the array are <em>not</em> regarded as stable.
+ * <p>
+ * If the field is an array type, then both the field value and
+ * all the components of the field value (if the field value is non-null)
+ * are indicated to be stable.
+ * If the field type is an array type with rank {@code N &gt; 1},
+ * then each component of the field value (if the field value is non-null),
+ * is regarded as a stable array of rank {@code N-1}.
+ * <p>
+ * Fields which are declared {@code final} may also be annotated as stable.
+ * Since final fields already behave as stable values, such an annotation
+ * indicates no additional information, unless the type of the field is
+ * an array type.
+ * <p>
+ * It is (currently) undefined what happens if a field annotated as stable
+ * is given a third value.  In practice, if the JVM relies on this annotation
+ * to promote a field reference to a constant, it may be that the Java memory
+ * model would appear to be broken, if such a constant (the second value of the field)
+ * is used as the value of the field even after the field value has changed.
+ */
+/* package-private */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Stable {
+}
diff --git a/ojluni/src/main/java/sun/invoke/empty/Empty.java b/ojluni/src/main/java/sun/invoke/empty/Empty.java
new file mode 100644
index 0000000..f75d2b3
--- /dev/null
+++ b/ojluni/src/main/java/sun/invoke/empty/Empty.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.invoke.empty;
+
+/**
+ * An empty class in an empty package.
+ * Used as a proxy for unprivileged code, since making access checks
+ * against it will only succeed against public methods in public types.
+ * <p>
+ * This class also stands (internally to sun.invoke) for the type of a
+ * value that cannot be produced, because the expression of this type
+ * always returns abnormally.  (Cf. Nothing in the closures proposal.)
+ * @author jrose
+ */
+public class Empty {
+    private Empty() { throw new InternalError(); }
+}
diff --git a/ojluni/src/main/java/sun/invoke/util/BytecodeDescriptor.java b/ojluni/src/main/java/sun/invoke/util/BytecodeDescriptor.java
new file mode 100644
index 0000000..ccc313c
--- /dev/null
+++ b/ojluni/src/main/java/sun/invoke/util/BytecodeDescriptor.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.invoke.util;
+
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility routines for dealing with bytecode-level signatures.
+ * @author jrose
+ */
+public class BytecodeDescriptor {
+
+    private BytecodeDescriptor() { }  // cannot instantiate
+
+    public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
+        return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
+    }
+
+    static List<Class<?>> parseMethod(String bytecodeSignature,
+            int start, int end, ClassLoader loader) {
+        if (loader == null)
+            loader = ClassLoader.getSystemClassLoader();
+        String str = bytecodeSignature;
+        int[] i = {start};
+        ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();
+        if (i[0] < end && str.charAt(i[0]) == '(') {
+            ++i[0];  // skip '('
+            while (i[0] < end && str.charAt(i[0]) != ')') {
+                Class<?> pt = parseSig(str, i, end, loader);
+                if (pt == null || pt == void.class)
+                    parseError(str, "bad argument type");
+                ptypes.add(pt);
+            }
+            ++i[0];  // skip ')'
+        } else {
+            parseError(str, "not a method type");
+        }
+        Class<?> rtype = parseSig(str, i, end, loader);
+        if (rtype == null || i[0] != end)
+            parseError(str, "bad return type");
+        ptypes.add(rtype);
+        return ptypes;
+    }
+
+    static private void parseError(String str, String msg) {
+        throw new IllegalArgumentException("bad signature: "+str+": "+msg);
+    }
+
+    static private Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {
+        if (i[0] == end)  return null;
+        char c = str.charAt(i[0]++);
+        if (c == 'L') {
+            int begc = i[0], endc = str.indexOf(';', begc);
+            if (endc < 0)  return null;
+            i[0] = endc+1;
+            String name = str.substring(begc, endc).replace('/', '.');
+            try {
+                return loader.loadClass(name);
+            } catch (ClassNotFoundException ex) {
+                throw new TypeNotPresentException(name, ex);
+            }
+        } else if (c == '[') {
+            Class<?> t = parseSig(str, i, end, loader);
+            if (t != null)
+                t = java.lang.reflect.Array.newInstance(t, 0).getClass();
+            return t;
+        } else {
+            return Wrapper.forBasicType(c).primitiveType();
+        }
+    }
+
+    public static String unparse(Class<?> type) {
+        StringBuilder sb = new StringBuilder();
+        unparseSig(type, sb);
+        return sb.toString();
+    }
+
+    public static String unparse(MethodType type) {
+        return unparseMethod(type.returnType(), type.parameterList());
+    }
+
+    public static String unparse(Object type) {
+        if (type instanceof Class<?>)
+            return unparse((Class<?>) type);
+        if (type instanceof MethodType)
+            return unparse((MethodType) type);
+        return (String) type;
+    }
+
+    public static String unparseMethod(Class<?> rtype, List<Class<?>> ptypes) {
+        StringBuilder sb = new StringBuilder();
+        sb.append('(');
+        for (Class<?> pt : ptypes)
+            unparseSig(pt, sb);
+        sb.append(')');
+        unparseSig(rtype, sb);
+        return sb.toString();
+    }
+
+    static private void unparseSig(Class<?> t, StringBuilder sb) {
+        char c = Wrapper.forBasicType(t).basicTypeChar();
+        if (c != 'L') {
+            sb.append(c);
+        } else {
+            boolean lsemi = (!t.isArray());
+            if (lsemi)  sb.append('L');
+            sb.append(t.getName().replace('.', '/'));
+            if (lsemi)  sb.append(';');
+        }
+    }
+
+}
diff --git a/ojluni/src/main/java/sun/invoke/util/Wrapper.java b/ojluni/src/main/java/sun/invoke/util/Wrapper.java
new file mode 100644
index 0000000..0a0d04b
--- /dev/null
+++ b/ojluni/src/main/java/sun/invoke/util/Wrapper.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.invoke.util;
+
+public enum Wrapper {
+    //        wrapperType    primitiveType  char            zero         emptyArray          format
+    BOOLEAN(  Boolean.class, boolean.class, 'Z',      (Boolean)false, new boolean[0], Format.unsigned( 1)),
+    // These must be in the order defined for widening primitive conversions in JLS 5.1.2
+    BYTE   (     Byte.class,    byte.class, 'B',       (Byte)(byte)0, new    byte[0], Format.signed(   8)),
+    SHORT  (    Short.class,   short.class, 'S',     (Short)(short)0, new   short[0], Format.signed(  16)),
+    CHAR   (Character.class,    char.class, 'C',  (Character)(char)0, new    char[0], Format.unsigned(16)),
+    INT    (  Integer.class,     int.class, 'I', (Integer)/*(int)*/0, new     int[0], Format.signed(  32)),
+    LONG   (     Long.class,    long.class, 'J',       (Long)(long)0, new    long[0], Format.signed(  64)),
+    FLOAT  (    Float.class,   float.class, 'F',     (Float)(float)0, new   float[0], Format.floating(32)),
+    DOUBLE (   Double.class,  double.class, 'D',   (Double)(double)0, new  double[0], Format.floating(64)),
+    OBJECT (   Object.class,  Object.class, 'L',                null, new  Object[0], Format.other(    1)),
+    // VOID must be the last type, since it is "assignable" from any other type:
+    VOID   (     Void.class,    void.class, 'V',                null,           null, Format.other(    0)),
+    ;
+
+    private final Class<?> wrapperType;
+    private final Class<?> primitiveType;
+    private final char     basicTypeChar;
+    private final Object   zero;
+    private final Object   emptyArray;
+    private final int      format;
+    private final String   wrapperSimpleName;
+    private final String   primitiveSimpleName;
+
+    private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, Object emptyArray, int format) {
+        this.wrapperType = wtype;
+        this.primitiveType = ptype;
+        this.basicTypeChar = tchar;
+        this.zero = zero;
+        this.emptyArray = emptyArray;
+        this.format = format;
+        this.wrapperSimpleName = wtype.getSimpleName();
+        this.primitiveSimpleName = ptype.getSimpleName();
+    }
+
+    /** For debugging, give the details of this wrapper. */
+    public String detailString() {
+        return wrapperSimpleName+
+                java.util.Arrays.asList(wrapperType, primitiveType,
+                basicTypeChar, zero,
+                "0x"+Integer.toHexString(format));
+    }
+
+    private static abstract class Format {
+        static final int SLOT_SHIFT = 0, SIZE_SHIFT = 2, KIND_SHIFT = 12;
+        static final int
+                SIGNED   = (-1) << KIND_SHIFT,
+                UNSIGNED = 0    << KIND_SHIFT,
+                FLOATING = 1    << KIND_SHIFT;
+        static final int
+                SLOT_MASK = ((1<<(SIZE_SHIFT-SLOT_SHIFT))-1),
+                SIZE_MASK = ((1<<(KIND_SHIFT-SIZE_SHIFT))-1);
+        static int format(int kind, int size, int slots) {
+            assert(((kind >> KIND_SHIFT) << KIND_SHIFT) == kind);
+            assert((size & (size-1)) == 0); // power of two
+            assert((kind == SIGNED)   ? (size > 0) :
+                   (kind == UNSIGNED) ? (size > 0) :
+                   (kind == FLOATING) ? (size == 32 || size == 64)  :
+                   false);
+            assert((slots == 2) ? (size == 64) :
+                   (slots == 1) ? (size <= 32) :
+                   false);
+            return kind | (size << SIZE_SHIFT) | (slots << SLOT_SHIFT);
+        }
+        static final int
+                INT      = SIGNED   | (32 << SIZE_SHIFT) | (1 << SLOT_SHIFT),
+                SHORT    = SIGNED   | (16 << SIZE_SHIFT) | (1 << SLOT_SHIFT),
+                BOOLEAN  = UNSIGNED | (1  << SIZE_SHIFT) | (1 << SLOT_SHIFT),
+                CHAR     = UNSIGNED | (16 << SIZE_SHIFT) | (1 << SLOT_SHIFT),
+                FLOAT    = FLOATING | (32 << SIZE_SHIFT) | (1 << SLOT_SHIFT),
+                VOID     = UNSIGNED | (0  << SIZE_SHIFT) | (0 << SLOT_SHIFT),
+                NUM_MASK = (-1) << SIZE_SHIFT;
+        static int signed(int size)   { return format(SIGNED,   size, (size > 32 ? 2 : 1)); }
+        static int unsigned(int size) { return format(UNSIGNED, size, (size > 32 ? 2 : 1)); }
+        static int floating(int size) { return format(FLOATING, size, (size > 32 ? 2 : 1)); }
+        static int other(int slots)   { return slots << SLOT_SHIFT; }
+    }
+
+    /// format queries:
+
+    /** How many bits are in the wrapped value?  Returns 0 for OBJECT or VOID. */
+    public int     bitWidth()      { return (format >> Format.SIZE_SHIFT) & Format.SIZE_MASK; }
+    /** How many JVM stack slots occupied by the wrapped value?  Returns 0 for VOID. */
+    public int     stackSlots()    { return (format >> Format.SLOT_SHIFT) & Format.SLOT_MASK; }
+    /** Does the wrapped value occupy a single JVM stack slot? */
+    public boolean isSingleWord()  { return (format & (1 << Format.SLOT_SHIFT)) != 0; }
+    /** Does the wrapped value occupy two JVM stack slots? */
+    public boolean isDoubleWord()  { return (format & (2 << Format.SLOT_SHIFT)) != 0; }
+    /** Is the wrapped type numeric (not void or object)? */
+    public boolean isNumeric()     { return (format & Format.NUM_MASK) != 0; }
+    /** Is the wrapped type a primitive other than float, double, or void? */
+    public boolean isIntegral()    { return isNumeric() && format < Format.FLOAT; }
+    /** Is the wrapped type one of int, boolean, byte, char, or short? */
+    public boolean isSubwordOrInt() { return isIntegral() && isSingleWord(); }
+    /* Is the wrapped value a signed integral type (one of byte, short, int, or long)? */
+    public boolean isSigned()      { return format < Format.VOID; }
+    /* Is the wrapped value an unsigned integral type (one of boolean or char)? */
+    public boolean isUnsigned()    { return format >= Format.BOOLEAN && format < Format.FLOAT; }
+    /** Is the wrapped type either float or double? */
+    public boolean isFloating()    { return format >= Format.FLOAT; }
+    /** Is the wrapped type either void or a reference? */
+    public boolean isOther()       { return (format & ~Format.SLOT_MASK) == 0; }
+
+    /** Does the JLS 5.1.2 allow a variable of this wrapper's
+     *  primitive type to be assigned from a value of the given wrapper's primitive type?
+     *  Cases:
+     *  <ul>
+     *  <li>unboxing followed by widening primitive conversion
+     *  <li>any type converted to {@code void} (i.e., dropping a method call's value)
+     *  <li>boxing conversion followed by widening reference conversion to {@code Object}
+     *  </ul>
+     *  These are the cases allowed by MethodHandle.asType.
+     */
+    public boolean isConvertibleFrom(Wrapper source) {
+        if (this == source)  return true;
+        if (this.compareTo(source) < 0) {
+            // At best, this is a narrowing conversion.
+            return false;
+        }
+        // All conversions are allowed in the enum order between floats and signed ints.
+        // First detect non-signed non-float types (boolean, char, Object, void).
+        boolean floatOrSigned = (((this.format & source.format) & Format.SIGNED) != 0);
+        if (!floatOrSigned) {
+            if (this.isOther())  return true;
+            // can convert char to int or wider, but nothing else
+            if (source.format == Format.CHAR)  return true;
+            // no other conversions are classified as widening
+            return false;
+        }
+        // All signed and float conversions in the enum order are widening.
+        assert(this.isFloating() || this.isSigned());
+        assert(source.isFloating() || source.isSigned());
+        return true;
+    }
+
+    static { assert(checkConvertibleFrom()); }
+    private static boolean checkConvertibleFrom() {
+        // Check the matrix for correct classification of widening conversions.
+        for (Wrapper w : values()) {
+            assert(w.isConvertibleFrom(w));
+            assert(VOID.isConvertibleFrom(w));
+            if (w != VOID) {
+                assert(OBJECT.isConvertibleFrom(w));
+                assert(!w.isConvertibleFrom(VOID));
+            }
+            // check relations with unsigned integral types:
+            if (w != CHAR) {
+                assert(!CHAR.isConvertibleFrom(w));
+                if (!w.isConvertibleFrom(INT))
+                    assert(!w.isConvertibleFrom(CHAR));
+            }
+            if (w != BOOLEAN) {
+                assert(!BOOLEAN.isConvertibleFrom(w));
+                if (w != VOID && w != OBJECT)
+                    assert(!w.isConvertibleFrom(BOOLEAN));
+            }
+            // check relations with signed integral types:
+            if (w.isSigned()) {
+                for (Wrapper x : values()) {
+                    if (w == x)  continue;
+                    if (x.isFloating())
+                        assert(!w.isConvertibleFrom(x));
+                    else if (x.isSigned()) {
+                        if (w.compareTo(x) < 0)
+                            assert(!w.isConvertibleFrom(x));
+                        else
+                            assert(w.isConvertibleFrom(x));
+                    }
+                }
+            }
+            // check relations with floating types:
+            if (w.isFloating()) {
+                for (Wrapper x : values()) {
+                    if (w == x)  continue;
+                    if (x.isSigned())
+                        assert(w.isConvertibleFrom(x));
+                    else if (x.isFloating()) {
+                        if (w.compareTo(x) < 0)
+                            assert(!w.isConvertibleFrom(x));
+                        else
+                            assert(w.isConvertibleFrom(x));
+                    }
+                }
+            }
+        }
+        return true;  // i.e., assert(true)
+    }
+
+    /** Produce a zero value for the given wrapper type.
+     *  This will be a numeric zero for a number or character,
+     *  false for a boolean, and null for a reference or void.
+     *  The common thread is that this is what is contained
+     *  in a default-initialized variable of the given primitive
+     *  type.  (For void, it is what a reflective method returns
+     *  instead of no value at all.)
+     */
+    public Object zero() { return zero; }
+
+    /** Produce a zero value for the given wrapper type T.
+     *  The optional argument must a type compatible with this wrapper.
+     *  Equivalent to {@code this.cast(this.zero(), type)}.
+     */
+    public <T> T zero(Class<T> type) { return convert(zero, type); }
+
+    /** Return the wrapper that wraps values of the given type.
+     *  The type may be {@code Object}, meaning the {@code OBJECT} wrapper.
+     *  Otherwise, the type must be a primitive.
+     *  @throws IllegalArgumentException for unexpected types
+     */
+    public static Wrapper forPrimitiveType(Class<?> type) {
+        Wrapper w = findPrimitiveType(type);
+        if (w != null)  return w;
+        if (type.isPrimitive())
+            throw new InternalError(); // redo hash function
+        throw newIllegalArgumentException("not primitive: "+type);
+    }
+
+    static Wrapper findPrimitiveType(Class<?> type) {
+        Wrapper w = FROM_PRIM[hashPrim(type)];
+        if (w != null && w.primitiveType == type) {
+            return w;
+        }
+        return null;
+    }
+
+    /** Return the wrapper that wraps values into the given wrapper type.
+     *  If it is {@code Object}, return {@code OBJECT}.
+     *  Otherwise, it must be a wrapper type.
+     *  The type must not be a primitive type.
+     *  @throws IllegalArgumentException for unexpected types
+     */
+    public static Wrapper forWrapperType(Class<?> type) {
+        Wrapper w = findWrapperType(type);
+        if (w != null)  return w;
+        for (Wrapper x : values())
+            if (x.wrapperType == type)
+                throw new InternalError(); // redo hash function
+        throw newIllegalArgumentException("not wrapper: "+type);
+    }
+
+    static Wrapper findWrapperType(Class<?> type) {
+        Wrapper w = FROM_WRAP[hashWrap(type)];
+        if (w != null && w.wrapperType == type) {
+            return w;
+        }
+        return null;
+    }
+
+    /** Return the wrapper that corresponds to the given bytecode
+     *  signature character.  Return {@code OBJECT} for the character 'L'.
+     *  @throws IllegalArgumentException for any non-signature character or {@code '['}.
+     */
+    public static Wrapper forBasicType(char type) {
+        Wrapper w = FROM_CHAR[hashChar(type)];
+        if (w != null && w.basicTypeChar == type) {
+            return w;
+        }
+        for (Wrapper x : values())
+            if (w.basicTypeChar == type)
+                throw new InternalError(); // redo hash function
+        throw newIllegalArgumentException("not basic type char: "+type);
+    }
+
+    /** Return the wrapper for the given type, if it is
+     *  a primitive type, else return {@code OBJECT}.
+     */
+    public static Wrapper forBasicType(Class<?> type) {
+        if (type.isPrimitive())
+            return forPrimitiveType(type);
+        return OBJECT;  // any reference, including wrappers or arrays
+    }
+
+    // Note on perfect hashes:
+    //   for signature chars c, do (c + (c >> 1)) % 16
+    //   for primitive type names n, do (n[0] + n[2]) % 16
+    // The type name hash works for both primitive and wrapper names.
+    // You can add "java/lang/Object" to the primitive names.
+    // But you add the wrapper name Object, use (n[2] + (3*n[1])) % 16.
+    private static final Wrapper[] FROM_PRIM = new Wrapper[16];
+    private static final Wrapper[] FROM_WRAP = new Wrapper[16];
+    private static final Wrapper[] FROM_CHAR = new Wrapper[16];
+    private static int hashPrim(Class<?> x) {
+        String xn = x.getName();
+        if (xn.length() < 3)  return 0;
+        return (xn.charAt(0) + xn.charAt(2)) % 16;
+    }
+    private static int hashWrap(Class<?> x) {
+        String xn = x.getName();
+        final int offset = 10; assert(offset == "java.lang.".length());
+        if (xn.length() < offset+3)  return 0;
+        return (3*xn.charAt(offset+1) + xn.charAt(offset+2)) % 16;
+    }
+    private static int hashChar(char x) {
+        return (x + (x >> 1)) % 16;
+    }
+    static {
+        for (Wrapper w : values()) {
+            int pi = hashPrim(w.primitiveType);
+            int wi = hashWrap(w.wrapperType);
+            int ci = hashChar(w.basicTypeChar);
+            assert(FROM_PRIM[pi] == null);
+            assert(FROM_WRAP[wi] == null);
+            assert(FROM_CHAR[ci] == null);
+            FROM_PRIM[pi] = w;
+            FROM_WRAP[wi] = w;
+            FROM_CHAR[ci] = w;
+        }
+        //assert(jdk.sun.invoke.util.WrapperTest.test(false));
+    }
+
+    /** What is the primitive type wrapped by this wrapper? */
+    public Class<?> primitiveType() { return primitiveType; }
+
+    /** What is the wrapper type for this wrapper? */
+    public Class<?> wrapperType() { return wrapperType; }
+
+    /** What is the wrapper type for this wrapper?
+     * Otherwise, the example type must be the wrapper type,
+     * or the corresponding primitive type.
+     * (For {@code OBJECT}, the example type can be any non-primitive,
+     * and is normalized to {@code Object.class}.)
+     * The resulting class type has the same type parameter.
+     */
+    public <T> Class<T> wrapperType(Class<T> exampleType) {
+        if (exampleType == wrapperType) {
+            return exampleType;
+        } else if (exampleType == primitiveType ||
+                   wrapperType == Object.class ||
+                   exampleType.isInterface()) {
+            return forceType(wrapperType, exampleType);
+        }
+        throw newClassCastException(exampleType, primitiveType);
+    }
+
+    private static ClassCastException newClassCastException(Class<?> actual, Class<?> expected) {
+        return new ClassCastException(actual + " is not compatible with " + expected);
+    }
+
+    /** If {@code type} is a primitive type, return the corresponding
+     *  wrapper type, else return {@code type} unchanged.
+     */
+    public static <T> Class<T> asWrapperType(Class<T> type) {
+        if (type.isPrimitive()) {
+            return forPrimitiveType(type).wrapperType(type);
+        }
+        return type;
+    }
+
+    /** If {@code type} is a wrapper type, return the corresponding
+     *  primitive type, else return {@code type} unchanged.
+     */
+    public static <T> Class<T> asPrimitiveType(Class<T> type) {
+        Wrapper w = findWrapperType(type);
+        if (w != null) {
+            return forceType(w.primitiveType(), type);
+        }
+        return type;
+    }
+
+    /** Query:  Is the given type a wrapper, such as {@code Integer} or {@code Void}? */
+    public static boolean isWrapperType(Class<?> type) {
+        return findWrapperType(type) != null;
+    }
+
+    /** Query:  Is the given type a primitive, such as {@code int} or {@code void}? */
+    public static boolean isPrimitiveType(Class<?> type) {
+        return type.isPrimitive();
+    }
+
+    /** What is the bytecode signature character for this type?
+     *  All non-primitives, including array types, report as 'L', the signature character for references.
+     */
+    public static char basicTypeChar(Class<?> type) {
+        if (!type.isPrimitive())
+            return 'L';
+        else
+            return forPrimitiveType(type).basicTypeChar();
+    }
+
+    /** What is the bytecode signature character for this wrapper's
+     *  primitive type?
+     */
+    public char basicTypeChar() { return basicTypeChar; }
+
+    /** What is the simple name of the wrapper type?
+     */
+    public String wrapperSimpleName() { return wrapperSimpleName; }
+
+    /** What is the simple name of the primitive type?
+     */
+    public String primitiveSimpleName() { return primitiveSimpleName; }
+
+//    /** Wrap a value in the given type, which may be either a primitive or wrapper type.
+//     *  Performs standard primitive conversions, including truncation and float conversions.
+//     */
+//    public static <T> T wrap(Object x, Class<T> type) {
+//        return Wrapper.valueOf(type).cast(x, type);
+//    }
+
+    /** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
+     *  The given target type must be this wrapper's primitive or wrapper type.
+     *  If this wrapper is OBJECT, the target type may also be an interface, perform no runtime check.
+     *  Performs standard primitive conversions, including truncation and float conversions.
+     *  The given type must be compatible with this wrapper.  That is, it must either
+     *  be the wrapper type (or a subtype, in the case of {@code OBJECT}) or else
+     *  it must be the wrapper's primitive type.
+     *  Primitive conversions are only performed if the given type is itself a primitive.
+     *  @throws ClassCastException if the given type is not compatible with this wrapper
+     */
+    public <T> T cast(Object x, Class<T> type) {
+        return convert(x, type, true);
+    }
+
+    /** Convert a wrapped value to the given type.
+     *  The given target type must be this wrapper's primitive or wrapper type.
+     *  This is equivalent to {@link #cast}, except that it refuses to perform
+     *  narrowing primitive conversions.
+     */
+    public <T> T convert(Object x, Class<T> type) {
+        return convert(x, type, false);
+    }
+
+    private <T> T convert(Object x, Class<T> type, boolean isCast) {
+        if (this == OBJECT) {
+            // If the target wrapper is OBJECT, just do a reference cast.
+            // If the target type is an interface, perform no runtime check.
+            // (This loophole is safe, and is allowed by the JVM verifier.)
+            // If the target type is a primitive, change it to a wrapper.
+            assert(!type.isPrimitive());
+            if (!type.isInterface())
+                type.cast(x);
+            @SuppressWarnings("unchecked")
+            T result = (T) x;  // unchecked warning is expected here
+            return result;
+        }
+        Class<T> wtype = wrapperType(type);
+        if (wtype.isInstance(x)) {
+            return wtype.cast(x);
+        }
+        if (!isCast) {
+            Class<?> sourceType = x.getClass();  // throw NPE if x is null
+            Wrapper source = findWrapperType(sourceType);
+            if (source == null || !this.isConvertibleFrom(source)) {
+                throw newClassCastException(wtype, sourceType);
+            }
+        } else if (x == null) {
+            @SuppressWarnings("unchecked")
+            T z = (T) zero;
+            return z;
+        }
+        @SuppressWarnings("unchecked")
+        T result = (T) wrap(x);  // unchecked warning is expected here
+        assert (result == null ? Void.class : result.getClass()) == wtype;
+        return result;
+    }
+
+    /** Cast a reference type to another reference type.
+     * If the target type is an interface, perform no runtime check.
+     * (This loophole is safe, and is allowed by the JVM verifier.)
+     * If the target type is a primitive, change it to a wrapper.
+     */
+    static <T> Class<T> forceType(Class<?> type, Class<T> exampleType) {
+        boolean z = (type == exampleType ||
+               type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
+               exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
+               type == Object.class && !exampleType.isPrimitive());
+        if (!z)
+            System.out.println(type+" <= "+exampleType);
+        assert(type == exampleType ||
+               type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
+               exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
+               type == Object.class && !exampleType.isPrimitive());
+        @SuppressWarnings("unchecked")
+        Class<T> result = (Class<T>) type;  // unchecked warning is expected here
+        return result;
+    }
+
+    /** Wrap a value in this wrapper's type.
+     * Performs standard primitive conversions, including truncation and float conversions.
+     * Performs returns the unchanged reference for {@code OBJECT}.
+     * Returns null for {@code VOID}.
+     * Returns a zero value for a null input.
+     * @throws ClassCastException if this wrapper is numeric and the operand
+     *                            is not a number, character, boolean, or null
+     */
+    public Object wrap(Object x) {
+        // do non-numeric wrappers first
+        switch (basicTypeChar) {
+            case 'L': return x;
+            case 'V': return null;
+        }
+        Number xn = numberValue(x);
+        switch (basicTypeChar) {
+            case 'I': return Integer.valueOf(xn.intValue());
+            case 'J': return Long.valueOf(xn.longValue());
+            case 'F': return Float.valueOf(xn.floatValue());
+            case 'D': return Double.valueOf(xn.doubleValue());
+            case 'S': return Short.valueOf((short) xn.intValue());
+            case 'B': return Byte.valueOf((byte) xn.intValue());
+            case 'C': return Character.valueOf((char) xn.intValue());
+            case 'Z': return Boolean.valueOf(boolValue(xn.byteValue()));
+        }
+        throw new InternalError("bad wrapper");
+    }
+
+    /** Wrap a value (an int or smaller value) in this wrapper's type.
+     * Performs standard primitive conversions, including truncation and float conversions.
+     * Produces an {@code Integer} for {@code OBJECT}, although the exact type
+     * of the operand is not known.
+     * Returns null for {@code VOID}.
+     */
+    public Object wrap(int x) {
+        if (basicTypeChar == 'L')  return (Integer)x;
+        switch (basicTypeChar) {
+            case 'L': throw newIllegalArgumentException("cannot wrap to object type");
+            case 'V': return null;
+            case 'I': return Integer.valueOf(x);
+            case 'J': return Long.valueOf(x);
+            case 'F': return Float.valueOf(x);
+            case 'D': return Double.valueOf(x);
+            case 'S': return Short.valueOf((short) x);
+            case 'B': return Byte.valueOf((byte) x);
+            case 'C': return Character.valueOf((char) x);
+            case 'Z': return Boolean.valueOf(boolValue((byte) x));
+        }
+        throw new InternalError("bad wrapper");
+    }
+
+    private static Number numberValue(Object x) {
+        if (x instanceof Number)     return (Number)x;
+        if (x instanceof Character)  return (int)(Character)x;
+        if (x instanceof Boolean)    return (Boolean)x ? 1 : 0;
+        // Remaining allowed case of void:  Must be a null reference.
+        return (Number)x;
+    }
+
+    // Parameter type of boolValue must be byte, because
+    // MethodHandles.explicitCastArguments defines boolean
+    // conversion as first converting to byte.
+    private static boolean boolValue(byte bits) {
+        bits &= 1;  // simple 31-bit zero extension
+        return (bits != 0);
+    }
+
+    private static RuntimeException newIllegalArgumentException(String message, Object x) {
+        return newIllegalArgumentException(message + x);
+    }
+    private static RuntimeException newIllegalArgumentException(String message) {
+        return new IllegalArgumentException(message);
+    }
+
+    // primitive array support
+    public Object makeArray(int len) {
+        return java.lang.reflect.Array.newInstance(primitiveType, len);
+    }
+    public Class<?> arrayType() {
+        return emptyArray.getClass();
+    }
+    public void copyArrayUnboxing(Object[] values, int vpos, Object a, int apos, int length) {
+        if (a.getClass() != arrayType())
+            arrayType().cast(a);  // throw NPE or CCE if bad type
+        for (int i = 0; i < length; i++) {
+            Object value = values[i+vpos];
+            value = convert(value, primitiveType);
+            java.lang.reflect.Array.set(a, i+apos, value);
+        }
+    }
+    public void copyArrayBoxing(Object a, int apos, Object[] values, int vpos, int length) {
+        if (a.getClass() != arrayType())
+            arrayType().cast(a);  // throw NPE or CCE if bad type
+        for (int i = 0; i < length; i++) {
+            Object value = java.lang.reflect.Array.get(a, i+apos);
+            //Already done: value = convert(value, primitiveType);
+            assert(value.getClass() == wrapperType);
+            values[i+vpos] = value;
+        }
+    }
+}
diff --git a/ojluni/src/main/java/sun/invoke/util/package-info.java b/ojluni/src/main/java/sun/invoke/util/package-info.java
new file mode 100644
index 0000000..785ca80
--- /dev/null
+++ b/ojluni/src/main/java/sun/invoke/util/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Extra support for using JSR 292 RI, package java.lang.invoke.
+ * @author jrose
+ */
+
+package sun.invoke.util;
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 69cf00c..3255c64 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1151,6 +1151,10 @@
     ojluni/src/main/java/sun/misc/FDBigInteger.java \
     ojluni/src/main/java/sun/misc/FloatingDecimal.java \
     ojluni/src/main/java/java/lang/invoke/LambdaConversionException.java \
+    ojluni/src/main/java/java/lang/invoke/MethodHandleStatics.java \
+    ojluni/src/main/java/java/lang/invoke/MethodType.java \
+    ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java \
+    ojluni/src/main/java/java/lang/invoke/Stable.java \
     ojluni/src/main/java/java/lang/invoke/WrongMethodTypeException.java \
     ojluni/src/main/java/java/text/spi/BreakIteratorProvider.java \
     ojluni/src/main/java/java/text/spi/CollatorProvider.java \
@@ -1166,6 +1170,9 @@
     ojluni/src/main/java/jdk/net/NetworkPermission.java \
     ojluni/src/main/java/jdk/net/SocketFlow.java \
     ojluni/src/main/java/jdk/net/Sockets.java \
+    ojluni/src/main/java/sun/invoke/empty/Empty.java \
+    ojluni/src/main/java/sun/invoke/util/BytecodeDescriptor.java \
+    ojluni/src/main/java/sun/invoke/util/Wrapper.java \
     ojluni/src/main/java/sun/misc/ASCIICaseInsensitiveComparator.java \
     ojluni/src/main/java/sun/misc/BASE64Decoder.java \
     ojluni/src/main/java/sun/misc/BASE64Encoder.java \
@@ -1608,5 +1615,4 @@
     ojluni/src/lambda/java/java/lang/invoke/MethodHandle.java \
     ojluni/src/lambda/java/java/lang/invoke/MethodHandleInfo.java \
     ojluni/src/lambda/java/java/lang/invoke/MethodHandles.java \
-    ojluni/src/lambda/java/java/lang/invoke/MethodType.java \
     ojluni/src/lambda/java/java/lang/invoke/SerializedLambda.java \
