Automatic sources dropoff on 2020-06-10 18:32:38.095721

The change is generated with prebuilt drop tool.

Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/java/lang/AbstractMethodError.java b/java/lang/AbstractMethodError.java
new file mode 100644
index 0000000..e266107
--- /dev/null
+++ b/java/lang/AbstractMethodError.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when an application tries to call an abstract method.
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of some class has
+ * incompatibly changed since the currently executing method was last
+ * compiled.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class AbstractMethodError extends IncompatibleClassChangeError {
+    private static final long serialVersionUID = -1654391082989018462L;
+
+    /**
+     * Constructs an <code>AbstractMethodError</code> with no detail  message.
+     */
+    public AbstractMethodError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>AbstractMethodError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public AbstractMethodError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/AbstractStringBuilder.java b/java/lang/AbstractStringBuilder.java
new file mode 100644
index 0000000..4c31e23
--- /dev/null
+++ b/java/lang/AbstractStringBuilder.java
@@ -0,0 +1,1466 @@
+/*
+ * Copyright (c) 2003, 2016, 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;
+
+import sun.misc.FloatingDecimal;
+import java.util.Arrays;
+
+/**
+ * A mutable sequence of characters.
+ * <p>
+ * Implements a modifiable string. At any point in time it contains some
+ * particular sequence of characters, but the length and content of the
+ * sequence can be changed through certain method calls.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author      Michael McCloskey
+ * @author      Martin Buchholz
+ * @author      Ulf Zibis
+ * @since       1.5
+ */
+abstract class AbstractStringBuilder implements Appendable, CharSequence {
+    /**
+     * The value is used for character storage.
+     */
+    char[] value;
+
+    /**
+     * The count is the number of characters used.
+     */
+    int count;
+
+    /**
+     * This no-arg constructor is necessary for serialization of subclasses.
+     */
+    AbstractStringBuilder() {
+    }
+
+    /**
+     * Creates an AbstractStringBuilder of the specified capacity.
+     */
+    AbstractStringBuilder(int capacity) {
+        value = new char[capacity];
+    }
+
+    /**
+     * Returns the length (character count).
+     *
+     * @return  the length of the sequence of characters currently
+     *          represented by this object
+     */
+    @Override
+    public int length() {
+        return count;
+    }
+
+    /**
+     * Returns the current capacity. The capacity is the amount of storage
+     * available for newly inserted characters, beyond which an allocation
+     * will occur.
+     *
+     * @return  the current capacity
+     */
+    public int capacity() {
+        return value.length;
+    }
+
+    /**
+     * Ensures that the capacity is at least equal to the specified minimum.
+     * If the current capacity is less than the argument, then a new internal
+     * array is allocated with greater capacity. The new capacity is the
+     * larger of:
+     * <ul>
+     * <li>The {@code minimumCapacity} argument.
+     * <li>Twice the old capacity, plus {@code 2}.
+     * </ul>
+     * If the {@code minimumCapacity} argument is nonpositive, this
+     * method takes no action and simply returns.
+     * Note that subsequent operations on this object can reduce the
+     * actual capacity below that requested here.
+     *
+     * @param   minimumCapacity   the minimum desired capacity.
+     */
+    public void ensureCapacity(int minimumCapacity) {
+        if (minimumCapacity > 0)
+            ensureCapacityInternal(minimumCapacity);
+    }
+
+    /**
+     * For positive values of {@code minimumCapacity}, this method
+     * behaves like {@code ensureCapacity}, however it is never
+     * synchronized.
+     * If {@code minimumCapacity} is non positive due to numeric
+     * overflow, this method throws {@code OutOfMemoryError}.
+     */
+    private void ensureCapacityInternal(int minimumCapacity) {
+        // overflow-conscious code
+        if (minimumCapacity - value.length > 0) {
+            value = Arrays.copyOf(value,
+                    newCapacity(minimumCapacity));
+        }
+    }
+
+    /**
+     * The maximum size of array to allocate (unless necessary).
+     * Some VMs reserve some header words in an array.
+     * Attempts to allocate larger arrays may result in
+     * OutOfMemoryError: Requested array size exceeds VM limit
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * Returns a capacity at least as large as the given minimum capacity.
+     * Returns the current capacity increased by the same amount + 2 if
+     * that suffices.
+     * Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
+     * unless the given minimum capacity is greater than that.
+     *
+     * @param  minCapacity the desired minimum capacity
+     * @throws OutOfMemoryError if minCapacity is less than zero or
+     *         greater than Integer.MAX_VALUE
+     */
+    private int newCapacity(int minCapacity) {
+        // overflow-conscious code
+        int newCapacity = (value.length << 1) + 2;
+        if (newCapacity - minCapacity < 0) {
+            newCapacity = minCapacity;
+        }
+        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
+            ? hugeCapacity(minCapacity)
+            : newCapacity;
+    }
+
+    private int hugeCapacity(int minCapacity) {
+        if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
+            throw new OutOfMemoryError();
+        }
+        return (minCapacity > MAX_ARRAY_SIZE)
+            ? minCapacity : MAX_ARRAY_SIZE;
+    }
+
+    /**
+     * Attempts to reduce storage used for the character sequence.
+     * If the buffer is larger than necessary to hold its current sequence of
+     * characters, then it may be resized to become more space efficient.
+     * Calling this method may, but is not required to, affect the value
+     * returned by a subsequent call to the {@link #capacity()} method.
+     */
+    public void trimToSize() {
+        if (count < value.length) {
+            value = Arrays.copyOf(value, count);
+        }
+    }
+
+    /**
+     * Sets the length of the character sequence.
+     * The sequence is changed to a new character sequence
+     * whose length is specified by the argument. For every nonnegative
+     * index <i>k</i> less than {@code newLength}, the character at
+     * index <i>k</i> in the new character sequence is the same as the
+     * character at index <i>k</i> in the old sequence if <i>k</i> is less
+     * than the length of the old character sequence; otherwise, it is the
+     * null character {@code '\u005Cu0000'}.
+     *
+     * In other words, if the {@code newLength} argument is less than
+     * the current length, the length is changed to the specified length.
+     * <p>
+     * If the {@code newLength} argument is greater than or equal
+     * to the current length, sufficient null characters
+     * ({@code '\u005Cu0000'}) are appended so that
+     * length becomes the {@code newLength} argument.
+     * <p>
+     * The {@code newLength} argument must be greater than or equal
+     * to {@code 0}.
+     *
+     * @param      newLength   the new length
+     * @throws     IndexOutOfBoundsException  if the
+     *               {@code newLength} argument is negative.
+     */
+    public void setLength(int newLength) {
+        if (newLength < 0)
+            throw new StringIndexOutOfBoundsException(newLength);
+        ensureCapacityInternal(newLength);
+
+        if (count < newLength) {
+            Arrays.fill(value, count, newLength, '\0');
+        }
+
+        count = newLength;
+    }
+
+    /**
+     * Returns the {@code char} value in this sequence at the specified index.
+     * The first {@code char} value is at index {@code 0}, the next at index
+     * {@code 1}, and so on, as in array indexing.
+     * <p>
+     * The index argument must be greater than or equal to
+     * {@code 0}, and less than the length of this sequence.
+     *
+     * <p>If the {@code char} value specified by the index is a
+     * <a href="Character.html#unicode">surrogate</a>, the surrogate
+     * value is returned.
+     *
+     * @param      index   the index of the desired {@code char} value.
+     * @return     the {@code char} value at the specified index.
+     * @throws     IndexOutOfBoundsException  if {@code index} is
+     *             negative or greater than or equal to {@code length()}.
+     */
+    @Override
+    public char charAt(int index) {
+        if ((index < 0) || (index >= count))
+            throw new StringIndexOutOfBoundsException(index);
+        return value[index];
+    }
+
+    /**
+     * Returns the character (Unicode code point) at the specified
+     * index. The index refers to {@code char} values
+     * (Unicode code units) and ranges from {@code 0} to
+     * {@link #length()}{@code  - 1}.
+     *
+     * <p> If the {@code char} value specified at the given index
+     * is in the high-surrogate range, the following index is less
+     * than the length of this sequence, and the
+     * {@code char} value at the following index is in the
+     * low-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at the given index is returned.
+     *
+     * @param      index the index to the {@code char} values
+     * @return     the code point value of the character at the
+     *             {@code index}
+     * @exception  IndexOutOfBoundsException  if the {@code index}
+     *             argument is negative or not less than the length of this
+     *             sequence.
+     */
+    public int codePointAt(int index) {
+        if ((index < 0) || (index >= count)) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        return Character.codePointAtImpl(value, index, count);
+    }
+
+    /**
+     * Returns the character (Unicode code point) before the specified
+     * index. The index refers to {@code char} values
+     * (Unicode code units) and ranges from {@code 1} to {@link
+     * #length()}.
+     *
+     * <p> If the {@code char} value at {@code (index - 1)}
+     * is in the low-surrogate range, {@code (index - 2)} is not
+     * negative, and the {@code char} value at {@code (index -
+     * 2)} is in the high-surrogate range, then the
+     * supplementary code point value of the surrogate pair is
+     * returned. If the {@code char} value at {@code index -
+     * 1} is an unpaired low-surrogate or a high-surrogate, the
+     * surrogate value is returned.
+     *
+     * @param     index the index following the code point that should be returned
+     * @return    the Unicode code point value before the given index.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     *            argument is less than 1 or greater than the length
+     *            of this sequence.
+     */
+    public int codePointBefore(int index) {
+        int i = index - 1;
+        if ((i < 0) || (i >= count)) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        return Character.codePointBeforeImpl(value, index, 0);
+    }
+
+    /**
+     * Returns the number of Unicode code points in the specified text
+     * range of this sequence. The text range begins at the specified
+     * {@code beginIndex} and extends to the {@code char} at
+     * index {@code endIndex - 1}. Thus the length (in
+     * {@code char}s) of the text range is
+     * {@code endIndex-beginIndex}. Unpaired surrogates within
+     * this sequence count as one code point each.
+     *
+     * @param beginIndex the index to the first {@code char} of
+     * the text range.
+     * @param endIndex the index after the last {@code char} of
+     * the text range.
+     * @return the number of Unicode code points in the specified text
+     * range
+     * @exception IndexOutOfBoundsException if the
+     * {@code beginIndex} is negative, or {@code endIndex}
+     * is larger than the length of this sequence, or
+     * {@code beginIndex} is larger than {@code endIndex}.
+     */
+    public int codePointCount(int beginIndex, int endIndex) {
+        if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
+            throw new IndexOutOfBoundsException();
+        }
+        return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
+    }
+
+    /**
+     * Returns the index within this sequence that is offset from the
+     * given {@code index} by {@code codePointOffset} code
+     * points. Unpaired surrogates within the text range given by
+     * {@code index} and {@code codePointOffset} count as
+     * one code point each.
+     *
+     * @param index the index to be offset
+     * @param codePointOffset the offset in code points
+     * @return the index within this sequence
+     * @exception IndexOutOfBoundsException if {@code index}
+     *   is negative or larger then the length of this sequence,
+     *   or if {@code codePointOffset} is positive and the subsequence
+     *   starting with {@code index} has fewer than
+     *   {@code codePointOffset} code points,
+     *   or if {@code codePointOffset} is negative and the subsequence
+     *   before {@code index} has fewer than the absolute value of
+     *   {@code codePointOffset} code points.
+     */
+    public int offsetByCodePoints(int index, int codePointOffset) {
+        if (index < 0 || index > count) {
+            throw new IndexOutOfBoundsException();
+        }
+        return Character.offsetByCodePointsImpl(value, 0, count,
+                                                index, codePointOffset);
+    }
+
+    /**
+     * Characters are copied from this sequence into the
+     * destination character array {@code dst}. The first character to
+     * be copied is at index {@code srcBegin}; the last character to
+     * be copied is at index {@code srcEnd-1}. The total number of
+     * characters to be copied is {@code srcEnd-srcBegin}. The
+     * characters are copied into the subarray of {@code dst} starting
+     * at index {@code dstBegin} and ending at index:
+     * <pre>{@code
+     * dstbegin + (srcEnd-srcBegin) - 1
+     * }</pre>
+     *
+     * @param      srcBegin   start copying at this offset.
+     * @param      srcEnd     stop copying at this offset.
+     * @param      dst        the array to copy the data into.
+     * @param      dstBegin   offset into {@code dst}.
+     * @throws     IndexOutOfBoundsException  if any of the following is true:
+     *             <ul>
+     *             <li>{@code srcBegin} is negative
+     *             <li>{@code dstBegin} is negative
+     *             <li>the {@code srcBegin} argument is greater than
+     *             the {@code srcEnd} argument.
+     *             <li>{@code srcEnd} is greater than
+     *             {@code this.length()}.
+     *             <li>{@code dstBegin+srcEnd-srcBegin} is greater than
+     *             {@code dst.length}
+     *             </ul>
+     */
+    public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
+    {
+        if (srcBegin < 0)
+            throw new StringIndexOutOfBoundsException(srcBegin);
+        if ((srcEnd < 0) || (srcEnd > count))
+            throw new StringIndexOutOfBoundsException(srcEnd);
+        if (srcBegin > srcEnd)
+            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
+        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+    }
+
+    /**
+     * The character at the specified index is set to {@code ch}. This
+     * sequence is altered to represent a new character sequence that is
+     * identical to the old character sequence, except that it contains the
+     * character {@code ch} at position {@code index}.
+     * <p>
+     * The index argument must be greater than or equal to
+     * {@code 0}, and less than the length of this sequence.
+     *
+     * @param      index   the index of the character to modify.
+     * @param      ch      the new character.
+     * @throws     IndexOutOfBoundsException  if {@code index} is
+     *             negative or greater than or equal to {@code length()}.
+     */
+    public void setCharAt(int index, char ch) {
+        if ((index < 0) || (index >= count))
+            throw new StringIndexOutOfBoundsException(index);
+        value[index] = ch;
+    }
+
+    /**
+     * Appends the string representation of the {@code Object} argument.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(Object)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   obj   an {@code Object}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(Object obj) {
+        return append(String.valueOf(obj));
+    }
+
+    /**
+     * Appends the specified string to this character sequence.
+     * <p>
+     * The characters of the {@code String} argument are appended, in
+     * order, increasing the length of this sequence by the length of the
+     * argument. If {@code str} is {@code null}, then the four
+     * characters {@code "null"} are appended.
+     * <p>
+     * Let <i>n</i> be the length of this character sequence just prior to
+     * execution of the {@code append} method. Then the character at
+     * index <i>k</i> in the new character sequence is equal to the character
+     * at index <i>k</i> in the old character sequence, if <i>k</i> is less
+     * than <i>n</i>; otherwise, it is equal to the character at index
+     * <i>k-n</i> in the argument {@code str}.
+     *
+     * @param   str   a string.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(String str) {
+        if (str == null)
+            return appendNull();
+        int len = str.length();
+        ensureCapacityInternal(count + len);
+        str.getChars(0, len, value, count);
+        count += len;
+        return this;
+    }
+
+    // Documentation in subclasses because of synchro difference
+    public AbstractStringBuilder append(StringBuffer sb) {
+        if (sb == null)
+            return appendNull();
+        int len = sb.length();
+        ensureCapacityInternal(count + len);
+        sb.getChars(0, len, value, count);
+        count += len;
+        return this;
+    }
+
+    /**
+     * @since 1.8
+     */
+    AbstractStringBuilder append(AbstractStringBuilder asb) {
+        if (asb == null)
+            return appendNull();
+        int len = asb.length();
+        ensureCapacityInternal(count + len);
+        asb.getChars(0, len, value, count);
+        count += len;
+        return this;
+    }
+
+    // Documentation in subclasses because of synchro difference
+    @Override
+    public AbstractStringBuilder append(CharSequence s) {
+        if (s == null)
+            return appendNull();
+        if (s instanceof String)
+            return this.append((String)s);
+        if (s instanceof AbstractStringBuilder)
+            return this.append((AbstractStringBuilder)s);
+
+        return this.append(s, 0, s.length());
+    }
+
+    private AbstractStringBuilder appendNull() {
+        int c = count;
+        ensureCapacityInternal(c + 4);
+        final char[] value = this.value;
+        value[c++] = 'n';
+        value[c++] = 'u';
+        value[c++] = 'l';
+        value[c++] = 'l';
+        count = c;
+        return this;
+    }
+
+    /**
+     * Appends a subsequence of the specified {@code CharSequence} to this
+     * sequence.
+     * <p>
+     * Characters of the argument {@code s}, starting at
+     * index {@code start}, are appended, in order, to the contents of
+     * this sequence up to the (exclusive) index {@code end}. The length
+     * of this sequence is increased by the value of {@code end - start}.
+     * <p>
+     * Let <i>n</i> be the length of this character sequence just prior to
+     * execution of the {@code append} method. Then the character at
+     * index <i>k</i> in this character sequence becomes equal to the
+     * character at index <i>k</i> in this sequence, if <i>k</i> is less than
+     * <i>n</i>; otherwise, it is equal to the character at index
+     * <i>k+start-n</i> in the argument {@code s}.
+     * <p>
+     * If {@code s} is {@code null}, then this method appends
+     * characters as if the s parameter was a sequence containing the four
+     * characters {@code "null"}.
+     *
+     * @param   s the sequence to append.
+     * @param   start   the starting index of the subsequence to be appended.
+     * @param   end     the end index of the subsequence to be appended.
+     * @return  a reference to this object.
+     * @throws     IndexOutOfBoundsException if
+     *             {@code start} is negative, or
+     *             {@code start} is greater than {@code end} or
+     *             {@code end} is greater than {@code s.length()}
+     */
+    @Override
+    public AbstractStringBuilder append(CharSequence s, int start, int end) {
+        if (s == null)
+            s = "null";
+        if ((start < 0) || (start > end) || (end > s.length()))
+            throw new IndexOutOfBoundsException(
+                "start " + start + ", end " + end + ", s.length() "
+                + s.length());
+        int len = end - start;
+        ensureCapacityInternal(count + len);
+        for (int i = start, j = count; i < end; i++, j++)
+            value[j] = s.charAt(i);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code char} array
+     * argument to this sequence.
+     * <p>
+     * The characters of the array argument are appended, in order, to
+     * the contents of this sequence. The length of this sequence
+     * increases by the length of the argument.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(char[])},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   str   the characters to be appended.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(char[] str) {
+        int len = str.length;
+        ensureCapacityInternal(count + len);
+        System.arraycopy(str, 0, value, count, len);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of a subarray of the
+     * {@code char} array argument to this sequence.
+     * <p>
+     * Characters of the {@code char} array {@code str}, starting at
+     * index {@code offset}, are appended, in order, to the contents
+     * of this sequence. The length of this sequence increases
+     * by the value of {@code len}.
+     * <p>
+     * The overall effect is exactly as if the arguments were converted
+     * to a string by the method {@link String#valueOf(char[],int,int)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   str      the characters to be appended.
+     * @param   offset   the index of the first {@code char} to append.
+     * @param   len      the number of {@code char}s to append.
+     * @return  a reference to this object.
+     * @throws IndexOutOfBoundsException
+     *         if {@code offset < 0} or {@code len < 0}
+     *         or {@code offset+len > str.length}
+     */
+    public AbstractStringBuilder append(char str[], int offset, int len) {
+        if (len > 0)                // let arraycopy report AIOOBE for len < 0
+            ensureCapacityInternal(count + len);
+        System.arraycopy(str, offset, value, count, len);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code boolean}
+     * argument to the sequence.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(boolean)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   b   a {@code boolean}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(boolean b) {
+        if (b) {
+            ensureCapacityInternal(count + 4);
+            value[count++] = 't';
+            value[count++] = 'r';
+            value[count++] = 'u';
+            value[count++] = 'e';
+        } else {
+            ensureCapacityInternal(count + 5);
+            value[count++] = 'f';
+            value[count++] = 'a';
+            value[count++] = 'l';
+            value[count++] = 's';
+            value[count++] = 'e';
+        }
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code char}
+     * argument to this sequence.
+     * <p>
+     * The argument is appended to the contents of this sequence.
+     * The length of this sequence increases by {@code 1}.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(char)},
+     * and the character in that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   c   a {@code char}.
+     * @return  a reference to this object.
+     */
+    @Override
+    public AbstractStringBuilder append(char c) {
+        ensureCapacityInternal(count + 1);
+        value[count++] = c;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code int}
+     * argument to this sequence.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(int)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   i   an {@code int}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(int i) {
+        if (i == Integer.MIN_VALUE) {
+            append("-2147483648");
+            return this;
+        }
+        int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
+                                     : Integer.stringSize(i);
+        int spaceNeeded = count + appendedLength;
+        ensureCapacityInternal(spaceNeeded);
+        Integer.getChars(i, spaceNeeded, value);
+        count = spaceNeeded;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code long}
+     * argument to this sequence.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(long)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   l   a {@code long}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(long l) {
+        if (l == Long.MIN_VALUE) {
+            append("-9223372036854775808");
+            return this;
+        }
+        int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
+                                     : Long.stringSize(l);
+        int spaceNeeded = count + appendedLength;
+        ensureCapacityInternal(spaceNeeded);
+        Long.getChars(l, spaceNeeded, value);
+        count = spaceNeeded;
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code float}
+     * argument to this sequence.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(float)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   f   a {@code float}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(float f) {
+        FloatingDecimal.appendTo(f,this);
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code double}
+     * argument to this sequence.
+     * <p>
+     * The overall effect is exactly as if the argument were converted
+     * to a string by the method {@link String#valueOf(double)},
+     * and the characters of that string were then
+     * {@link #append(String) appended} to this character sequence.
+     *
+     * @param   d   a {@code double}.
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder append(double d) {
+        FloatingDecimal.appendTo(d,this);
+        return this;
+    }
+
+    /**
+     * Removes the characters in a substring of this sequence.
+     * The substring begins at the specified {@code start} and extends to
+     * the character at index {@code end - 1} or to the end of the
+     * sequence if no such character exists. If
+     * {@code start} is equal to {@code end}, no changes are made.
+     *
+     * @param      start  The beginning index, inclusive.
+     * @param      end    The ending index, exclusive.
+     * @return     This object.
+     * @throws     StringIndexOutOfBoundsException  if {@code start}
+     *             is negative, greater than {@code length()}, or
+     *             greater than {@code end}.
+     */
+    public AbstractStringBuilder delete(int start, int end) {
+        if (start < 0)
+            throw new StringIndexOutOfBoundsException(start);
+        if (end > count)
+            end = count;
+        if (start > end)
+            throw new StringIndexOutOfBoundsException();
+        int len = end - start;
+        if (len > 0) {
+            System.arraycopy(value, start+len, value, start, count-end);
+            count -= len;
+        }
+        return this;
+    }
+
+    /**
+     * Appends the string representation of the {@code codePoint}
+     * argument to this sequence.
+     *
+     * <p> The argument is appended to the contents of this sequence.
+     * The length of this sequence increases by
+     * {@link Character#charCount(int) Character.charCount(codePoint)}.
+     *
+     * <p> The overall effect is exactly as if the argument were
+     * converted to a {@code char} array by the method
+     * {@link Character#toChars(int)} and the character in that array
+     * were then {@link #append(char[]) appended} to this character
+     * sequence.
+     *
+     * @param   codePoint   a Unicode code point
+     * @return  a reference to this object.
+     * @exception IllegalArgumentException if the specified
+     * {@code codePoint} isn't a valid Unicode code point
+     */
+    public AbstractStringBuilder appendCodePoint(int codePoint) {
+        final int count = this.count;
+
+        if (Character.isBmpCodePoint(codePoint)) {
+            ensureCapacityInternal(count + 1);
+            value[count] = (char) codePoint;
+            this.count = count + 1;
+        } else if (Character.isValidCodePoint(codePoint)) {
+            ensureCapacityInternal(count + 2);
+            Character.toSurrogates(codePoint, value, count);
+            this.count = count + 2;
+        } else {
+            throw new IllegalArgumentException();
+        }
+        return this;
+    }
+
+    /**
+     * Removes the {@code char} at the specified position in this
+     * sequence. This sequence is shortened by one {@code char}.
+     *
+     * <p>Note: If the character at the given index is a supplementary
+     * character, this method does not remove the entire character. If
+     * correct handling of supplementary characters is required,
+     * determine the number of {@code char}s to remove by calling
+     * {@code Character.charCount(thisSequence.codePointAt(index))},
+     * where {@code thisSequence} is this sequence.
+     *
+     * @param       index  Index of {@code char} to remove
+     * @return      This object.
+     * @throws      StringIndexOutOfBoundsException  if the {@code index}
+     *              is negative or greater than or equal to
+     *              {@code length()}.
+     */
+    public AbstractStringBuilder deleteCharAt(int index) {
+        if ((index < 0) || (index >= count))
+            throw new StringIndexOutOfBoundsException(index);
+        System.arraycopy(value, index+1, value, index, count-index-1);
+        count--;
+        return this;
+    }
+
+    /**
+     * Replaces the characters in a substring of this sequence
+     * with characters in the specified {@code String}. The substring
+     * begins at the specified {@code start} and extends to the character
+     * at index {@code end - 1} or to the end of the
+     * sequence if no such character exists. First the
+     * characters in the substring are removed and then the specified
+     * {@code String} is inserted at {@code start}. (This
+     * sequence will be lengthened to accommodate the
+     * specified String if necessary.)
+     *
+     * @param      start    The beginning index, inclusive.
+     * @param      end      The ending index, exclusive.
+     * @param      str   String that will replace previous contents.
+     * @return     This object.
+     * @throws     StringIndexOutOfBoundsException  if {@code start}
+     *             is negative, greater than {@code length()}, or
+     *             greater than {@code end}.
+     */
+    public AbstractStringBuilder replace(int start, int end, String str) {
+        if (start < 0)
+            throw new StringIndexOutOfBoundsException(start);
+        if (start > count)
+            throw new StringIndexOutOfBoundsException("start > length()");
+        if (start > end)
+            throw new StringIndexOutOfBoundsException("start > end");
+
+        if (end > count)
+            end = count;
+        int len = str.length();
+        int newCount = count + len - (end - start);
+        ensureCapacityInternal(newCount);
+
+        System.arraycopy(value, end, value, start + len, count - end);
+        str.getChars(value, start);
+        count = newCount;
+        return this;
+    }
+
+    /**
+     * Returns a new {@code String} that contains a subsequence of
+     * characters currently contained in this character sequence. The
+     * substring begins at the specified index and extends to the end of
+     * this sequence.
+     *
+     * @param      start    The beginning index, inclusive.
+     * @return     The new string.
+     * @throws     StringIndexOutOfBoundsException  if {@code start} is
+     *             less than zero, or greater than the length of this object.
+     */
+    public String substring(int start) {
+        return substring(start, count);
+    }
+
+    /**
+     * Returns a new character sequence that is a subsequence of this sequence.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <pre>{@code
+     * sb.subSequence(begin,&nbsp;end)}</pre>
+     *
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>{@code
+     * sb.substring(begin,&nbsp;end)}</pre>
+     *
+     * This method is provided so that this class can
+     * implement the {@link CharSequence} interface.
+     *
+     * @param      start   the start index, inclusive.
+     * @param      end     the end index, exclusive.
+     * @return     the specified subsequence.
+     *
+     * @throws  IndexOutOfBoundsException
+     *          if {@code start} or {@code end} are negative,
+     *          if {@code end} is greater than {@code length()},
+     *          or if {@code start} is greater than {@code end}
+     * @spec JSR-51
+     */
+    @Override
+    public CharSequence subSequence(int start, int end) {
+        return substring(start, end);
+    }
+
+    /**
+     * Returns a new {@code String} that contains a subsequence of
+     * characters currently contained in this sequence. The
+     * substring begins at the specified {@code start} and
+     * extends to the character at index {@code end - 1}.
+     *
+     * @param      start    The beginning index, inclusive.
+     * @param      end      The ending index, exclusive.
+     * @return     The new string.
+     * @throws     StringIndexOutOfBoundsException  if {@code start}
+     *             or {@code end} are negative or greater than
+     *             {@code length()}, or {@code start} is
+     *             greater than {@code end}.
+     */
+    public String substring(int start, int end) {
+        if (start < 0)
+            throw new StringIndexOutOfBoundsException(start);
+        if (end > count)
+            throw new StringIndexOutOfBoundsException(end);
+        if (start > end)
+            throw new StringIndexOutOfBoundsException(end - start);
+        return new String(value, start, end - start);
+    }
+
+    /**
+     * Inserts the string representation of a subarray of the {@code str}
+     * array argument into this sequence. The subarray begins at the
+     * specified {@code offset} and extends {@code len} {@code char}s.
+     * The characters of the subarray are inserted into this sequence at
+     * the position indicated by {@code index}. The length of this
+     * sequence increases by {@code len} {@code char}s.
+     *
+     * @param      index    position at which to insert subarray.
+     * @param      str       A {@code char} array.
+     * @param      offset   the index of the first {@code char} in subarray to
+     *             be inserted.
+     * @param      len      the number of {@code char}s in the subarray to
+     *             be inserted.
+     * @return     This object
+     * @throws     StringIndexOutOfBoundsException  if {@code index}
+     *             is negative or greater than {@code length()}, or
+     *             {@code offset} or {@code len} are negative, or
+     *             {@code (offset+len)} is greater than
+     *             {@code str.length}.
+     */
+    public AbstractStringBuilder insert(int index, char[] str, int offset,
+                                        int len)
+    {
+        if ((index < 0) || (index > length()))
+            throw new StringIndexOutOfBoundsException(index);
+        if ((offset < 0) || (len < 0) || (offset > str.length - len))
+            throw new StringIndexOutOfBoundsException(
+                "offset " + offset + ", len " + len + ", str.length "
+                + str.length);
+        ensureCapacityInternal(count + len);
+        System.arraycopy(value, index, value, index + len, count - index);
+        System.arraycopy(str, offset, value, index, len);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Inserts the string representation of the {@code Object}
+     * argument into this character sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(Object)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      obj      an {@code Object}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, Object obj) {
+        return insert(offset, String.valueOf(obj));
+    }
+
+    /**
+     * Inserts the string into this character sequence.
+     * <p>
+     * The characters of the {@code String} argument are inserted, in
+     * order, into this sequence at the indicated offset, moving up any
+     * characters originally above that position and increasing the length
+     * of this sequence by the length of the argument. If
+     * {@code str} is {@code null}, then the four characters
+     * {@code "null"} are inserted into this sequence.
+     * <p>
+     * The character at index <i>k</i> in the new character sequence is
+     * equal to:
+     * <ul>
+     * <li>the character at index <i>k</i> in the old character sequence, if
+     * <i>k</i> is less than {@code offset}
+     * <li>the character at index <i>k</i>{@code -offset} in the
+     * argument {@code str}, if <i>k</i> is not less than
+     * {@code offset} but is less than {@code offset+str.length()}
+     * <li>the character at index <i>k</i>{@code -str.length()} in the
+     * old character sequence, if <i>k</i> is not less than
+     * {@code offset+str.length()}
+     * </ul><p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      str      a string.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, String str) {
+        if ((offset < 0) || (offset > length()))
+            throw new StringIndexOutOfBoundsException(offset);
+        if (str == null)
+            str = "null";
+        int len = str.length();
+        ensureCapacityInternal(count + len);
+        System.arraycopy(value, offset, value, offset + len, count - offset);
+        str.getChars(value, offset);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Inserts the string representation of the {@code char} array
+     * argument into this sequence.
+     * <p>
+     * The characters of the array argument are inserted into the
+     * contents of this sequence at the position indicated by
+     * {@code offset}. The length of this sequence increases by
+     * the length of the argument.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(char[])},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      str      a character array.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, char[] str) {
+        if ((offset < 0) || (offset > length()))
+            throw new StringIndexOutOfBoundsException(offset);
+        int len = str.length;
+        ensureCapacityInternal(count + len);
+        System.arraycopy(value, offset, value, offset + len, count - offset);
+        System.arraycopy(str, 0, value, offset, len);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Inserts the specified {@code CharSequence} into this sequence.
+     * <p>
+     * The characters of the {@code CharSequence} argument are inserted,
+     * in order, into this sequence at the indicated offset, moving up
+     * any characters originally above that position and increasing the length
+     * of this sequence by the length of the argument s.
+     * <p>
+     * The result of this method is exactly the same as if it were an
+     * invocation of this object's
+     * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
+     * method.
+     *
+     * <p>If {@code s} is {@code null}, then the four characters
+     * {@code "null"} are inserted into this sequence.
+     *
+     * @param      dstOffset   the offset.
+     * @param      s the sequence to be inserted
+     * @return     a reference to this object.
+     * @throws     IndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
+        if (s == null)
+            s = "null";
+        if (s instanceof String)
+            return this.insert(dstOffset, (String)s);
+        return this.insert(dstOffset, s, 0, s.length());
+    }
+
+    /**
+     * Inserts a subsequence of the specified {@code CharSequence} into
+     * this sequence.
+     * <p>
+     * The subsequence of the argument {@code s} specified by
+     * {@code start} and {@code end} are inserted,
+     * in order, into this sequence at the specified destination offset, moving
+     * up any characters originally above that position. The length of this
+     * sequence is increased by {@code end - start}.
+     * <p>
+     * The character at index <i>k</i> in this sequence becomes equal to:
+     * <ul>
+     * <li>the character at index <i>k</i> in this sequence, if
+     * <i>k</i> is less than {@code dstOffset}
+     * <li>the character at index <i>k</i>{@code +start-dstOffset} in
+     * the argument {@code s}, if <i>k</i> is greater than or equal to
+     * {@code dstOffset} but is less than {@code dstOffset+end-start}
+     * <li>the character at index <i>k</i>{@code -(end-start)} in this
+     * sequence, if <i>k</i> is greater than or equal to
+     * {@code dstOffset+end-start}
+     * </ul><p>
+     * The {@code dstOffset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     * <p>The start argument must be nonnegative, and not greater than
+     * {@code end}.
+     * <p>The end argument must be greater than or equal to
+     * {@code start}, and less than or equal to the length of s.
+     *
+     * <p>If {@code s} is {@code null}, then this method inserts
+     * characters as if the s parameter was a sequence containing the four
+     * characters {@code "null"}.
+     *
+     * @param      dstOffset   the offset in this sequence.
+     * @param      s       the sequence to be inserted.
+     * @param      start   the starting index of the subsequence to be inserted.
+     * @param      end     the end index of the subsequence to be inserted.
+     * @return     a reference to this object.
+     * @throws     IndexOutOfBoundsException  if {@code dstOffset}
+     *             is negative or greater than {@code this.length()}, or
+     *              {@code start} or {@code end} are negative, or
+     *              {@code start} is greater than {@code end} or
+     *              {@code end} is greater than {@code s.length()}
+     */
+     public AbstractStringBuilder insert(int dstOffset, CharSequence s,
+                                         int start, int end) {
+        if (s == null)
+            s = "null";
+        if ((dstOffset < 0) || (dstOffset > this.length()))
+            throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
+        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
+            throw new IndexOutOfBoundsException(
+                "start " + start + ", end " + end + ", s.length() "
+                + s.length());
+        int len = end - start;
+        ensureCapacityInternal(count + len);
+        System.arraycopy(value, dstOffset, value, dstOffset + len,
+                         count - dstOffset);
+        for (int i=start; i<end; i++)
+            value[dstOffset++] = s.charAt(i);
+        count += len;
+        return this;
+    }
+
+    /**
+     * Inserts the string representation of the {@code boolean}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(boolean)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      b        a {@code boolean}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, boolean b) {
+        return insert(offset, String.valueOf(b));
+    }
+
+    /**
+     * Inserts the string representation of the {@code char}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(char)},
+     * and the character in that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      c        a {@code char}.
+     * @return     a reference to this object.
+     * @throws     IndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, char c) {
+        ensureCapacityInternal(count + 1);
+        System.arraycopy(value, offset, value, offset + 1, count - offset);
+        value[offset] = c;
+        count += 1;
+        return this;
+    }
+
+    /**
+     * Inserts the string representation of the second {@code int}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(int)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      i        an {@code int}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, int i) {
+        return insert(offset, String.valueOf(i));
+    }
+
+    /**
+     * Inserts the string representation of the {@code long}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(long)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      l        a {@code long}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, long l) {
+        return insert(offset, String.valueOf(l));
+    }
+
+    /**
+     * Inserts the string representation of the {@code float}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(float)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      f        a {@code float}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, float f) {
+        return insert(offset, String.valueOf(f));
+    }
+
+    /**
+     * Inserts the string representation of the {@code double}
+     * argument into this sequence.
+     * <p>
+     * The overall effect is exactly as if the second argument were
+     * converted to a string by the method {@link String#valueOf(double)},
+     * and the characters of that string were then
+     * {@link #insert(int,String) inserted} into this character
+     * sequence at the indicated offset.
+     * <p>
+     * The {@code offset} argument must be greater than or equal to
+     * {@code 0}, and less than or equal to the {@linkplain #length() length}
+     * of this sequence.
+     *
+     * @param      offset   the offset.
+     * @param      d        a {@code double}.
+     * @return     a reference to this object.
+     * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
+     */
+    public AbstractStringBuilder insert(int offset, double d) {
+        return insert(offset, String.valueOf(d));
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of the
+     * specified substring. The integer returned is the smallest value
+     * <i>k</i> such that:
+     * <pre>{@code
+     * this.toString().startsWith(str, <i>k</i>)
+     * }</pre>
+     * is {@code true}.
+     *
+     * @param   str   any string.
+     * @return  if the string argument occurs as a substring within this
+     *          object, then the index of the first character of the first
+     *          such substring is returned; if it does not occur as a
+     *          substring, {@code -1} is returned.
+     */
+    public int indexOf(String str) {
+        return indexOf(str, 0);
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of the
+     * specified substring, starting at the specified index.  The integer
+     * returned is the smallest value {@code k} for which:
+     * <pre>{@code
+     *     k >= Math.min(fromIndex, this.length()) &&
+     *                   this.toString().startsWith(str, k)
+     * }</pre>
+     * If no such value of <i>k</i> exists, then -1 is returned.
+     *
+     * @param   str         the substring for which to search.
+     * @param   fromIndex   the index from which to start the search.
+     * @return  the index within this string of the first occurrence of the
+     *          specified substring, starting at the specified index.
+     */
+    public int indexOf(String str, int fromIndex) {
+        return String.indexOf(value, 0, count, str, fromIndex);
+    }
+
+    /**
+     * Returns the index within this string of the rightmost occurrence
+     * of the specified substring.  The rightmost empty string "" is
+     * considered to occur at the index value {@code this.length()}.
+     * The returned index is the largest value <i>k</i> such that
+     * <pre>{@code
+     * this.toString().startsWith(str, k)
+     * }</pre>
+     * is true.
+     *
+     * @param   str   the substring to search for.
+     * @return  if the string argument occurs one or more times as a substring
+     *          within this object, then the index of the first character of
+     *          the last such substring is returned. If it does not occur as
+     *          a substring, {@code -1} is returned.
+     */
+    public int lastIndexOf(String str) {
+        return lastIndexOf(str, count);
+    }
+
+    /**
+     * Returns the index within this string of the last occurrence of the
+     * specified substring. The integer returned is the largest value <i>k</i>
+     * such that:
+     * <pre>{@code
+     *     k <= Math.min(fromIndex, this.length()) &&
+     *                   this.toString().startsWith(str, k)
+     * }</pre>
+     * If no such value of <i>k</i> exists, then -1 is returned.
+     *
+     * @param   str         the substring to search for.
+     * @param   fromIndex   the index to start the search from.
+     * @return  the index within this sequence of the last occurrence of the
+     *          specified substring.
+     */
+    public int lastIndexOf(String str, int fromIndex) {
+        return String.lastIndexOf(value, 0, count, str, fromIndex);
+    }
+
+    /**
+     * Causes this character sequence to be replaced by the reverse of
+     * the sequence. If there are any surrogate pairs included in the
+     * sequence, these are treated as single characters for the
+     * reverse operation. Thus, the order of the high-low surrogates
+     * is never reversed.
+     *
+     * Let <i>n</i> be the character length of this character sequence
+     * (not the length in {@code char} values) just prior to
+     * execution of the {@code reverse} method. Then the
+     * character at index <i>k</i> in the new character sequence is
+     * equal to the character at index <i>n-k-1</i> in the old
+     * character sequence.
+     *
+     * <p>Note that the reverse operation may result in producing
+     * surrogate pairs that were unpaired low-surrogates and
+     * high-surrogates before the operation. For example, reversing
+     * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
+     * a valid surrogate pair.
+     *
+     * @return  a reference to this object.
+     */
+    public AbstractStringBuilder reverse() {
+        boolean hasSurrogates = false;
+        int n = count - 1;
+        for (int j = (n-1) >> 1; j >= 0; j--) {
+            int k = n - j;
+            char cj = value[j];
+            char ck = value[k];
+            value[j] = ck;
+            value[k] = cj;
+            if (Character.isSurrogate(cj) ||
+                Character.isSurrogate(ck)) {
+                hasSurrogates = true;
+            }
+        }
+        if (hasSurrogates) {
+            reverseAllValidSurrogatePairs();
+        }
+        return this;
+    }
+
+    /** Outlined helper method for reverse() */
+    private void reverseAllValidSurrogatePairs() {
+        for (int i = 0; i < count - 1; i++) {
+            char c2 = value[i];
+            if (Character.isLowSurrogate(c2)) {
+                char c1 = value[i + 1];
+                if (Character.isHighSurrogate(c1)) {
+                    value[i++] = c1;
+                    value[i] = c2;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a string representing the data in this sequence.
+     * A new {@code String} object is allocated and initialized to
+     * contain the character sequence currently represented by this
+     * object. This {@code String} is then returned. Subsequent
+     * changes to this sequence do not affect the contents of the
+     * {@code String}.
+     *
+     * @return  a string representation of this sequence of characters.
+     */
+    @Override
+    public abstract String toString();
+
+    /**
+     * Needed by {@code String} for the contentEquals method.
+     */
+    final char[] getValue() {
+        return value;
+    }
+
+}
diff --git a/java/lang/AndroidHardcodedSystemProperties.java b/java/lang/AndroidHardcodedSystemProperties.java
new file mode 100644
index 0000000..931994f
--- /dev/null
+++ b/java/lang/AndroidHardcodedSystemProperties.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (C) 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 java.lang;
+
+import java.util.Properties;
+
+/**
+ * A class encoding all hardcoded system property values on Android. A compiler may
+ * take advantage of these properties. Changing them at load-time (-D) or runtime
+ * may not have any effect.
+ *
+ * @hide
+ */
+public final class AndroidHardcodedSystemProperties {
+
+    // This value is shared with sun.misc.Version. It is defined here so that the compiler
+    // can use it.
+    public final static String JAVA_VERSION = "0";
+
+    final static String[][] STATIC_PROPERTIES = {
+        // None of these four are meaningful on Android, but these keys are guaranteed
+        // to be present for System.getProperty. For java.class.version, we use the maximum
+        // class file version that dx currently supports.
+        { "java.class.version", "50.0" },
+        { "java.version", JAVA_VERSION },
+        { "java.compiler", "" },
+        { "java.ext.dirs", "" },
+
+        { "java.specification.name", "Dalvik Core Library" },
+        { "java.specification.vendor", "The Android Project" },
+        { "java.specification.version", "0.9" },
+
+        { "java.vendor", "The Android Project" },
+        { "java.vendor.url", "http://www.android.com/" },
+        { "java.vm.name", "Dalvik" },
+        { "java.vm.specification.name", "Dalvik Virtual Machine Specification" },
+        { "java.vm.specification.vendor", "The Android Project" },
+        { "java.vm.specification.version", "0.9" },
+        { "java.vm.vendor", "The Android Project" },
+
+        { "java.vm.vendor.url", "http://www.android.com/" },
+
+        { "java.net.preferIPv6Addresses", "false" },
+
+        { "file.encoding", "UTF-8" },
+
+        { "file.separator", "/" },
+        { "line.separator", "\n" },
+        { "path.separator", ":" },
+
+        // Turn off ICU debugging. This allows compile-time initialization of a range of
+        // classes. b/28039175
+        { "ICUDebug", null },
+
+        // Hardcode DecimalFormat parsing flag to be default. b/27265238
+        { "android.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", null },
+        // Hardcode MessagePattern apostrophe mode to be default. b/27265238
+        { "android.icu.text.MessagePattern.ApostropheMode", null },
+
+        // Hardcode "sun.io.useCanonCaches" to use the default (off). b/28174137, b/62301183
+        { "sun.io.useCanonCaches", null },
+        { "sun.io.useCanonPrefixCache", null },
+
+        // Hardcode some http properties to use the default. b/28174137
+        { "http.keepAlive", null },
+        { "http.keepAliveDuration", null },
+        { "http.maxConnections", null },
+
+        // Turn off javax.net debugging. This allows compile-time initialization of a range
+        // of classes. b/28174137
+        { "javax.net.debug", null },
+
+        // Hardcode default value for AVA. b/28174137
+        { "com.sun.security.preserveOldDCEncoding", null },
+
+        // Hardcode default value for LogManager. b/28174137
+        { "java.util.logging.manager", null },
+    };
+}
diff --git a/java/lang/Appendable.annotated.java b/java/lang/Appendable.annotated.java
new file mode 100644
index 0000000..0ef58db
--- /dev/null
+++ b/java/lang/Appendable.annotated.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2003, 2004, 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;
+
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Appendable {
+
[email protected] public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq) throws java.io.IOException;
+
[email protected] public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) throws java.io.IOException;
+
[email protected] public java.lang.Appendable append(char c) throws java.io.IOException;
+}
+
diff --git a/java/lang/Appendable.java b/java/lang/Appendable.java
new file mode 100644
index 0000000..46fd78d
--- /dev/null
+++ b/java/lang/Appendable.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003, 2004, 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;
+
+import java.io.IOException;
+
+/**
+ * An object to which <tt>char</tt> sequences and values can be appended.  The
+ * <tt>Appendable</tt> interface must be implemented by any class whose
+ * instances are intended to receive formatted output from a {@link
+ * java.util.Formatter}.
+ *
+ * <p> The characters to be appended should be valid Unicode characters as
+ * described in <a href="Character.html#unicode">Unicode Character
+ * Representation</a>.  Note that supplementary characters may be composed of
+ * multiple 16-bit <tt>char</tt> values.
+ *
+ * <p> Appendables are not necessarily safe for multithreaded access.  Thread
+ * safety is the responsibility of classes that extend and implement this
+ * interface.
+ *
+ * <p> Since this interface may be implemented by existing classes
+ * with different styles of error handling there is no guarantee that
+ * errors will be propagated to the invoker.
+ *
+ * @since 1.5
+ */
+public interface Appendable {
+
+    /**
+     * Appends the specified character sequence to this <tt>Appendable</tt>.
+     *
+     * <p> Depending on which class implements the character sequence
+     * <tt>csq</tt>, the entire sequence may not be appended.  For
+     * instance, if <tt>csq</tt> is a {@link java.nio.CharBuffer} then
+     * the subsequence to append is defined by the buffer's position and limit.
+     *
+     * @param  csq
+     *         The character sequence to append.  If <tt>csq</tt> is
+     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
+     *         appended to this Appendable.
+     *
+     * @return  A reference to this <tt>Appendable</tt>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    Appendable append(CharSequence csq) throws IOException;
+
+    /**
+     * Appends a subsequence of the specified character sequence to this
+     * <tt>Appendable</tt>.
+     *
+     * <p> An invocation of this method of the form <tt>out.append(csq, start,
+     * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
+     * exactly the same way as the invocation
+     *
+     * <pre>
+     *     out.append(csq.subSequence(start, end)) </pre>
+     *
+     * @param  csq
+     *         The character sequence from which a subsequence will be
+     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
+     *         will be appended as if <tt>csq</tt> contained the four
+     *         characters <tt>"null"</tt>.
+     *
+     * @param  start
+     *         The index of the first character in the subsequence
+     *
+     * @param  end
+     *         The index of the character following the last character in the
+     *         subsequence
+     *
+     * @return  A reference to this <tt>Appendable</tt>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
+     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
+     *          <tt>csq.length()</tt>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    Appendable append(CharSequence csq, int start, int end) throws IOException;
+
+    /**
+     * Appends the specified character to this <tt>Appendable</tt>.
+     *
+     * @param  c
+     *         The character to append
+     *
+     * @return  A reference to this <tt>Appendable</tt>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    Appendable append(char c) throws IOException;
+}
diff --git a/java/lang/ArithmeticException.java b/java/lang/ArithmeticException.java
new file mode 100644
index 0000000..af00777
--- /dev/null
+++ b/java/lang/ArithmeticException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * Thrown when an exceptional arithmetic condition has occurred. For
+ * example, an integer "divide by zero" throws an
+ * instance of this class.
+ *
+ * {@code ArithmeticException} objects may be constructed by the
+ * virtual machine as if {@linkplain Throwable#Throwable(String,
+ * Throwable, boolean, boolean) suppression were disabled and/or the
+ * stack trace was not writable}.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public class ArithmeticException extends RuntimeException {
+    private static final long serialVersionUID = 2256477558314496007L;
+
+    /**
+     * Constructs an {@code ArithmeticException} with no detail
+     * message.
+     */
+    public ArithmeticException() {
+        super();
+    }
+
+    /**
+     * Constructs an {@code ArithmeticException} with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ArithmeticException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/ArrayIndexOutOfBoundsException.java b/java/lang/ArrayIndexOutOfBoundsException.java
new file mode 100644
index 0000000..d07a4b2
--- /dev/null
+++ b/java/lang/ArrayIndexOutOfBoundsException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown to indicate that an array has been accessed with an
+ * illegal index. The index is either negative or greater than or
+ * equal to the size of the array.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
+    private static final long serialVersionUID = -5116101128118950844L;
+
+    /**
+     * Constructs an <code>ArrayIndexOutOfBoundsException</code> with no
+     * detail message.
+     */
+    public ArrayIndexOutOfBoundsException() {
+        super();
+    }
+
+    /**
+     * Constructs a new <code>ArrayIndexOutOfBoundsException</code>
+     * class with an argument indicating the illegal index.
+     *
+     * @param   index   the illegal index.
+     */
+    public ArrayIndexOutOfBoundsException(int index) {
+        super("Array index out of range: " + index);
+    }
+
+    /**
+     * Constructs an <code>ArrayIndexOutOfBoundsException</code> class
+     * with the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ArrayIndexOutOfBoundsException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/ArrayStoreException.java b/java/lang/ArrayStoreException.java
new file mode 100644
index 0000000..5ea0aa9
--- /dev/null
+++ b/java/lang/ArrayStoreException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1995, 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;
+
+/**
+ * Thrown to indicate that an attempt has been made to store the
+ * wrong type of object into an array of objects. For example, the
+ * following code generates an <code>ArrayStoreException</code>:
+ * <blockquote><pre>
+ *     Object x[] = new String[3];
+ *     x[0] = new Integer(0);
+ * </pre></blockquote>
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class ArrayStoreException extends RuntimeException {
+    private static final long serialVersionUID = -4522193890499838241L;
+
+    /**
+     * Constructs an <code>ArrayStoreException</code> with no detail message.
+     */
+    public ArrayStoreException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>ArrayStoreException</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ArrayStoreException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/AssertionError.java b/java/lang/AssertionError.java
new file mode 100644
index 0000000..a560af5
--- /dev/null
+++ b/java/lang/AssertionError.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2000, 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 java.lang;
+
+/**
+ * Thrown to indicate that an assertion has failed.
+ *
+ * <p>The seven one-argument public constructors provided by this
+ * class ensure that the assertion error returned by the invocation:
+ * <pre>
+ *     new AssertionError(<i>expression</i>)
+ * </pre>
+ * has as its detail message the <i>string conversion</i> of
+ * <i>expression</i> (as defined in section 15.18.1.1 of
+ * <cite>The Java&trade; Language Specification</cite>),
+ * regardless of the type of <i>expression</i>.
+ *
+ * @since   1.4
+ */
+public class AssertionError extends Error {
+    private static final long serialVersionUID = -5013299493970297370L;
+
+    /**
+     * Constructs an AssertionError with no detail message.
+     */
+    public AssertionError() {
+    }
+
+    /**
+     * This internal constructor does no processing on its string argument,
+     * even if it is a null reference.  The public constructors will
+     * never call this constructor with a null argument.
+     */
+    private AssertionError(String detailMessage) {
+        super(detailMessage);
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified object, which is converted to a string as
+     * defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *<p>
+     * If the specified object is an instance of {@code Throwable}, it
+     * becomes the <i>cause</i> of the newly constructed assertion error.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     * @see   Throwable#getCause()
+     */
+    public AssertionError(Object detailMessage) {
+        this(String.valueOf(detailMessage));
+        if (detailMessage instanceof Throwable)
+            initCause((Throwable) detailMessage);
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>boolean</code>, which is converted to
+     * a string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(boolean detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>char</code>, which is converted to a
+     * string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(char detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>int</code>, which is converted to a
+     * string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(int detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>long</code>, which is converted to a
+     * string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(long detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>float</code>, which is converted to a
+     * string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(float detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs an AssertionError with its detail message derived
+     * from the specified <code>double</code>, which is converted to a
+     * string as defined in section 15.18.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param detailMessage value to be used in constructing detail message
+     */
+    public AssertionError(double detailMessage) {
+        this(String.valueOf(detailMessage));
+    }
+
+    /**
+     * Constructs a new {@code AssertionError} with the specified
+     * detail message and cause.
+     *
+     * <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this error's detail message.
+     *
+     * @param  message the detail message, may be {@code null}
+     * @param  cause the cause, may be {@code null}
+     *
+     * @since 1.7
+     */
+    public AssertionError(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/java/lang/AutoCloseable.java b/java/lang/AutoCloseable.java
new file mode 100644
index 0000000..135d9fe
--- /dev/null
+++ b/java/lang/AutoCloseable.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009, 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;
+
+/**
+ * An object that may hold resources (such as file or socket handles)
+ * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
+ * object is called automatically when exiting a {@code
+ * try}-with-resources block for which the object has been declared in
+ * the resource specification header. This construction ensures prompt
+ * release, avoiding resource exhaustion exceptions and errors that
+ * may otherwise occur.
+ *
+ * @apiNote
+ * <p>It is possible, and in fact common, for a base class to
+ * implement AutoCloseable even though not all of its subclasses or
+ * instances will hold releasable resources.  For code that must operate
+ * in complete generality, or when it is known that the {@code AutoCloseable}
+ * instance requires resource release, it is recommended to use {@code
+ * try}-with-resources constructions. However, when using facilities such as
+ * {@link java.util.stream.Stream} that support both I/O-based and
+ * non-I/O-based forms, {@code try}-with-resources blocks are in
+ * general unnecessary when using non-I/O-based forms.
+ *
+ * @author Josh Bloch
+ * @since 1.7
+ */
+public interface AutoCloseable {
+    /**
+     * Closes this resource, relinquishing any underlying resources.
+     * This method is invoked automatically on objects managed by the
+     * {@code try}-with-resources statement.
+     *
+     * <p>While this interface method is declared to throw {@code
+     * Exception}, implementers are <em>strongly</em> encouraged to
+     * declare concrete implementations of the {@code close} method to
+     * throw more specific exceptions, or to throw no exception at all
+     * if the close operation cannot fail.
+     *
+     * <p> Cases where the close operation may fail require careful
+     * attention by implementers. It is strongly advised to relinquish
+     * the underlying resources and to internally <em>mark</em> the
+     * resource as closed, prior to throwing the exception. The {@code
+     * close} method is unlikely to be invoked more than once and so
+     * this ensures that the resources are released in a timely manner.
+     * Furthermore it reduces problems that could arise when the resource
+     * wraps, or is wrapped, by another resource.
+     *
+     * <p><em>Implementers of this interface are also strongly advised
+     * to not have the {@code close} method throw {@link
+     * InterruptedException}.</em>
+     *
+     * This exception interacts with a thread's interrupted status,
+     * and runtime misbehavior is likely to occur if an {@code
+     * InterruptedException} is {@linkplain Throwable#addSuppressed
+     * suppressed}.
+     *
+     * More generally, if it would cause problems for an
+     * exception to be suppressed, the {@code AutoCloseable.close}
+     * method should not throw it.
+     *
+     * <p>Note that unlike the {@link java.io.Closeable#close close}
+     * method of {@link java.io.Closeable}, this {@code close} method
+     * is <em>not</em> required to be idempotent.  In other words,
+     * calling this {@code close} method more than once may have some
+     * visible side effect, unlike {@code Closeable.close} which is
+     * required to have no effect if called more than once.
+     *
+     * However, implementers of this interface are strongly encouraged
+     * to make their {@code close} methods idempotent.
+     *
+     * @throws Exception if this resource cannot be closed
+     */
+    void close() throws Exception;
+}
diff --git a/java/lang/Boolean.annotated.java b/java/lang/Boolean.annotated.java
new file mode 100644
index 0000000..8022814
--- /dev/null
+++ b/java/lang/Boolean.annotated.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Boolean implements java.io.Serializable, java.lang.Comparable<java.lang.Boolean> {
+
+public Boolean(boolean value) { throw new RuntimeException("Stub!"); }
+
+public Boolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean parseBoolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public boolean booleanValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Boolean valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Boolean valueOf(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(boolean value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Boolean b) { throw new RuntimeException("Stub!"); }
+
+public static int compare(boolean x, boolean y) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalAnd(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalOr(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalXor(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Boolean FALSE;
+static { FALSE = null; }
+
+public static final java.lang.Boolean TRUE;
+static { TRUE = null; }
+
+public static final java.lang.Class<java.lang.Boolean> TYPE;
+static { TYPE = null; }
+}
diff --git a/java/lang/Boolean.java b/java/lang/Boolean.java
new file mode 100644
index 0000000..a9293ba
--- /dev/null
+++ b/java/lang/Boolean.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1994, 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;
+
+/**
+ * The Boolean class wraps a value of the primitive type
+ * {@code boolean} in an object. An object of type
+ * {@code Boolean} contains a single field whose type is
+ * {@code boolean}.
+ * <p>
+ * In addition, this class provides many methods for
+ * converting a {@code boolean} to a {@code String} and a
+ * {@code String} to a {@code boolean}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code boolean}.
+ *
+ * @author  Arthur van Hoff
+ * @since   JDK1.0
+ */
+public final class Boolean implements java.io.Serializable,
+                                      Comparable<Boolean>
+{
+    /**
+     * The {@code Boolean} object corresponding to the primitive
+     * value {@code true}.
+     */
+    public static final Boolean TRUE = new Boolean(true);
+
+    /**
+     * The {@code Boolean} object corresponding to the primitive
+     * value {@code false}.
+     */
+    public static final Boolean FALSE = new Boolean(false);
+
+    /**
+     * The Class object representing the primitive type boolean.
+     *
+     * @since   JDK1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
+
+    /**
+     * The value of the Boolean.
+     *
+     * @serial
+     */
+    private final boolean value;
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -3665804199014368530L;
+
+    /**
+     * Allocates a {@code Boolean} object representing the
+     * {@code value} argument.
+     *
+     * <p><b>Note: It is rarely appropriate to use this constructor.
+     * Unless a <i>new</i> instance is required, the static factory
+     * {@link #valueOf(boolean)} is generally a better choice. It is
+     * likely to yield significantly better space and time performance.</b>
+     *
+     * @param   value   the value of the {@code Boolean}.
+     */
+    public Boolean(boolean value) {
+        this.value = value;
+    }
+
+    /**
+     * Allocates a {@code Boolean} object representing the value
+     * {@code true} if the string argument is not {@code null}
+     * and is equal, ignoring case, to the string {@code "true"}.
+     * Otherwise, allocate a {@code Boolean} object representing the
+     * value {@code false}. Examples:<p>
+     * {@code new Boolean("True")} produces a {@code Boolean} object
+     * that represents {@code true}.<br>
+     * {@code new Boolean("yes")} produces a {@code Boolean} object
+     * that represents {@code false}.
+     *
+     * @param   s   the string to be converted to a {@code Boolean}.
+     */
+    public Boolean(String s) {
+        this(parseBoolean(s));
+    }
+
+    /**
+     * Parses the string argument as a boolean.  The {@code boolean}
+     * returned represents the value {@code true} if the string argument
+     * is not {@code null} and is equal, ignoring case, to the string
+     * {@code "true"}. <p>
+     * Example: {@code Boolean.parseBoolean("True")} returns {@code true}.<br>
+     * Example: {@code Boolean.parseBoolean("yes")} returns {@code false}.
+     *
+     * @param      s   the {@code String} containing the boolean
+     *                 representation to be parsed
+     * @return     the boolean represented by the string argument
+     * @since 1.5
+     */
+    public static boolean parseBoolean(String s) {
+        return ((s != null) && s.equalsIgnoreCase("true"));
+    }
+
+    /**
+     * Returns the value of this {@code Boolean} object as a boolean
+     * primitive.
+     *
+     * @return  the primitive {@code boolean} value of this object.
+     */
+    public boolean booleanValue() {
+        return value;
+    }
+
+    /**
+     * Returns a {@code Boolean} instance representing the specified
+     * {@code boolean} value.  If the specified {@code boolean} value
+     * is {@code true}, this method returns {@code Boolean.TRUE};
+     * if it is {@code false}, this method returns {@code Boolean.FALSE}.
+     * If a new {@code Boolean} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Boolean(boolean)}, as this method is likely to yield
+     * significantly better space and time performance.
+     *
+     * @param  b a boolean value.
+     * @return a {@code Boolean} instance representing {@code b}.
+     * @since  1.4
+     */
+    public static Boolean valueOf(boolean b) {
+        return (b ? TRUE : FALSE);
+    }
+
+    /**
+     * Returns a {@code Boolean} with a value represented by the
+     * specified string.  The {@code Boolean} returned represents a
+     * true value if the string argument is not {@code null}
+     * and is equal, ignoring case, to the string {@code "true"}.
+     *
+     * @param   s   a string.
+     * @return  the {@code Boolean} value represented by the string.
+     */
+    public static Boolean valueOf(String s) {
+        return parseBoolean(s) ? TRUE : FALSE;
+    }
+
+    /**
+     * Returns a {@code String} object representing the specified
+     * boolean.  If the specified boolean is {@code true}, then
+     * the string {@code "true"} will be returned, otherwise the
+     * string {@code "false"} will be returned.
+     *
+     * @param b the boolean to be converted
+     * @return the string representation of the specified {@code boolean}
+     * @since 1.4
+     */
+    public static String toString(boolean b) {
+        return b ? "true" : "false";
+    }
+
+    /**
+     * Returns a {@code String} object representing this Boolean's
+     * value.  If this object represents the value {@code true},
+     * a string equal to {@code "true"} is returned. Otherwise, a
+     * string equal to {@code "false"} is returned.
+     *
+     * @return  a string representation of this object.
+     */
+    public String toString() {
+        return value ? "true" : "false";
+    }
+
+    /**
+     * Returns a hash code for this {@code Boolean} object.
+     *
+     * @return  the integer {@code 1231} if this object represents
+     * {@code true}; returns the integer {@code 1237} if this
+     * object represents {@code false}.
+     */
+    @Override
+    public int hashCode() {
+        return Boolean.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code boolean} value; compatible with
+     * {@code Boolean.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code boolean} value.
+     * @since 1.8
+     */
+    public static int hashCode(boolean value) {
+        return value ? 1231 : 1237;
+    }
+
+   /**
+     * Returns {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Boolean} object that
+     * represents the same {@code boolean} value as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  {@code true} if the Boolean objects represent the
+     *          same value; {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Boolean) {
+            return value == ((Boolean)obj).booleanValue();
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if and only if the system property
+     * named by the argument exists and is equal to the string
+     * {@code "true"}. (Beginning with version 1.0.2 of the
+     * Java<small><sup>TM</sup></small> platform, the test of
+     * this string is case insensitive.) A system property is accessible
+     * through {@code getProperty}, a method defined by the
+     * {@code System} class.
+     * <p>
+     * If there is no property with the specified name, or if the specified
+     * name is empty or null, then {@code false} is returned.
+     *
+     * @param   name   the system property name.
+     * @return  the {@code boolean} value of the system property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     java.lang.System#getProperty(java.lang.String)
+     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static boolean getBoolean(String name) {
+        boolean result = false;
+        try {
+            result = parseBoolean(System.getProperty(name));
+        } catch (IllegalArgumentException | NullPointerException e) {
+        }
+        return result;
+    }
+
+    /**
+     * Compares this {@code Boolean} instance with another.
+     *
+     * @param   b the {@code Boolean} instance to be compared
+     * @return  zero if this object represents the same boolean value as the
+     *          argument; a positive value if this object represents true
+     *          and the argument represents false; and a negative value if
+     *          this object represents false and the argument represents true
+     * @throws  NullPointerException if the argument is {@code null}
+     * @see     Comparable
+     * @since  1.5
+     */
+    public int compareTo(Boolean b) {
+        return compare(this.value, b.value);
+    }
+
+    /**
+     * Compares two {@code boolean} values.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code boolean} to compare
+     * @param  y the second {@code boolean} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code !x && y}; and
+     *         a value greater than {@code 0} if {@code x && !y}
+     * @since 1.7
+     */
+    public static int compare(boolean x, boolean y) {
+        return (x == y) ? 0 : (x ? 1 : -1);
+    }
+
+    /**
+     * Returns the result of applying the logical AND operator to the
+     * specified {@code boolean} operands.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the logical AND of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static boolean logicalAnd(boolean a, boolean b) {
+        return a && b;
+    }
+
+    /**
+     * Returns the result of applying the logical OR operator to the
+     * specified {@code boolean} operands.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the logical OR of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static boolean logicalOr(boolean a, boolean b) {
+        return a || b;
+    }
+
+    /**
+     * Returns the result of applying the logical XOR operator to the
+     * specified {@code boolean} operands.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return  the logical XOR of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static boolean logicalXor(boolean a, boolean b) {
+        return a ^ b;
+    }
+}
diff --git a/java/lang/BootstrapMethodError.java b/java/lang/BootstrapMethodError.java
new file mode 100644
index 0000000..a1509a0
--- /dev/null
+++ b/java/lang/BootstrapMethodError.java
@@ -0,0 +1,80 @@
+/*
+ * 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 java.lang;
+
+/**
+ * Thrown to indicate that an {@code invokedynamic} instruction has
+ * failed to find its bootstrap method,
+ * or the bootstrap method has failed to provide a
+ * {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
+ * of the correct {@linkplain java.lang.invoke.MethodHandle#type method type}.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class BootstrapMethodError extends LinkageError {
+    private static final long serialVersionUID = 292L;
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with no detail message.
+     */
+    public BootstrapMethodError() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with the specified
+     * detail message.
+     *
+     * @param s the detail message.
+     */
+    public BootstrapMethodError(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with the specified
+     * detail message and cause.
+     *
+     * @param s the detail message.
+     * @param cause the cause, may be {@code null}.
+     */
+    public BootstrapMethodError(String s, Throwable cause) {
+        super(s, cause);
+    }
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with the specified
+     * cause.
+     *
+     * @param cause the cause, may be {@code null}.
+     */
+    public BootstrapMethodError(Throwable cause) {
+        // cf. Throwable(Throwable cause) constructor.
+        super(cause == null ? null : cause.toString());
+        initCause(cause);
+    }
+}
diff --git a/java/lang/Byte.annotated.java b/java/lang/Byte.annotated.java
new file mode 100644
index 0000000..b64ca1e
--- /dev/null
+++ b/java/lang/Byte.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+
+public Byte(byte value) { throw new RuntimeException("Stub!"); }
+
+public Byte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
+
+public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
+
+public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 1; // 0x1
+
+public static final byte MAX_VALUE = 127; // 0x7f
+
+public static final byte MIN_VALUE = -128; // 0xffffff80
+
+public static final int SIZE = 8; // 0x8
+
+public static final java.lang.Class<java.lang.Byte> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Byte.java b/java/lang/Byte.java
new file mode 100644
index 0000000..deb4ecb
--- /dev/null
+++ b/java/lang/Byte.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 1996, 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;
+
+import libcore.util.HexEncoding;
+
+/**
+ *
+ * The {@code Byte} class wraps a value of primitive type {@code byte}
+ * in an object.  An object of type {@code Byte} contains a single
+ * field whose type is {@code byte}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * a {@code byte} to a {@code String} and a {@code String} to a {@code
+ * byte}, as well as other constants and methods useful when dealing
+ * with a {@code byte}.
+ *
+ * @author  Nakul Saraiya
+ * @author  Joseph D. Darcy
+ * @see     java.lang.Number
+ * @since   JDK1.1
+ */
+public final class Byte extends Number implements Comparable<Byte> {
+
+    /**
+     * A constant holding the minimum value a {@code byte} can
+     * have, -2<sup>7</sup>.
+     */
+    public static final byte   MIN_VALUE = -128;
+
+    /**
+     * A constant holding the maximum value a {@code byte} can
+     * have, 2<sup>7</sup>-1.
+     */
+    public static final byte   MAX_VALUE = 127;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code byte}.
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
+
+    /**
+     * Returns a new {@code String} object representing the
+     * specified {@code byte}. The radix is assumed to be 10.
+     *
+     * @param b the {@code byte} to be converted
+     * @return the string representation of the specified {@code byte}
+     * @see java.lang.Integer#toString(int)
+     */
+    public static String toString(byte b) {
+        return Integer.toString((int)b, 10);
+    }
+
+    private static class ByteCache {
+        private ByteCache(){}
+
+        static final Byte cache[] = new Byte[-(-128) + 127 + 1];
+
+        static {
+            for(int i = 0; i < cache.length; i++)
+                cache[i] = new Byte((byte)(i - 128));
+        }
+    }
+
+    /**
+     * Returns a {@code Byte} instance representing the specified
+     * {@code byte} value.
+     * If a new {@code Byte} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Byte(byte)}, as this method is likely to yield
+     * significantly better space and time performance since
+     * all byte values are cached.
+     *
+     * @param  b a byte value.
+     * @return a {@code Byte} instance representing {@code b}.
+     * @since  1.5
+     */
+    public static Byte valueOf(byte b) {
+        final int offset = 128;
+        return ByteCache.cache[(int)b + offset];
+    }
+
+    /**
+     * Parses the string argument as a signed {@code byte} in the
+     * radix specified by the second argument. The characters in the
+     * string must all be digits, of the specified radix (as
+     * determined by whether {@link java.lang.Character#digit(char,
+     * int)} returns a nonnegative value) except that the first
+     * character may be an ASCII minus sign {@code '-'}
+     * ({@code '\u005Cu002D'}) to indicate a negative value or an
+     * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+     * indicate a positive value.  The resulting {@code byte} value is
+     * returned.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     * <li> The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li> The radix is either smaller than {@link
+     * java.lang.Character#MIN_RADIX} or larger than {@link
+     * java.lang.Character#MAX_RADIX}.
+     *
+     * <li> Any character of the string is not a digit of the
+     * specified radix, except that the first character may be a minus
+     * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+     * string is longer than length 1.
+     *
+     * <li> The value represented by the string is not a value of type
+     * {@code byte}.
+     * </ul>
+     *
+     * @param s         the {@code String} containing the
+     *                  {@code byte}
+     *                  representation to be parsed
+     * @param radix     the radix to be used while parsing {@code s}
+     * @return          the {@code byte} value represented by the string
+     *                   argument in the specified radix
+     * @throws          NumberFormatException If the string does
+     *                  not contain a parsable {@code byte}.
+     */
+    public static byte parseByte(String s, int radix)
+        throws NumberFormatException {
+        int i = Integer.parseInt(s, radix);
+        if (i < MIN_VALUE || i > MAX_VALUE)
+            throw new NumberFormatException(
+                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
+        return (byte)i;
+    }
+
+    /**
+     * Parses the string argument as a signed decimal {@code
+     * byte}. The characters in the string must all be decimal digits,
+     * except that the first character may be an ASCII minus sign
+     * {@code '-'} ({@code '\u005Cu002D'}) to indicate a negative
+     * value or an ASCII plus sign {@code '+'}
+     * ({@code '\u005Cu002B'}) to indicate a positive value. The
+     * resulting {@code byte} value is returned, exactly as if the
+     * argument and the radix 10 were given as arguments to the {@link
+     * #parseByte(java.lang.String, int)} method.
+     *
+     * @param s         a {@code String} containing the
+     *                  {@code byte} representation to be parsed
+     * @return          the {@code byte} value represented by the
+     *                  argument in decimal
+     * @throws          NumberFormatException if the string does not
+     *                  contain a parsable {@code byte}.
+     */
+    public static byte parseByte(String s) throws NumberFormatException {
+        return parseByte(s, 10);
+    }
+
+    /**
+     * Returns a {@code Byte} object holding the value
+     * extracted from the specified {@code String} when parsed
+     * with the radix given by the second argument. The first argument
+     * is interpreted as representing a signed {@code byte} in
+     * the radix specified by the second argument, exactly as if the
+     * argument were given to the {@link #parseByte(java.lang.String,
+     * int)} method. The result is a {@code Byte} object that
+     * represents the {@code byte} value specified by the string.
+     *
+     * <p> In other words, this method returns a {@code Byte} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     * {@code new Byte(Byte.parseByte(s, radix))}
+     * </blockquote>
+     *
+     * @param s         the string to be parsed
+     * @param radix     the radix to be used in interpreting {@code s}
+     * @return          a {@code Byte} object holding the value
+     *                  represented by the string argument in the
+     *                  specified radix.
+     * @throws          NumberFormatException If the {@code String} does
+     *                  not contain a parsable {@code byte}.
+     */
+    public static Byte valueOf(String s, int radix)
+        throws NumberFormatException {
+        return valueOf(parseByte(s, radix));
+    }
+
+    /**
+     * Returns a {@code Byte} object holding the value
+     * given by the specified {@code String}. The argument is
+     * interpreted as representing a signed decimal {@code byte},
+     * exactly as if the argument were given to the {@link
+     * #parseByte(java.lang.String)} method. The result is a
+     * {@code Byte} object that represents the {@code byte}
+     * value specified by the string.
+     *
+     * <p> In other words, this method returns a {@code Byte} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     * {@code new Byte(Byte.parseByte(s))}
+     * </blockquote>
+     *
+     * @param s         the string to be parsed
+     * @return          a {@code Byte} object holding the value
+     *                  represented by the string argument
+     * @throws          NumberFormatException If the {@code String} does
+     *                  not contain a parsable {@code byte}.
+     */
+    public static Byte valueOf(String s) throws NumberFormatException {
+        return valueOf(s, 10);
+    }
+
+    /**
+     * Decodes a {@code String} into a {@code Byte}.
+     * Accepts decimal, hexadecimal, and octal numbers given by
+     * the following grammar:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>DecodableString:</i>
+     * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+     *
+     * <dt><i>Sign:</i>
+     * <dd>{@code -}
+     * <dd>{@code +}
+     * </dl>
+     * </blockquote>
+     *
+     * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+     * are as defined in section 3.10.1 of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     *
+     * <p>The sequence of characters following an optional
+     * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+     * "{@code #}", or leading zero) is parsed as by the {@code
+     * Byte.parseByte} method with the indicated radix (10, 16, or 8).
+     * This sequence of characters must represent a positive value or
+     * a {@link NumberFormatException} will be thrown.  The result is
+     * negated if first character of the specified {@code String} is
+     * the minus sign.  No whitespace characters are permitted in the
+     * {@code String}.
+     *
+     * @param     nm the {@code String} to decode.
+     * @return   a {@code Byte} object holding the {@code byte}
+     *          value represented by {@code nm}
+     * @throws  NumberFormatException  if the {@code String} does not
+     *            contain a parsable {@code byte}.
+     * @see java.lang.Byte#parseByte(java.lang.String, int)
+     */
+    public static Byte decode(String nm) throws NumberFormatException {
+        int i = Integer.decode(nm);
+        if (i < MIN_VALUE || i > MAX_VALUE)
+            throw new NumberFormatException(
+                    "Value " + i + " out of range from input " + nm);
+        return valueOf((byte)i);
+    }
+
+    /**
+     * The value of the {@code Byte}.
+     *
+     * @serial
+     */
+    private final byte value;
+
+    /**
+     * Constructs a newly allocated {@code Byte} object that
+     * represents the specified {@code byte} value.
+     *
+     * @param value     the value to be represented by the
+     *                  {@code Byte}.
+     */
+    public Byte(byte value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Byte} object that
+     * represents the {@code byte} value indicated by the
+     * {@code String} parameter. The string is converted to a
+     * {@code byte} value in exactly the manner used by the
+     * {@code parseByte} method for radix 10.
+     *
+     * @param s         the {@code String} to be converted to a
+     *                  {@code Byte}
+     * @throws           NumberFormatException If the {@code String}
+     *                  does not contain a parsable {@code byte}.
+     * @see        java.lang.Byte#parseByte(java.lang.String, int)
+     */
+    public Byte(String s) throws NumberFormatException {
+        this.value = parseByte(s, 10);
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as a
+     * {@code byte}.
+     */
+    public byte byteValue() {
+        return value;
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as a {@code short} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public short shortValue() {
+        return (short)value;
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as an {@code int} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public int intValue() {
+        return (int)value;
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as a {@code long} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public long longValue() {
+        return (long)value;
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as a {@code float} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public float floatValue() {
+        return (float)value;
+    }
+
+    /**
+     * Returns the value of this {@code Byte} as a {@code double}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public double doubleValue() {
+        return (double)value;
+    }
+
+    /**
+     * Returns a {@code String} object representing this
+     * {@code Byte}'s value.  The value is converted to signed
+     * decimal representation and returned as a string, exactly as if
+     * the {@code byte} value were given as an argument to the
+     * {@link java.lang.Byte#toString(byte)} method.
+     *
+     * @return  a string representation of the value of this object in
+     *          base&nbsp;10.
+     */
+    public String toString() {
+        return Integer.toString((int)value);
+    }
+
+    /**
+     * Returns a hash code for this {@code Byte}; equal to the result
+     * of invoking {@code intValue()}.
+     *
+     * @return a hash code value for this {@code Byte}
+     */
+    @Override
+    public int hashCode() {
+        return Byte.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code byte} value; compatible with
+     * {@code Byte.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code byte} value.
+     * @since 1.8
+     */
+    public static int hashCode(byte value) {
+        return (int)value;
+    }
+
+    /**
+     * Compares this object to the specified object.  The result is
+     * {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Byte} object that
+     * contains the same {@code byte} value as this object.
+     *
+     * @param obj       the object to compare with
+     * @return          {@code true} if the objects are the same;
+     *                  {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Byte) {
+            return value == ((Byte)obj).byteValue();
+        }
+        return false;
+    }
+
+    /**
+     * Compares two {@code Byte} objects numerically.
+     *
+     * @param   anotherByte   the {@code Byte} to be compared.
+     * @return  the value {@code 0} if this {@code Byte} is
+     *          equal to the argument {@code Byte}; a value less than
+     *          {@code 0} if this {@code Byte} is numerically less
+     *          than the argument {@code Byte}; and a value greater than
+     *           {@code 0} if this {@code Byte} is numerically
+     *           greater than the argument {@code Byte} (signed
+     *           comparison).
+     * @since   1.2
+     */
+    public int compareTo(Byte anotherByte) {
+        return compare(this.value, anotherByte.value);
+    }
+
+    /**
+     * Compares two {@code byte} values numerically.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Byte.valueOf(x).compareTo(Byte.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code byte} to compare
+     * @param  y the second {@code byte} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code x < y}; and
+     *         a value greater than {@code 0} if {@code x > y}
+     * @since 1.7
+     */
+    public static int compare(byte x, byte y) {
+        return x - y;
+    }
+
+    /**
+     * Converts the argument to an {@code int} by an unsigned
+     * conversion.  In an unsigned conversion to an {@code int}, the
+     * high-order 24 bits of the {@code int} are zero and the
+     * low-order 8 bits are equal to the bits of the {@code byte} argument.
+     *
+     * Consequently, zero and positive {@code byte} values are mapped
+     * to a numerically equal {@code int} value and negative {@code
+     * byte} values are mapped to an {@code int} value equal to the
+     * input plus 2<sup>8</sup>.
+     *
+     * @param  x the value to convert to an unsigned {@code int}
+     * @return the argument converted to {@code int} by an unsigned
+     *         conversion
+     * @since 1.8
+     */
+    public static int toUnsignedInt(byte x) {
+        return ((int) x) & 0xff;
+    }
+
+    /**
+     * Converts the argument to a {@code long} by an unsigned
+     * conversion.  In an unsigned conversion to a {@code long}, the
+     * high-order 56 bits of the {@code long} are zero and the
+     * low-order 8 bits are equal to the bits of the {@code byte} argument.
+     *
+     * Consequently, zero and positive {@code byte} values are mapped
+     * to a numerically equal {@code long} value and negative {@code
+     * byte} values are mapped to a {@code long} value equal to the
+     * input plus 2<sup>8</sup>.
+     *
+     * @param  x the value to convert to an unsigned {@code long}
+     * @return the argument converted to {@code long} by an unsigned
+     *         conversion
+     * @since 1.8
+     */
+    public static long toUnsignedLong(byte x) {
+        return ((long) x) & 0xffL;
+    }
+
+
+    /**
+     * The number of bits used to represent a {@code byte} value in two's
+     * complement binary form.
+     *
+     * @since 1.5
+     */
+    public static final int SIZE = 8;
+
+    /**
+     * The number of bytes used to represent a {@code byte} value in two's
+     * complement binary form.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /** use serialVersionUID from JDK 1.1. for interoperability */
+    private static final long serialVersionUID = -7183698231559129828L;
+
+    // BEGIN Android-added: toHexString() for internal use.
+    /**
+     * @hide
+     */
+    public static String toHexString(byte b, boolean upperCase) {
+        // This method currently retained because it is marked @UnsupportedAppUsage.
+        return HexEncoding.encodeToString(b, upperCase);
+    }
+    // END Android-added: toHexString() for internal use.
+}
diff --git a/java/lang/CaseMapper.java b/java/lang/CaseMapper.java
new file mode 100644
index 0000000..04eef09
--- /dev/null
+++ b/java/lang/CaseMapper.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.icu.text.Transliterator;
+import com.android.icu.util.CaseMapperNative;
+import java.util.Locale;
+
+/**
+ * Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
+ */
+class CaseMapper {
+    private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".toCharArray();
+    private static final char[] upperValues2 = "\u000b\u0000\f\u0000\r\u0000\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>\u0000\u0000?@A\u0000BC\u0000\u0000\u0000\u0000D\u0000\u0000\u0000\u0000\u0000EFG\u0000HI\u0000\u0000\u0000\u0000J\u0000\u0000\u0000\u0000\u0000KL\u0000\u0000MN\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000OPQ\u0000RS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TUV\u0000WX\u0000\u0000\u0000\u0000Y".toCharArray();
+
+    private static final char LATIN_CAPITAL_I_WITH_DOT = '\u0130';
+    private static final char GREEK_CAPITAL_SIGMA = '\u03a3';
+    private static final char GREEK_SMALL_FINAL_SIGMA = '\u03c2';
+
+    /**
+     * Our current GC makes short-lived objects more expensive than we'd like. When that's fixed,
+     * this class should be changed so that you instantiate it with the String and its value,
+     * and count fields.
+     */
+    private CaseMapper() {
+    }
+
+    /**
+     * Implements String.toLowerCase. The original String instance is returned if nothing changes.
+     */
+    public static String toLowerCase(Locale locale, String s) {
+        // Punt hard cases to ICU4C.
+        // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase.
+        String languageCode = locale.getLanguage();
+        if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+            return CaseMapperNative.toLowerCase(s, locale);
+        }
+
+        char[] newValue = null;
+        for (int i = 0, end = s.length(); i < end; ++i) {
+            char ch = s.charAt(i);
+            char newCh;
+            if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) {
+                // Punt these hard cases.
+                return CaseMapperNative.toLowerCase(s, locale);
+            } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(s, i)) {
+                newCh = GREEK_SMALL_FINAL_SIGMA;
+            } else {
+                newCh = Character.toLowerCase(ch);
+            }
+            if (ch != newCh) {
+                if (newValue == null) {
+                    newValue = new char[end];
+                    s.getCharsNoCheck(0, end, newValue, 0);
+                }
+                newValue[i] = newCh;
+            }
+        }
+        return newValue != null ? new String(newValue) : s;
+    }
+
+    /**
+     * True if 'index' is preceded by a sequence consisting of a cased letter and a case-ignorable
+     * sequence, and 'index' is not followed by a sequence consisting of an ignorable sequence and
+     * then a cased letter.
+     */
+    private static boolean isFinalSigma(String s, int index) {
+        // TODO: we don't skip case-ignorable sequences like we should.
+        // TODO: we should add a more direct way to test for a cased letter.
+        if (index <= 0) {
+            return false;
+        }
+        char previous = s.charAt(index - 1);
+        if (!(Character.isLowerCase(previous) || Character.isUpperCase(previous) || Character.isTitleCase(previous))) {
+            return false;
+        }
+        if (index + 1 >= s.length()) {
+            return true;
+        }
+        char next = s.charAt(index + 1);
+        if (Character.isLowerCase(next) || Character.isUpperCase(next) || Character.isTitleCase(next)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Return the index of the specified character into the upperValues table.
+     * The upperValues table contains three entries at each position. These
+     * three characters are the upper case conversion. If only two characters
+     * are used, the third character in the table is \u0000.
+     * @return the index into the upperValues table, or -1
+     */
+    private static int upperIndex(int ch) {
+        int index = -1;
+        if (ch >= 0xdf) {
+            if (ch <= 0x587) {
+                switch (ch) {
+                case 0xdf: return 0;
+                case 0x149: return 1;
+                case 0x1f0: return 2;
+                case 0x390: return 3;
+                case 0x3b0: return 4;
+                case 0x587: return 5;
+                }
+            } else if (ch >= 0x1e96) {
+                if (ch <= 0x1e9a) {
+                    index = 6 + ch - 0x1e96;
+                } else if (ch >= 0x1f50 && ch <= 0x1ffc) {
+                    index = upperValues2[ch - 0x1f50];
+                    if (index == 0) {
+                        index = -1;
+                    }
+                } else if (ch >= 0xfb00) {
+                    if (ch <= 0xfb06) {
+                        index = 90 + ch - 0xfb00;
+                    } else if (ch >= 0xfb13 && ch <= 0xfb17) {
+                        index = 97 + ch - 0xfb13;
+                    }
+                }
+            }
+        }
+        return index;
+    }
+
+    private static final ThreadLocal<Transliterator> EL_UPPER = new ThreadLocal<Transliterator>() {
+        @Override protected Transliterator initialValue() {
+            return Transliterator.getInstance("el-Upper");
+        }
+    };
+
+    public static String toUpperCase(Locale locale, String s, int count) {
+        String languageCode = locale.getLanguage();
+        if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+            return CaseMapperNative.toUpperCase(s, locale);
+        }
+        if (languageCode.equals("el")) {
+            return EL_UPPER.get().transliterate(s);
+        }
+
+        char[] output = null;
+        int i = 0;
+        for (int o = 0; o < count; o++) {
+            char ch = s.charAt(o);
+            if (Character.isHighSurrogate(ch)) {
+                return CaseMapperNative.toUpperCase(s, locale);
+            }
+            int index = upperIndex(ch);
+            if (index == -1) {
+                if (output != null && i >= output.length) {
+                    char[] newoutput = new char[output.length + (count / 6) + 2];
+                    System.arraycopy(output, 0, newoutput, 0, output.length);
+                    output = newoutput;
+                }
+                char upch = Character.toUpperCase(ch);
+                if (output != null) {
+                    output[i++] = upch;
+                } else if (ch != upch) {
+                    output = new char[count];
+                    i = o;
+                    s.getCharsNoCheck(0, i, output, 0);
+                    output[i++] = upch;
+                }
+            } else {
+                int target = index * 3;
+                char val3 = upperValues[target + 2];
+                if (output == null) {
+                    output = new char[count + (count / 6) + 2];
+                    i = o;
+                    s.getCharsNoCheck(0, i, output, 0);
+                } else if (i + (val3 == 0 ? 1 : 2) >= output.length) {
+                    char[] newoutput = new char[output.length + (count / 6) + 3];
+                    System.arraycopy(output, 0, newoutput, 0, output.length);
+                    output = newoutput;
+                }
+
+                char val = upperValues[target];
+                output[i++] = val;
+                val = upperValues[target + 1];
+                output[i++] = val;
+                if (val3 != 0) {
+                    output[i++] = val3;
+                }
+            }
+        }
+        if (output == null) {
+            return s;
+        }
+        return output.length == i || output.length - i < 8 ? new String(0, i, output) : new String(output, 0, i);
+    }
+}
diff --git a/java/lang/CharSequence.annotated.java b/java/lang/CharSequence.annotated.java
new file mode 100644
index 0000000..e61d5d4
--- /dev/null
+++ b/java/lang/CharSequence.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000, 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;
+
+import java.util.stream.IntStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface CharSequence {
+
+public int length();
+
+public char charAt(int index);
+
[email protected] public java.lang.CharSequence subSequence(int start, int end);
+
[email protected] public java.lang.String toString();
+
[email protected] public default java.util.stream.IntStream chars() { throw new RuntimeException("Stub!"); }
+
[email protected] public default java.util.stream.IntStream codePoints() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/CharSequence.java b/java/lang/CharSequence.java
new file mode 100644
index 0000000..4d9ab3f
--- /dev/null
+++ b/java/lang/CharSequence.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 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;
+
+import java.util.NoSuchElementException;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.IntConsumer;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
+
+/**
+ * A <tt>CharSequence</tt> is a readable sequence of <code>char</code> values. This
+ * interface provides uniform, read-only access to many different kinds of
+ * <code>char</code> sequences.
+ * A <code>char</code> value represents a character in the <i>Basic
+ * Multilingual Plane (BMP)</i> or a surrogate. Refer to <a
+ * href="Character.html#unicode">Unicode Character Representation</a> for details.
+ *
+ * <p> This interface does not refine the general contracts of the {@link
+ * java.lang.Object#equals(java.lang.Object) equals} and {@link
+ * java.lang.Object#hashCode() hashCode} methods.  The result of comparing two
+ * objects that implement <tt>CharSequence</tt> is therefore, in general,
+ * undefined.  Each object may be implemented by a different class, and there
+ * is no guarantee that each class will be capable of testing its instances
+ * for equality with those of the other.  It is therefore inappropriate to use
+ * arbitrary <tt>CharSequence</tt> instances as elements in a set or as keys in
+ * a map. </p>
+ *
+ * @author Mike McCloskey
+ * @since 1.4
+ * @spec JSR-51
+ */
+
+public interface CharSequence {
+
+    /**
+     * Returns the length of this character sequence.  The length is the number
+     * of 16-bit <code>char</code>s in the sequence.
+     *
+     * @return  the number of <code>char</code>s in this sequence
+     */
+    int length();
+
+    /**
+     * Returns the <code>char</code> value at the specified index.  An index ranges from zero
+     * to <tt>length() - 1</tt>.  The first <code>char</code> value of the sequence is at
+     * index zero, the next at index one, and so on, as for array
+     * indexing.
+     *
+     * <p>If the <code>char</code> value specified by the index is a
+     * <a href="{@docRoot}/java/lang/Character.html#unicode">surrogate</a>, the surrogate
+     * value is returned.
+     *
+     * @param   index   the index of the <code>char</code> value to be returned
+     *
+     * @return  the specified <code>char</code> value
+     *
+     * @throws  IndexOutOfBoundsException
+     *          if the <tt>index</tt> argument is negative or not less than
+     *          <tt>length()</tt>
+     */
+    char charAt(int index);
+
+    /**
+     * Returns a <code>CharSequence</code> that is a subsequence of this sequence.
+     * The subsequence starts with the <code>char</code> value at the specified index and
+     * ends with the <code>char</code> value at index <tt>end - 1</tt>.  The length
+     * (in <code>char</code>s) of the
+     * returned sequence is <tt>end - start</tt>, so if <tt>start == end</tt>
+     * then an empty sequence is returned.
+     *
+     * @param   start   the start index, inclusive
+     * @param   end     the end index, exclusive
+     *
+     * @return  the specified subsequence
+     *
+     * @throws  IndexOutOfBoundsException
+     *          if <tt>start</tt> or <tt>end</tt> are negative,
+     *          if <tt>end</tt> is greater than <tt>length()</tt>,
+     *          or if <tt>start</tt> is greater than <tt>end</tt>
+     */
+    CharSequence subSequence(int start, int end);
+
+    /**
+     * Returns a string containing the characters in this sequence in the same
+     * order as this sequence.  The length of the string will be the length of
+     * this sequence.
+     *
+     * @return  a string consisting of exactly this sequence of characters
+     */
+    public String toString();
+
+    /**
+     * Returns a stream of {@code int} zero-extending the {@code char} values
+     * from this sequence.  Any char which maps to a <a
+     * href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
+     * point</a> is passed through uninterpreted.
+     *
+     * <p>If the sequence is mutated while the stream is being read, the
+     * result is undefined.
+     *
+     * @return an IntStream of char values from this sequence
+     * @since 1.8
+     */
+    public default IntStream chars() {
+        class CharIterator implements PrimitiveIterator.OfInt {
+            int cur = 0;
+
+            public boolean hasNext() {
+                return cur < length();
+            }
+
+            public int nextInt() {
+                if (hasNext()) {
+                    return charAt(cur++);
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+
+            @Override
+            public void forEachRemaining(IntConsumer block) {
+                for (; cur < length(); cur++) {
+                    block.accept(charAt(cur));
+                }
+            }
+        }
+
+        return StreamSupport.intStream(() ->
+                Spliterators.spliterator(
+                        new CharIterator(),
+                        length(),
+                        Spliterator.ORDERED),
+                Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED,
+                false);
+    }
+
+    /**
+     * Returns a stream of code point values from this sequence.  Any surrogate
+     * pairs encountered in the sequence are combined as if by {@linkplain
+     * Character#toCodePoint Character.toCodePoint} and the result is passed
+     * to the stream. Any other code units, including ordinary BMP characters,
+     * unpaired surrogates, and undefined code units, are zero-extended to
+     * {@code int} values which are then passed to the stream.
+     *
+     * <p>If the sequence is mutated while the stream is being read, the result
+     * is undefined.
+     *
+     * @return an IntStream of Unicode code points from this sequence
+     * @since 1.8
+     */
+    public default IntStream codePoints() {
+        class CodePointIterator implements PrimitiveIterator.OfInt {
+            int cur = 0;
+
+            @Override
+            public void forEachRemaining(IntConsumer block) {
+                final int length = length();
+                int i = cur;
+                try {
+                    while (i < length) {
+                        char c1 = charAt(i++);
+                        if (!Character.isHighSurrogate(c1) || i >= length) {
+                            block.accept(c1);
+                        } else {
+                            char c2 = charAt(i);
+                            if (Character.isLowSurrogate(c2)) {
+                                i++;
+                                block.accept(Character.toCodePoint(c1, c2));
+                            } else {
+                                block.accept(c1);
+                            }
+                        }
+                    }
+                } finally {
+                    cur = i;
+                }
+            }
+
+            public boolean hasNext() {
+                return cur < length();
+            }
+
+            public int nextInt() {
+                final int length = length();
+
+                if (cur >= length) {
+                    throw new NoSuchElementException();
+                }
+                char c1 = charAt(cur++);
+                if (Character.isHighSurrogate(c1) && cur < length) {
+                    char c2 = charAt(cur);
+                    if (Character.isLowSurrogate(c2)) {
+                        cur++;
+                        return Character.toCodePoint(c1, c2);
+                    }
+                }
+                return c1;
+            }
+        }
+
+        return StreamSupport.intStream(() ->
+                Spliterators.spliteratorUnknownSize(
+                        new CodePointIterator(),
+                        Spliterator.ORDERED),
+                Spliterator.ORDERED,
+                false);
+    }
+}
diff --git a/java/lang/Character.annotated.java b/java/lang/Character.annotated.java
new file mode 100644
index 0000000..d50474f
--- /dev/null
+++ b/java/lang/Character.annotated.java
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (c) 2002, 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;
+
+import java.util.Locale;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Character implements java.io.Serializable, java.lang.Comparable<java.lang.Character> {
+
+public Character(char value) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+public char charValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(char value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isValidCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isBmpCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSupplementaryCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isHighSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogatePair(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int charCount(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toCodePoint(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index, int limit) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index, int start) { throw new RuntimeException("Stub!"); }
+
+public static char highSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char lowSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toChars(int codePoint, char[] dst, int dstIndex) { throw new RuntimeException("Stub!"); }
+
+public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(@libcore.util.NonNull java.lang.CharSequence seq, int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(char[] a, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(@libcore.util.NonNull java.lang.CharSequence seq, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isAlphabetic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdeographic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int digit(char ch, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int digit(int codePoint, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isSpace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int getType(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getType(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char forDigit(int digit, int radix) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(char ch) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Character anotherCharacter) { throw new RuntimeException("Stub!"); }
+
+public static int compare(char x, char y) { throw new RuntimeException("Stub!"); }
+
+public static char reverseBytes(char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String getName(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 2; // 0x2
+
+public static final byte COMBINING_SPACING_MARK = 8; // 0x8
+
+public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
+
+public static final byte CONTROL = 15; // 0xf
+
+public static final byte CURRENCY_SYMBOL = 26; // 0x1a
+
+public static final byte DASH_PUNCTUATION = 20; // 0x14
+
+public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
+
+public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
+
+public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
+
+public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
+
+public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
+
+public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
+
+public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
+
+public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
+
+public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
+
+public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
+
+public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
+
+public static final byte ENCLOSING_MARK = 7; // 0x7
+
+public static final byte END_PUNCTUATION = 22; // 0x16
+
+public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
+
+public static final byte FORMAT = 16; // 0x10
+
+public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
+
+public static final byte LETTER_NUMBER = 10; // 0xa
+
+public static final byte LINE_SEPARATOR = 13; // 0xd
+
+public static final byte LOWERCASE_LETTER = 2; // 0x2
+
+public static final byte MATH_SYMBOL = 25; // 0x19
+
+public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
+
+public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
+
+public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final int MAX_RADIX = 36; // 0x24
+
+public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
+
+public static final int MIN_CODE_POINT = 0; // 0x0
+
+public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
+
+public static final int MIN_RADIX = 2; // 0x2
+
+public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
+
+public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
+
+public static final byte MODIFIER_LETTER = 4; // 0x4
+
+public static final byte MODIFIER_SYMBOL = 27; // 0x1b
+
+public static final byte NON_SPACING_MARK = 6; // 0x6
+
+public static final byte OTHER_LETTER = 5; // 0x5
+
+public static final byte OTHER_NUMBER = 11; // 0xb
+
+public static final byte OTHER_PUNCTUATION = 24; // 0x18
+
+public static final byte OTHER_SYMBOL = 28; // 0x1c
+
+public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
+
+public static final byte PRIVATE_USE = 18; // 0x12
+
+public static final int SIZE = 16; // 0x10
+
+public static final byte SPACE_SEPARATOR = 12; // 0xc
+
+public static final byte START_PUNCTUATION = 21; // 0x15
+
+public static final byte SURROGATE = 19; // 0x13
+
+public static final byte TITLECASE_LETTER = 3; // 0x3
+
+public static final java.lang.Class<java.lang.Character> TYPE;
+static { TYPE = null; }
+
+public static final byte UNASSIGNED = 0; // 0x0
+
+public static final byte UPPERCASE_LETTER = 1; // 0x1
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Subset {
+
+protected Subset(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class UnicodeBlock extends java.lang.Character.Subset {
+
+UnicodeBlock(java.lang.String idName) { super(null); throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock of(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock of(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock forName(@libcore.util.NonNull java.lang.String blockName) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+static { AEGEAN_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
+static { ALCHEMICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+static { ALPHABETIC_PRESENTATION_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+static { ANCIENT_GREEK_MUSICAL_NOTATION = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+static { ANCIENT_GREEK_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
+static { ANCIENT_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC;
+static { ARABIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
+static { ARABIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
+static { ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
+static { ARABIC_PRESENTATION_FORMS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+static { ARABIC_PRESENTATION_FORMS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
+static { ARABIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ARMENIAN;
+static { ARMENIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock ARROWS;
+static { ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock AVESTAN;
+static { AVESTAN = null; }
+
+public static final java.lang.Character.UnicodeBlock BALINESE;
+static { BALINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM;
+static { BAMUM = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
+static { BAMUM_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+static { BASIC_LATIN = null; }
+
+public static final java.lang.Character.UnicodeBlock BATAK;
+static { BATAK = null; }
+
+public static final java.lang.Character.UnicodeBlock BENGALI;
+static { BENGALI = null; }
+
+public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
+static { BLOCK_ELEMENTS = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO;
+static { BOPOMOFO = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
+static { BOPOMOFO_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+static { BOX_DRAWING = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAHMI;
+static { BRAHMI = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+static { BRAILLE_PATTERNS = null; }
+
+public static final java.lang.Character.UnicodeBlock BUGINESE;
+static { BUGINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BUHID;
+static { BUHID = null; }
+
+public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+static { BYZANTINE_MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CARIAN;
+static { CARIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAKMA;
+static { CHAKMA = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAM;
+static { CHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock CHEROKEE;
+static { CHEROKEE = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
+static { CJK_COMPATIBILITY = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
+static { CJK_COMPATIBILITY_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
+static { CJK_COMPATIBILITY_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+static { CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+static { CJK_RADICALS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_STROKES;
+static { CJK_STROKES = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
+static { CJK_SYMBOLS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
+static { CJK_UNIFIED_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+static { COMBINING_DIACRITICAL_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
+static { COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
+static { COMBINING_HALF_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+static { COMBINING_MARKS_FOR_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
+static { COMMON_INDIC_NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+static { CONTROL_PICTURES = null; }
+
+public static final java.lang.Character.UnicodeBlock COPTIC;
+static { COPTIC = null; }
+
+public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+static { COUNTING_ROD_NUMERALS = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+static { CUNEIFORM = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
+static { CUNEIFORM_NUMBERS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
+static { CURRENCY_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
+static { CYPRIOT_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC;
+static { CYRILLIC = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+static { CYRILLIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
+static { CYRILLIC_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
+static { CYRILLIC_SUPPLEMENTARY = null; }
+
+public static final java.lang.Character.UnicodeBlock DESERET;
+static { DESERET = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+static { DEVANAGARI = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
+static { DEVANAGARI_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock DINGBATS;
+static { DINGBATS = null; }
+
+public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+static { DOMINO_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+static { EGYPTIAN_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock EMOTICONS;
+static { EMOTICONS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+static { ENCLOSED_ALPHANUMERICS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
+static { ENCLOSED_ALPHANUMERIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+static { ENCLOSED_CJK_LETTERS_AND_MONTHS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
+static { ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+static { ETHIOPIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+static { ETHIOPIC_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+static { ETHIOPIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
+static { ETHIOPIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
+static { GENERAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
+static { GEOMETRIC_SHAPES = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN;
+static { GEORGIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+static { GEORGIAN_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
+static { GLAGOLITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GOTHIC;
+static { GOTHIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK;
+static { GREEK = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
+static { GREEK_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock GUJARATI;
+static { GUJARATI = null; }
+
+public static final java.lang.Character.UnicodeBlock GURMUKHI;
+static { GURMUKHI = null; }
+
+public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
+static { HALFWIDTH_AND_FULLWIDTH_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
+static { HANGUL_COMPATIBILITY_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+static { HANGUL_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+static { HANGUL_JAMO_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
+static { HANGUL_JAMO_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
+static { HANGUL_SYLLABLES = null; }
+
+public static final java.lang.Character.UnicodeBlock HANUNOO;
+static { HANUNOO = null; }
+
+public static final java.lang.Character.UnicodeBlock HEBREW;
+static { HEBREW = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
+static { HIGH_PRIVATE_USE_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
+static { HIGH_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIRAGANA;
+static { HIRAGANA = null; }
+
+public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+static { IDEOGRAPHIC_DESCRIPTION_CHARACTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+static { IMPERIAL_ARAMAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+static { INSCRIPTIONAL_PAHLAVI = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
+static { INSCRIPTIONAL_PARTHIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+static { IPA_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock JAVANESE;
+static { JAVANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock KAITHI;
+static { KAITHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
+static { KANA_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock KANBUN;
+static { KANBUN = null; }
+
+public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
+static { KANGXI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock KANNADA;
+static { KANNADA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA;
+static { KATAKANA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+static { KATAKANA_PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+static { KAYAH_LI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
+static { KHAROSHTHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER;
+static { KHMER = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
+static { KHMER_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LAO;
+static { LAO = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
+static { LATIN_1_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
+static { LATIN_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
+static { LATIN_EXTENDED_ADDITIONAL = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+static { LATIN_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+static { LATIN_EXTENDED_C = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+static { LATIN_EXTENDED_D = null; }
+
+public static final java.lang.Character.UnicodeBlock LEPCHA;
+static { LEPCHA = null; }
+
+public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
+static { LETTERLIKE_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LIMBU;
+static { LIMBU = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
+static { LINEAR_B_IDEOGRAMS = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+static { LINEAR_B_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock LISU;
+static { LISU = null; }
+
+public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+static { LOW_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock LYCIAN;
+static { LYCIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock LYDIAN;
+static { LYDIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
+static { MAHJONG_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock MALAYALAM;
+static { MALAYALAM = null; }
+
+public static final java.lang.Character.UnicodeBlock MANDAIC;
+static { MANDAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+static { MATHEMATICAL_ALPHANUMERIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+static { MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
+static { MEETEI_MAYEK = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
+static { MEETEI_MAYEK_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
+static { MEROITIC_CURSIVE = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
+static { MEROITIC_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MIAO;
+static { MIAO = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
+static { MISCELLANEOUS_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+static { MISCELLANEOUS_SYMBOLS_AND_ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
+static { MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+static { MISCELLANEOUS_TECHNICAL = null; }
+
+public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
+static { MODIFIER_TONE_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock MONGOLIAN;
+static { MONGOLIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
+static { MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR;
+static { MYANMAR = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+static { MYANMAR_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+static { NEW_TAI_LUE = null; }
+
+public static final java.lang.Character.UnicodeBlock NKO;
+static { NKO = null; }
+
+public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
+static { NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock OGHAM;
+static { OGHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+static { OLD_ITALIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+static { OLD_PERSIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+static { OLD_SOUTH_ARABIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+static { OLD_TURKIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OL_CHIKI;
+static { OL_CHIKI = null; }
+
+public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
+static { OPTICAL_CHARACTER_RECOGNITION = null; }
+
+public static final java.lang.Character.UnicodeBlock ORIYA;
+static { ORIYA = null; }
+
+public static final java.lang.Character.UnicodeBlock OSMANYA;
+static { OSMANYA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+static { PHAGS_PA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+static { PHAISTOS_DISC = null; }
+
+public static final java.lang.Character.UnicodeBlock PHOENICIAN;
+static { PHOENICIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+static { PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+static { PHONETIC_EXTENSIONS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
+static { PLAYING_CARDS = null; }
+
+public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+static { PRIVATE_USE_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock REJANG;
+static { REJANG = null; }
+
+public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
+static { RUMI_NUMERAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock RUNIC;
+static { RUNIC = null; }
+
+public static final java.lang.Character.UnicodeBlock SAMARITAN;
+static { SAMARITAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SAURASHTRA;
+static { SAURASHTRA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHARADA;
+static { SHARADA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHAVIAN;
+static { SHAVIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SINHALA;
+static { SINHALA = null; }
+
+public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
+static { SMALL_FORM_VARIANTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
+static { SORA_SOMPENG = null; }
+
+public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
+static { SPACING_MODIFIER_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock SPECIALS;
+static { SPECIALS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE;
+static { SUNDANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
+static { SUNDANESE_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
+static { SUPERSCRIPTS_AND_SUBSCRIPTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
+static { SUPPLEMENTAL_ARROWS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
+static { SUPPLEMENTAL_ARROWS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+static { SUPPLEMENTAL_MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
+static { SUPPLEMENTAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_B = null; }
+
+@Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
+static { SURROGATES_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
+static { SYLOTI_NAGRI = null; }
+
+public static final java.lang.Character.UnicodeBlock SYRIAC;
+static { SYRIAC = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGALOG;
+static { TAGALOG = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGBANWA;
+static { TAGBANWA = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGS;
+static { TAGS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_LE;
+static { TAI_LE = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_THAM;
+static { TAI_THAM = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_VIET;
+static { TAI_VIET = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
+static { TAI_XUAN_JING_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAKRI;
+static { TAKRI = null; }
+
+public static final java.lang.Character.UnicodeBlock TAMIL;
+static { TAMIL = null; }
+
+public static final java.lang.Character.UnicodeBlock TELUGU;
+static { TELUGU = null; }
+
+public static final java.lang.Character.UnicodeBlock THAANA;
+static { THAANA = null; }
+
+public static final java.lang.Character.UnicodeBlock THAI;
+static { THAI = null; }
+
+public static final java.lang.Character.UnicodeBlock TIBETAN;
+static { TIBETAN = null; }
+
+public static final java.lang.Character.UnicodeBlock TIFINAGH;
+static { TIFINAGH = null; }
+
+public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
+static { TRANSPORT_AND_MAP_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock UGARITIC;
+static { UGARITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock VAI;
+static { VAI = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
+static { VARIATION_SELECTORS = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+static { VARIATION_SELECTORS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+static { VEDIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
+static { VERTICAL_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
+static { YIJING_HEXAGRAM_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_RADICALS;
+static { YI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
+static { YI_SYLLABLES = null; }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum UnicodeScript {
+COMMON,
+LATIN,
+GREEK,
+CYRILLIC,
+ARMENIAN,
+HEBREW,
+ARABIC,
+SYRIAC,
+THAANA,
+DEVANAGARI,
+BENGALI,
+GURMUKHI,
+GUJARATI,
+ORIYA,
+TAMIL,
+TELUGU,
+KANNADA,
+MALAYALAM,
+SINHALA,
+THAI,
+LAO,
+TIBETAN,
+MYANMAR,
+GEORGIAN,
+HANGUL,
+ETHIOPIC,
+CHEROKEE,
+CANADIAN_ABORIGINAL,
+OGHAM,
+RUNIC,
+KHMER,
+MONGOLIAN,
+HIRAGANA,
+KATAKANA,
+BOPOMOFO,
+HAN,
+YI,
+OLD_ITALIC,
+GOTHIC,
+DESERET,
+INHERITED,
+TAGALOG,
+HANUNOO,
+BUHID,
+TAGBANWA,
+LIMBU,
+TAI_LE,
+LINEAR_B,
+UGARITIC,
+SHAVIAN,
+OSMANYA,
+CYPRIOT,
+BRAILLE,
+BUGINESE,
+COPTIC,
+NEW_TAI_LUE,
+GLAGOLITIC,
+TIFINAGH,
+SYLOTI_NAGRI,
+OLD_PERSIAN,
+KHAROSHTHI,
+BALINESE,
+CUNEIFORM,
+PHOENICIAN,
+PHAGS_PA,
+NKO,
+SUNDANESE,
+BATAK,
+LEPCHA,
+OL_CHIKI,
+VAI,
+SAURASHTRA,
+KAYAH_LI,
+REJANG,
+LYCIAN,
+CARIAN,
+LYDIAN,
+CHAM,
+TAI_THAM,
+TAI_VIET,
+AVESTAN,
+EGYPTIAN_HIEROGLYPHS,
+SAMARITAN,
+MANDAIC,
+LISU,
+BAMUM,
+JAVANESE,
+MEETEI_MAYEK,
+IMPERIAL_ARAMAIC,
+OLD_SOUTH_ARABIAN,
+INSCRIPTIONAL_PARTHIAN,
+INSCRIPTIONAL_PAHLAVI,
+OLD_TURKIC,
+BRAHMI,
+KAITHI,
+MEROITIC_HIEROGLYPHS,
+MEROITIC_CURSIVE,
+SORA_SOMPENG,
+CHAKMA,
+SHARADA,
+TAKRI,
+MIAO,
+UNKNOWN;
+
[email protected] public static java.lang.Character.UnicodeScript of(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeScript forName(@libcore.util.NonNull java.lang.String scriptName) { throw new RuntimeException("Stub!"); }
+}
+
+}
+
diff --git a/java/lang/Character.java b/java/lang/Character.java
new file mode 100644
index 0000000..8b1635d
--- /dev/null
+++ b/java/lang/Character.java
@@ -0,0 +1,7659 @@
+/*
+ * Copyright (c) 2002, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+// Android-changed: Remove reference to a specific unicode standard version
+/**
+ * The {@code Character} class wraps a value of the primitive
+ * type {@code char} in an object. An object of type
+ * {@code Character} contains a single field whose type is
+ * {@code char}.
+ * <p>
+ * In addition, this class provides several methods for determining
+ * a character's category (lowercase letter, digit, etc.) and for converting
+ * characters from uppercase to lowercase and vice versa.
+ * <p>
+ * Character information is based on the Unicode Standard
+ * <p>
+ * The methods and data of class {@code Character} are defined by
+ * the information in the <i>UnicodeData</i> file that is part of the
+ * Unicode Character Database maintained by the Unicode
+ * Consortium. This file specifies various properties including name
+ * and general category for every defined Unicode code point or
+ * character range.
+ * <p>
+ * The file and its description are available from the Unicode Consortium at:
+ * <ul>
+ * <li><a href="http://www.unicode.org">http://www.unicode.org</a>
+ * </ul>
+ *
+ * <h3><a name="unicode">Unicode Character Representations</a></h3>
+ *
+ * <p>The {@code char} data type (and therefore the value that a
+ * {@code Character} object encapsulates) are based on the
+ * original Unicode specification, which defined characters as
+ * fixed-width 16-bit entities. The Unicode Standard has since been
+ * changed to allow for characters whose representation requires more
+ * than 16 bits.  The range of legal <em>code point</em>s is now
+ * U+0000 to U+10FFFF, known as <em>Unicode scalar value</em>.
+ * (Refer to the <a
+ * href="http://www.unicode.org/reports/tr27/#notation"><i>
+ * definition</i></a> of the U+<i>n</i> notation in the Unicode
+ * Standard.)
+ *
+ * <p><a name="BMP">The set of characters from U+0000 to U+FFFF</a> is
+ * sometimes referred to as the <em>Basic Multilingual Plane (BMP)</em>.
+ * <a name="supplementary">Characters</a> whose code points are greater
+ * than U+FFFF are called <em>supplementary character</em>s.  The Java
+ * platform uses the UTF-16 representation in {@code char} arrays and
+ * in the {@code String} and {@code StringBuffer} classes. In
+ * this representation, supplementary characters are represented as a pair
+ * of {@code char} values, the first from the <em>high-surrogates</em>
+ * range, (&#92;uD800-&#92;uDBFF), the second from the
+ * <em>low-surrogates</em> range (&#92;uDC00-&#92;uDFFF).
+ *
+ * <p>A {@code char} value, therefore, represents Basic
+ * Multilingual Plane (BMP) code points, including the surrogate
+ * code points, or code units of the UTF-16 encoding. An
+ * {@code int} value represents all Unicode code points,
+ * including supplementary code points. The lower (least significant)
+ * 21 bits of {@code int} are used to represent Unicode code
+ * points and the upper (most significant) 11 bits must be zero.
+ * Unless otherwise specified, the behavior with respect to
+ * supplementary characters and surrogate {@code char} values is
+ * as follows:
+ *
+ * <ul>
+ * <li>The methods that only accept a {@code char} value cannot support
+ * supplementary characters. They treat {@code char} values from the
+ * surrogate ranges as undefined characters. For example,
+ * {@code Character.isLetter('\u005CuD840')} returns {@code false}, even though
+ * this specific value if followed by any low-surrogate value in a string
+ * would represent a letter.
+ *
+ * <li>The methods that accept an {@code int} value support all
+ * Unicode characters, including supplementary characters. For
+ * example, {@code Character.isLetter(0x2F81A)} returns
+ * {@code true} because the code point value represents a letter
+ * (a CJK ideograph).
+ * </ul>
+ *
+ * <p>In the Java SE API documentation, <em>Unicode code point</em> is
+ * used for character values in the range between U+0000 and U+10FFFF,
+ * and <em>Unicode code unit</em> is used for 16-bit
+ * {@code char} values that are code units of the <em>UTF-16</em>
+ * encoding. For more information on Unicode terminology, refer to the
+ * <a href="http://www.unicode.org/glossary/">Unicode Glossary</a>.
+ *
+ * @author  Lee Boynton
+ * @author  Guy Steele
+ * @author  Akira Tanaka
+ * @author  Martin Buchholz
+ * @author  Ulf Zibis
+ * @since   1.0
+ */
+public final
+class Character implements java.io.Serializable, Comparable<Character> {
+    /**
+     * The minimum radix available for conversion to and from strings.
+     * The constant value of this field is the smallest value permitted
+     * for the radix argument in radix-conversion methods such as the
+     * {@code digit} method, the {@code forDigit} method, and the
+     * {@code toString} method of class {@code Integer}.
+     *
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Integer#toString(int, int)
+     * @see     Integer#valueOf(String)
+     */
+    public static final int MIN_RADIX = 2;
+
+    /**
+     * The maximum radix available for conversion to and from strings.
+     * The constant value of this field is the largest value permitted
+     * for the radix argument in radix-conversion methods such as the
+     * {@code digit} method, the {@code forDigit} method, and the
+     * {@code toString} method of class {@code Integer}.
+     *
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Integer#toString(int, int)
+     * @see     Integer#valueOf(String)
+     */
+    public static final int MAX_RADIX = 36;
+
+    /**
+     * The constant value of this field is the smallest value of type
+     * {@code char}, {@code '\u005Cu0000'}.
+     *
+     * @since   1.0.2
+     */
+    public static final char MIN_VALUE = '\u0000';
+
+    /**
+     * The constant value of this field is the largest value of type
+     * {@code char}, {@code '\u005CuFFFF'}.
+     *
+     * @since   1.0.2
+     */
+    public static final char MAX_VALUE = '\uFFFF';
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code char}.
+     *
+     * @since   1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");
+
+    /*
+     * Normative general types
+     */
+
+    /*
+     * General character types
+     */
+
+    /**
+     * General category "Cn" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte UNASSIGNED = 0;
+
+    /**
+     * General category "Lu" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte UPPERCASE_LETTER = 1;
+
+    /**
+     * General category "Ll" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LOWERCASE_LETTER = 2;
+
+    /**
+     * General category "Lt" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte TITLECASE_LETTER = 3;
+
+    /**
+     * General category "Lm" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MODIFIER_LETTER = 4;
+
+    /**
+     * General category "Lo" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_LETTER = 5;
+
+    /**
+     * General category "Mn" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte NON_SPACING_MARK = 6;
+
+    /**
+     * General category "Me" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte ENCLOSING_MARK = 7;
+
+    /**
+     * General category "Mc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte COMBINING_SPACING_MARK = 8;
+
+    /**
+     * General category "Nd" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte DECIMAL_DIGIT_NUMBER        = 9;
+
+    /**
+     * General category "Nl" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LETTER_NUMBER = 10;
+
+    /**
+     * General category "No" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_NUMBER = 11;
+
+    /**
+     * General category "Zs" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte SPACE_SEPARATOR = 12;
+
+    /**
+     * General category "Zl" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte LINE_SEPARATOR = 13;
+
+    /**
+     * General category "Zp" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte PARAGRAPH_SEPARATOR = 14;
+
+    /**
+     * General category "Cc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CONTROL = 15;
+
+    /**
+     * General category "Cf" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte FORMAT = 16;
+
+    /**
+     * General category "Co" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte PRIVATE_USE = 18;
+
+    /**
+     * General category "Cs" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte SURROGATE = 19;
+
+    /**
+     * General category "Pd" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte DASH_PUNCTUATION = 20;
+
+    /**
+     * General category "Ps" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte START_PUNCTUATION = 21;
+
+    /**
+     * General category "Pe" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte END_PUNCTUATION = 22;
+
+    /**
+     * General category "Pc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CONNECTOR_PUNCTUATION = 23;
+
+    /**
+     * General category "Po" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_PUNCTUATION = 24;
+
+    /**
+     * General category "Sm" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MATH_SYMBOL = 25;
+
+    /**
+     * General category "Sc" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte CURRENCY_SYMBOL = 26;
+
+    /**
+     * General category "Sk" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte MODIFIER_SYMBOL = 27;
+
+    /**
+     * General category "So" in the Unicode specification.
+     * @since   1.1
+     */
+    public static final byte OTHER_SYMBOL = 28;
+
+    /**
+     * General category "Pi" in the Unicode specification.
+     * @since   1.4
+     */
+    public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
+
+    /**
+     * General category "Pf" in the Unicode specification.
+     * @since   1.4
+     */
+    public static final byte FINAL_QUOTE_PUNCTUATION = 30;
+
+    /**
+     * Error flag. Use int (code point) to avoid confusion with U+FFFF.
+     */
+    static final int ERROR = 0xFFFFFFFF;
+
+
+    /**
+     * Undefined bidirectional character type. Undefined {@code char}
+     * values have undefined directionality in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_UNDEFINED = -1;
+
+    /**
+     * Strong bidirectional character type "L" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
+
+    /**
+     * Strong bidirectional character type "R" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
+
+    /**
+    * Strong bidirectional character type "AL" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
+
+    /**
+     * Weak bidirectional character type "EN" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
+
+    /**
+     * Weak bidirectional character type "ES" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
+
+    /**
+     * Weak bidirectional character type "ET" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
+
+    /**
+     * Weak bidirectional character type "AN" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6;
+
+    /**
+     * Weak bidirectional character type "CS" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
+
+    /**
+     * Weak bidirectional character type "NSM" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_NONSPACING_MARK = 8;
+
+    /**
+     * Weak bidirectional character type "BN" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
+
+    /**
+     * Neutral bidirectional character type "B" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
+
+    /**
+     * Neutral bidirectional character type "S" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
+
+    /**
+     * Neutral bidirectional character type "WS" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_WHITESPACE = 12;
+
+    /**
+     * Neutral bidirectional character type "ON" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13;
+
+    /**
+     * Strong bidirectional character type "LRE" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
+
+    /**
+     * Strong bidirectional character type "LRO" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
+
+    /**
+     * Strong bidirectional character type "RLE" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
+
+    /**
+     * Strong bidirectional character type "RLO" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
+
+    /**
+     * Weak bidirectional character type "PDF" in the Unicode specification.
+     * @since 1.4
+     */
+    public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
+
+    /**
+     * The minimum value of a
+     * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+     * Unicode high-surrogate code unit</a>
+     * in the UTF-16 encoding, constant {@code '\u005CuD800'}.
+     * A high-surrogate is also known as a <i>leading-surrogate</i>.
+     *
+     * @since 1.5
+     */
+    public static final char MIN_HIGH_SURROGATE = '\uD800';
+
+    /**
+     * The maximum value of a
+     * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+     * Unicode high-surrogate code unit</a>
+     * in the UTF-16 encoding, constant {@code '\u005CuDBFF'}.
+     * A high-surrogate is also known as a <i>leading-surrogate</i>.
+     *
+     * @since 1.5
+     */
+    public static final char MAX_HIGH_SURROGATE = '\uDBFF';
+
+    /**
+     * The minimum value of a
+     * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+     * Unicode low-surrogate code unit</a>
+     * in the UTF-16 encoding, constant {@code '\u005CuDC00'}.
+     * A low-surrogate is also known as a <i>trailing-surrogate</i>.
+     *
+     * @since 1.5
+     */
+    public static final char MIN_LOW_SURROGATE  = '\uDC00';
+
+    /**
+     * The maximum value of a
+     * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+     * Unicode low-surrogate code unit</a>
+     * in the UTF-16 encoding, constant {@code '\u005CuDFFF'}.
+     * A low-surrogate is also known as a <i>trailing-surrogate</i>.
+     *
+     * @since 1.5
+     */
+    public static final char MAX_LOW_SURROGATE  = '\uDFFF';
+
+    /**
+     * The minimum value of a Unicode surrogate code unit in the
+     * UTF-16 encoding, constant {@code '\u005CuD800'}.
+     *
+     * @since 1.5
+     */
+    public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
+
+    /**
+     * The maximum value of a Unicode surrogate code unit in the
+     * UTF-16 encoding, constant {@code '\u005CuDFFF'}.
+     *
+     * @since 1.5
+     */
+    public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
+
+    /**
+     * The minimum value of a
+     * <a href="http://www.unicode.org/glossary/#supplementary_code_point">
+     * Unicode supplementary code point</a>, constant {@code U+10000}.
+     *
+     * @since 1.5
+     */
+    public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
+
+    /**
+     * The minimum value of a
+     * <a href="http://www.unicode.org/glossary/#code_point">
+     * Unicode code point</a>, constant {@code U+0000}.
+     *
+     * @since 1.5
+     */
+    public static final int MIN_CODE_POINT = 0x000000;
+
+    /**
+     * The maximum value of a
+     * <a href="http://www.unicode.org/glossary/#code_point">
+     * Unicode code point</a>, constant {@code U+10FFFF}.
+     *
+     * @since 1.5
+     */
+    public static final int MAX_CODE_POINT = 0X10FFFF;
+
+    // BEGIN Android-added: Use ICU.
+    // The indices in int[] DIRECTIONALITY are based on icu4c's u_charDirection(),
+    // accessed via getDirectionalityImpl(), implemented in Character.cpp.
+    private static final byte[] DIRECTIONALITY = new byte[] {
+            DIRECTIONALITY_LEFT_TO_RIGHT, DIRECTIONALITY_RIGHT_TO_LEFT,
+            DIRECTIONALITY_EUROPEAN_NUMBER,
+            DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+            DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+            DIRECTIONALITY_ARABIC_NUMBER,
+            DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+            DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+            DIRECTIONALITY_SEGMENT_SEPARATOR, DIRECTIONALITY_WHITESPACE,
+            DIRECTIONALITY_OTHER_NEUTRALS,
+            DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
+            DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
+            DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
+            DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
+            DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
+            DIRECTIONALITY_POP_DIRECTIONAL_FORMAT,
+            DIRECTIONALITY_NONSPACING_MARK, DIRECTIONALITY_BOUNDARY_NEUTRAL };
+    // END Android-added: Use ICU.
+
+    /**
+     * Instances of this class represent particular subsets of the Unicode
+     * character set.  The only family of subsets defined in the
+     * {@code Character} class is {@link Character.UnicodeBlock}.
+     * Other portions of the Java API may define other subsets for their
+     * own purposes.
+     *
+     * @since 1.2
+     */
+    public static class Subset  {
+
+        private String name;
+
+        /**
+         * Constructs a new {@code Subset} instance.
+         *
+         * @param  name  The name of this subset
+         * @exception NullPointerException if name is {@code null}
+         */
+        protected Subset(String name) {
+            if (name == null) {
+                throw new NullPointerException("name");
+            }
+            this.name = name;
+        }
+
+        /**
+         * Compares two {@code Subset} objects for equality.
+         * This method returns {@code true} if and only if
+         * {@code this} and the argument refer to the same
+         * object; since this method is {@code final}, this
+         * guarantee holds for all subclasses.
+         */
+        public final boolean equals(Object obj) {
+            return (this == obj);
+        }
+
+        /**
+         * Returns the standard hash code as defined by the
+         * {@link Object#hashCode} method.  This method
+         * is {@code final} in order to ensure that the
+         * {@code equals} and {@code hashCode} methods will
+         * be consistent in all subclasses.
+         */
+        public final int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Returns the name of this subset.
+         */
+        public final String toString() {
+            return name;
+        }
+    }
+
+    // See http://www.unicode.org/Public/UNIDATA/Blocks.txt
+    // for the latest specification of Unicode Blocks.
+
+    /**
+     * A family of character subsets representing the character blocks in the
+     * Unicode specification. Character blocks generally define characters
+     * used for a specific script or purpose. A character is contained by
+     * at most one Unicode block.
+     *
+     * @since 1.2
+     */
+    public static final class UnicodeBlock extends Subset {
+
+        private static Map<String, UnicodeBlock> map = new HashMap<>(256);
+
+        /**
+         * Creates a UnicodeBlock with the given identifier name.
+         * This name must be the same as the block identifier.
+         */
+        private UnicodeBlock(String idName) {
+            super(idName);
+            map.put(idName, this);
+        }
+
+        // BEGIN Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+        // Add a (String, boolean) constructor for use by SURROGATES_AREA.
+        private UnicodeBlock(String idName, boolean isMap) {
+            super(idName);
+            if (isMap) {
+                map.put(idName, this);
+            }
+        }
+        // END Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+
+        /**
+         * Creates a UnicodeBlock with the given identifier name and
+         * alias name.
+         */
+        private UnicodeBlock(String idName, String alias) {
+            this(idName);
+            map.put(alias, this);
+        }
+
+        /**
+         * Creates a UnicodeBlock with the given identifier name and
+         * alias names.
+         */
+        private UnicodeBlock(String idName, String... aliases) {
+            this(idName);
+            for (String alias : aliases)
+                map.put(alias, this);
+        }
+
+        /**
+         * Constant for the "Basic Latin" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock  BASIC_LATIN =
+            new UnicodeBlock("BASIC_LATIN",
+                             "BASIC LATIN",
+                             "BASICLATIN");
+
+        /**
+         * Constant for the "Latin-1 Supplement" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LATIN_1_SUPPLEMENT =
+            new UnicodeBlock("LATIN_1_SUPPLEMENT",
+                             "LATIN-1 SUPPLEMENT",
+                             "LATIN-1SUPPLEMENT");
+
+        /**
+         * Constant for the "Latin Extended-A" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LATIN_EXTENDED_A =
+            new UnicodeBlock("LATIN_EXTENDED_A",
+                             "LATIN EXTENDED-A",
+                             "LATINEXTENDED-A");
+
+        /**
+         * Constant for the "Latin Extended-B" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LATIN_EXTENDED_B =
+            new UnicodeBlock("LATIN_EXTENDED_B",
+                             "LATIN EXTENDED-B",
+                             "LATINEXTENDED-B");
+
+        /**
+         * Constant for the "IPA Extensions" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock IPA_EXTENSIONS =
+            new UnicodeBlock("IPA_EXTENSIONS",
+                             "IPA EXTENSIONS",
+                             "IPAEXTENSIONS");
+
+        /**
+         * Constant for the "Spacing Modifier Letters" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock SPACING_MODIFIER_LETTERS =
+            new UnicodeBlock("SPACING_MODIFIER_LETTERS",
+                             "SPACING MODIFIER LETTERS",
+                             "SPACINGMODIFIERLETTERS");
+
+        /**
+         * Constant for the "Combining Diacritical Marks" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS =
+            new UnicodeBlock("COMBINING_DIACRITICAL_MARKS",
+                             "COMBINING DIACRITICAL MARKS",
+                             "COMBININGDIACRITICALMARKS");
+
+        /**
+         * Constant for the "Greek and Coptic" Unicode character block.
+         * <p>
+         * This block was previously known as the "Greek" block.
+         *
+         * @since 1.2
+         */
+        public static final UnicodeBlock GREEK =
+            new UnicodeBlock("GREEK",
+                             "GREEK AND COPTIC",
+                             "GREEKANDCOPTIC");
+
+        /**
+         * Constant for the "Cyrillic" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CYRILLIC =
+            new UnicodeBlock("CYRILLIC");
+
+        /**
+         * Constant for the "Armenian" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ARMENIAN =
+            new UnicodeBlock("ARMENIAN");
+
+        /**
+         * Constant for the "Hebrew" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HEBREW =
+            new UnicodeBlock("HEBREW");
+
+        /**
+         * Constant for the "Arabic" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ARABIC =
+            new UnicodeBlock("ARABIC");
+
+        /**
+         * Constant for the "Devanagari" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock DEVANAGARI =
+            new UnicodeBlock("DEVANAGARI");
+
+        /**
+         * Constant for the "Bengali" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock BENGALI =
+            new UnicodeBlock("BENGALI");
+
+        /**
+         * Constant for the "Gurmukhi" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GURMUKHI =
+            new UnicodeBlock("GURMUKHI");
+
+        /**
+         * Constant for the "Gujarati" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GUJARATI =
+            new UnicodeBlock("GUJARATI");
+
+        /**
+         * Constant for the "Oriya" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ORIYA =
+            new UnicodeBlock("ORIYA");
+
+        /**
+         * Constant for the "Tamil" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock TAMIL =
+            new UnicodeBlock("TAMIL");
+
+        /**
+         * Constant for the "Telugu" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock TELUGU =
+            new UnicodeBlock("TELUGU");
+
+        /**
+         * Constant for the "Kannada" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock KANNADA =
+            new UnicodeBlock("KANNADA");
+
+        /**
+         * Constant for the "Malayalam" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock MALAYALAM =
+            new UnicodeBlock("MALAYALAM");
+
+        /**
+         * Constant for the "Thai" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock THAI =
+            new UnicodeBlock("THAI");
+
+        /**
+         * Constant for the "Lao" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LAO =
+            new UnicodeBlock("LAO");
+
+        /**
+         * Constant for the "Tibetan" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock TIBETAN =
+            new UnicodeBlock("TIBETAN");
+
+        /**
+         * Constant for the "Georgian" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GEORGIAN =
+            new UnicodeBlock("GEORGIAN");
+
+        /**
+         * Constant for the "Hangul Jamo" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HANGUL_JAMO =
+            new UnicodeBlock("HANGUL_JAMO",
+                             "HANGUL JAMO",
+                             "HANGULJAMO");
+
+        /**
+         * Constant for the "Latin Extended Additional" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL =
+            new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL",
+                             "LATIN EXTENDED ADDITIONAL",
+                             "LATINEXTENDEDADDITIONAL");
+
+        /**
+         * Constant for the "Greek Extended" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GREEK_EXTENDED =
+            new UnicodeBlock("GREEK_EXTENDED",
+                             "GREEK EXTENDED",
+                             "GREEKEXTENDED");
+
+        /**
+         * Constant for the "General Punctuation" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GENERAL_PUNCTUATION =
+            new UnicodeBlock("GENERAL_PUNCTUATION",
+                             "GENERAL PUNCTUATION",
+                             "GENERALPUNCTUATION");
+
+        /**
+         * Constant for the "Superscripts and Subscripts" Unicode character
+         * block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS =
+            new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS",
+                             "SUPERSCRIPTS AND SUBSCRIPTS",
+                             "SUPERSCRIPTSANDSUBSCRIPTS");
+
+        /**
+         * Constant for the "Currency Symbols" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CURRENCY_SYMBOLS =
+            new UnicodeBlock("CURRENCY_SYMBOLS",
+                             "CURRENCY SYMBOLS",
+                             "CURRENCYSYMBOLS");
+
+        /**
+         * Constant for the "Combining Diacritical Marks for Symbols" Unicode
+         * character block.
+         * <p>
+         * This block was previously known as "Combining Marks for Symbols".
+         * @since 1.2
+         */
+        public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS =
+            new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS",
+                             "COMBINING DIACRITICAL MARKS FOR SYMBOLS",
+                             "COMBININGDIACRITICALMARKSFORSYMBOLS",
+                             "COMBINING MARKS FOR SYMBOLS",
+                             "COMBININGMARKSFORSYMBOLS");
+
+        /**
+         * Constant for the "Letterlike Symbols" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock LETTERLIKE_SYMBOLS =
+            new UnicodeBlock("LETTERLIKE_SYMBOLS",
+                             "LETTERLIKE SYMBOLS",
+                             "LETTERLIKESYMBOLS");
+
+        /**
+         * Constant for the "Number Forms" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock NUMBER_FORMS =
+            new UnicodeBlock("NUMBER_FORMS",
+                             "NUMBER FORMS",
+                             "NUMBERFORMS");
+
+        /**
+         * Constant for the "Arrows" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ARROWS =
+            new UnicodeBlock("ARROWS");
+
+        /**
+         * Constant for the "Mathematical Operators" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock MATHEMATICAL_OPERATORS =
+            new UnicodeBlock("MATHEMATICAL_OPERATORS",
+                             "MATHEMATICAL OPERATORS",
+                             "MATHEMATICALOPERATORS");
+
+        /**
+         * Constant for the "Miscellaneous Technical" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock MISCELLANEOUS_TECHNICAL =
+            new UnicodeBlock("MISCELLANEOUS_TECHNICAL",
+                             "MISCELLANEOUS TECHNICAL",
+                             "MISCELLANEOUSTECHNICAL");
+
+        /**
+         * Constant for the "Control Pictures" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CONTROL_PICTURES =
+            new UnicodeBlock("CONTROL_PICTURES",
+                             "CONTROL PICTURES",
+                             "CONTROLPICTURES");
+
+        /**
+         * Constant for the "Optical Character Recognition" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION =
+            new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION",
+                             "OPTICAL CHARACTER RECOGNITION",
+                             "OPTICALCHARACTERRECOGNITION");
+
+        /**
+         * Constant for the "Enclosed Alphanumerics" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ENCLOSED_ALPHANUMERICS =
+            new UnicodeBlock("ENCLOSED_ALPHANUMERICS",
+                             "ENCLOSED ALPHANUMERICS",
+                             "ENCLOSEDALPHANUMERICS");
+
+        /**
+         * Constant for the "Box Drawing" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock BOX_DRAWING =
+            new UnicodeBlock("BOX_DRAWING",
+                             "BOX DRAWING",
+                             "BOXDRAWING");
+
+        /**
+         * Constant for the "Block Elements" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock BLOCK_ELEMENTS =
+            new UnicodeBlock("BLOCK_ELEMENTS",
+                             "BLOCK ELEMENTS",
+                             "BLOCKELEMENTS");
+
+        /**
+         * Constant for the "Geometric Shapes" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock GEOMETRIC_SHAPES =
+            new UnicodeBlock("GEOMETRIC_SHAPES",
+                             "GEOMETRIC SHAPES",
+                             "GEOMETRICSHAPES");
+
+        /**
+         * Constant for the "Miscellaneous Symbols" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock MISCELLANEOUS_SYMBOLS =
+            new UnicodeBlock("MISCELLANEOUS_SYMBOLS",
+                             "MISCELLANEOUS SYMBOLS",
+                             "MISCELLANEOUSSYMBOLS");
+
+        /**
+         * Constant for the "Dingbats" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock DINGBATS =
+            new UnicodeBlock("DINGBATS");
+
+        /**
+         * Constant for the "CJK Symbols and Punctuation" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION =
+            new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION",
+                             "CJK SYMBOLS AND PUNCTUATION",
+                             "CJKSYMBOLSANDPUNCTUATION");
+
+        /**
+         * Constant for the "Hiragana" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HIRAGANA =
+            new UnicodeBlock("HIRAGANA");
+
+        /**
+         * Constant for the "Katakana" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock KATAKANA =
+            new UnicodeBlock("KATAKANA");
+
+        /**
+         * Constant for the "Bopomofo" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock BOPOMOFO =
+            new UnicodeBlock("BOPOMOFO");
+
+        /**
+         * Constant for the "Hangul Compatibility Jamo" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO =
+            new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO",
+                             "HANGUL COMPATIBILITY JAMO",
+                             "HANGULCOMPATIBILITYJAMO");
+
+        /**
+         * Constant for the "Kanbun" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock KANBUN =
+            new UnicodeBlock("KANBUN");
+
+        /**
+         * Constant for the "Enclosed CJK Letters and Months" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS =
+            new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS",
+                             "ENCLOSED CJK LETTERS AND MONTHS",
+                             "ENCLOSEDCJKLETTERSANDMONTHS");
+
+        /**
+         * Constant for the "CJK Compatibility" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CJK_COMPATIBILITY =
+            new UnicodeBlock("CJK_COMPATIBILITY",
+                             "CJK COMPATIBILITY",
+                             "CJKCOMPATIBILITY");
+
+        /**
+         * Constant for the "CJK Unified Ideographs" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS =
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS",
+                             "CJK UNIFIED IDEOGRAPHS",
+                             "CJKUNIFIEDIDEOGRAPHS");
+
+        /**
+         * Constant for the "Hangul Syllables" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HANGUL_SYLLABLES =
+            new UnicodeBlock("HANGUL_SYLLABLES",
+                             "HANGUL SYLLABLES",
+                             "HANGULSYLLABLES");
+
+        /**
+         * Constant for the "Private Use Area" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock PRIVATE_USE_AREA =
+            new UnicodeBlock("PRIVATE_USE_AREA",
+                             "PRIVATE USE AREA",
+                             "PRIVATEUSEAREA");
+
+        /**
+         * Constant for the "CJK Compatibility Ideographs" Unicode character
+         * block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS =
+            new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS",
+                             "CJK COMPATIBILITY IDEOGRAPHS",
+                             "CJKCOMPATIBILITYIDEOGRAPHS");
+
+        /**
+         * Constant for the "Alphabetic Presentation Forms" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS =
+            new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS",
+                             "ALPHABETIC PRESENTATION FORMS",
+                             "ALPHABETICPRESENTATIONFORMS");
+
+        /**
+         * Constant for the "Arabic Presentation Forms-A" Unicode character
+         * block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A =
+            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A",
+                             "ARABIC PRESENTATION FORMS-A",
+                             "ARABICPRESENTATIONFORMS-A");
+
+        /**
+         * Constant for the "Combining Half Marks" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock COMBINING_HALF_MARKS =
+            new UnicodeBlock("COMBINING_HALF_MARKS",
+                             "COMBINING HALF MARKS",
+                             "COMBININGHALFMARKS");
+
+        /**
+         * Constant for the "CJK Compatibility Forms" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock CJK_COMPATIBILITY_FORMS =
+            new UnicodeBlock("CJK_COMPATIBILITY_FORMS",
+                             "CJK COMPATIBILITY FORMS",
+                             "CJKCOMPATIBILITYFORMS");
+
+        /**
+         * Constant for the "Small Form Variants" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock SMALL_FORM_VARIANTS =
+            new UnicodeBlock("SMALL_FORM_VARIANTS",
+                             "SMALL FORM VARIANTS",
+                             "SMALLFORMVARIANTS");
+
+        /**
+         * Constant for the "Arabic Presentation Forms-B" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B =
+            new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B",
+                             "ARABIC PRESENTATION FORMS-B",
+                             "ARABICPRESENTATIONFORMS-B");
+
+        /**
+         * Constant for the "Halfwidth and Fullwidth Forms" Unicode character
+         * block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS =
+            new UnicodeBlock("HALFWIDTH_AND_FULLWIDTH_FORMS",
+                             "HALFWIDTH AND FULLWIDTH FORMS",
+                             "HALFWIDTHANDFULLWIDTHFORMS");
+
+        /**
+         * Constant for the "Specials" Unicode character block.
+         * @since 1.2
+         */
+        public static final UnicodeBlock SPECIALS =
+            new UnicodeBlock("SPECIALS");
+
+        /**
+         * @deprecated As of J2SE 5, use {@link #HIGH_SURROGATES},
+         *             {@link #HIGH_PRIVATE_USE_SURROGATES}, and
+         *             {@link #LOW_SURROGATES}. These new constants match
+         *             the block definitions of the Unicode Standard.
+         *             The {@link #of(char)} and {@link #of(int)} methods
+         *             return the new constants, not SURROGATES_AREA.
+         */
+        @Deprecated
+        public static final UnicodeBlock SURROGATES_AREA =
+            // Android-changed: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+            // new UnicodeBlock("SURROGATES_AREA");
+            new UnicodeBlock("SURROGATES_AREA", false);
+
+        /**
+         * Constant for the "Syriac" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock SYRIAC =
+            new UnicodeBlock("SYRIAC");
+
+        /**
+         * Constant for the "Thaana" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock THAANA =
+            new UnicodeBlock("THAANA");
+
+        /**
+         * Constant for the "Sinhala" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock SINHALA =
+            new UnicodeBlock("SINHALA");
+
+        /**
+         * Constant for the "Myanmar" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock MYANMAR =
+            new UnicodeBlock("MYANMAR");
+
+        /**
+         * Constant for the "Ethiopic" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock ETHIOPIC =
+            new UnicodeBlock("ETHIOPIC");
+
+        /**
+         * Constant for the "Cherokee" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock CHEROKEE =
+            new UnicodeBlock("CHEROKEE");
+
+        /**
+         * Constant for the "Unified Canadian Aboriginal Syllabics" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS =
+            new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS",
+                             "UNIFIED CANADIAN ABORIGINAL SYLLABICS",
+                             "UNIFIEDCANADIANABORIGINALSYLLABICS");
+
+        /**
+         * Constant for the "Ogham" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock OGHAM =
+            new UnicodeBlock("OGHAM");
+
+        /**
+         * Constant for the "Runic" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock RUNIC =
+            new UnicodeBlock("RUNIC");
+
+        /**
+         * Constant for the "Khmer" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock KHMER =
+            new UnicodeBlock("KHMER");
+
+        /**
+         * Constant for the "Mongolian" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock MONGOLIAN =
+            new UnicodeBlock("MONGOLIAN");
+
+        /**
+         * Constant for the "Braille Patterns" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock BRAILLE_PATTERNS =
+            new UnicodeBlock("BRAILLE_PATTERNS",
+                             "BRAILLE PATTERNS",
+                             "BRAILLEPATTERNS");
+
+        /**
+         * Constant for the "CJK Radicals Supplement" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT =
+            new UnicodeBlock("CJK_RADICALS_SUPPLEMENT",
+                             "CJK RADICALS SUPPLEMENT",
+                             "CJKRADICALSSUPPLEMENT");
+
+        /**
+         * Constant for the "Kangxi Radicals" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock KANGXI_RADICALS =
+            new UnicodeBlock("KANGXI_RADICALS",
+                             "KANGXI RADICALS",
+                             "KANGXIRADICALS");
+
+        /**
+         * Constant for the "Ideographic Description Characters" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS =
+            new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS",
+                             "IDEOGRAPHIC DESCRIPTION CHARACTERS",
+                             "IDEOGRAPHICDESCRIPTIONCHARACTERS");
+
+        /**
+         * Constant for the "Bopomofo Extended" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock BOPOMOFO_EXTENDED =
+            new UnicodeBlock("BOPOMOFO_EXTENDED",
+                             "BOPOMOFO EXTENDED",
+                             "BOPOMOFOEXTENDED");
+
+        /**
+         * Constant for the "CJK Unified Ideographs Extension A" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A =
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A",
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION A",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIONA");
+
+        /**
+         * Constant for the "Yi Syllables" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock YI_SYLLABLES =
+            new UnicodeBlock("YI_SYLLABLES",
+                             "YI SYLLABLES",
+                             "YISYLLABLES");
+
+        /**
+         * Constant for the "Yi Radicals" Unicode character block.
+         * @since 1.4
+         */
+        public static final UnicodeBlock YI_RADICALS =
+            new UnicodeBlock("YI_RADICALS",
+                             "YI RADICALS",
+                             "YIRADICALS");
+
+        /**
+         * Constant for the "Cyrillic Supplementary" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY =
+            new UnicodeBlock("CYRILLIC_SUPPLEMENTARY",
+                             "CYRILLIC SUPPLEMENTARY",
+                             "CYRILLICSUPPLEMENTARY",
+                             "CYRILLIC SUPPLEMENT",
+                             "CYRILLICSUPPLEMENT");
+
+        /**
+         * Constant for the "Tagalog" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock TAGALOG =
+            new UnicodeBlock("TAGALOG");
+
+        /**
+         * Constant for the "Hanunoo" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock HANUNOO =
+            new UnicodeBlock("HANUNOO");
+
+        /**
+         * Constant for the "Buhid" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock BUHID =
+            new UnicodeBlock("BUHID");
+
+        /**
+         * Constant for the "Tagbanwa" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock TAGBANWA =
+            new UnicodeBlock("TAGBANWA");
+
+        /**
+         * Constant for the "Limbu" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock LIMBU =
+            new UnicodeBlock("LIMBU");
+
+        /**
+         * Constant for the "Tai Le" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock TAI_LE =
+            new UnicodeBlock("TAI_LE",
+                             "TAI LE",
+                             "TAILE");
+
+        /**
+         * Constant for the "Khmer Symbols" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock KHMER_SYMBOLS =
+            new UnicodeBlock("KHMER_SYMBOLS",
+                             "KHMER SYMBOLS",
+                             "KHMERSYMBOLS");
+
+        /**
+         * Constant for the "Phonetic Extensions" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock PHONETIC_EXTENSIONS =
+            new UnicodeBlock("PHONETIC_EXTENSIONS",
+                             "PHONETIC EXTENSIONS",
+                             "PHONETICEXTENSIONS");
+
+        /**
+         * Constant for the "Miscellaneous Mathematical Symbols-A" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A =
+            new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A",
+                             "MISCELLANEOUS MATHEMATICAL SYMBOLS-A",
+                             "MISCELLANEOUSMATHEMATICALSYMBOLS-A");
+
+        /**
+         * Constant for the "Supplemental Arrows-A" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A =
+            new UnicodeBlock("SUPPLEMENTAL_ARROWS_A",
+                             "SUPPLEMENTAL ARROWS-A",
+                             "SUPPLEMENTALARROWS-A");
+
+        /**
+         * Constant for the "Supplemental Arrows-B" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B =
+            new UnicodeBlock("SUPPLEMENTAL_ARROWS_B",
+                             "SUPPLEMENTAL ARROWS-B",
+                             "SUPPLEMENTALARROWS-B");
+
+        /**
+         * Constant for the "Miscellaneous Mathematical Symbols-B" Unicode
+         * character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B =
+            new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
+                             "MISCELLANEOUS MATHEMATICAL SYMBOLS-B",
+                             "MISCELLANEOUSMATHEMATICALSYMBOLS-B");
+
+        /**
+         * Constant for the "Supplemental Mathematical Operators" Unicode
+         * character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS =
+            new UnicodeBlock("SUPPLEMENTAL_MATHEMATICAL_OPERATORS",
+                             "SUPPLEMENTAL MATHEMATICAL OPERATORS",
+                             "SUPPLEMENTALMATHEMATICALOPERATORS");
+
+        /**
+         * Constant for the "Miscellaneous Symbols and Arrows" Unicode character
+         * block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS =
+            new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS",
+                             "MISCELLANEOUS SYMBOLS AND ARROWS",
+                             "MISCELLANEOUSSYMBOLSANDARROWS");
+
+        /**
+         * Constant for the "Katakana Phonetic Extensions" Unicode character
+         * block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS =
+            new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS",
+                             "KATAKANA PHONETIC EXTENSIONS",
+                             "KATAKANAPHONETICEXTENSIONS");
+
+        /**
+         * Constant for the "Yijing Hexagram Symbols" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS =
+            new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS",
+                             "YIJING HEXAGRAM SYMBOLS",
+                             "YIJINGHEXAGRAMSYMBOLS");
+
+        /**
+         * Constant for the "Variation Selectors" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock VARIATION_SELECTORS =
+            new UnicodeBlock("VARIATION_SELECTORS",
+                             "VARIATION SELECTORS",
+                             "VARIATIONSELECTORS");
+
+        /**
+         * Constant for the "Linear B Syllabary" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock LINEAR_B_SYLLABARY =
+            new UnicodeBlock("LINEAR_B_SYLLABARY",
+                             "LINEAR B SYLLABARY",
+                             "LINEARBSYLLABARY");
+
+        /**
+         * Constant for the "Linear B Ideograms" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock LINEAR_B_IDEOGRAMS =
+            new UnicodeBlock("LINEAR_B_IDEOGRAMS",
+                             "LINEAR B IDEOGRAMS",
+                             "LINEARBIDEOGRAMS");
+
+        /**
+         * Constant for the "Aegean Numbers" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock AEGEAN_NUMBERS =
+            new UnicodeBlock("AEGEAN_NUMBERS",
+                             "AEGEAN NUMBERS",
+                             "AEGEANNUMBERS");
+
+        /**
+         * Constant for the "Old Italic" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock OLD_ITALIC =
+            new UnicodeBlock("OLD_ITALIC",
+                             "OLD ITALIC",
+                             "OLDITALIC");
+
+        /**
+         * Constant for the "Gothic" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock GOTHIC =
+            new UnicodeBlock("GOTHIC");
+
+        /**
+         * Constant for the "Ugaritic" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock UGARITIC =
+            new UnicodeBlock("UGARITIC");
+
+        /**
+         * Constant for the "Deseret" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock DESERET =
+            new UnicodeBlock("DESERET");
+
+        /**
+         * Constant for the "Shavian" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SHAVIAN =
+            new UnicodeBlock("SHAVIAN");
+
+        /**
+         * Constant for the "Osmanya" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock OSMANYA =
+            new UnicodeBlock("OSMANYA");
+
+        /**
+         * Constant for the "Cypriot Syllabary" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock CYPRIOT_SYLLABARY =
+            new UnicodeBlock("CYPRIOT_SYLLABARY",
+                             "CYPRIOT SYLLABARY",
+                             "CYPRIOTSYLLABARY");
+
+        /**
+         * Constant for the "Byzantine Musical Symbols" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS =
+            new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS",
+                             "BYZANTINE MUSICAL SYMBOLS",
+                             "BYZANTINEMUSICALSYMBOLS");
+
+        /**
+         * Constant for the "Musical Symbols" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock MUSICAL_SYMBOLS =
+            new UnicodeBlock("MUSICAL_SYMBOLS",
+                             "MUSICAL SYMBOLS",
+                             "MUSICALSYMBOLS");
+
+        /**
+         * Constant for the "Tai Xuan Jing Symbols" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS =
+            new UnicodeBlock("TAI_XUAN_JING_SYMBOLS",
+                             "TAI XUAN JING SYMBOLS",
+                             "TAIXUANJINGSYMBOLS");
+
+        /**
+         * Constant for the "Mathematical Alphanumeric Symbols" Unicode
+         * character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS =
+            new UnicodeBlock("MATHEMATICAL_ALPHANUMERIC_SYMBOLS",
+                             "MATHEMATICAL ALPHANUMERIC SYMBOLS",
+                             "MATHEMATICALALPHANUMERICSYMBOLS");
+
+        /**
+         * Constant for the "CJK Unified Ideographs Extension B" Unicode
+         * character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B =
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B",
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION B",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIONB");
+
+        /**
+         * Constant for the "CJK Compatibility Ideographs Supplement" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT =
+            new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT",
+                             "CJK COMPATIBILITY IDEOGRAPHS SUPPLEMENT",
+                             "CJKCOMPATIBILITYIDEOGRAPHSSUPPLEMENT");
+
+        /**
+         * Constant for the "Tags" Unicode character block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock TAGS =
+            new UnicodeBlock("TAGS");
+
+        /**
+         * Constant for the "Variation Selectors Supplement" Unicode character
+         * block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT =
+            new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT",
+                             "VARIATION SELECTORS SUPPLEMENT",
+                             "VARIATIONSELECTORSSUPPLEMENT");
+
+        /**
+         * Constant for the "Supplementary Private Use Area-A" Unicode character
+         * block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A =
+            new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_A",
+                             "SUPPLEMENTARY PRIVATE USE AREA-A",
+                             "SUPPLEMENTARYPRIVATEUSEAREA-A");
+
+        /**
+         * Constant for the "Supplementary Private Use Area-B" Unicode character
+         * block.
+         * @since 1.5
+         */
+        public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B =
+            new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_B",
+                             "SUPPLEMENTARY PRIVATE USE AREA-B",
+                             "SUPPLEMENTARYPRIVATEUSEAREA-B");
+
+        /**
+         * Constant for the "High Surrogates" Unicode character block.
+         * This block represents codepoint values in the high surrogate
+         * range: U+D800 through U+DB7F
+         *
+         * @since 1.5
+         */
+        public static final UnicodeBlock HIGH_SURROGATES =
+            new UnicodeBlock("HIGH_SURROGATES",
+                             "HIGH SURROGATES",
+                             "HIGHSURROGATES");
+
+        /**
+         * Constant for the "High Private Use Surrogates" Unicode character
+         * block.
+         * This block represents codepoint values in the private use high
+         * surrogate range: U+DB80 through U+DBFF
+         *
+         * @since 1.5
+         */
+        public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES =
+            new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES",
+                             "HIGH PRIVATE USE SURROGATES",
+                             "HIGHPRIVATEUSESURROGATES");
+
+        /**
+         * Constant for the "Low Surrogates" Unicode character block.
+         * This block represents codepoint values in the low surrogate
+         * range: U+DC00 through U+DFFF
+         *
+         * @since 1.5
+         */
+        public static final UnicodeBlock LOW_SURROGATES =
+            new UnicodeBlock("LOW_SURROGATES",
+                             "LOW SURROGATES",
+                             "LOWSURROGATES");
+
+        /**
+         * Constant for the "Arabic Supplement" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ARABIC_SUPPLEMENT =
+            new UnicodeBlock("ARABIC_SUPPLEMENT",
+                             "ARABIC SUPPLEMENT",
+                             "ARABICSUPPLEMENT");
+
+        /**
+         * Constant for the "NKo" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock NKO =
+            new UnicodeBlock("NKO");
+
+        /**
+         * Constant for the "Samaritan" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock SAMARITAN =
+            new UnicodeBlock("SAMARITAN");
+
+        /**
+         * Constant for the "Mandaic" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MANDAIC =
+            new UnicodeBlock("MANDAIC");
+
+        /**
+         * Constant for the "Ethiopic Supplement" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ETHIOPIC_SUPPLEMENT =
+            new UnicodeBlock("ETHIOPIC_SUPPLEMENT",
+                             "ETHIOPIC SUPPLEMENT",
+                             "ETHIOPICSUPPLEMENT");
+
+        /**
+         * Constant for the "Unified Canadian Aboriginal Syllabics Extended"
+         * Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED =
+            new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED",
+                             "UNIFIED CANADIAN ABORIGINAL SYLLABICS EXTENDED",
+                             "UNIFIEDCANADIANABORIGINALSYLLABICSEXTENDED");
+
+        /**
+         * Constant for the "New Tai Lue" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock NEW_TAI_LUE =
+            new UnicodeBlock("NEW_TAI_LUE",
+                             "NEW TAI LUE",
+                             "NEWTAILUE");
+
+        /**
+         * Constant for the "Buginese" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BUGINESE =
+            new UnicodeBlock("BUGINESE");
+
+        /**
+         * Constant for the "Tai Tham" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock TAI_THAM =
+            new UnicodeBlock("TAI_THAM",
+                             "TAI THAM",
+                             "TAITHAM");
+
+        /**
+         * Constant for the "Balinese" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BALINESE =
+            new UnicodeBlock("BALINESE");
+
+        /**
+         * Constant for the "Sundanese" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock SUNDANESE =
+            new UnicodeBlock("SUNDANESE");
+
+        /**
+         * Constant for the "Batak" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BATAK =
+            new UnicodeBlock("BATAK");
+
+        /**
+         * Constant for the "Lepcha" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LEPCHA =
+            new UnicodeBlock("LEPCHA");
+
+        /**
+         * Constant for the "Ol Chiki" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock OL_CHIKI =
+            new UnicodeBlock("OL_CHIKI",
+                             "OL CHIKI",
+                             "OLCHIKI");
+
+        /**
+         * Constant for the "Vedic Extensions" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock VEDIC_EXTENSIONS =
+            new UnicodeBlock("VEDIC_EXTENSIONS",
+                             "VEDIC EXTENSIONS",
+                             "VEDICEXTENSIONS");
+
+        /**
+         * Constant for the "Phonetic Extensions Supplement" Unicode character
+         * block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT =
+            new UnicodeBlock("PHONETIC_EXTENSIONS_SUPPLEMENT",
+                             "PHONETIC EXTENSIONS SUPPLEMENT",
+                             "PHONETICEXTENSIONSSUPPLEMENT");
+
+        /**
+         * Constant for the "Combining Diacritical Marks Supplement" Unicode
+         * character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT =
+            new UnicodeBlock("COMBINING_DIACRITICAL_MARKS_SUPPLEMENT",
+                             "COMBINING DIACRITICAL MARKS SUPPLEMENT",
+                             "COMBININGDIACRITICALMARKSSUPPLEMENT");
+
+        /**
+         * Constant for the "Glagolitic" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock GLAGOLITIC =
+            new UnicodeBlock("GLAGOLITIC");
+
+        /**
+         * Constant for the "Latin Extended-C" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LATIN_EXTENDED_C =
+            new UnicodeBlock("LATIN_EXTENDED_C",
+                             "LATIN EXTENDED-C",
+                             "LATINEXTENDED-C");
+
+        /**
+         * Constant for the "Coptic" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock COPTIC =
+            new UnicodeBlock("COPTIC");
+
+        /**
+         * Constant for the "Georgian Supplement" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock GEORGIAN_SUPPLEMENT =
+            new UnicodeBlock("GEORGIAN_SUPPLEMENT",
+                             "GEORGIAN SUPPLEMENT",
+                             "GEORGIANSUPPLEMENT");
+
+        /**
+         * Constant for the "Tifinagh" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock TIFINAGH =
+            new UnicodeBlock("TIFINAGH");
+
+        /**
+         * Constant for the "Ethiopic Extended" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ETHIOPIC_EXTENDED =
+            new UnicodeBlock("ETHIOPIC_EXTENDED",
+                             "ETHIOPIC EXTENDED",
+                             "ETHIOPICEXTENDED");
+
+        /**
+         * Constant for the "Cyrillic Extended-A" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CYRILLIC_EXTENDED_A =
+            new UnicodeBlock("CYRILLIC_EXTENDED_A",
+                             "CYRILLIC EXTENDED-A",
+                             "CYRILLICEXTENDED-A");
+
+        /**
+         * Constant for the "Supplemental Punctuation" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock SUPPLEMENTAL_PUNCTUATION =
+            new UnicodeBlock("SUPPLEMENTAL_PUNCTUATION",
+                             "SUPPLEMENTAL PUNCTUATION",
+                             "SUPPLEMENTALPUNCTUATION");
+
+        /**
+         * Constant for the "CJK Strokes" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CJK_STROKES =
+            new UnicodeBlock("CJK_STROKES",
+                             "CJK STROKES",
+                             "CJKSTROKES");
+
+        /**
+         * Constant for the "Lisu" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LISU =
+            new UnicodeBlock("LISU");
+
+        /**
+         * Constant for the "Vai" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock VAI =
+            new UnicodeBlock("VAI");
+
+        /**
+         * Constant for the "Cyrillic Extended-B" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CYRILLIC_EXTENDED_B =
+            new UnicodeBlock("CYRILLIC_EXTENDED_B",
+                             "CYRILLIC EXTENDED-B",
+                             "CYRILLICEXTENDED-B");
+
+        /**
+         * Constant for the "Bamum" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BAMUM =
+            new UnicodeBlock("BAMUM");
+
+        /**
+         * Constant for the "Modifier Tone Letters" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MODIFIER_TONE_LETTERS =
+            new UnicodeBlock("MODIFIER_TONE_LETTERS",
+                             "MODIFIER TONE LETTERS",
+                             "MODIFIERTONELETTERS");
+
+        /**
+         * Constant for the "Latin Extended-D" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LATIN_EXTENDED_D =
+            new UnicodeBlock("LATIN_EXTENDED_D",
+                             "LATIN EXTENDED-D",
+                             "LATINEXTENDED-D");
+
+        /**
+         * Constant for the "Syloti Nagri" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock SYLOTI_NAGRI =
+            new UnicodeBlock("SYLOTI_NAGRI",
+                             "SYLOTI NAGRI",
+                             "SYLOTINAGRI");
+
+        /**
+         * Constant for the "Common Indic Number Forms" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock COMMON_INDIC_NUMBER_FORMS =
+            new UnicodeBlock("COMMON_INDIC_NUMBER_FORMS",
+                             "COMMON INDIC NUMBER FORMS",
+                             "COMMONINDICNUMBERFORMS");
+
+        /**
+         * Constant for the "Phags-pa" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock PHAGS_PA =
+            new UnicodeBlock("PHAGS_PA",
+                             "PHAGS-PA");
+
+        /**
+         * Constant for the "Saurashtra" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock SAURASHTRA =
+            new UnicodeBlock("SAURASHTRA");
+
+        /**
+         * Constant for the "Devanagari Extended" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock DEVANAGARI_EXTENDED =
+            new UnicodeBlock("DEVANAGARI_EXTENDED",
+                             "DEVANAGARI EXTENDED",
+                             "DEVANAGARIEXTENDED");
+
+        /**
+         * Constant for the "Kayah Li" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock KAYAH_LI =
+            new UnicodeBlock("KAYAH_LI",
+                             "KAYAH LI",
+                             "KAYAHLI");
+
+        /**
+         * Constant for the "Rejang" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock REJANG =
+            new UnicodeBlock("REJANG");
+
+        /**
+         * Constant for the "Hangul Jamo Extended-A" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock HANGUL_JAMO_EXTENDED_A =
+            new UnicodeBlock("HANGUL_JAMO_EXTENDED_A",
+                             "HANGUL JAMO EXTENDED-A",
+                             "HANGULJAMOEXTENDED-A");
+
+        /**
+         * Constant for the "Javanese" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock JAVANESE =
+            new UnicodeBlock("JAVANESE");
+
+        /**
+         * Constant for the "Cham" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CHAM =
+            new UnicodeBlock("CHAM");
+
+        /**
+         * Constant for the "Myanmar Extended-A" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MYANMAR_EXTENDED_A =
+            new UnicodeBlock("MYANMAR_EXTENDED_A",
+                             "MYANMAR EXTENDED-A",
+                             "MYANMAREXTENDED-A");
+
+        /**
+         * Constant for the "Tai Viet" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock TAI_VIET =
+            new UnicodeBlock("TAI_VIET",
+                             "TAI VIET",
+                             "TAIVIET");
+
+        /**
+         * Constant for the "Ethiopic Extended-A" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ETHIOPIC_EXTENDED_A =
+            new UnicodeBlock("ETHIOPIC_EXTENDED_A",
+                             "ETHIOPIC EXTENDED-A",
+                             "ETHIOPICEXTENDED-A");
+
+        /**
+         * Constant for the "Meetei Mayek" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MEETEI_MAYEK =
+            new UnicodeBlock("MEETEI_MAYEK",
+                             "MEETEI MAYEK",
+                             "MEETEIMAYEK");
+
+        /**
+         * Constant for the "Hangul Jamo Extended-B" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock HANGUL_JAMO_EXTENDED_B =
+            new UnicodeBlock("HANGUL_JAMO_EXTENDED_B",
+                             "HANGUL JAMO EXTENDED-B",
+                             "HANGULJAMOEXTENDED-B");
+
+        /**
+         * Constant for the "Vertical Forms" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock VERTICAL_FORMS =
+            new UnicodeBlock("VERTICAL_FORMS",
+                             "VERTICAL FORMS",
+                             "VERTICALFORMS");
+
+        /**
+         * Constant for the "Ancient Greek Numbers" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ANCIENT_GREEK_NUMBERS =
+            new UnicodeBlock("ANCIENT_GREEK_NUMBERS",
+                             "ANCIENT GREEK NUMBERS",
+                             "ANCIENTGREEKNUMBERS");
+
+        /**
+         * Constant for the "Ancient Symbols" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ANCIENT_SYMBOLS =
+            new UnicodeBlock("ANCIENT_SYMBOLS",
+                             "ANCIENT SYMBOLS",
+                             "ANCIENTSYMBOLS");
+
+        /**
+         * Constant for the "Phaistos Disc" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock PHAISTOS_DISC =
+            new UnicodeBlock("PHAISTOS_DISC",
+                             "PHAISTOS DISC",
+                             "PHAISTOSDISC");
+
+        /**
+         * Constant for the "Lycian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LYCIAN =
+            new UnicodeBlock("LYCIAN");
+
+        /**
+         * Constant for the "Carian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CARIAN =
+            new UnicodeBlock("CARIAN");
+
+        /**
+         * Constant for the "Old Persian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock OLD_PERSIAN =
+            new UnicodeBlock("OLD_PERSIAN",
+                             "OLD PERSIAN",
+                             "OLDPERSIAN");
+
+        /**
+         * Constant for the "Imperial Aramaic" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock IMPERIAL_ARAMAIC =
+            new UnicodeBlock("IMPERIAL_ARAMAIC",
+                             "IMPERIAL ARAMAIC",
+                             "IMPERIALARAMAIC");
+
+        /**
+         * Constant for the "Phoenician" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock PHOENICIAN =
+            new UnicodeBlock("PHOENICIAN");
+
+        /**
+         * Constant for the "Lydian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock LYDIAN =
+            new UnicodeBlock("LYDIAN");
+
+        /**
+         * Constant for the "Kharoshthi" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock KHAROSHTHI =
+            new UnicodeBlock("KHAROSHTHI");
+
+        /**
+         * Constant for the "Old South Arabian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock OLD_SOUTH_ARABIAN =
+            new UnicodeBlock("OLD_SOUTH_ARABIAN",
+                             "OLD SOUTH ARABIAN",
+                             "OLDSOUTHARABIAN");
+
+        /**
+         * Constant for the "Avestan" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock AVESTAN =
+            new UnicodeBlock("AVESTAN");
+
+        /**
+         * Constant for the "Inscriptional Parthian" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock INSCRIPTIONAL_PARTHIAN =
+            new UnicodeBlock("INSCRIPTIONAL_PARTHIAN",
+                             "INSCRIPTIONAL PARTHIAN",
+                             "INSCRIPTIONALPARTHIAN");
+
+        /**
+         * Constant for the "Inscriptional Pahlavi" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock INSCRIPTIONAL_PAHLAVI =
+            new UnicodeBlock("INSCRIPTIONAL_PAHLAVI",
+                             "INSCRIPTIONAL PAHLAVI",
+                             "INSCRIPTIONALPAHLAVI");
+
+        /**
+         * Constant for the "Old Turkic" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock OLD_TURKIC =
+            new UnicodeBlock("OLD_TURKIC",
+                             "OLD TURKIC",
+                             "OLDTURKIC");
+
+        /**
+         * Constant for the "Rumi Numeral Symbols" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock RUMI_NUMERAL_SYMBOLS =
+            new UnicodeBlock("RUMI_NUMERAL_SYMBOLS",
+                             "RUMI NUMERAL SYMBOLS",
+                             "RUMINUMERALSYMBOLS");
+
+        /**
+         * Constant for the "Brahmi" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BRAHMI =
+            new UnicodeBlock("BRAHMI");
+
+        /**
+         * Constant for the "Kaithi" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock KAITHI =
+            new UnicodeBlock("KAITHI");
+
+        /**
+         * Constant for the "Cuneiform" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CUNEIFORM =
+            new UnicodeBlock("CUNEIFORM");
+
+        /**
+         * Constant for the "Cuneiform Numbers and Punctuation" Unicode
+         * character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION =
+            new UnicodeBlock("CUNEIFORM_NUMBERS_AND_PUNCTUATION",
+                             "CUNEIFORM NUMBERS AND PUNCTUATION",
+                             "CUNEIFORMNUMBERSANDPUNCTUATION");
+
+        /**
+         * Constant for the "Egyptian Hieroglyphs" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock EGYPTIAN_HIEROGLYPHS =
+            new UnicodeBlock("EGYPTIAN_HIEROGLYPHS",
+                             "EGYPTIAN HIEROGLYPHS",
+                             "EGYPTIANHIEROGLYPHS");
+
+        /**
+         * Constant for the "Bamum Supplement" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock BAMUM_SUPPLEMENT =
+            new UnicodeBlock("BAMUM_SUPPLEMENT",
+                             "BAMUM SUPPLEMENT",
+                             "BAMUMSUPPLEMENT");
+
+        /**
+         * Constant for the "Kana Supplement" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock KANA_SUPPLEMENT =
+            new UnicodeBlock("KANA_SUPPLEMENT",
+                             "KANA SUPPLEMENT",
+                             "KANASUPPLEMENT");
+
+        /**
+         * Constant for the "Ancient Greek Musical Notation" Unicode character
+         * block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION =
+            new UnicodeBlock("ANCIENT_GREEK_MUSICAL_NOTATION",
+                             "ANCIENT GREEK MUSICAL NOTATION",
+                             "ANCIENTGREEKMUSICALNOTATION");
+
+        /**
+         * Constant for the "Counting Rod Numerals" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock COUNTING_ROD_NUMERALS =
+            new UnicodeBlock("COUNTING_ROD_NUMERALS",
+                             "COUNTING ROD NUMERALS",
+                             "COUNTINGRODNUMERALS");
+
+        /**
+         * Constant for the "Mahjong Tiles" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MAHJONG_TILES =
+            new UnicodeBlock("MAHJONG_TILES",
+                             "MAHJONG TILES",
+                             "MAHJONGTILES");
+
+        /**
+         * Constant for the "Domino Tiles" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock DOMINO_TILES =
+            new UnicodeBlock("DOMINO_TILES",
+                             "DOMINO TILES",
+                             "DOMINOTILES");
+
+        /**
+         * Constant for the "Playing Cards" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock PLAYING_CARDS =
+            new UnicodeBlock("PLAYING_CARDS",
+                             "PLAYING CARDS",
+                             "PLAYINGCARDS");
+
+        /**
+         * Constant for the "Enclosed Alphanumeric Supplement" Unicode character
+         * block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT =
+            new UnicodeBlock("ENCLOSED_ALPHANUMERIC_SUPPLEMENT",
+                             "ENCLOSED ALPHANUMERIC SUPPLEMENT",
+                             "ENCLOSEDALPHANUMERICSUPPLEMENT");
+
+        /**
+         * Constant for the "Enclosed Ideographic Supplement" Unicode character
+         * block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT =
+            new UnicodeBlock("ENCLOSED_IDEOGRAPHIC_SUPPLEMENT",
+                             "ENCLOSED IDEOGRAPHIC SUPPLEMENT",
+                             "ENCLOSEDIDEOGRAPHICSUPPLEMENT");
+
+        /**
+         * Constant for the "Miscellaneous Symbols And Pictographs" Unicode
+         * character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS =
+            new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS",
+                             "MISCELLANEOUS SYMBOLS AND PICTOGRAPHS",
+                             "MISCELLANEOUSSYMBOLSANDPICTOGRAPHS");
+
+        /**
+         * Constant for the "Emoticons" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock EMOTICONS =
+            new UnicodeBlock("EMOTICONS");
+
+        /**
+         * Constant for the "Transport And Map Symbols" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS =
+            new UnicodeBlock("TRANSPORT_AND_MAP_SYMBOLS",
+                             "TRANSPORT AND MAP SYMBOLS",
+                             "TRANSPORTANDMAPSYMBOLS");
+
+        /**
+         * Constant for the "Alchemical Symbols" Unicode character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock ALCHEMICAL_SYMBOLS =
+            new UnicodeBlock("ALCHEMICAL_SYMBOLS",
+                             "ALCHEMICAL SYMBOLS",
+                             "ALCHEMICALSYMBOLS");
+
+        /**
+         * Constant for the "CJK Unified Ideographs Extension C" Unicode
+         * character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C =
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C",
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION C",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIONC");
+
+        /**
+         * Constant for the "CJK Unified Ideographs Extension D" Unicode
+         * character block.
+         * @since 1.7
+         */
+        public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D =
+            new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D",
+                             "CJK UNIFIED IDEOGRAPHS EXTENSION D",
+                             "CJKUNIFIEDIDEOGRAPHSEXTENSIOND");
+
+        /**
+         * Constant for the "Arabic Extended-A" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock ARABIC_EXTENDED_A =
+            new UnicodeBlock("ARABIC_EXTENDED_A",
+                             "ARABIC EXTENDED-A",
+                             "ARABICEXTENDED-A");
+
+        /**
+         * Constant for the "Sundanese Supplement" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock SUNDANESE_SUPPLEMENT =
+            new UnicodeBlock("SUNDANESE_SUPPLEMENT",
+                             "SUNDANESE SUPPLEMENT",
+                             "SUNDANESESUPPLEMENT");
+
+        /**
+         * Constant for the "Meetei Mayek Extensions" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock MEETEI_MAYEK_EXTENSIONS =
+            new UnicodeBlock("MEETEI_MAYEK_EXTENSIONS",
+                             "MEETEI MAYEK EXTENSIONS",
+                             "MEETEIMAYEKEXTENSIONS");
+
+        /**
+         * Constant for the "Meroitic Hieroglyphs" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock MEROITIC_HIEROGLYPHS =
+            new UnicodeBlock("MEROITIC_HIEROGLYPHS",
+                             "MEROITIC HIEROGLYPHS",
+                             "MEROITICHIEROGLYPHS");
+
+        /**
+         * Constant for the "Meroitic Cursive" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock MEROITIC_CURSIVE =
+            new UnicodeBlock("MEROITIC_CURSIVE",
+                             "MEROITIC CURSIVE",
+                             "MEROITICCURSIVE");
+
+        /**
+         * Constant for the "Sora Sompeng" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock SORA_SOMPENG =
+            new UnicodeBlock("SORA_SOMPENG",
+                             "SORA SOMPENG",
+                             "SORASOMPENG");
+
+        /**
+         * Constant for the "Chakma" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock CHAKMA =
+            new UnicodeBlock("CHAKMA");
+
+        /**
+         * Constant for the "Sharada" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock SHARADA =
+            new UnicodeBlock("SHARADA");
+
+        /**
+         * Constant for the "Takri" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock TAKRI =
+            new UnicodeBlock("TAKRI");
+
+        /**
+         * Constant for the "Miao" Unicode character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock MIAO =
+            new UnicodeBlock("MIAO");
+
+        /**
+         * Constant for the "Arabic Mathematical Alphabetic Symbols" Unicode
+         * character block.
+         * @since 1.8
+         */
+        public static final UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS =
+            new UnicodeBlock("ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS",
+                             "ARABIC MATHEMATICAL ALPHABETIC SYMBOLS",
+                             "ARABICMATHEMATICALALPHABETICSYMBOLS");
+
+        private static final int blockStarts[] = {
+            0x0000,   // 0000..007F; Basic Latin
+            0x0080,   // 0080..00FF; Latin-1 Supplement
+            0x0100,   // 0100..017F; Latin Extended-A
+            0x0180,   // 0180..024F; Latin Extended-B
+            0x0250,   // 0250..02AF; IPA Extensions
+            0x02B0,   // 02B0..02FF; Spacing Modifier Letters
+            0x0300,   // 0300..036F; Combining Diacritical Marks
+            0x0370,   // 0370..03FF; Greek and Coptic
+            0x0400,   // 0400..04FF; Cyrillic
+            0x0500,   // 0500..052F; Cyrillic Supplement
+            0x0530,   // 0530..058F; Armenian
+            0x0590,   // 0590..05FF; Hebrew
+            0x0600,   // 0600..06FF; Arabic
+            0x0700,   // 0700..074F; Syriac
+            0x0750,   // 0750..077F; Arabic Supplement
+            0x0780,   // 0780..07BF; Thaana
+            0x07C0,   // 07C0..07FF; NKo
+            0x0800,   // 0800..083F; Samaritan
+            0x0840,   // 0840..085F; Mandaic
+            0x0860,   //             unassigned
+            0x08A0,   // 08A0..08FF; Arabic Extended-A
+            0x0900,   // 0900..097F; Devanagari
+            0x0980,   // 0980..09FF; Bengali
+            0x0A00,   // 0A00..0A7F; Gurmukhi
+            0x0A80,   // 0A80..0AFF; Gujarati
+            0x0B00,   // 0B00..0B7F; Oriya
+            0x0B80,   // 0B80..0BFF; Tamil
+            0x0C00,   // 0C00..0C7F; Telugu
+            0x0C80,   // 0C80..0CFF; Kannada
+            0x0D00,   // 0D00..0D7F; Malayalam
+            0x0D80,   // 0D80..0DFF; Sinhala
+            0x0E00,   // 0E00..0E7F; Thai
+            0x0E80,   // 0E80..0EFF; Lao
+            0x0F00,   // 0F00..0FFF; Tibetan
+            0x1000,   // 1000..109F; Myanmar
+            0x10A0,   // 10A0..10FF; Georgian
+            0x1100,   // 1100..11FF; Hangul Jamo
+            0x1200,   // 1200..137F; Ethiopic
+            0x1380,   // 1380..139F; Ethiopic Supplement
+            0x13A0,   // 13A0..13FF; Cherokee
+            0x1400,   // 1400..167F; Unified Canadian Aboriginal Syllabics
+            0x1680,   // 1680..169F; Ogham
+            0x16A0,   // 16A0..16FF; Runic
+            0x1700,   // 1700..171F; Tagalog
+            0x1720,   // 1720..173F; Hanunoo
+            0x1740,   // 1740..175F; Buhid
+            0x1760,   // 1760..177F; Tagbanwa
+            0x1780,   // 1780..17FF; Khmer
+            0x1800,   // 1800..18AF; Mongolian
+            0x18B0,   // 18B0..18FF; Unified Canadian Aboriginal Syllabics Extended
+            0x1900,   // 1900..194F; Limbu
+            0x1950,   // 1950..197F; Tai Le
+            0x1980,   // 1980..19DF; New Tai Lue
+            0x19E0,   // 19E0..19FF; Khmer Symbols
+            0x1A00,   // 1A00..1A1F; Buginese
+            0x1A20,   // 1A20..1AAF; Tai Tham
+            0x1AB0,   //             unassigned
+            0x1B00,   // 1B00..1B7F; Balinese
+            0x1B80,   // 1B80..1BBF; Sundanese
+            0x1BC0,   // 1BC0..1BFF; Batak
+            0x1C00,   // 1C00..1C4F; Lepcha
+            0x1C50,   // 1C50..1C7F; Ol Chiki
+            0x1C80,   //             unassigned
+            0x1CC0,   // 1CC0..1CCF; Sundanese Supplement
+            0x1CD0,   // 1CD0..1CFF; Vedic Extensions
+            0x1D00,   // 1D00..1D7F; Phonetic Extensions
+            0x1D80,   // 1D80..1DBF; Phonetic Extensions Supplement
+            0x1DC0,   // 1DC0..1DFF; Combining Diacritical Marks Supplement
+            0x1E00,   // 1E00..1EFF; Latin Extended Additional
+            0x1F00,   // 1F00..1FFF; Greek Extended
+            0x2000,   // 2000..206F; General Punctuation
+            0x2070,   // 2070..209F; Superscripts and Subscripts
+            0x20A0,   // 20A0..20CF; Currency Symbols
+            0x20D0,   // 20D0..20FF; Combining Diacritical Marks for Symbols
+            0x2100,   // 2100..214F; Letterlike Symbols
+            0x2150,   // 2150..218F; Number Forms
+            0x2190,   // 2190..21FF; Arrows
+            0x2200,   // 2200..22FF; Mathematical Operators
+            0x2300,   // 2300..23FF; Miscellaneous Technical
+            0x2400,   // 2400..243F; Control Pictures
+            0x2440,   // 2440..245F; Optical Character Recognition
+            0x2460,   // 2460..24FF; Enclosed Alphanumerics
+            0x2500,   // 2500..257F; Box Drawing
+            0x2580,   // 2580..259F; Block Elements
+            0x25A0,   // 25A0..25FF; Geometric Shapes
+            0x2600,   // 2600..26FF; Miscellaneous Symbols
+            0x2700,   // 2700..27BF; Dingbats
+            0x27C0,   // 27C0..27EF; Miscellaneous Mathematical Symbols-A
+            0x27F0,   // 27F0..27FF; Supplemental Arrows-A
+            0x2800,   // 2800..28FF; Braille Patterns
+            0x2900,   // 2900..297F; Supplemental Arrows-B
+            0x2980,   // 2980..29FF; Miscellaneous Mathematical Symbols-B
+            0x2A00,   // 2A00..2AFF; Supplemental Mathematical Operators
+            0x2B00,   // 2B00..2BFF; Miscellaneous Symbols and Arrows
+            0x2C00,   // 2C00..2C5F; Glagolitic
+            0x2C60,   // 2C60..2C7F; Latin Extended-C
+            0x2C80,   // 2C80..2CFF; Coptic
+            0x2D00,   // 2D00..2D2F; Georgian Supplement
+            0x2D30,   // 2D30..2D7F; Tifinagh
+            0x2D80,   // 2D80..2DDF; Ethiopic Extended
+            0x2DE0,   // 2DE0..2DFF; Cyrillic Extended-A
+            0x2E00,   // 2E00..2E7F; Supplemental Punctuation
+            0x2E80,   // 2E80..2EFF; CJK Radicals Supplement
+            0x2F00,   // 2F00..2FDF; Kangxi Radicals
+            0x2FE0,   //             unassigned
+            0x2FF0,   // 2FF0..2FFF; Ideographic Description Characters
+            0x3000,   // 3000..303F; CJK Symbols and Punctuation
+            0x3040,   // 3040..309F; Hiragana
+            0x30A0,   // 30A0..30FF; Katakana
+            0x3100,   // 3100..312F; Bopomofo
+            0x3130,   // 3130..318F; Hangul Compatibility Jamo
+            0x3190,   // 3190..319F; Kanbun
+            0x31A0,   // 31A0..31BF; Bopomofo Extended
+            0x31C0,   // 31C0..31EF; CJK Strokes
+            0x31F0,   // 31F0..31FF; Katakana Phonetic Extensions
+            0x3200,   // 3200..32FF; Enclosed CJK Letters and Months
+            0x3300,   // 3300..33FF; CJK Compatibility
+            0x3400,   // 3400..4DBF; CJK Unified Ideographs Extension A
+            0x4DC0,   // 4DC0..4DFF; Yijing Hexagram Symbols
+            0x4E00,   // 4E00..9FFF; CJK Unified Ideographs
+            0xA000,   // A000..A48F; Yi Syllables
+            0xA490,   // A490..A4CF; Yi Radicals
+            0xA4D0,   // A4D0..A4FF; Lisu
+            0xA500,   // A500..A63F; Vai
+            0xA640,   // A640..A69F; Cyrillic Extended-B
+            0xA6A0,   // A6A0..A6FF; Bamum
+            0xA700,   // A700..A71F; Modifier Tone Letters
+            0xA720,   // A720..A7FF; Latin Extended-D
+            0xA800,   // A800..A82F; Syloti Nagri
+            0xA830,   // A830..A83F; Common Indic Number Forms
+            0xA840,   // A840..A87F; Phags-pa
+            0xA880,   // A880..A8DF; Saurashtra
+            0xA8E0,   // A8E0..A8FF; Devanagari Extended
+            0xA900,   // A900..A92F; Kayah Li
+            0xA930,   // A930..A95F; Rejang
+            0xA960,   // A960..A97F; Hangul Jamo Extended-A
+            0xA980,   // A980..A9DF; Javanese
+            0xA9E0,   //             unassigned
+            0xAA00,   // AA00..AA5F; Cham
+            0xAA60,   // AA60..AA7F; Myanmar Extended-A
+            0xAA80,   // AA80..AADF; Tai Viet
+            0xAAE0,   // AAE0..AAFF; Meetei Mayek Extensions
+            0xAB00,   // AB00..AB2F; Ethiopic Extended-A
+            0xAB30,   //             unassigned
+            0xABC0,   // ABC0..ABFF; Meetei Mayek
+            0xAC00,   // AC00..D7AF; Hangul Syllables
+            0xD7B0,   // D7B0..D7FF; Hangul Jamo Extended-B
+            0xD800,   // D800..DB7F; High Surrogates
+            0xDB80,   // DB80..DBFF; High Private Use Surrogates
+            0xDC00,   // DC00..DFFF; Low Surrogates
+            0xE000,   // E000..F8FF; Private Use Area
+            0xF900,   // F900..FAFF; CJK Compatibility Ideographs
+            0xFB00,   // FB00..FB4F; Alphabetic Presentation Forms
+            0xFB50,   // FB50..FDFF; Arabic Presentation Forms-A
+            0xFE00,   // FE00..FE0F; Variation Selectors
+            0xFE10,   // FE10..FE1F; Vertical Forms
+            0xFE20,   // FE20..FE2F; Combining Half Marks
+            0xFE30,   // FE30..FE4F; CJK Compatibility Forms
+            0xFE50,   // FE50..FE6F; Small Form Variants
+            0xFE70,   // FE70..FEFF; Arabic Presentation Forms-B
+            0xFF00,   // FF00..FFEF; Halfwidth and Fullwidth Forms
+            0xFFF0,   // FFF0..FFFF; Specials
+            0x10000,  // 10000..1007F; Linear B Syllabary
+            0x10080,  // 10080..100FF; Linear B Ideograms
+            0x10100,  // 10100..1013F; Aegean Numbers
+            0x10140,  // 10140..1018F; Ancient Greek Numbers
+            0x10190,  // 10190..101CF; Ancient Symbols
+            0x101D0,  // 101D0..101FF; Phaistos Disc
+            0x10200,  //               unassigned
+            0x10280,  // 10280..1029F; Lycian
+            0x102A0,  // 102A0..102DF; Carian
+            0x102E0,  //               unassigned
+            0x10300,  // 10300..1032F; Old Italic
+            0x10330,  // 10330..1034F; Gothic
+            0x10350,  //               unassigned
+            0x10380,  // 10380..1039F; Ugaritic
+            0x103A0,  // 103A0..103DF; Old Persian
+            0x103E0,  //               unassigned
+            0x10400,  // 10400..1044F; Deseret
+            0x10450,  // 10450..1047F; Shavian
+            0x10480,  // 10480..104AF; Osmanya
+            0x104B0,  //               unassigned
+            0x10800,  // 10800..1083F; Cypriot Syllabary
+            0x10840,  // 10840..1085F; Imperial Aramaic
+            0x10860,  //               unassigned
+            0x10900,  // 10900..1091F; Phoenician
+            0x10920,  // 10920..1093F; Lydian
+            0x10940,  //               unassigned
+            0x10980,  // 10980..1099F; Meroitic Hieroglyphs
+            0x109A0,  // 109A0..109FF; Meroitic Cursive
+            0x10A00,  // 10A00..10A5F; Kharoshthi
+            0x10A60,  // 10A60..10A7F; Old South Arabian
+            0x10A80,  //               unassigned
+            0x10B00,  // 10B00..10B3F; Avestan
+            0x10B40,  // 10B40..10B5F; Inscriptional Parthian
+            0x10B60,  // 10B60..10B7F; Inscriptional Pahlavi
+            0x10B80,  //               unassigned
+            0x10C00,  // 10C00..10C4F; Old Turkic
+            0x10C50,  //               unassigned
+            0x10E60,  // 10E60..10E7F; Rumi Numeral Symbols
+            0x10E80,  //               unassigned
+            0x11000,  // 11000..1107F; Brahmi
+            0x11080,  // 11080..110CF; Kaithi
+            0x110D0,  // 110D0..110FF; Sora Sompeng
+            0x11100,  // 11100..1114F; Chakma
+            0x11150,  //               unassigned
+            0x11180,  // 11180..111DF; Sharada
+            0x111E0,  //               unassigned
+            0x11680,  // 11680..116CF; Takri
+            0x116D0,  //               unassigned
+            0x12000,  // 12000..123FF; Cuneiform
+            0x12400,  // 12400..1247F; Cuneiform Numbers and Punctuation
+            0x12480,  //               unassigned
+            0x13000,  // 13000..1342F; Egyptian Hieroglyphs
+            0x13430,  //               unassigned
+            0x16800,  // 16800..16A3F; Bamum Supplement
+            0x16A40,  //               unassigned
+            0x16F00,  // 16F00..16F9F; Miao
+            0x16FA0,  //               unassigned
+            0x1B000,  // 1B000..1B0FF; Kana Supplement
+            0x1B100,  //               unassigned
+            0x1D000,  // 1D000..1D0FF; Byzantine Musical Symbols
+            0x1D100,  // 1D100..1D1FF; Musical Symbols
+            0x1D200,  // 1D200..1D24F; Ancient Greek Musical Notation
+            0x1D250,  //               unassigned
+            0x1D300,  // 1D300..1D35F; Tai Xuan Jing Symbols
+            0x1D360,  // 1D360..1D37F; Counting Rod Numerals
+            0x1D380,  //               unassigned
+            0x1D400,  // 1D400..1D7FF; Mathematical Alphanumeric Symbols
+            0x1D800,  //               unassigned
+            0x1EE00,  // 1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols
+            0x1EF00,  //               unassigned
+            0x1F000,  // 1F000..1F02F; Mahjong Tiles
+            0x1F030,  // 1F030..1F09F; Domino Tiles
+            0x1F0A0,  // 1F0A0..1F0FF; Playing Cards
+            0x1F100,  // 1F100..1F1FF; Enclosed Alphanumeric Supplement
+            0x1F200,  // 1F200..1F2FF; Enclosed Ideographic Supplement
+            0x1F300,  // 1F300..1F5FF; Miscellaneous Symbols And Pictographs
+            0x1F600,  // 1F600..1F64F; Emoticons
+            0x1F650,  //               unassigned
+            0x1F680,  // 1F680..1F6FF; Transport And Map Symbols
+            0x1F700,  // 1F700..1F77F; Alchemical Symbols
+            0x1F780,  //               unassigned
+            0x20000,  // 20000..2A6DF; CJK Unified Ideographs Extension B
+            0x2A6E0,  //               unassigned
+            0x2A700,  // 2A700..2B73F; CJK Unified Ideographs Extension C
+            0x2B740,  // 2B740..2B81F; CJK Unified Ideographs Extension D
+            0x2B820,  //               unassigned
+            0x2F800,  // 2F800..2FA1F; CJK Compatibility Ideographs Supplement
+            0x2FA20,  //               unassigned
+            0xE0000,  // E0000..E007F; Tags
+            0xE0080,  //               unassigned
+            0xE0100,  // E0100..E01EF; Variation Selectors Supplement
+            0xE01F0,  //               unassigned
+            0xF0000,  // F0000..FFFFF; Supplementary Private Use Area-A
+            0x100000  // 100000..10FFFF; Supplementary Private Use Area-B
+        };
+
+        private static final UnicodeBlock[] blocks = {
+            BASIC_LATIN,
+            LATIN_1_SUPPLEMENT,
+            LATIN_EXTENDED_A,
+            LATIN_EXTENDED_B,
+            IPA_EXTENSIONS,
+            SPACING_MODIFIER_LETTERS,
+            COMBINING_DIACRITICAL_MARKS,
+            GREEK,
+            CYRILLIC,
+            CYRILLIC_SUPPLEMENTARY,
+            ARMENIAN,
+            HEBREW,
+            ARABIC,
+            SYRIAC,
+            ARABIC_SUPPLEMENT,
+            THAANA,
+            NKO,
+            SAMARITAN,
+            MANDAIC,
+            null,
+            ARABIC_EXTENDED_A,
+            DEVANAGARI,
+            BENGALI,
+            GURMUKHI,
+            GUJARATI,
+            ORIYA,
+            TAMIL,
+            TELUGU,
+            KANNADA,
+            MALAYALAM,
+            SINHALA,
+            THAI,
+            LAO,
+            TIBETAN,
+            MYANMAR,
+            GEORGIAN,
+            HANGUL_JAMO,
+            ETHIOPIC,
+            ETHIOPIC_SUPPLEMENT,
+            CHEROKEE,
+            UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS,
+            OGHAM,
+            RUNIC,
+            TAGALOG,
+            HANUNOO,
+            BUHID,
+            TAGBANWA,
+            KHMER,
+            MONGOLIAN,
+            UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED,
+            LIMBU,
+            TAI_LE,
+            NEW_TAI_LUE,
+            KHMER_SYMBOLS,
+            BUGINESE,
+            TAI_THAM,
+            null,
+            BALINESE,
+            SUNDANESE,
+            BATAK,
+            LEPCHA,
+            OL_CHIKI,
+            null,
+            SUNDANESE_SUPPLEMENT,
+            VEDIC_EXTENSIONS,
+            PHONETIC_EXTENSIONS,
+            PHONETIC_EXTENSIONS_SUPPLEMENT,
+            COMBINING_DIACRITICAL_MARKS_SUPPLEMENT,
+            LATIN_EXTENDED_ADDITIONAL,
+            GREEK_EXTENDED,
+            GENERAL_PUNCTUATION,
+            SUPERSCRIPTS_AND_SUBSCRIPTS,
+            CURRENCY_SYMBOLS,
+            COMBINING_MARKS_FOR_SYMBOLS,
+            LETTERLIKE_SYMBOLS,
+            NUMBER_FORMS,
+            ARROWS,
+            MATHEMATICAL_OPERATORS,
+            MISCELLANEOUS_TECHNICAL,
+            CONTROL_PICTURES,
+            OPTICAL_CHARACTER_RECOGNITION,
+            ENCLOSED_ALPHANUMERICS,
+            BOX_DRAWING,
+            BLOCK_ELEMENTS,
+            GEOMETRIC_SHAPES,
+            MISCELLANEOUS_SYMBOLS,
+            DINGBATS,
+            MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A,
+            SUPPLEMENTAL_ARROWS_A,
+            BRAILLE_PATTERNS,
+            SUPPLEMENTAL_ARROWS_B,
+            MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B,
+            SUPPLEMENTAL_MATHEMATICAL_OPERATORS,
+            MISCELLANEOUS_SYMBOLS_AND_ARROWS,
+            GLAGOLITIC,
+            LATIN_EXTENDED_C,
+            COPTIC,
+            GEORGIAN_SUPPLEMENT,
+            TIFINAGH,
+            ETHIOPIC_EXTENDED,
+            CYRILLIC_EXTENDED_A,
+            SUPPLEMENTAL_PUNCTUATION,
+            CJK_RADICALS_SUPPLEMENT,
+            KANGXI_RADICALS,
+            null,
+            IDEOGRAPHIC_DESCRIPTION_CHARACTERS,
+            CJK_SYMBOLS_AND_PUNCTUATION,
+            HIRAGANA,
+            KATAKANA,
+            BOPOMOFO,
+            HANGUL_COMPATIBILITY_JAMO,
+            KANBUN,
+            BOPOMOFO_EXTENDED,
+            CJK_STROKES,
+            KATAKANA_PHONETIC_EXTENSIONS,
+            ENCLOSED_CJK_LETTERS_AND_MONTHS,
+            CJK_COMPATIBILITY,
+            CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A,
+            YIJING_HEXAGRAM_SYMBOLS,
+            CJK_UNIFIED_IDEOGRAPHS,
+            YI_SYLLABLES,
+            YI_RADICALS,
+            LISU,
+            VAI,
+            CYRILLIC_EXTENDED_B,
+            BAMUM,
+            MODIFIER_TONE_LETTERS,
+            LATIN_EXTENDED_D,
+            SYLOTI_NAGRI,
+            COMMON_INDIC_NUMBER_FORMS,
+            PHAGS_PA,
+            SAURASHTRA,
+            DEVANAGARI_EXTENDED,
+            KAYAH_LI,
+            REJANG,
+            HANGUL_JAMO_EXTENDED_A,
+            JAVANESE,
+            null,
+            CHAM,
+            MYANMAR_EXTENDED_A,
+            TAI_VIET,
+            MEETEI_MAYEK_EXTENSIONS,
+            ETHIOPIC_EXTENDED_A,
+            null,
+            MEETEI_MAYEK,
+            HANGUL_SYLLABLES,
+            HANGUL_JAMO_EXTENDED_B,
+            HIGH_SURROGATES,
+            HIGH_PRIVATE_USE_SURROGATES,
+            LOW_SURROGATES,
+            PRIVATE_USE_AREA,
+            CJK_COMPATIBILITY_IDEOGRAPHS,
+            ALPHABETIC_PRESENTATION_FORMS,
+            ARABIC_PRESENTATION_FORMS_A,
+            VARIATION_SELECTORS,
+            VERTICAL_FORMS,
+            COMBINING_HALF_MARKS,
+            CJK_COMPATIBILITY_FORMS,
+            SMALL_FORM_VARIANTS,
+            ARABIC_PRESENTATION_FORMS_B,
+            HALFWIDTH_AND_FULLWIDTH_FORMS,
+            SPECIALS,
+            LINEAR_B_SYLLABARY,
+            LINEAR_B_IDEOGRAMS,
+            AEGEAN_NUMBERS,
+            ANCIENT_GREEK_NUMBERS,
+            ANCIENT_SYMBOLS,
+            PHAISTOS_DISC,
+            null,
+            LYCIAN,
+            CARIAN,
+            null,
+            OLD_ITALIC,
+            GOTHIC,
+            null,
+            UGARITIC,
+            OLD_PERSIAN,
+            null,
+            DESERET,
+            SHAVIAN,
+            OSMANYA,
+            null,
+            CYPRIOT_SYLLABARY,
+            IMPERIAL_ARAMAIC,
+            null,
+            PHOENICIAN,
+            LYDIAN,
+            null,
+            MEROITIC_HIEROGLYPHS,
+            MEROITIC_CURSIVE,
+            KHAROSHTHI,
+            OLD_SOUTH_ARABIAN,
+            null,
+            AVESTAN,
+            INSCRIPTIONAL_PARTHIAN,
+            INSCRIPTIONAL_PAHLAVI,
+            null,
+            OLD_TURKIC,
+            null,
+            RUMI_NUMERAL_SYMBOLS,
+            null,
+            BRAHMI,
+            KAITHI,
+            SORA_SOMPENG,
+            CHAKMA,
+            null,
+            SHARADA,
+            null,
+            TAKRI,
+            null,
+            CUNEIFORM,
+            CUNEIFORM_NUMBERS_AND_PUNCTUATION,
+            null,
+            EGYPTIAN_HIEROGLYPHS,
+            null,
+            BAMUM_SUPPLEMENT,
+            null,
+            MIAO,
+            null,
+            KANA_SUPPLEMENT,
+            null,
+            BYZANTINE_MUSICAL_SYMBOLS,
+            MUSICAL_SYMBOLS,
+            ANCIENT_GREEK_MUSICAL_NOTATION,
+            null,
+            TAI_XUAN_JING_SYMBOLS,
+            COUNTING_ROD_NUMERALS,
+            null,
+            MATHEMATICAL_ALPHANUMERIC_SYMBOLS,
+            null,
+            ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS,
+            null,
+            MAHJONG_TILES,
+            DOMINO_TILES,
+            PLAYING_CARDS,
+            ENCLOSED_ALPHANUMERIC_SUPPLEMENT,
+            ENCLOSED_IDEOGRAPHIC_SUPPLEMENT,
+            MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS,
+            EMOTICONS,
+            null,
+            TRANSPORT_AND_MAP_SYMBOLS,
+            ALCHEMICAL_SYMBOLS,
+            null,
+            CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B,
+            null,
+            CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C,
+            CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D,
+            null,
+            CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT,
+            null,
+            TAGS,
+            null,
+            VARIATION_SELECTORS_SUPPLEMENT,
+            null,
+            SUPPLEMENTARY_PRIVATE_USE_AREA_A,
+            SUPPLEMENTARY_PRIVATE_USE_AREA_B
+        };
+
+
+        /**
+         * Returns the object representing the Unicode block containing the
+         * given character, or {@code null} if the character is not a
+         * member of a defined block.
+         *
+         * <p><b>Note:</b> This method cannot handle
+         * <a href="Character.html#supplementary"> supplementary
+         * characters</a>.  To support all Unicode characters, including
+         * supplementary characters, use the {@link #of(int)} method.
+         *
+         * @param   c  The character in question
+         * @return  The {@code UnicodeBlock} instance representing the
+         *          Unicode block of which this character is a member, or
+         *          {@code null} if the character is not a member of any
+         *          Unicode block
+         */
+        public static UnicodeBlock of(char c) {
+            return of((int)c);
+        }
+
+        /**
+         * Returns the object representing the Unicode block
+         * containing the given character (Unicode code point), or
+         * {@code null} if the character is not a member of a
+         * defined block.
+         *
+         * @param   codePoint the character (Unicode code point) in question.
+         * @return  The {@code UnicodeBlock} instance representing the
+         *          Unicode block of which this character is a member, or
+         *          {@code null} if the character is not a member of any
+         *          Unicode block
+         * @exception IllegalArgumentException if the specified
+         * {@code codePoint} is an invalid Unicode code point.
+         * @see Character#isValidCodePoint(int)
+         * @since   1.5
+         */
+        public static UnicodeBlock of(int codePoint) {
+            if (!isValidCodePoint(codePoint)) {
+                throw new IllegalArgumentException();
+            }
+
+            int top, bottom, current;
+            bottom = 0;
+            top = blockStarts.length;
+            current = top/2;
+
+            // invariant: top > current >= bottom && codePoint >= unicodeBlockStarts[bottom]
+            while (top - bottom > 1) {
+                if (codePoint >= blockStarts[current]) {
+                    bottom = current;
+                } else {
+                    top = current;
+                }
+                current = (top + bottom) / 2;
+            }
+            return blocks[current];
+        }
+
+        /**
+         * Returns the UnicodeBlock with the given name. Block
+         * names are determined by The Unicode Standard. The file
+         * Blocks-&lt;version&gt;.txt defines blocks for a particular
+         * version of the standard. The {@link Character} class specifies
+         * the version of the standard that it supports.
+         * <p>
+         * This method accepts block names in the following forms:
+         * <ol>
+         * <li> Canonical block names as defined by the Unicode Standard.
+         * For example, the standard defines a "Basic Latin" block. Therefore, this
+         * method accepts "Basic Latin" as a valid block name. The documentation of
+         * each UnicodeBlock provides the canonical name.
+         * <li>Canonical block names with all spaces removed. For example, "BasicLatin"
+         * is a valid block name for the "Basic Latin" block.
+         * <li>The text representation of each constant UnicodeBlock identifier.
+         * For example, this method will return the {@link #BASIC_LATIN} block if
+         * provided with the "BASIC_LATIN" name. This form replaces all spaces and
+         * hyphens in the canonical name with underscores.
+         * </ol>
+         * Finally, character case is ignored for all of the valid block name forms.
+         * For example, "BASIC_LATIN" and "basic_latin" are both valid block names.
+         * The en_US locale's case mapping rules are used to provide case-insensitive
+         * string comparisons for block name validation.
+         * <p>
+         * If the Unicode Standard changes block names, both the previous and
+         * current names will be accepted.
+         *
+         * @param blockName A {@code UnicodeBlock} name.
+         * @return The {@code UnicodeBlock} instance identified
+         *         by {@code blockName}
+         * @throws IllegalArgumentException if {@code blockName} is an
+         *         invalid name
+         * @throws NullPointerException if {@code blockName} is null
+         * @since 1.5
+         */
+        public static final UnicodeBlock forName(String blockName) {
+            UnicodeBlock block = map.get(blockName.toUpperCase(Locale.US));
+            if (block == null) {
+                throw new IllegalArgumentException();
+            }
+            return block;
+        }
+    }
+
+
+    /**
+     * A family of character subsets representing the character scripts
+     * defined in the <a href="http://www.unicode.org/reports/tr24/">
+     * <i>Unicode Standard Annex #24: Script Names</i></a>. Every Unicode
+     * character is assigned to a single Unicode script, either a specific
+     * script, such as {@link Character.UnicodeScript#LATIN Latin}, or
+     * one of the following three special values,
+     * {@link Character.UnicodeScript#INHERITED Inherited},
+     * {@link Character.UnicodeScript#COMMON Common} or
+     * {@link Character.UnicodeScript#UNKNOWN Unknown}.
+     *
+     * @since 1.7
+     */
+    public static enum UnicodeScript {
+        /**
+         * Unicode script "Common".
+         */
+        COMMON,
+
+        /**
+         * Unicode script "Latin".
+         */
+        LATIN,
+
+        /**
+         * Unicode script "Greek".
+         */
+        GREEK,
+
+        /**
+         * Unicode script "Cyrillic".
+         */
+        CYRILLIC,
+
+        /**
+         * Unicode script "Armenian".
+         */
+        ARMENIAN,
+
+        /**
+         * Unicode script "Hebrew".
+         */
+        HEBREW,
+
+        /**
+         * Unicode script "Arabic".
+         */
+        ARABIC,
+
+        /**
+         * Unicode script "Syriac".
+         */
+        SYRIAC,
+
+        /**
+         * Unicode script "Thaana".
+         */
+        THAANA,
+
+        /**
+         * Unicode script "Devanagari".
+         */
+        DEVANAGARI,
+
+        /**
+         * Unicode script "Bengali".
+         */
+        BENGALI,
+
+        /**
+         * Unicode script "Gurmukhi".
+         */
+        GURMUKHI,
+
+        /**
+         * Unicode script "Gujarati".
+         */
+        GUJARATI,
+
+        /**
+         * Unicode script "Oriya".
+         */
+        ORIYA,
+
+        /**
+         * Unicode script "Tamil".
+         */
+        TAMIL,
+
+        /**
+         * Unicode script "Telugu".
+         */
+        TELUGU,
+
+        /**
+         * Unicode script "Kannada".
+         */
+        KANNADA,
+
+        /**
+         * Unicode script "Malayalam".
+         */
+        MALAYALAM,
+
+        /**
+         * Unicode script "Sinhala".
+         */
+        SINHALA,
+
+        /**
+         * Unicode script "Thai".
+         */
+        THAI,
+
+        /**
+         * Unicode script "Lao".
+         */
+        LAO,
+
+        /**
+         * Unicode script "Tibetan".
+         */
+        TIBETAN,
+
+        /**
+         * Unicode script "Myanmar".
+         */
+        MYANMAR,
+
+        /**
+         * Unicode script "Georgian".
+         */
+        GEORGIAN,
+
+        /**
+         * Unicode script "Hangul".
+         */
+        HANGUL,
+
+        /**
+         * Unicode script "Ethiopic".
+         */
+        ETHIOPIC,
+
+        /**
+         * Unicode script "Cherokee".
+         */
+        CHEROKEE,
+
+        /**
+         * Unicode script "Canadian_Aboriginal".
+         */
+        CANADIAN_ABORIGINAL,
+
+        /**
+         * Unicode script "Ogham".
+         */
+        OGHAM,
+
+        /**
+         * Unicode script "Runic".
+         */
+        RUNIC,
+
+        /**
+         * Unicode script "Khmer".
+         */
+        KHMER,
+
+        /**
+         * Unicode script "Mongolian".
+         */
+        MONGOLIAN,
+
+        /**
+         * Unicode script "Hiragana".
+         */
+        HIRAGANA,
+
+        /**
+         * Unicode script "Katakana".
+         */
+        KATAKANA,
+
+        /**
+         * Unicode script "Bopomofo".
+         */
+        BOPOMOFO,
+
+        /**
+         * Unicode script "Han".
+         */
+        HAN,
+
+        /**
+         * Unicode script "Yi".
+         */
+        YI,
+
+        /**
+         * Unicode script "Old_Italic".
+         */
+        OLD_ITALIC,
+
+        /**
+         * Unicode script "Gothic".
+         */
+        GOTHIC,
+
+        /**
+         * Unicode script "Deseret".
+         */
+        DESERET,
+
+        /**
+         * Unicode script "Inherited".
+         */
+        INHERITED,
+
+        /**
+         * Unicode script "Tagalog".
+         */
+        TAGALOG,
+
+        /**
+         * Unicode script "Hanunoo".
+         */
+        HANUNOO,
+
+        /**
+         * Unicode script "Buhid".
+         */
+        BUHID,
+
+        /**
+         * Unicode script "Tagbanwa".
+         */
+        TAGBANWA,
+
+        /**
+         * Unicode script "Limbu".
+         */
+        LIMBU,
+
+        /**
+         * Unicode script "Tai_Le".
+         */
+        TAI_LE,
+
+        /**
+         * Unicode script "Linear_B".
+         */
+        LINEAR_B,
+
+        /**
+         * Unicode script "Ugaritic".
+         */
+        UGARITIC,
+
+        /**
+         * Unicode script "Shavian".
+         */
+        SHAVIAN,
+
+        /**
+         * Unicode script "Osmanya".
+         */
+        OSMANYA,
+
+        /**
+         * Unicode script "Cypriot".
+         */
+        CYPRIOT,
+
+        /**
+         * Unicode script "Braille".
+         */
+        BRAILLE,
+
+        /**
+         * Unicode script "Buginese".
+         */
+        BUGINESE,
+
+        /**
+         * Unicode script "Coptic".
+         */
+        COPTIC,
+
+        /**
+         * Unicode script "New_Tai_Lue".
+         */
+        NEW_TAI_LUE,
+
+        /**
+         * Unicode script "Glagolitic".
+         */
+        GLAGOLITIC,
+
+        /**
+         * Unicode script "Tifinagh".
+         */
+        TIFINAGH,
+
+        /**
+         * Unicode script "Syloti_Nagri".
+         */
+        SYLOTI_NAGRI,
+
+        /**
+         * Unicode script "Old_Persian".
+         */
+        OLD_PERSIAN,
+
+        /**
+         * Unicode script "Kharoshthi".
+         */
+        KHAROSHTHI,
+
+        /**
+         * Unicode script "Balinese".
+         */
+        BALINESE,
+
+        /**
+         * Unicode script "Cuneiform".
+         */
+        CUNEIFORM,
+
+        /**
+         * Unicode script "Phoenician".
+         */
+        PHOENICIAN,
+
+        /**
+         * Unicode script "Phags_Pa".
+         */
+        PHAGS_PA,
+
+        /**
+         * Unicode script "Nko".
+         */
+        NKO,
+
+        /**
+         * Unicode script "Sundanese".
+         */
+        SUNDANESE,
+
+        /**
+         * Unicode script "Batak".
+         */
+        BATAK,
+
+        /**
+         * Unicode script "Lepcha".
+         */
+        LEPCHA,
+
+        /**
+         * Unicode script "Ol_Chiki".
+         */
+        OL_CHIKI,
+
+        /**
+         * Unicode script "Vai".
+         */
+        VAI,
+
+        /**
+         * Unicode script "Saurashtra".
+         */
+        SAURASHTRA,
+
+        /**
+         * Unicode script "Kayah_Li".
+         */
+        KAYAH_LI,
+
+        /**
+         * Unicode script "Rejang".
+         */
+        REJANG,
+
+        /**
+         * Unicode script "Lycian".
+         */
+        LYCIAN,
+
+        /**
+         * Unicode script "Carian".
+         */
+        CARIAN,
+
+        /**
+         * Unicode script "Lydian".
+         */
+        LYDIAN,
+
+        /**
+         * Unicode script "Cham".
+         */
+        CHAM,
+
+        /**
+         * Unicode script "Tai_Tham".
+         */
+        TAI_THAM,
+
+        /**
+         * Unicode script "Tai_Viet".
+         */
+        TAI_VIET,
+
+        /**
+         * Unicode script "Avestan".
+         */
+        AVESTAN,
+
+        /**
+         * Unicode script "Egyptian_Hieroglyphs".
+         */
+        EGYPTIAN_HIEROGLYPHS,
+
+        /**
+         * Unicode script "Samaritan".
+         */
+        SAMARITAN,
+
+        /**
+         * Unicode script "Mandaic".
+         */
+        MANDAIC,
+
+        /**
+         * Unicode script "Lisu".
+         */
+        LISU,
+
+        /**
+         * Unicode script "Bamum".
+         */
+        BAMUM,
+
+        /**
+         * Unicode script "Javanese".
+         */
+        JAVANESE,
+
+        /**
+         * Unicode script "Meetei_Mayek".
+         */
+        MEETEI_MAYEK,
+
+        /**
+         * Unicode script "Imperial_Aramaic".
+         */
+        IMPERIAL_ARAMAIC,
+
+        /**
+         * Unicode script "Old_South_Arabian".
+         */
+        OLD_SOUTH_ARABIAN,
+
+        /**
+         * Unicode script "Inscriptional_Parthian".
+         */
+        INSCRIPTIONAL_PARTHIAN,
+
+        /**
+         * Unicode script "Inscriptional_Pahlavi".
+         */
+        INSCRIPTIONAL_PAHLAVI,
+
+        /**
+         * Unicode script "Old_Turkic".
+         */
+        OLD_TURKIC,
+
+        /**
+         * Unicode script "Brahmi".
+         */
+        BRAHMI,
+
+        /**
+         * Unicode script "Kaithi".
+         */
+        KAITHI,
+
+        /**
+         * Unicode script "Meroitic Hieroglyphs".
+         */
+        MEROITIC_HIEROGLYPHS,
+
+        /**
+         * Unicode script "Meroitic Cursive".
+         */
+        MEROITIC_CURSIVE,
+
+        /**
+         * Unicode script "Sora Sompeng".
+         */
+        SORA_SOMPENG,
+
+        /**
+         * Unicode script "Chakma".
+         */
+        CHAKMA,
+
+        /**
+         * Unicode script "Sharada".
+         */
+        SHARADA,
+
+        /**
+         * Unicode script "Takri".
+         */
+        TAKRI,
+
+        /**
+         * Unicode script "Miao".
+         */
+        MIAO,
+
+        /**
+         * Unicode script "Unknown".
+         */
+        UNKNOWN;
+
+        private static final int[] scriptStarts = {
+            0x0000,   // 0000..0040; COMMON
+            0x0041,   // 0041..005A; LATIN
+            0x005B,   // 005B..0060; COMMON
+            0x0061,   // 0061..007A; LATIN
+            0x007B,   // 007B..00A9; COMMON
+            0x00AA,   // 00AA..00AA; LATIN
+            0x00AB,   // 00AB..00B9; COMMON
+            0x00BA,   // 00BA..00BA; LATIN
+            0x00BB,   // 00BB..00BF; COMMON
+            0x00C0,   // 00C0..00D6; LATIN
+            0x00D7,   // 00D7..00D7; COMMON
+            0x00D8,   // 00D8..00F6; LATIN
+            0x00F7,   // 00F7..00F7; COMMON
+            0x00F8,   // 00F8..02B8; LATIN
+            0x02B9,   // 02B9..02DF; COMMON
+            0x02E0,   // 02E0..02E4; LATIN
+            0x02E5,   // 02E5..02E9; COMMON
+            0x02EA,   // 02EA..02EB; BOPOMOFO
+            0x02EC,   // 02EC..02FF; COMMON
+            0x0300,   // 0300..036F; INHERITED
+            0x0370,   // 0370..0373; GREEK
+            0x0374,   // 0374..0374; COMMON
+            0x0375,   // 0375..037D; GREEK
+            0x037E,   // 037E..0383; COMMON
+            0x0384,   // 0384..0384; GREEK
+            0x0385,   // 0385..0385; COMMON
+            0x0386,   // 0386..0386; GREEK
+            0x0387,   // 0387..0387; COMMON
+            0x0388,   // 0388..03E1; GREEK
+            0x03E2,   // 03E2..03EF; COPTIC
+            0x03F0,   // 03F0..03FF; GREEK
+            0x0400,   // 0400..0484; CYRILLIC
+            0x0485,   // 0485..0486; INHERITED
+            0x0487,   // 0487..0530; CYRILLIC
+            0x0531,   // 0531..0588; ARMENIAN
+            0x0589,   // 0589..0589; COMMON
+            0x058A,   // 058A..0590; ARMENIAN
+            0x0591,   // 0591..05FF; HEBREW
+            0x0600,   // 0600..060B; ARABIC
+            0x060C,   // 060C..060C; COMMON
+            0x060D,   // 060D..061A; ARABIC
+            0x061B,   // 061B..061D; COMMON
+            0x061E,   // 061E..061E; ARABIC
+            0x061F,   // 061F..061F; COMMON
+            0x0620,   // 0620..063F; ARABIC
+            0x0640,   // 0640..0640; COMMON
+            0x0641,   // 0641..064A; ARABIC
+            0x064B,   // 064B..0655; INHERITED
+            0x0656,   // 0656..065F; ARABIC
+            0x0660,   // 0660..0669; COMMON
+            0x066A,   // 066A..066F; ARABIC
+            0x0670,   // 0670..0670; INHERITED
+            0x0671,   // 0671..06DC; ARABIC
+            0x06DD,   // 06DD..06DD; COMMON
+            0x06DE,   // 06DE..06FF; ARABIC
+            0x0700,   // 0700..074F; SYRIAC
+            0x0750,   // 0750..077F; ARABIC
+            0x0780,   // 0780..07BF; THAANA
+            0x07C0,   // 07C0..07FF; NKO
+            0x0800,   // 0800..083F; SAMARITAN
+            0x0840,   // 0840..089F; MANDAIC
+            0x08A0,   // 08A0..08FF; ARABIC
+            0x0900,   // 0900..0950; DEVANAGARI
+            0x0951,   // 0951..0952; INHERITED
+            0x0953,   // 0953..0963; DEVANAGARI
+            0x0964,   // 0964..0965; COMMON
+            0x0966,   // 0966..0980; DEVANAGARI
+            0x0981,   // 0981..0A00; BENGALI
+            0x0A01,   // 0A01..0A80; GURMUKHI
+            0x0A81,   // 0A81..0B00; GUJARATI
+            0x0B01,   // 0B01..0B81; ORIYA
+            0x0B82,   // 0B82..0C00; TAMIL
+            0x0C01,   // 0C01..0C81; TELUGU
+            0x0C82,   // 0C82..0CF0; KANNADA
+            0x0D02,   // 0D02..0D81; MALAYALAM
+            0x0D82,   // 0D82..0E00; SINHALA
+            0x0E01,   // 0E01..0E3E; THAI
+            0x0E3F,   // 0E3F..0E3F; COMMON
+            0x0E40,   // 0E40..0E80; THAI
+            0x0E81,   // 0E81..0EFF; LAO
+            0x0F00,   // 0F00..0FD4; TIBETAN
+            0x0FD5,   // 0FD5..0FD8; COMMON
+            0x0FD9,   // 0FD9..0FFF; TIBETAN
+            0x1000,   // 1000..109F; MYANMAR
+            0x10A0,   // 10A0..10FA; GEORGIAN
+            0x10FB,   // 10FB..10FB; COMMON
+            0x10FC,   // 10FC..10FF; GEORGIAN
+            0x1100,   // 1100..11FF; HANGUL
+            0x1200,   // 1200..139F; ETHIOPIC
+            0x13A0,   // 13A0..13FF; CHEROKEE
+            0x1400,   // 1400..167F; CANADIAN_ABORIGINAL
+            0x1680,   // 1680..169F; OGHAM
+            0x16A0,   // 16A0..16EA; RUNIC
+            0x16EB,   // 16EB..16ED; COMMON
+            0x16EE,   // 16EE..16FF; RUNIC
+            0x1700,   // 1700..171F; TAGALOG
+            0x1720,   // 1720..1734; HANUNOO
+            0x1735,   // 1735..173F; COMMON
+            0x1740,   // 1740..175F; BUHID
+            0x1760,   // 1760..177F; TAGBANWA
+            0x1780,   // 1780..17FF; KHMER
+            0x1800,   // 1800..1801; MONGOLIAN
+            0x1802,   // 1802..1803; COMMON
+            0x1804,   // 1804..1804; MONGOLIAN
+            0x1805,   // 1805..1805; COMMON
+            0x1806,   // 1806..18AF; MONGOLIAN
+            0x18B0,   // 18B0..18FF; CANADIAN_ABORIGINAL
+            0x1900,   // 1900..194F; LIMBU
+            0x1950,   // 1950..197F; TAI_LE
+            0x1980,   // 1980..19DF; NEW_TAI_LUE
+            0x19E0,   // 19E0..19FF; KHMER
+            0x1A00,   // 1A00..1A1F; BUGINESE
+            0x1A20,   // 1A20..1AFF; TAI_THAM
+            0x1B00,   // 1B00..1B7F; BALINESE
+            0x1B80,   // 1B80..1BBF; SUNDANESE
+            0x1BC0,   // 1BC0..1BFF; BATAK
+            0x1C00,   // 1C00..1C4F; LEPCHA
+            0x1C50,   // 1C50..1CBF; OL_CHIKI
+            0x1CC0,   // 1CC0..1CCF; SUNDANESE
+            0x1CD0,   // 1CD0..1CD2; INHERITED
+            0x1CD3,   // 1CD3..1CD3; COMMON
+            0x1CD4,   // 1CD4..1CE0; INHERITED
+            0x1CE1,   // 1CE1..1CE1; COMMON
+            0x1CE2,   // 1CE2..1CE8; INHERITED
+            0x1CE9,   // 1CE9..1CEC; COMMON
+            0x1CED,   // 1CED..1CED; INHERITED
+            0x1CEE,   // 1CEE..1CF3; COMMON
+            0x1CF4,   // 1CF4..1CF4; INHERITED
+            0x1CF5,   // 1CF5..1CFF; COMMON
+            0x1D00,   // 1D00..1D25; LATIN
+            0x1D26,   // 1D26..1D2A; GREEK
+            0x1D2B,   // 1D2B..1D2B; CYRILLIC
+            0x1D2C,   // 1D2C..1D5C; LATIN
+            0x1D5D,   // 1D5D..1D61; GREEK
+            0x1D62,   // 1D62..1D65; LATIN
+            0x1D66,   // 1D66..1D6A; GREEK
+            0x1D6B,   // 1D6B..1D77; LATIN
+            0x1D78,   // 1D78..1D78; CYRILLIC
+            0x1D79,   // 1D79..1DBE; LATIN
+            0x1DBF,   // 1DBF..1DBF; GREEK
+            0x1DC0,   // 1DC0..1DFF; INHERITED
+            0x1E00,   // 1E00..1EFF; LATIN
+            0x1F00,   // 1F00..1FFF; GREEK
+            0x2000,   // 2000..200B; COMMON
+            0x200C,   // 200C..200D; INHERITED
+            0x200E,   // 200E..2070; COMMON
+            0x2071,   // 2071..2073; LATIN
+            0x2074,   // 2074..207E; COMMON
+            0x207F,   // 207F..207F; LATIN
+            0x2080,   // 2080..208F; COMMON
+            0x2090,   // 2090..209F; LATIN
+            0x20A0,   // 20A0..20CF; COMMON
+            0x20D0,   // 20D0..20FF; INHERITED
+            0x2100,   // 2100..2125; COMMON
+            0x2126,   // 2126..2126; GREEK
+            0x2127,   // 2127..2129; COMMON
+            0x212A,   // 212A..212B; LATIN
+            0x212C,   // 212C..2131; COMMON
+            0x2132,   // 2132..2132; LATIN
+            0x2133,   // 2133..214D; COMMON
+            0x214E,   // 214E..214E; LATIN
+            0x214F,   // 214F..215F; COMMON
+            0x2160,   // 2160..2188; LATIN
+            0x2189,   // 2189..27FF; COMMON
+            0x2800,   // 2800..28FF; BRAILLE
+            0x2900,   // 2900..2BFF; COMMON
+            0x2C00,   // 2C00..2C5F; GLAGOLITIC
+            0x2C60,   // 2C60..2C7F; LATIN
+            0x2C80,   // 2C80..2CFF; COPTIC
+            0x2D00,   // 2D00..2D2F; GEORGIAN
+            0x2D30,   // 2D30..2D7F; TIFINAGH
+            0x2D80,   // 2D80..2DDF; ETHIOPIC
+            0x2DE0,   // 2DE0..2DFF; CYRILLIC
+            0x2E00,   // 2E00..2E7F; COMMON
+            0x2E80,   // 2E80..2FEF; HAN
+            0x2FF0,   // 2FF0..3004; COMMON
+            0x3005,   // 3005..3005; HAN
+            0x3006,   // 3006..3006; COMMON
+            0x3007,   // 3007..3007; HAN
+            0x3008,   // 3008..3020; COMMON
+            0x3021,   // 3021..3029; HAN
+            0x302A,   // 302A..302D; INHERITED
+            0x302E,   // 302E..302F; HANGUL
+            0x3030,   // 3030..3037; COMMON
+            0x3038,   // 3038..303B; HAN
+            0x303C,   // 303C..3040; COMMON
+            0x3041,   // 3041..3098; HIRAGANA
+            0x3099,   // 3099..309A; INHERITED
+            0x309B,   // 309B..309C; COMMON
+            0x309D,   // 309D..309F; HIRAGANA
+            0x30A0,   // 30A0..30A0; COMMON
+            0x30A1,   // 30A1..30FA; KATAKANA
+            0x30FB,   // 30FB..30FC; COMMON
+            0x30FD,   // 30FD..3104; KATAKANA
+            0x3105,   // 3105..3130; BOPOMOFO
+            0x3131,   // 3131..318F; HANGUL
+            0x3190,   // 3190..319F; COMMON
+            0x31A0,   // 31A0..31BF; BOPOMOFO
+            0x31C0,   // 31C0..31EF; COMMON
+            0x31F0,   // 31F0..31FF; KATAKANA
+            0x3200,   // 3200..321F; HANGUL
+            0x3220,   // 3220..325F; COMMON
+            0x3260,   // 3260..327E; HANGUL
+            0x327F,   // 327F..32CF; COMMON
+            0x32D0,   // 32D0..3357; KATAKANA
+            0x3358,   // 3358..33FF; COMMON
+            0x3400,   // 3400..4DBF; HAN
+            0x4DC0,   // 4DC0..4DFF; COMMON
+            0x4E00,   // 4E00..9FFF; HAN
+            0xA000,   // A000..A4CF; YI
+            0xA4D0,   // A4D0..A4FF; LISU
+            0xA500,   // A500..A63F; VAI
+            0xA640,   // A640..A69F; CYRILLIC
+            0xA6A0,   // A6A0..A6FF; BAMUM
+            0xA700,   // A700..A721; COMMON
+            0xA722,   // A722..A787; LATIN
+            0xA788,   // A788..A78A; COMMON
+            0xA78B,   // A78B..A7FF; LATIN
+            0xA800,   // A800..A82F; SYLOTI_NAGRI
+            0xA830,   // A830..A83F; COMMON
+            0xA840,   // A840..A87F; PHAGS_PA
+            0xA880,   // A880..A8DF; SAURASHTRA
+            0xA8E0,   // A8E0..A8FF; DEVANAGARI
+            0xA900,   // A900..A92F; KAYAH_LI
+            0xA930,   // A930..A95F; REJANG
+            0xA960,   // A960..A97F; HANGUL
+            0xA980,   // A980..A9FF; JAVANESE
+            0xAA00,   // AA00..AA5F; CHAM
+            0xAA60,   // AA60..AA7F; MYANMAR
+            0xAA80,   // AA80..AADF; TAI_VIET
+            0xAAE0,   // AAE0..AB00; MEETEI_MAYEK
+            0xAB01,   // AB01..ABBF; ETHIOPIC
+            0xABC0,   // ABC0..ABFF; MEETEI_MAYEK
+            0xAC00,   // AC00..D7FB; HANGUL
+            0xD7FC,   // D7FC..F8FF; UNKNOWN
+            0xF900,   // F900..FAFF; HAN
+            0xFB00,   // FB00..FB12; LATIN
+            0xFB13,   // FB13..FB1C; ARMENIAN
+            0xFB1D,   // FB1D..FB4F; HEBREW
+            0xFB50,   // FB50..FD3D; ARABIC
+            0xFD3E,   // FD3E..FD4F; COMMON
+            0xFD50,   // FD50..FDFC; ARABIC
+            0xFDFD,   // FDFD..FDFF; COMMON
+            0xFE00,   // FE00..FE0F; INHERITED
+            0xFE10,   // FE10..FE1F; COMMON
+            0xFE20,   // FE20..FE2F; INHERITED
+            0xFE30,   // FE30..FE6F; COMMON
+            0xFE70,   // FE70..FEFE; ARABIC
+            0xFEFF,   // FEFF..FF20; COMMON
+            0xFF21,   // FF21..FF3A; LATIN
+            0xFF3B,   // FF3B..FF40; COMMON
+            0xFF41,   // FF41..FF5A; LATIN
+            0xFF5B,   // FF5B..FF65; COMMON
+            0xFF66,   // FF66..FF6F; KATAKANA
+            0xFF70,   // FF70..FF70; COMMON
+            0xFF71,   // FF71..FF9D; KATAKANA
+            0xFF9E,   // FF9E..FF9F; COMMON
+            0xFFA0,   // FFA0..FFDF; HANGUL
+            0xFFE0,   // FFE0..FFFF; COMMON
+            0x10000,  // 10000..100FF; LINEAR_B
+            0x10100,  // 10100..1013F; COMMON
+            0x10140,  // 10140..1018F; GREEK
+            0x10190,  // 10190..101FC; COMMON
+            0x101FD,  // 101FD..1027F; INHERITED
+            0x10280,  // 10280..1029F; LYCIAN
+            0x102A0,  // 102A0..102FF; CARIAN
+            0x10300,  // 10300..1032F; OLD_ITALIC
+            0x10330,  // 10330..1037F; GOTHIC
+            0x10380,  // 10380..1039F; UGARITIC
+            0x103A0,  // 103A0..103FF; OLD_PERSIAN
+            0x10400,  // 10400..1044F; DESERET
+            0x10450,  // 10450..1047F; SHAVIAN
+            0x10480,  // 10480..107FF; OSMANYA
+            0x10800,  // 10800..1083F; CYPRIOT
+            0x10840,  // 10840..108FF; IMPERIAL_ARAMAIC
+            0x10900,  // 10900..1091F; PHOENICIAN
+            0x10920,  // 10920..1097F; LYDIAN
+            0x10980,  // 10980..1099F; MEROITIC_HIEROGLYPHS
+            0x109A0,  // 109A0..109FF; MEROITIC_CURSIVE
+            0x10A00,  // 10A00..10A5F; KHAROSHTHI
+            0x10A60,  // 10A60..10AFF; OLD_SOUTH_ARABIAN
+            0x10B00,  // 10B00..10B3F; AVESTAN
+            0x10B40,  // 10B40..10B5F; INSCRIPTIONAL_PARTHIAN
+            0x10B60,  // 10B60..10BFF; INSCRIPTIONAL_PAHLAVI
+            0x10C00,  // 10C00..10E5F; OLD_TURKIC
+            0x10E60,  // 10E60..10FFF; ARABIC
+            0x11000,  // 11000..1107F; BRAHMI
+            0x11080,  // 11080..110CF; KAITHI
+            0x110D0,  // 110D0..110FF; SORA_SOMPENG
+            0x11100,  // 11100..1117F; CHAKMA
+            0x11180,  // 11180..1167F; SHARADA
+            0x11680,  // 11680..116CF; TAKRI
+            0x12000,  // 12000..12FFF; CUNEIFORM
+            0x13000,  // 13000..167FF; EGYPTIAN_HIEROGLYPHS
+            0x16800,  // 16800..16A38; BAMUM
+            0x16F00,  // 16F00..16F9F; MIAO
+            0x1B000,  // 1B000..1B000; KATAKANA
+            0x1B001,  // 1B001..1CFFF; HIRAGANA
+            0x1D000,  // 1D000..1D166; COMMON
+            0x1D167,  // 1D167..1D169; INHERITED
+            0x1D16A,  // 1D16A..1D17A; COMMON
+            0x1D17B,  // 1D17B..1D182; INHERITED
+            0x1D183,  // 1D183..1D184; COMMON
+            0x1D185,  // 1D185..1D18B; INHERITED
+            0x1D18C,  // 1D18C..1D1A9; COMMON
+            0x1D1AA,  // 1D1AA..1D1AD; INHERITED
+            0x1D1AE,  // 1D1AE..1D1FF; COMMON
+            0x1D200,  // 1D200..1D2FF; GREEK
+            0x1D300,  // 1D300..1EDFF; COMMON
+            0x1EE00,  // 1EE00..1EFFF; ARABIC
+            0x1F000,  // 1F000..1F1FF; COMMON
+            0x1F200,  // 1F200..1F200; HIRAGANA
+            0x1F201,  // 1F210..1FFFF; COMMON
+            0x20000,  // 20000..E0000; HAN
+            0xE0001,  // E0001..E00FF; COMMON
+            0xE0100,  // E0100..E01EF; INHERITED
+            0xE01F0   // E01F0..10FFFF; UNKNOWN
+
+        };
+
+        private static final UnicodeScript[] scripts = {
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            BOPOMOFO,
+            COMMON,
+            INHERITED,
+            GREEK,
+            COMMON,
+            GREEK,
+            COMMON,
+            GREEK,
+            COMMON,
+            GREEK,
+            COMMON,
+            GREEK,
+            COPTIC,
+            GREEK,
+            CYRILLIC,
+            INHERITED,
+            CYRILLIC,
+            ARMENIAN,
+            COMMON,
+            ARMENIAN,
+            HEBREW,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            INHERITED,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            INHERITED,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            SYRIAC,
+            ARABIC,
+            THAANA,
+            NKO,
+            SAMARITAN,
+            MANDAIC,
+            ARABIC,
+            DEVANAGARI,
+            INHERITED,
+            DEVANAGARI,
+            COMMON,
+            DEVANAGARI,
+            BENGALI,
+            GURMUKHI,
+            GUJARATI,
+            ORIYA,
+            TAMIL,
+            TELUGU,
+            KANNADA,
+            MALAYALAM,
+            SINHALA,
+            THAI,
+            COMMON,
+            THAI,
+            LAO,
+            TIBETAN,
+            COMMON,
+            TIBETAN,
+            MYANMAR,
+            GEORGIAN,
+            COMMON,
+            GEORGIAN,
+            HANGUL,
+            ETHIOPIC,
+            CHEROKEE,
+            CANADIAN_ABORIGINAL,
+            OGHAM,
+            RUNIC,
+            COMMON,
+            RUNIC,
+            TAGALOG,
+            HANUNOO,
+            COMMON,
+            BUHID,
+            TAGBANWA,
+            KHMER,
+            MONGOLIAN,
+            COMMON,
+            MONGOLIAN,
+            COMMON,
+            MONGOLIAN,
+            CANADIAN_ABORIGINAL,
+            LIMBU,
+            TAI_LE,
+            NEW_TAI_LUE,
+            KHMER,
+            BUGINESE,
+            TAI_THAM,
+            BALINESE,
+            SUNDANESE,
+            BATAK,
+            LEPCHA,
+            OL_CHIKI,
+            SUNDANESE,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            LATIN,
+            GREEK,
+            CYRILLIC,
+            LATIN,
+            GREEK,
+            LATIN,
+            GREEK,
+            LATIN,
+            CYRILLIC,
+            LATIN,
+            GREEK,
+            INHERITED,
+            LATIN,
+            GREEK,
+            COMMON,
+            INHERITED,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            INHERITED,
+            COMMON,
+            GREEK,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            BRAILLE,
+            COMMON,
+            GLAGOLITIC,
+            LATIN,
+            COPTIC,
+            GEORGIAN,
+            TIFINAGH,
+            ETHIOPIC,
+            CYRILLIC,
+            COMMON,
+            HAN,
+            COMMON,
+            HAN,
+            COMMON,
+            HAN,
+            COMMON,
+            HAN,
+            INHERITED,
+            HANGUL,
+            COMMON,
+            HAN,
+            COMMON,
+            HIRAGANA,
+            INHERITED,
+            COMMON,
+            HIRAGANA,
+            COMMON,
+            KATAKANA,
+            COMMON,
+            KATAKANA,
+            BOPOMOFO,
+            HANGUL,
+            COMMON,
+            BOPOMOFO,
+            COMMON,
+            KATAKANA,
+            HANGUL,
+            COMMON,
+            HANGUL,
+            COMMON,
+            KATAKANA,
+            COMMON,
+            HAN,
+            COMMON,
+            HAN,
+            YI,
+            LISU,
+            VAI,
+            CYRILLIC,
+            BAMUM,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            SYLOTI_NAGRI,
+            COMMON,
+            PHAGS_PA,
+            SAURASHTRA,
+            DEVANAGARI,
+            KAYAH_LI,
+            REJANG,
+            HANGUL,
+            JAVANESE,
+            CHAM,
+            MYANMAR,
+            TAI_VIET,
+            MEETEI_MAYEK,
+            ETHIOPIC,
+            MEETEI_MAYEK,
+            HANGUL,
+            UNKNOWN     ,
+            HAN,
+            LATIN,
+            ARMENIAN,
+            HEBREW,
+            ARABIC,
+            COMMON,
+            ARABIC,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            ARABIC,
+            COMMON,
+            LATIN,
+            COMMON,
+            LATIN,
+            COMMON,
+            KATAKANA,
+            COMMON,
+            KATAKANA,
+            COMMON,
+            HANGUL,
+            COMMON,
+            LINEAR_B,
+            COMMON,
+            GREEK,
+            COMMON,
+            INHERITED,
+            LYCIAN,
+            CARIAN,
+            OLD_ITALIC,
+            GOTHIC,
+            UGARITIC,
+            OLD_PERSIAN,
+            DESERET,
+            SHAVIAN,
+            OSMANYA,
+            CYPRIOT,
+            IMPERIAL_ARAMAIC,
+            PHOENICIAN,
+            LYDIAN,
+            MEROITIC_HIEROGLYPHS,
+            MEROITIC_CURSIVE,
+            KHAROSHTHI,
+            OLD_SOUTH_ARABIAN,
+            AVESTAN,
+            INSCRIPTIONAL_PARTHIAN,
+            INSCRIPTIONAL_PAHLAVI,
+            OLD_TURKIC,
+            ARABIC,
+            BRAHMI,
+            KAITHI,
+            SORA_SOMPENG,
+            CHAKMA,
+            SHARADA,
+            TAKRI,
+            CUNEIFORM,
+            EGYPTIAN_HIEROGLYPHS,
+            BAMUM,
+            MIAO,
+            KATAKANA,
+            HIRAGANA,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            INHERITED,
+            COMMON,
+            GREEK,
+            COMMON,
+            ARABIC,
+            COMMON,
+            HIRAGANA,
+            COMMON,
+            HAN,
+            COMMON,
+            INHERITED,
+            UNKNOWN
+        };
+
+        private static HashMap<String, Character.UnicodeScript> aliases;
+        static {
+            aliases = new HashMap<>(128);
+            aliases.put("ARAB", ARABIC);
+            aliases.put("ARMI", IMPERIAL_ARAMAIC);
+            aliases.put("ARMN", ARMENIAN);
+            aliases.put("AVST", AVESTAN);
+            aliases.put("BALI", BALINESE);
+            aliases.put("BAMU", BAMUM);
+            aliases.put("BATK", BATAK);
+            aliases.put("BENG", BENGALI);
+            aliases.put("BOPO", BOPOMOFO);
+            aliases.put("BRAI", BRAILLE);
+            aliases.put("BRAH", BRAHMI);
+            aliases.put("BUGI", BUGINESE);
+            aliases.put("BUHD", BUHID);
+            aliases.put("CAKM", CHAKMA);
+            aliases.put("CANS", CANADIAN_ABORIGINAL);
+            aliases.put("CARI", CARIAN);
+            aliases.put("CHAM", CHAM);
+            aliases.put("CHER", CHEROKEE);
+            aliases.put("COPT", COPTIC);
+            aliases.put("CPRT", CYPRIOT);
+            aliases.put("CYRL", CYRILLIC);
+            aliases.put("DEVA", DEVANAGARI);
+            aliases.put("DSRT", DESERET);
+            aliases.put("EGYP", EGYPTIAN_HIEROGLYPHS);
+            aliases.put("ETHI", ETHIOPIC);
+            aliases.put("GEOR", GEORGIAN);
+            aliases.put("GLAG", GLAGOLITIC);
+            aliases.put("GOTH", GOTHIC);
+            aliases.put("GREK", GREEK);
+            aliases.put("GUJR", GUJARATI);
+            aliases.put("GURU", GURMUKHI);
+            aliases.put("HANG", HANGUL);
+            aliases.put("HANI", HAN);
+            aliases.put("HANO", HANUNOO);
+            aliases.put("HEBR", HEBREW);
+            aliases.put("HIRA", HIRAGANA);
+            // it appears we don't have the KATAKANA_OR_HIRAGANA
+            //aliases.put("HRKT", KATAKANA_OR_HIRAGANA);
+            aliases.put("ITAL", OLD_ITALIC);
+            aliases.put("JAVA", JAVANESE);
+            aliases.put("KALI", KAYAH_LI);
+            aliases.put("KANA", KATAKANA);
+            aliases.put("KHAR", KHAROSHTHI);
+            aliases.put("KHMR", KHMER);
+            aliases.put("KNDA", KANNADA);
+            aliases.put("KTHI", KAITHI);
+            aliases.put("LANA", TAI_THAM);
+            aliases.put("LAOO", LAO);
+            aliases.put("LATN", LATIN);
+            aliases.put("LEPC", LEPCHA);
+            aliases.put("LIMB", LIMBU);
+            aliases.put("LINB", LINEAR_B);
+            aliases.put("LISU", LISU);
+            aliases.put("LYCI", LYCIAN);
+            aliases.put("LYDI", LYDIAN);
+            aliases.put("MAND", MANDAIC);
+            aliases.put("MERC", MEROITIC_CURSIVE);
+            aliases.put("MERO", MEROITIC_HIEROGLYPHS);
+            aliases.put("MLYM", MALAYALAM);
+            aliases.put("MONG", MONGOLIAN);
+            aliases.put("MTEI", MEETEI_MAYEK);
+            aliases.put("MYMR", MYANMAR);
+            aliases.put("NKOO", NKO);
+            aliases.put("OGAM", OGHAM);
+            aliases.put("OLCK", OL_CHIKI);
+            aliases.put("ORKH", OLD_TURKIC);
+            aliases.put("ORYA", ORIYA);
+            aliases.put("OSMA", OSMANYA);
+            aliases.put("PHAG", PHAGS_PA);
+            aliases.put("PLRD", MIAO);
+            aliases.put("PHLI", INSCRIPTIONAL_PAHLAVI);
+            aliases.put("PHNX", PHOENICIAN);
+            aliases.put("PRTI", INSCRIPTIONAL_PARTHIAN);
+            aliases.put("RJNG", REJANG);
+            aliases.put("RUNR", RUNIC);
+            aliases.put("SAMR", SAMARITAN);
+            aliases.put("SARB", OLD_SOUTH_ARABIAN);
+            aliases.put("SAUR", SAURASHTRA);
+            aliases.put("SHAW", SHAVIAN);
+            aliases.put("SHRD", SHARADA);
+            aliases.put("SINH", SINHALA);
+            aliases.put("SORA", SORA_SOMPENG);
+            aliases.put("SUND", SUNDANESE);
+            aliases.put("SYLO", SYLOTI_NAGRI);
+            aliases.put("SYRC", SYRIAC);
+            aliases.put("TAGB", TAGBANWA);
+            aliases.put("TALE", TAI_LE);
+            aliases.put("TAKR", TAKRI);
+            aliases.put("TALU", NEW_TAI_LUE);
+            aliases.put("TAML", TAMIL);
+            aliases.put("TAVT", TAI_VIET);
+            aliases.put("TELU", TELUGU);
+            aliases.put("TFNG", TIFINAGH);
+            aliases.put("TGLG", TAGALOG);
+            aliases.put("THAA", THAANA);
+            aliases.put("THAI", THAI);
+            aliases.put("TIBT", TIBETAN);
+            aliases.put("UGAR", UGARITIC);
+            aliases.put("VAII", VAI);
+            aliases.put("XPEO", OLD_PERSIAN);
+            aliases.put("XSUX", CUNEIFORM);
+            aliases.put("YIII", YI);
+            aliases.put("ZINH", INHERITED);
+            aliases.put("ZYYY", COMMON);
+            aliases.put("ZZZZ", UNKNOWN);
+        }
+
+        /**
+         * Returns the enum constant representing the Unicode script of which
+         * the given character (Unicode code point) is assigned to.
+         *
+         * @param   codePoint the character (Unicode code point) in question.
+         * @return  The {@code UnicodeScript} constant representing the
+         *          Unicode script of which this character is assigned to.
+         *
+         * @exception IllegalArgumentException if the specified
+         * {@code codePoint} is an invalid Unicode code point.
+         * @see Character#isValidCodePoint(int)
+         *
+         */
+        public static UnicodeScript of(int codePoint) {
+            if (!isValidCodePoint(codePoint))
+                throw new IllegalArgumentException();
+            int type = getType(codePoint);
+            // leave SURROGATE and PRIVATE_USE for table lookup
+            if (type == UNASSIGNED)
+                return UNKNOWN;
+            int index = Arrays.binarySearch(scriptStarts, codePoint);
+            if (index < 0)
+                index = -index - 2;
+            return scripts[index];
+        }
+
+        /**
+         * Returns the UnicodeScript constant with the given Unicode script
+         * name or the script name alias. Script names and their aliases are
+         * determined by The Unicode Standard. The files Scripts&lt;version&gt;.txt
+         * and PropertyValueAliases&lt;version&gt;.txt define script names
+         * and the script name aliases for a particular version of the
+         * standard. The {@link Character} class specifies the version of
+         * the standard that it supports.
+         * <p>
+         * Character case is ignored for all of the valid script names.
+         * The en_US locale's case mapping rules are used to provide
+         * case-insensitive string comparisons for script name validation.
+         * <p>
+         *
+         * @param scriptName A {@code UnicodeScript} name.
+         * @return The {@code UnicodeScript} constant identified
+         *         by {@code scriptName}
+         * @throws IllegalArgumentException if {@code scriptName} is an
+         *         invalid name
+         * @throws NullPointerException if {@code scriptName} is null
+         */
+        public static final UnicodeScript forName(String scriptName) {
+            scriptName = scriptName.toUpperCase(Locale.ENGLISH);
+                                 //.replace(' ', '_'));
+            UnicodeScript sc = aliases.get(scriptName);
+            if (sc != null)
+                return sc;
+            return valueOf(scriptName);
+        }
+    }
+
+    /**
+     * The value of the {@code Character}.
+     *
+     * @serial
+     */
+    private final char value;
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = 3786198910865385080L;
+
+    /**
+     * Constructs a newly allocated {@code Character} object that
+     * represents the specified {@code char} value.
+     *
+     * @param  value   the value to be represented by the
+     *                  {@code Character} object.
+     */
+    public Character(char value) {
+        this.value = value;
+    }
+
+    private static class CharacterCache {
+        private CharacterCache(){}
+
+        static final Character cache[] = new Character[127 + 1];
+
+        static {
+            for (int i = 0; i < cache.length; i++)
+                cache[i] = new Character((char)i);
+        }
+    }
+
+    /**
+     * Returns a <tt>Character</tt> instance representing the specified
+     * <tt>char</tt> value.
+     * If a new <tt>Character</tt> instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Character(char)}, as this method is likely to yield
+     * significantly better space and time performance by caching
+     * frequently requested values.
+     *
+     * This method will always cache values in the range {@code
+     * '\u005Cu0000'} to {@code '\u005Cu007F'}, inclusive, and may
+     * cache other values outside of this range.
+     *
+     * @param  c a char value.
+     * @return a <tt>Character</tt> instance representing <tt>c</tt>.
+     * @since  1.5
+     */
+    public static Character valueOf(char c) {
+        if (c <= 127) { // must cache
+            return CharacterCache.cache[(int)c];
+        }
+        return new Character(c);
+    }
+
+    /**
+     * Returns the value of this {@code Character} object.
+     * @return  the primitive {@code char} value represented by
+     *          this object.
+     */
+    public char charValue() {
+        return value;
+    }
+
+    /**
+     * Returns a hash code for this {@code Character}; equal to the result
+     * of invoking {@code charValue()}.
+     *
+     * @return a hash code value for this {@code Character}
+     */
+    @Override
+    public int hashCode() {
+        return Character.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code char} value; compatible with
+     * {@code Character.hashCode()}.
+     *
+     * @since 1.8
+     *
+     * @param value The {@code char} for which to return a hash code.
+     * @return a hash code value for a {@code char} value.
+     */
+    public static int hashCode(char value) {
+        return (int)value;
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Character} object that
+     * represents the same {@code char} value as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Character) {
+            return value == ((Character)obj).charValue();
+        }
+        return false;
+    }
+
+    /**
+     * Returns a {@code String} object representing this
+     * {@code Character}'s value.  The result is a string of
+     * length 1 whose sole component is the primitive
+     * {@code char} value represented by this
+     * {@code Character} object.
+     *
+     * @return  a string representation of this object.
+     */
+    public String toString() {
+        char buf[] = {value};
+        return String.valueOf(buf);
+    }
+
+    /**
+     * Returns a {@code String} object representing the
+     * specified {@code char}.  The result is a string of length
+     * 1 consisting solely of the specified {@code char}.
+     *
+     * @param c the {@code char} to be converted
+     * @return the string representation of the specified {@code char}
+     * @since 1.4
+     */
+    public static String toString(char c) {
+        return String.valueOf(c);
+    }
+
+    /**
+     * Determines whether the specified code point is a valid
+     * <a href="http://www.unicode.org/glossary/#code_point">
+     * Unicode code point value</a>.
+     *
+     * @param  codePoint the Unicode code point to be tested
+     * @return {@code true} if the specified code point value is between
+     *         {@link #MIN_CODE_POINT} and
+     *         {@link #MAX_CODE_POINT} inclusive;
+     *         {@code false} otherwise.
+     * @since  1.5
+     */
+    public static boolean isValidCodePoint(int codePoint) {
+        // Optimized form of:
+        //     codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
+        int plane = codePoint >>> 16;
+        return plane < ((MAX_CODE_POINT + 1) >>> 16);
+    }
+
+    /**
+     * Determines whether the specified character (Unicode code point)
+     * is in the <a href="#BMP">Basic Multilingual Plane (BMP)</a>.
+     * Such code points can be represented using a single {@code char}.
+     *
+     * @param  codePoint the character (Unicode code point) to be tested
+     * @return {@code true} if the specified code point is between
+     *         {@link #MIN_VALUE} and {@link #MAX_VALUE} inclusive;
+     *         {@code false} otherwise.
+     * @since  1.7
+     */
+    public static boolean isBmpCodePoint(int codePoint) {
+        return codePoint >>> 16 == 0;
+        // Optimized form of:
+        //     codePoint >= MIN_VALUE && codePoint <= MAX_VALUE
+        // We consistently use logical shift (>>>) to facilitate
+        // additional runtime optimizations.
+    }
+
+    /**
+     * Determines whether the specified character (Unicode code point)
+     * is in the <a href="#supplementary">supplementary character</a> range.
+     *
+     * @param  codePoint the character (Unicode code point) to be tested
+     * @return {@code true} if the specified code point is between
+     *         {@link #MIN_SUPPLEMENTARY_CODE_POINT} and
+     *         {@link #MAX_CODE_POINT} inclusive;
+     *         {@code false} otherwise.
+     * @since  1.5
+     */
+    public static boolean isSupplementaryCodePoint(int codePoint) {
+        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
+            && codePoint <  MAX_CODE_POINT + 1;
+    }
+
+    /**
+     * Determines if the given {@code char} value is a
+     * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+     * Unicode high-surrogate code unit</a>
+     * (also known as <i>leading-surrogate code unit</i>).
+     *
+     * <p>Such values do not represent characters by themselves,
+     * but are used in the representation of
+     * <a href="#supplementary">supplementary characters</a>
+     * in the UTF-16 encoding.
+     *
+     * @param  ch the {@code char} value to be tested.
+     * @return {@code true} if the {@code char} value is between
+     *         {@link #MIN_HIGH_SURROGATE} and
+     *         {@link #MAX_HIGH_SURROGATE} inclusive;
+     *         {@code false} otherwise.
+     * @see    Character#isLowSurrogate(char)
+     * @see    Character.UnicodeBlock#of(int)
+     * @since  1.5
+     */
+    public static boolean isHighSurrogate(char ch) {
+        // Help VM constant-fold; MAX_HIGH_SURROGATE + 1 == MIN_LOW_SURROGATE
+        return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
+    }
+
+    /**
+     * Determines if the given {@code char} value is a
+     * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+     * Unicode low-surrogate code unit</a>
+     * (also known as <i>trailing-surrogate code unit</i>).
+     *
+     * <p>Such values do not represent characters by themselves,
+     * but are used in the representation of
+     * <a href="#supplementary">supplementary characters</a>
+     * in the UTF-16 encoding.
+     *
+     * @param  ch the {@code char} value to be tested.
+     * @return {@code true} if the {@code char} value is between
+     *         {@link #MIN_LOW_SURROGATE} and
+     *         {@link #MAX_LOW_SURROGATE} inclusive;
+     *         {@code false} otherwise.
+     * @see    Character#isHighSurrogate(char)
+     * @since  1.5
+     */
+    public static boolean isLowSurrogate(char ch) {
+        return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
+    }
+
+    /**
+     * Determines if the given {@code char} value is a Unicode
+     * <i>surrogate code unit</i>.
+     *
+     * <p>Such values do not represent characters by themselves,
+     * but are used in the representation of
+     * <a href="#supplementary">supplementary characters</a>
+     * in the UTF-16 encoding.
+     *
+     * <p>A char value is a surrogate code unit if and only if it is either
+     * a {@linkplain #isLowSurrogate(char) low-surrogate code unit} or
+     * a {@linkplain #isHighSurrogate(char) high-surrogate code unit}.
+     *
+     * @param  ch the {@code char} value to be tested.
+     * @return {@code true} if the {@code char} value is between
+     *         {@link #MIN_SURROGATE} and
+     *         {@link #MAX_SURROGATE} inclusive;
+     *         {@code false} otherwise.
+     * @since  1.7
+     */
+    public static boolean isSurrogate(char ch) {
+        return ch >= MIN_SURROGATE && ch < (MAX_SURROGATE + 1);
+    }
+
+    /**
+     * Determines whether the specified pair of {@code char}
+     * values is a valid
+     * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+     * Unicode surrogate pair</a>.
+
+     * <p>This method is equivalent to the expression:
+     * <blockquote><pre>{@code
+     * isHighSurrogate(high) && isLowSurrogate(low)
+     * }</pre></blockquote>
+     *
+     * @param  high the high-surrogate code value to be tested
+     * @param  low the low-surrogate code value to be tested
+     * @return {@code true} if the specified high and
+     * low-surrogate code values represent a valid surrogate pair;
+     * {@code false} otherwise.
+     * @since  1.5
+     */
+    public static boolean isSurrogatePair(char high, char low) {
+        return isHighSurrogate(high) && isLowSurrogate(low);
+    }
+
+    /**
+     * Determines the number of {@code char} values needed to
+     * represent the specified character (Unicode code point). If the
+     * specified character is equal to or greater than 0x10000, then
+     * the method returns 2. Otherwise, the method returns 1.
+     *
+     * <p>This method doesn't validate the specified character to be a
+     * valid Unicode code point. The caller must validate the
+     * character value using {@link #isValidCodePoint(int) isValidCodePoint}
+     * if necessary.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  2 if the character is a valid supplementary character; 1 otherwise.
+     * @see     Character#isSupplementaryCodePoint(int)
+     * @since   1.5
+     */
+    public static int charCount(int codePoint) {
+        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
+    }
+
+    /**
+     * Converts the specified surrogate pair to its supplementary code
+     * point value. This method does not validate the specified
+     * surrogate pair. The caller must validate it using {@link
+     * #isSurrogatePair(char, char) isSurrogatePair} if necessary.
+     *
+     * @param  high the high-surrogate code unit
+     * @param  low the low-surrogate code unit
+     * @return the supplementary code point composed from the
+     *         specified surrogate pair.
+     * @since  1.5
+     */
+    public static int toCodePoint(char high, char low) {
+        // Optimized form of:
+        // return ((high - MIN_HIGH_SURROGATE) << 10)
+        //         + (low - MIN_LOW_SURROGATE)
+        //         + MIN_SUPPLEMENTARY_CODE_POINT;
+        return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT
+                                       - (MIN_HIGH_SURROGATE << 10)
+                                       - MIN_LOW_SURROGATE);
+    }
+
+    /**
+     * Returns the code point at the given index of the
+     * {@code CharSequence}. If the {@code char} value at
+     * the given index in the {@code CharSequence} is in the
+     * high-surrogate range, the following index is less than the
+     * length of the {@code CharSequence}, and the
+     * {@code char} value at the following index is in the
+     * low-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at the given index is returned.
+     *
+     * @param seq a sequence of {@code char} values (Unicode code
+     * units)
+     * @param index the index to the {@code char} values (Unicode
+     * code units) in {@code seq} to be converted
+     * @return the Unicode code point at the given index
+     * @exception NullPointerException if {@code seq} is null.
+     * @exception IndexOutOfBoundsException if the value
+     * {@code index} is negative or not less than
+     * {@link CharSequence#length() seq.length()}.
+     * @since  1.5
+     */
+    public static int codePointAt(CharSequence seq, int index) {
+        char c1 = seq.charAt(index);
+        if (isHighSurrogate(c1) && ++index < seq.length()) {
+            char c2 = seq.charAt(index);
+            if (isLowSurrogate(c2)) {
+                return toCodePoint(c1, c2);
+            }
+        }
+        return c1;
+    }
+
+    /**
+     * Returns the code point at the given index of the
+     * {@code char} array. If the {@code char} value at
+     * the given index in the {@code char} array is in the
+     * high-surrogate range, the following index is less than the
+     * length of the {@code char} array, and the
+     * {@code char} value at the following index is in the
+     * low-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at the given index is returned.
+     *
+     * @param a the {@code char} array
+     * @param index the index to the {@code char} values (Unicode
+     * code units) in the {@code char} array to be converted
+     * @return the Unicode code point at the given index
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException if the value
+     * {@code index} is negative or not less than
+     * the length of the {@code char} array.
+     * @since  1.5
+     */
+    public static int codePointAt(char[] a, int index) {
+        return codePointAtImpl(a, index, a.length);
+    }
+
+    /**
+     * Returns the code point at the given index of the
+     * {@code char} array, where only array elements with
+     * {@code index} less than {@code limit} can be used. If
+     * the {@code char} value at the given index in the
+     * {@code char} array is in the high-surrogate range, the
+     * following index is less than the {@code limit}, and the
+     * {@code char} value at the following index is in the
+     * low-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at the given index is returned.
+     *
+     * @param a the {@code char} array
+     * @param index the index to the {@code char} values (Unicode
+     * code units) in the {@code char} array to be converted
+     * @param limit the index after the last array element that
+     * can be used in the {@code char} array
+     * @return the Unicode code point at the given index
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     * argument is negative or not less than the {@code limit}
+     * argument, or if the {@code limit} argument is negative or
+     * greater than the length of the {@code char} array.
+     * @since  1.5
+     */
+    public static int codePointAt(char[] a, int index, int limit) {
+        if (index >= limit || limit < 0 || limit > a.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        return codePointAtImpl(a, index, limit);
+    }
+
+    // throws ArrayIndexOutOfBoundsException if index out of bounds
+    static int codePointAtImpl(char[] a, int index, int limit) {
+        char c1 = a[index];
+        if (isHighSurrogate(c1) && ++index < limit) {
+            char c2 = a[index];
+            if (isLowSurrogate(c2)) {
+                return toCodePoint(c1, c2);
+            }
+        }
+        return c1;
+    }
+
+    /**
+     * Returns the code point preceding the given index of the
+     * {@code CharSequence}. If the {@code char} value at
+     * {@code (index - 1)} in the {@code CharSequence} is in
+     * the low-surrogate range, {@code (index - 2)} is not
+     * negative, and the {@code char} value at {@code (index - 2)}
+     * in the {@code CharSequence} is in the
+     * high-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at {@code (index - 1)} is
+     * returned.
+     *
+     * @param seq the {@code CharSequence} instance
+     * @param index the index following the code point that should be returned
+     * @return the Unicode code point value before the given index.
+     * @exception NullPointerException if {@code seq} is null.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     * argument is less than 1 or greater than {@link
+     * CharSequence#length() seq.length()}.
+     * @since  1.5
+     */
+    public static int codePointBefore(CharSequence seq, int index) {
+        char c2 = seq.charAt(--index);
+        if (isLowSurrogate(c2) && index > 0) {
+            char c1 = seq.charAt(--index);
+            if (isHighSurrogate(c1)) {
+                return toCodePoint(c1, c2);
+            }
+        }
+        return c2;
+    }
+
+    /**
+     * Returns the code point preceding the given index of the
+     * {@code char} array. If the {@code char} value at
+     * {@code (index - 1)} in the {@code char} array is in
+     * the low-surrogate range, {@code (index - 2)} is not
+     * negative, and the {@code char} value at {@code (index - 2)}
+     * in the {@code char} array is in the
+     * high-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at {@code (index - 1)} is
+     * returned.
+     *
+     * @param a the {@code char} array
+     * @param index the index following the code point that should be returned
+     * @return the Unicode code point value before the given index.
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     * argument is less than 1 or greater than the length of the
+     * {@code char} array
+     * @since  1.5
+     */
+    public static int codePointBefore(char[] a, int index) {
+        return codePointBeforeImpl(a, index, 0);
+    }
+
+    /**
+     * Returns the code point preceding the given index of the
+     * {@code char} array, where only array elements with
+     * {@code index} greater than or equal to {@code start}
+     * can be used. If the {@code char} value at {@code (index - 1)}
+     * in the {@code char} array is in the
+     * low-surrogate range, {@code (index - 2)} is not less than
+     * {@code start}, and the {@code char} value at
+     * {@code (index - 2)} in the {@code char} array is in
+     * the high-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at {@code (index - 1)} is
+     * returned.
+     *
+     * @param a the {@code char} array
+     * @param index the index following the code point that should be returned
+     * @param start the index of the first array element in the
+     * {@code char} array
+     * @return the Unicode code point value before the given index.
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     * argument is not greater than the {@code start} argument or
+     * is greater than the length of the {@code char} array, or
+     * if the {@code start} argument is negative or not less than
+     * the length of the {@code char} array.
+     * @since  1.5
+     */
+    public static int codePointBefore(char[] a, int index, int start) {
+        if (index <= start || start < 0 || start >= a.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        return codePointBeforeImpl(a, index, start);
+    }
+
+    // throws ArrayIndexOutOfBoundsException if index-1 out of bounds
+    static int codePointBeforeImpl(char[] a, int index, int start) {
+        char c2 = a[--index];
+        if (isLowSurrogate(c2) && index > start) {
+            char c1 = a[--index];
+            if (isHighSurrogate(c1)) {
+                return toCodePoint(c1, c2);
+            }
+        }
+        return c2;
+    }
+
+    /**
+     * Returns the leading surrogate (a
+     * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+     * high surrogate code unit</a>) of the
+     * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+     * surrogate pair</a>
+     * representing the specified supplementary character (Unicode
+     * code point) in the UTF-16 encoding.  If the specified character
+     * is not a
+     * <a href="Character.html#supplementary">supplementary character</a>,
+     * an unspecified {@code char} is returned.
+     *
+     * <p>If
+     * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+     * is {@code true}, then
+     * {@link #isHighSurrogate isHighSurrogate}{@code (highSurrogate(x))} and
+     * {@link #toCodePoint toCodePoint}{@code (highSurrogate(x), }{@link #lowSurrogate lowSurrogate}{@code (x)) == x}
+     * are also always {@code true}.
+     *
+     * @param   codePoint a supplementary character (Unicode code point)
+     * @return  the leading surrogate code unit used to represent the
+     *          character in the UTF-16 encoding
+     * @since   1.7
+     */
+    public static char highSurrogate(int codePoint) {
+        return (char) ((codePoint >>> 10)
+            + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
+    }
+
+    /**
+     * Returns the trailing surrogate (a
+     * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+     * low surrogate code unit</a>) of the
+     * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+     * surrogate pair</a>
+     * representing the specified supplementary character (Unicode
+     * code point) in the UTF-16 encoding.  If the specified character
+     * is not a
+     * <a href="Character.html#supplementary">supplementary character</a>,
+     * an unspecified {@code char} is returned.
+     *
+     * <p>If
+     * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+     * is {@code true}, then
+     * {@link #isLowSurrogate isLowSurrogate}{@code (lowSurrogate(x))} and
+     * {@link #toCodePoint toCodePoint}{@code (}{@link #highSurrogate highSurrogate}{@code (x), lowSurrogate(x)) == x}
+     * are also always {@code true}.
+     *
+     * @param   codePoint a supplementary character (Unicode code point)
+     * @return  the trailing surrogate code unit used to represent the
+     *          character in the UTF-16 encoding
+     * @since   1.7
+     */
+    public static char lowSurrogate(int codePoint) {
+        return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
+    }
+
+    /**
+     * Converts the specified character (Unicode code point) to its
+     * UTF-16 representation. If the specified code point is a BMP
+     * (Basic Multilingual Plane or Plane 0) value, the same value is
+     * stored in {@code dst[dstIndex]}, and 1 is returned. If the
+     * specified code point is a supplementary character, its
+     * surrogate values are stored in {@code dst[dstIndex]}
+     * (high-surrogate) and {@code dst[dstIndex+1]}
+     * (low-surrogate), and 2 is returned.
+     *
+     * @param  codePoint the character (Unicode code point) to be converted.
+     * @param  dst an array of {@code char} in which the
+     * {@code codePoint}'s UTF-16 value is stored.
+     * @param dstIndex the start index into the {@code dst}
+     * array where the converted value is stored.
+     * @return 1 if the code point is a BMP code point, 2 if the
+     * code point is a supplementary code point.
+     * @exception IllegalArgumentException if the specified
+     * {@code codePoint} is not a valid Unicode code point.
+     * @exception NullPointerException if the specified {@code dst} is null.
+     * @exception IndexOutOfBoundsException if {@code dstIndex}
+     * is negative or not less than {@code dst.length}, or if
+     * {@code dst} at {@code dstIndex} doesn't have enough
+     * array element(s) to store the resulting {@code char}
+     * value(s). (If {@code dstIndex} is equal to
+     * {@code dst.length-1} and the specified
+     * {@code codePoint} is a supplementary character, the
+     * high-surrogate value is not stored in
+     * {@code dst[dstIndex]}.)
+     * @since  1.5
+     */
+    public static int toChars(int codePoint, char[] dst, int dstIndex) {
+        if (isBmpCodePoint(codePoint)) {
+            dst[dstIndex] = (char) codePoint;
+            return 1;
+        } else if (isValidCodePoint(codePoint)) {
+            toSurrogates(codePoint, dst, dstIndex);
+            return 2;
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Converts the specified character (Unicode code point) to its
+     * UTF-16 representation stored in a {@code char} array. If
+     * the specified code point is a BMP (Basic Multilingual Plane or
+     * Plane 0) value, the resulting {@code char} array has
+     * the same value as {@code codePoint}. If the specified code
+     * point is a supplementary code point, the resulting
+     * {@code char} array has the corresponding surrogate pair.
+     *
+     * @param  codePoint a Unicode code point
+     * @return a {@code char} array having
+     *         {@code codePoint}'s UTF-16 representation.
+     * @exception IllegalArgumentException if the specified
+     * {@code codePoint} is not a valid Unicode code point.
+     * @since  1.5
+     */
+    public static char[] toChars(int codePoint) {
+        if (isBmpCodePoint(codePoint)) {
+            return new char[] { (char) codePoint };
+        } else if (isValidCodePoint(codePoint)) {
+            char[] result = new char[2];
+            toSurrogates(codePoint, result, 0);
+            return result;
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    static void toSurrogates(int codePoint, char[] dst, int index) {
+        // We write elements "backwards" to guarantee all-or-nothing
+        dst[index+1] = lowSurrogate(codePoint);
+        dst[index] = highSurrogate(codePoint);
+    }
+
+    /**
+     * Returns the number of Unicode code points in the text range of
+     * the specified char sequence. The text range begins at the
+     * specified {@code beginIndex} and extends to the
+     * {@code char} at index {@code endIndex - 1}. Thus the
+     * length (in {@code char}s) of the text range is
+     * {@code endIndex-beginIndex}. Unpaired surrogates within
+     * the text range count as one code point each.
+     *
+     * @param seq the char sequence
+     * @param beginIndex the index to the first {@code char} of
+     * the text range.
+     * @param endIndex the index after the last {@code char} of
+     * the text range.
+     * @return the number of Unicode code points in the specified text
+     * range
+     * @exception NullPointerException if {@code seq} is null.
+     * @exception IndexOutOfBoundsException if the
+     * {@code beginIndex} is negative, or {@code endIndex}
+     * is larger than the length of the given sequence, or
+     * {@code beginIndex} is larger than {@code endIndex}.
+     * @since  1.5
+     */
+    public static int codePointCount(CharSequence seq, int beginIndex, int endIndex) {
+        int length = seq.length();
+        if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) {
+            throw new IndexOutOfBoundsException();
+        }
+        int n = endIndex - beginIndex;
+        for (int i = beginIndex; i < endIndex; ) {
+            if (isHighSurrogate(seq.charAt(i++)) && i < endIndex &&
+                isLowSurrogate(seq.charAt(i))) {
+                n--;
+                i++;
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Returns the number of Unicode code points in a subarray of the
+     * {@code char} array argument. The {@code offset}
+     * argument is the index of the first {@code char} of the
+     * subarray and the {@code count} argument specifies the
+     * length of the subarray in {@code char}s. Unpaired
+     * surrogates within the subarray count as one code point each.
+     *
+     * @param a the {@code char} array
+     * @param offset the index of the first {@code char} in the
+     * given {@code char} array
+     * @param count the length of the subarray in {@code char}s
+     * @return the number of Unicode code points in the specified subarray
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException if {@code offset} or
+     * {@code count} is negative, or if {@code offset +
+     * count} is larger than the length of the given array.
+     * @since  1.5
+     */
+    public static int codePointCount(char[] a, int offset, int count) {
+        if (count > a.length - offset || offset < 0 || count < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        return codePointCountImpl(a, offset, count);
+    }
+
+    static int codePointCountImpl(char[] a, int offset, int count) {
+        int endIndex = offset + count;
+        int n = count;
+        for (int i = offset; i < endIndex; ) {
+            if (isHighSurrogate(a[i++]) && i < endIndex &&
+                isLowSurrogate(a[i])) {
+                n--;
+                i++;
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Returns the index within the given char sequence that is offset
+     * from the given {@code index} by {@code codePointOffset}
+     * code points. Unpaired surrogates within the text range given by
+     * {@code index} and {@code codePointOffset} count as
+     * one code point each.
+     *
+     * @param seq the char sequence
+     * @param index the index to be offset
+     * @param codePointOffset the offset in code points
+     * @return the index within the char sequence
+     * @exception NullPointerException if {@code seq} is null.
+     * @exception IndexOutOfBoundsException if {@code index}
+     *   is negative or larger then the length of the char sequence,
+     *   or if {@code codePointOffset} is positive and the
+     *   subsequence starting with {@code index} has fewer than
+     *   {@code codePointOffset} code points, or if
+     *   {@code codePointOffset} is negative and the subsequence
+     *   before {@code index} has fewer than the absolute value
+     *   of {@code codePointOffset} code points.
+     * @since 1.5
+     */
+    public static int offsetByCodePoints(CharSequence seq, int index,
+                                         int codePointOffset) {
+        int length = seq.length();
+        if (index < 0 || index > length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int x = index;
+        if (codePointOffset >= 0) {
+            int i;
+            for (i = 0; x < length && i < codePointOffset; i++) {
+                if (isHighSurrogate(seq.charAt(x++)) && x < length &&
+                    isLowSurrogate(seq.charAt(x))) {
+                    x++;
+                }
+            }
+            if (i < codePointOffset) {
+                throw new IndexOutOfBoundsException();
+            }
+        } else {
+            int i;
+            for (i = codePointOffset; x > 0 && i < 0; i++) {
+                if (isLowSurrogate(seq.charAt(--x)) && x > 0 &&
+                    isHighSurrogate(seq.charAt(x-1))) {
+                    x--;
+                }
+            }
+            if (i < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+        }
+        return x;
+    }
+
+    /**
+     * Returns the index within the given {@code char} subarray
+     * that is offset from the given {@code index} by
+     * {@code codePointOffset} code points. The
+     * {@code start} and {@code count} arguments specify a
+     * subarray of the {@code char} array. Unpaired surrogates
+     * within the text range given by {@code index} and
+     * {@code codePointOffset} count as one code point each.
+     *
+     * @param a the {@code char} array
+     * @param start the index of the first {@code char} of the
+     * subarray
+     * @param count the length of the subarray in {@code char}s
+     * @param index the index to be offset
+     * @param codePointOffset the offset in code points
+     * @return the index within the subarray
+     * @exception NullPointerException if {@code a} is null.
+     * @exception IndexOutOfBoundsException
+     *   if {@code start} or {@code count} is negative,
+     *   or if {@code start + count} is larger than the length of
+     *   the given array,
+     *   or if {@code index} is less than {@code start} or
+     *   larger then {@code start + count},
+     *   or if {@code codePointOffset} is positive and the text range
+     *   starting with {@code index} and ending with {@code start + count - 1}
+     *   has fewer than {@code codePointOffset} code
+     *   points,
+     *   or if {@code codePointOffset} is negative and the text range
+     *   starting with {@code start} and ending with {@code index - 1}
+     *   has fewer than the absolute value of
+     *   {@code codePointOffset} code points.
+     * @since 1.5
+     */
+    public static int offsetByCodePoints(char[] a, int start, int count,
+                                         int index, int codePointOffset) {
+        if (count > a.length-start || start < 0 || count < 0
+            || index < start || index > start+count) {
+            throw new IndexOutOfBoundsException();
+        }
+        return offsetByCodePointsImpl(a, start, count, index, codePointOffset);
+    }
+
+    static int offsetByCodePointsImpl(char[]a, int start, int count,
+                                      int index, int codePointOffset) {
+        int x = index;
+        if (codePointOffset >= 0) {
+            int limit = start + count;
+            int i;
+            for (i = 0; x < limit && i < codePointOffset; i++) {
+                if (isHighSurrogate(a[x++]) && x < limit &&
+                    isLowSurrogate(a[x])) {
+                    x++;
+                }
+            }
+            if (i < codePointOffset) {
+                throw new IndexOutOfBoundsException();
+            }
+        } else {
+            int i;
+            for (i = codePointOffset; x > start && i < 0; i++) {
+                if (isLowSurrogate(a[--x]) && x > start &&
+                    isHighSurrogate(a[x-1])) {
+                    x--;
+                }
+            }
+            if (i < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+        }
+        return x;
+    }
+
+    /**
+     * Determines if the specified character is a lowercase character.
+     * <p>
+     * A character is lowercase if its general category type, provided
+     * by {@code Character.getType(ch)}, is
+     * {@code LOWERCASE_LETTER}, or it has contributory property
+     * Other_Lowercase as defined by the Unicode Standard.
+     * <p>
+     * The following are examples of lowercase characters:
+     * <blockquote><pre>
+     * a b c d e f g h i j k l m n o p q r s t u v w x y z
+     * '&#92;u00DF' '&#92;u00E0' '&#92;u00E1' '&#92;u00E2' '&#92;u00E3' '&#92;u00E4' '&#92;u00E5' '&#92;u00E6'
+     * '&#92;u00E7' '&#92;u00E8' '&#92;u00E9' '&#92;u00EA' '&#92;u00EB' '&#92;u00EC' '&#92;u00ED' '&#92;u00EE'
+     * '&#92;u00EF' '&#92;u00F0' '&#92;u00F1' '&#92;u00F2' '&#92;u00F3' '&#92;u00F4' '&#92;u00F5' '&#92;u00F6'
+     * '&#92;u00F8' '&#92;u00F9' '&#92;u00FA' '&#92;u00FB' '&#92;u00FC' '&#92;u00FD' '&#92;u00FE' '&#92;u00FF'
+     * </pre></blockquote>
+     * <p> Many other Unicode characters are lowercase too.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isLowerCase(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is lowercase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#getType(char)
+     */
+    public static boolean isLowerCase(char ch) {
+        return isLowerCase((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a
+     * lowercase character.
+     * <p>
+     * A character is lowercase if its general category type, provided
+     * by {@link Character#getType getType(codePoint)}, is
+     * {@code LOWERCASE_LETTER}, or it has contributory property
+     * Other_Lowercase as defined by the Unicode Standard.
+     * <p>
+     * The following are examples of lowercase characters:
+     * <blockquote><pre>
+     * a b c d e f g h i j k l m n o p q r s t u v w x y z
+     * '&#92;u00DF' '&#92;u00E0' '&#92;u00E1' '&#92;u00E2' '&#92;u00E3' '&#92;u00E4' '&#92;u00E5' '&#92;u00E6'
+     * '&#92;u00E7' '&#92;u00E8' '&#92;u00E9' '&#92;u00EA' '&#92;u00EB' '&#92;u00EC' '&#92;u00ED' '&#92;u00EE'
+     * '&#92;u00EF' '&#92;u00F0' '&#92;u00F1' '&#92;u00F2' '&#92;u00F3' '&#92;u00F4' '&#92;u00F5' '&#92;u00F6'
+     * '&#92;u00F8' '&#92;u00F9' '&#92;u00FA' '&#92;u00FB' '&#92;u00FC' '&#92;u00FD' '&#92;u00FE' '&#92;u00FF'
+     * </pre></blockquote>
+     * <p> Many other Unicode characters are lowercase too.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is lowercase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toLowerCase(int)
+     * @see     Character#getType(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLowerCase(int codePoint) {
+        return getType(codePoint) == Character.LOWERCASE_LETTER ||
+               CharacterData.of(codePoint).isOtherLowercase(codePoint);
+    }
+    */
+    public static boolean isLowerCase(int codePoint) {
+        return isLowerCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isLowerCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is an uppercase character.
+     * <p>
+     * A character is uppercase if its general category type, provided by
+     * {@code Character.getType(ch)}, is {@code UPPERCASE_LETTER}.
+     * or it has contributory property Other_Uppercase as defined by the Unicode Standard.
+     * <p>
+     * The following are examples of uppercase characters:
+     * <blockquote><pre>
+     * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+     * '&#92;u00C0' '&#92;u00C1' '&#92;u00C2' '&#92;u00C3' '&#92;u00C4' '&#92;u00C5' '&#92;u00C6' '&#92;u00C7'
+     * '&#92;u00C8' '&#92;u00C9' '&#92;u00CA' '&#92;u00CB' '&#92;u00CC' '&#92;u00CD' '&#92;u00CE' '&#92;u00CF'
+     * '&#92;u00D0' '&#92;u00D1' '&#92;u00D2' '&#92;u00D3' '&#92;u00D4' '&#92;u00D5' '&#92;u00D6' '&#92;u00D8'
+     * '&#92;u00D9' '&#92;u00DA' '&#92;u00DB' '&#92;u00DC' '&#92;u00DD' '&#92;u00DE'
+     * </pre></blockquote>
+     * <p> Many other Unicode characters are uppercase too.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isUpperCase(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is uppercase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toUpperCase(char)
+     * @see     Character#getType(char)
+     * @since   1.0
+     */
+    public static boolean isUpperCase(char ch) {
+        return isUpperCase((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is an uppercase character.
+     * <p>
+     * A character is uppercase if its general category type, provided by
+     * {@link Character#getType(int) getType(codePoint)}, is {@code UPPERCASE_LETTER},
+     * or it has contributory property Other_Uppercase as defined by the Unicode Standard.
+     * <p>
+     * The following are examples of uppercase characters:
+     * <blockquote><pre>
+     * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+     * '&#92;u00C0' '&#92;u00C1' '&#92;u00C2' '&#92;u00C3' '&#92;u00C4' '&#92;u00C5' '&#92;u00C6' '&#92;u00C7'
+     * '&#92;u00C8' '&#92;u00C9' '&#92;u00CA' '&#92;u00CB' '&#92;u00CC' '&#92;u00CD' '&#92;u00CE' '&#92;u00CF'
+     * '&#92;u00D0' '&#92;u00D1' '&#92;u00D2' '&#92;u00D3' '&#92;u00D4' '&#92;u00D5' '&#92;u00D6' '&#92;u00D8'
+     * '&#92;u00D9' '&#92;u00DA' '&#92;u00DB' '&#92;u00DC' '&#92;u00DD' '&#92;u00DE'
+     * </pre></blockquote>
+     * <p> Many other Unicode characters are uppercase too.<p>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is uppercase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toUpperCase(int)
+     * @see     Character#getType(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUpperCase(int codePoint) {
+        return getType(codePoint) == Character.UPPERCASE_LETTER ||
+               CharacterData.of(codePoint).isOtherUppercase(codePoint);
+    }
+    */
+    public static boolean isUpperCase(int codePoint) {
+        return isUpperCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isUpperCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is a titlecase character.
+     * <p>
+     * A character is a titlecase character if its general
+     * category type, provided by {@code Character.getType(ch)},
+     * is {@code TITLECASE_LETTER}.
+     * <p>
+     * Some characters look like pairs of Latin letters. For example, there
+     * is an uppercase letter that looks like "LJ" and has a corresponding
+     * lowercase letter that looks like "lj". A third form, which looks like "Lj",
+     * is the appropriate form to use when rendering a word in lowercase
+     * with initial capitals, as for a book title.
+     * <p>
+     * These are some of the Unicode characters for which this method returns
+     * {@code true}:
+     * <ul>
+     * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON}
+     * <li>{@code LATIN CAPITAL LETTER L WITH SMALL LETTER J}
+     * <li>{@code LATIN CAPITAL LETTER N WITH SMALL LETTER J}
+     * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z}
+     * </ul>
+     * <p> Many other Unicode characters are titlecase too.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isTitleCase(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is titlecase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isUpperCase(char)
+     * @see     Character#toTitleCase(char)
+     * @see     Character#getType(char)
+     * @since   1.0.2
+     */
+    public static boolean isTitleCase(char ch) {
+        return isTitleCase((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a titlecase character.
+     * <p>
+     * A character is a titlecase character if its general
+     * category type, provided by {@link Character#getType(int) getType(codePoint)},
+     * is {@code TITLECASE_LETTER}.
+     * <p>
+     * Some characters look like pairs of Latin letters. For example, there
+     * is an uppercase letter that looks like "LJ" and has a corresponding
+     * lowercase letter that looks like "lj". A third form, which looks like "Lj",
+     * is the appropriate form to use when rendering a word in lowercase
+     * with initial capitals, as for a book title.
+     * <p>
+     * These are some of the Unicode characters for which this method returns
+     * {@code true}:
+     * <ul>
+     * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON}
+     * <li>{@code LATIN CAPITAL LETTER L WITH SMALL LETTER J}
+     * <li>{@code LATIN CAPITAL LETTER N WITH SMALL LETTER J}
+     * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z}
+     * </ul>
+     * <p> Many other Unicode characters are titlecase too.<p>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is titlecase;
+     *          {@code false} otherwise.
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isUpperCase(int)
+     * @see     Character#toTitleCase(int)
+     * @see     Character#getType(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isTitleCase(int codePoint) {
+        return getType(codePoint) == Character.TITLECASE_LETTER;
+    }
+    */
+    public static boolean isTitleCase(int codePoint) {
+        return isTitleCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isTitleCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is a digit.
+     * <p>
+     * A character is a digit if its general category type, provided
+     * by {@code Character.getType(ch)}, is
+     * {@code DECIMAL_DIGIT_NUMBER}.
+     * <p>
+     * Some Unicode character ranges that contain digits:
+     * <ul>
+     * <li>{@code '\u005Cu0030'} through {@code '\u005Cu0039'},
+     *     ISO-LATIN-1 digits ({@code '0'} through {@code '9'})
+     * <li>{@code '\u005Cu0660'} through {@code '\u005Cu0669'},
+     *     Arabic-Indic digits
+     * <li>{@code '\u005Cu06F0'} through {@code '\u005Cu06F9'},
+     *     Extended Arabic-Indic digits
+     * <li>{@code '\u005Cu0966'} through {@code '\u005Cu096F'},
+     *     Devanagari digits
+     * <li>{@code '\u005CuFF10'} through {@code '\u005CuFF19'},
+     *     Fullwidth digits
+     * </ul>
+     *
+     * Many other character ranges contain digits as well.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isDigit(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is a digit;
+     *          {@code false} otherwise.
+     * @see     Character#digit(char, int)
+     * @see     Character#forDigit(int, int)
+     * @see     Character#getType(char)
+     */
+    public static boolean isDigit(char ch) {
+        return isDigit((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a digit.
+     * <p>
+     * A character is a digit if its general category type, provided
+     * by {@link Character#getType(int) getType(codePoint)}, is
+     * {@code DECIMAL_DIGIT_NUMBER}.
+     * <p>
+     * Some Unicode character ranges that contain digits:
+     * <ul>
+     * <li>{@code '\u005Cu0030'} through {@code '\u005Cu0039'},
+     *     ISO-LATIN-1 digits ({@code '0'} through {@code '9'})
+     * <li>{@code '\u005Cu0660'} through {@code '\u005Cu0669'},
+     *     Arabic-Indic digits
+     * <li>{@code '\u005Cu06F0'} through {@code '\u005Cu06F9'},
+     *     Extended Arabic-Indic digits
+     * <li>{@code '\u005Cu0966'} through {@code '\u005Cu096F'},
+     *     Devanagari digits
+     * <li>{@code '\u005CuFF10'} through {@code '\u005CuFF19'},
+     *     Fullwidth digits
+     * </ul>
+     *
+     * Many other character ranges contain digits as well.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is a digit;
+     *          {@code false} otherwise.
+     * @see     Character#forDigit(int, int)
+     * @see     Character#getType(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isDigit(int codePoint) {
+        return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
+    }
+    */
+    public static boolean isDigit(int codePoint) {
+        return isDigitImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isDigitImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if a character is defined in Unicode.
+     * <p>
+     * A character is defined if at least one of the following is true:
+     * <ul>
+     * <li>It has an entry in the UnicodeData file.
+     * <li>It has a value in a range defined by the UnicodeData file.
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isDefined(int)} method.
+     *
+     * @param   ch   the character to be tested
+     * @return  {@code true} if the character has a defined meaning
+     *          in Unicode; {@code false} otherwise.
+     * @see     Character#isDigit(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#isUpperCase(char)
+     * @since   1.0.2
+     */
+    public static boolean isDefined(char ch) {
+        return isDefined((int)ch);
+    }
+
+    /**
+     * Determines if a character (Unicode code point) is defined in Unicode.
+     * <p>
+     * A character is defined if at least one of the following is true:
+     * <ul>
+     * <li>It has an entry in the UnicodeData file.
+     * <li>It has a value in a range defined by the UnicodeData file.
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character has a defined meaning
+     *          in Unicode; {@code false} otherwise.
+     * @see     Character#isDigit(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#isUpperCase(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isDefined(int codePoint) {
+        return getType(codePoint) != Character.UNASSIGNED;
+    }
+    */
+    public static boolean isDefined(int codePoint) {
+        return isDefinedImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isDefinedImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is a letter.
+     * <p>
+     * A character is considered to be a letter if its general
+     * category type, provided by {@code Character.getType(ch)},
+     * is any of the following:
+     * <ul>
+     * <li> {@code UPPERCASE_LETTER}
+     * <li> {@code LOWERCASE_LETTER}
+     * <li> {@code TITLECASE_LETTER}
+     * <li> {@code MODIFIER_LETTER}
+     * <li> {@code OTHER_LETTER}
+     * </ul>
+     *
+     * Not all letters have case. Many characters are
+     * letters but are neither uppercase nor lowercase nor titlecase.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isLetter(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is a letter;
+     *          {@code false} otherwise.
+     * @see     Character#isDigit(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isTitleCase(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
+     * @see     Character#isUpperCase(char)
+     */
+    public static boolean isLetter(char ch) {
+        return isLetter((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a letter.
+     * <p>
+     * A character is considered to be a letter if its general
+     * category type, provided by {@link Character#getType(int) getType(codePoint)},
+     * is any of the following:
+     * <ul>
+     * <li> {@code UPPERCASE_LETTER}
+     * <li> {@code LOWERCASE_LETTER}
+     * <li> {@code TITLECASE_LETTER}
+     * <li> {@code MODIFIER_LETTER}
+     * <li> {@code OTHER_LETTER}
+     * </ul>
+     *
+     * Not all letters have case. Many characters are
+     * letters but are neither uppercase nor lowercase nor titlecase.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is a letter;
+     *          {@code false} otherwise.
+     * @see     Character#isDigit(int)
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isLowerCase(int)
+     * @see     Character#isTitleCase(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
+     * @see     Character#isUpperCase(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLetter(int codePoint) {
+        return ((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
+    public static boolean isLetter(int codePoint) {
+        return isLetterImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isLetterImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is a letter or digit.
+     * <p>
+     * A character is considered to be a letter or digit if either
+     * {@code Character.isLetter(char ch)} or
+     * {@code Character.isDigit(char ch)} returns
+     * {@code true} for the character.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isLetterOrDigit(int)} method.
+     *
+     * @param   ch   the character to be tested.
+     * @return  {@code true} if the character is a letter or digit;
+     *          {@code false} otherwise.
+     * @see     Character#isDigit(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @since   1.0.2
+     */
+    public static boolean isLetterOrDigit(char ch) {
+        return isLetterOrDigit((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a letter or digit.
+     * <p>
+     * A character is considered to be a letter or digit if either
+     * {@link #isLetter(int) isLetter(codePoint)} or
+     * {@link #isDigit(int) isDigit(codePoint)} returns
+     * {@code true} for the character.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is a letter or digit;
+     *          {@code false} otherwise.
+     * @see     Character#isDigit(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isLetterOrDigit(int codePoint) {
+        return ((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER) |
+            (1 << Character.DECIMAL_DIGIT_NUMBER)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
+    public static boolean isLetterOrDigit(int codePoint) {
+        return isLetterOrDigitImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isLetterOrDigitImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is permissible as the first
+     * character in a Java identifier.
+     * <p>
+     * A character may start a Java identifier if and only if
+     * one of the following is true:
+     * <ul>
+     * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+     * <li> {@link #getType(char) getType(ch)} returns {@code LETTER_NUMBER}
+     * <li> {@code ch} is a currency symbol (such as {@code '$'})
+     * <li> {@code ch} is a connecting punctuation character (such as {@code '_'}).
+     * </ul>
+     *
+     * @param   ch the character to be tested.
+     * @return  {@code true} if the character may start a Java
+     *          identifier; {@code false} otherwise.
+     * @see     Character#isJavaLetterOrDigit(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
+     * @since   1.02
+     * @deprecated Replaced by isJavaIdentifierStart(char).
+     */
+    @Deprecated
+    public static boolean isJavaLetter(char ch) {
+        return isJavaIdentifierStart(ch);
+    }
+
+    /**
+     * Determines if the specified character may be part of a Java
+     * identifier as other than the first character.
+     * <p>
+     * A character may be part of a Java identifier if and only if any
+     * of the following are true:
+     * <ul>
+     * <li>  it is a letter
+     * <li>  it is a currency symbol (such as {@code '$'})
+     * <li>  it is a connecting punctuation character (such as {@code '_'})
+     * <li>  it is a digit
+     * <li>  it is a numeric letter (such as a Roman numeral character)
+     * <li>  it is a combining mark
+     * <li>  it is a non-spacing mark
+     * <li> {@code isIdentifierIgnorable} returns
+     * {@code true} for the character.
+     * </ul>
+     *
+     * @param   ch the character to be tested.
+     * @return  {@code true} if the character may be part of a
+     *          Java identifier; {@code false} otherwise.
+     * @see     Character#isJavaLetter(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @see     Character#isIdentifierIgnorable(char)
+     * @since   1.02
+     * @deprecated Replaced by isJavaIdentifierPart(char).
+     */
+    @Deprecated
+    public static boolean isJavaLetterOrDigit(char ch) {
+        return isJavaIdentifierPart(ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is an alphabet.
+     * <p>
+     * A character is considered to be alphabetic if its general category type,
+     * provided by {@link Character#getType(int) getType(codePoint)}, is any of
+     * the following:
+     * <ul>
+     * <li> <code>UPPERCASE_LETTER</code>
+     * <li> <code>LOWERCASE_LETTER</code>
+     * <li> <code>TITLECASE_LETTER</code>
+     * <li> <code>MODIFIER_LETTER</code>
+     * <li> <code>OTHER_LETTER</code>
+     * <li> <code>LETTER_NUMBER</code>
+     * </ul>
+     * or it has contributory property Other_Alphabetic as defined by the
+     * Unicode Standard.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  <code>true</code> if the character is a Unicode alphabet
+     *          character, <code>false</code> otherwise.
+     * @since   1.7
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isAlphabetic(int codePoint) {
+        return (((((1 << Character.UPPERCASE_LETTER) |
+            (1 << Character.LOWERCASE_LETTER) |
+            (1 << Character.TITLECASE_LETTER) |
+            (1 << Character.MODIFIER_LETTER) |
+            (1 << Character.OTHER_LETTER) |
+            (1 << Character.LETTER_NUMBER)) >> getType(codePoint)) & 1) != 0) ||
+            CharacterData.of(codePoint).isOtherAlphabetic(codePoint);
+    }
+    */
+    public static boolean isAlphabetic(int codePoint) {
+        return isAlphabeticImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isAlphabeticImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character (Unicode code point) is a CJKV
+     * (Chinese, Japanese, Korean and Vietnamese) ideograph, as defined by
+     * the Unicode Standard.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  <code>true</code> if the character is a Unicode ideograph
+     *          character, <code>false</code> otherwise.
+     * @since   1.7
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isIdeographic(int codePoint) {
+        return CharacterData.of(codePoint).isIdeographic(codePoint);
+    }
+    */
+    public static boolean isIdeographic(int codePoint) {
+        return isIdeographicImpl(codePoint);
+    }
+    @FastNative
+    static native boolean isIdeographicImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+    /**
+     * Determines if the specified character is
+     * permissible as the first character in a Java identifier.
+     * <p>
+     * A character may start a Java identifier if and only if
+     * one of the following conditions is true:
+     * <ul>
+     * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+     * <li> {@link #getType(char) getType(ch)} returns {@code LETTER_NUMBER}
+     * <li> {@code ch} is a currency symbol (such as {@code '$'})
+     * <li> {@code ch} is a connecting punctuation character (such as {@code '_'}).
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isJavaIdentifierStart(int)} method.
+     *
+     * @param   ch the character to be tested.
+     * @return  {@code true} if the character may start a Java identifier;
+     *          {@code false} otherwise.
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
+     * @since   1.1
+     */
+    public static boolean isJavaIdentifierStart(char ch) {
+        return isJavaIdentifierStart((int)ch);
+    }
+
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+    /**
+     * Determines if the character (Unicode code point) is
+     * permissible as the first character in a Java identifier.
+     * <p>
+     * A character may start a Java identifier if and only if
+     * one of the following conditions is true:
+     * <ul>
+     * <li> {@link #isLetter(int) isLetter(codePoint)}
+     *      returns {@code true}
+     * <li> {@link #getType(int) getType(codePoint)}
+     *      returns {@code LETTER_NUMBER}
+     * <li> the referenced character is a currency symbol (such as {@code '$'})
+     * <li> the referenced character is a connecting punctuation character
+     *      (such as {@code '_'}).
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character may start a Java identifier;
+     *          {@code false} otherwise.
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Use ICU.
+    /*
+    public static boolean isJavaIdentifierStart(int codePoint) {
+        return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint);
+    }
+    */
+    public static boolean isJavaIdentifierStart(int codePoint) {
+        // Use precomputed bitmasks to optimize the ASCII range.
+        if (codePoint < 64) {
+            return (codePoint == '$'); // There's only one character in this range.
+        } else if (codePoint < 128) {
+            return (0x7fffffe87fffffeL & (1L << (codePoint - 64))) != 0;
+        }
+        return ((1 << getType(codePoint))
+                & ((1 << UPPERCASE_LETTER)
+                   | (1 << LOWERCASE_LETTER)
+                   | (1  << TITLECASE_LETTER)
+                   | (1  << MODIFIER_LETTER)
+                   | (1  << OTHER_LETTER)
+                   | (1  << CURRENCY_SYMBOL)
+                   | (1  << CONNECTOR_PUNCTUATION)
+                   | (1  << LETTER_NUMBER))) != 0;
+    }
+    // END Android-changed: Use ICU.
+
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+    /**
+     * Determines if the specified character may be part of a Java
+     * identifier as other than the first character.
+     * <p>
+     * A character may be part of a Java identifier if any of the following
+     * are true:
+     * <ul>
+     * <li>  it is a letter
+     * <li>  it is a currency symbol (such as {@code '$'})
+     * <li>  it is a connecting punctuation character (such as {@code '_'})
+     * <li>  it is a digit
+     * <li>  it is a numeric letter (such as a Roman numeral character)
+     * <li>  it is a combining mark
+     * <li>  it is a non-spacing mark
+     * <li> {@code isIdentifierIgnorable} returns
+     * {@code true} for the character
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isJavaIdentifierPart(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return {@code true} if the character may be part of a
+     *          Java identifier; {@code false} otherwise.
+     * @see     Character#isIdentifierIgnorable(char)
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @since   1.1
+     */
+    public static boolean isJavaIdentifierPart(char ch) {
+        return isJavaIdentifierPart((int)ch);
+    }
+
+    // Android-changed: Removed @see tag (target does not exist on Android):
+    // @see     javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+    /**
+     * Determines if the character (Unicode code point) may be part of a Java
+     * identifier as other than the first character.
+     * <p>
+     * A character may be part of a Java identifier if any of the following
+     * are true:
+     * <ul>
+     * <li>  it is a letter
+     * <li>  it is a currency symbol (such as {@code '$'})
+     * <li>  it is a connecting punctuation character (such as {@code '_'})
+     * <li>  it is a digit
+     * <li>  it is a numeric letter (such as a Roman numeral character)
+     * <li>  it is a combining mark
+     * <li>  it is a non-spacing mark
+     * <li> {@link #isIdentifierIgnorable(int)
+     * isIdentifierIgnorable(codePoint)} returns {@code true} for
+     * the character
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return {@code true} if the character may be part of a
+     *          Java identifier; {@code false} otherwise.
+     * @see     Character#isIdentifierIgnorable(int)
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Use ICU.
+    /*
+    public static boolean isJavaIdentifierPart(int codePoint) {
+        return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint);
+    }
+    */
+    public static boolean isJavaIdentifierPart(int codePoint) {
+        // Use precomputed bitmasks to optimize the ASCII range.
+        if (codePoint < 64) {
+            return (0x3ff00100fffc1ffL & (1L << codePoint)) != 0;
+        } else if (codePoint < 128) {
+            return (0x87fffffe87fffffeL & (1L << (codePoint - 64))) != 0;
+        }
+        return ((1 << getType(codePoint))
+                & ((1 << UPPERCASE_LETTER)
+                   | (1 << LOWERCASE_LETTER)
+                   | (1 << TITLECASE_LETTER)
+                   | (1 << MODIFIER_LETTER)
+                   | (1 << OTHER_LETTER)
+                   | (1 << CURRENCY_SYMBOL)
+                   | (1 << CONNECTOR_PUNCTUATION)
+                   | (1 << DECIMAL_DIGIT_NUMBER)
+                   | (1 << LETTER_NUMBER)
+                   | (1 << FORMAT)
+                   | (1 << COMBINING_SPACING_MARK)
+                   | (1 << NON_SPACING_MARK))) != 0
+                || (codePoint >= 0 && codePoint <= 8) || (codePoint >= 0xe && codePoint <= 0x1b)
+                || (codePoint >= 0x7f && codePoint <= 0x9f);
+    }
+    // END Android-changed: Use ICU.
+
+    /**
+     * Determines if the specified character is permissible as the
+     * first character in a Unicode identifier.
+     * <p>
+     * A character may start a Unicode identifier if and only if
+     * one of the following conditions is true:
+     * <ul>
+     * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+     * <li> {@link #getType(char) getType(ch)} returns
+     *      {@code LETTER_NUMBER}.
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isUnicodeIdentifierStart(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  {@code true} if the character may start a Unicode
+     *          identifier; {@code false} otherwise.
+     * @see     Character#isJavaIdentifierStart(char)
+     * @see     Character#isLetter(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @since   1.1
+     */
+    public static boolean isUnicodeIdentifierStart(char ch) {
+        return isUnicodeIdentifierStart((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is permissible as the
+     * first character in a Unicode identifier.
+     * <p>
+     * A character may start a Unicode identifier if and only if
+     * one of the following conditions is true:
+     * <ul>
+     * <li> {@link #isLetter(int) isLetter(codePoint)}
+     *      returns {@code true}
+     * <li> {@link #getType(int) getType(codePoint)}
+     *      returns {@code LETTER_NUMBER}.
+     * </ul>
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character may start a Unicode
+     *          identifier; {@code false} otherwise.
+     * @see     Character#isJavaIdentifierStart(int)
+     * @see     Character#isLetter(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUnicodeIdentifierStart(int codePoint) {
+        return CharacterData.of(codePoint).isUnicodeIdentifierStart(codePoint);
+    }
+    */
+    public static boolean isUnicodeIdentifierStart(int codePoint) {
+        return isUnicodeIdentifierStartImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isUnicodeIdentifierStartImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character may be part of a Unicode
+     * identifier as other than the first character.
+     * <p>
+     * A character may be part of a Unicode identifier if and only if
+     * one of the following statements is true:
+     * <ul>
+     * <li>  it is a letter
+     * <li>  it is a connecting punctuation character (such as {@code '_'})
+     * <li>  it is a digit
+     * <li>  it is a numeric letter (such as a Roman numeral character)
+     * <li>  it is a combining mark
+     * <li>  it is a non-spacing mark
+     * <li> {@code isIdentifierIgnorable} returns
+     * {@code true} for this character.
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isUnicodeIdentifierPart(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  {@code true} if the character may be part of a
+     *          Unicode identifier; {@code false} otherwise.
+     * @see     Character#isIdentifierIgnorable(char)
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isLetterOrDigit(char)
+     * @see     Character#isUnicodeIdentifierStart(char)
+     * @since   1.1
+     */
+    public static boolean isUnicodeIdentifierPart(char ch) {
+        return isUnicodeIdentifierPart((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) may be part of a Unicode
+     * identifier as other than the first character.
+     * <p>
+     * A character may be part of a Unicode identifier if and only if
+     * one of the following statements is true:
+     * <ul>
+     * <li>  it is a letter
+     * <li>  it is a connecting punctuation character (such as {@code '_'})
+     * <li>  it is a digit
+     * <li>  it is a numeric letter (such as a Roman numeral character)
+     * <li>  it is a combining mark
+     * <li>  it is a non-spacing mark
+     * <li> {@code isIdentifierIgnorable} returns
+     * {@code true} for this character.
+     * </ul>
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character may be part of a
+     *          Unicode identifier; {@code false} otherwise.
+     * @see     Character#isIdentifierIgnorable(int)
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isLetterOrDigit(int)
+     * @see     Character#isUnicodeIdentifierStart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isUnicodeIdentifierPart(int codePoint) {
+        return CharacterData.of(codePoint).isUnicodeIdentifierPart(codePoint);
+    }
+    */
+    public static boolean isUnicodeIdentifierPart(int codePoint) {
+        return isUnicodeIdentifierPartImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isUnicodeIdentifierPartImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character should be regarded as
+     * an ignorable character in a Java identifier or a Unicode identifier.
+     * <p>
+     * The following Unicode characters are ignorable in a Java identifier
+     * or a Unicode identifier:
+     * <ul>
+     * <li>ISO control characters that are not whitespace
+     * <ul>
+     * <li>{@code '\u005Cu0000'} through {@code '\u005Cu0008'}
+     * <li>{@code '\u005Cu000E'} through {@code '\u005Cu001B'}
+     * <li>{@code '\u005Cu007F'} through {@code '\u005Cu009F'}
+     * </ul>
+     *
+     * <li>all characters that have the {@code FORMAT} general
+     * category value
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isIdentifierIgnorable(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  {@code true} if the character is an ignorable control
+     *          character that may be part of a Java or Unicode identifier;
+     *           {@code false} otherwise.
+     * @see     Character#isJavaIdentifierPart(char)
+     * @see     Character#isUnicodeIdentifierPart(char)
+     * @since   1.1
+     */
+    public static boolean isIdentifierIgnorable(char ch) {
+        return isIdentifierIgnorable((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) should be regarded as
+     * an ignorable character in a Java identifier or a Unicode identifier.
+     * <p>
+     * The following Unicode characters are ignorable in a Java identifier
+     * or a Unicode identifier:
+     * <ul>
+     * <li>ISO control characters that are not whitespace
+     * <ul>
+     * <li>{@code '\u005Cu0000'} through {@code '\u005Cu0008'}
+     * <li>{@code '\u005Cu000E'} through {@code '\u005Cu001B'}
+     * <li>{@code '\u005Cu007F'} through {@code '\u005Cu009F'}
+     * </ul>
+     *
+     * <li>all characters that have the {@code FORMAT} general
+     * category value
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is an ignorable control
+     *          character that may be part of a Java or Unicode identifier;
+     *          {@code false} otherwise.
+     * @see     Character#isJavaIdentifierPart(int)
+     * @see     Character#isUnicodeIdentifierPart(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isIdentifierIgnorable(int codePoint) {
+        return CharacterData.of(codePoint).isIdentifierIgnorable(codePoint);
+    }
+    */
+    public static boolean isIdentifierIgnorable(int codePoint) {
+        return isIdentifierIgnorableImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isIdentifierIgnorableImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Converts the character argument to lowercase using case
+     * mapping information from the UnicodeData file.
+     * <p>
+     * Note that
+     * {@code Character.isLowerCase(Character.toLowerCase(ch))}
+     * does not always return {@code true} for some ranges of
+     * characters, particularly those that are symbols or ideographs.
+     *
+     * <p>In general, {@link String#toLowerCase()} should be used to map
+     * characters to lowercase. {@code String} case mapping methods
+     * have several benefits over {@code Character} case mapping methods.
+     * {@code String} case mapping methods can perform locale-sensitive
+     * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+     * the {@code Character} case mapping methods cannot.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #toLowerCase(int)} method.
+     *
+     * @param   ch   the character to be converted.
+     * @return  the lowercase equivalent of the character, if any;
+     *          otherwise, the character itself.
+     * @see     Character#isLowerCase(char)
+     * @see     String#toLowerCase()
+     */
+    public static char toLowerCase(char ch) {
+        return (char)toLowerCase((int)ch);
+    }
+
+    /**
+     * Converts the character (Unicode code point) argument to
+     * lowercase using case mapping information from the UnicodeData
+     * file.
+     *
+     * <p> Note that
+     * {@code Character.isLowerCase(Character.toLowerCase(codePoint))}
+     * does not always return {@code true} for some ranges of
+     * characters, particularly those that are symbols or ideographs.
+     *
+     * <p>In general, {@link String#toLowerCase()} should be used to map
+     * characters to lowercase. {@code String} case mapping methods
+     * have several benefits over {@code Character} case mapping methods.
+     * {@code String} case mapping methods can perform locale-sensitive
+     * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+     * the {@code Character} case mapping methods cannot.
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return  the lowercase equivalent of the character (Unicode code
+     *          point), if any; otherwise, the character itself.
+     * @see     Character#isLowerCase(int)
+     * @see     String#toLowerCase()
+     *
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toLowerCase(int codePoint) {
+        return CharacterData.of(codePoint).toLowerCase(codePoint);
+    }
+    */
+    public static int toLowerCase(int codePoint) {
+        if (codePoint >= 'A' && codePoint <= 'Z') {
+            return codePoint + ('a' - 'A');
+        }
+
+        // All ASCII codepoints except the ones above remain unchanged.
+        if (codePoint < 0x80) {
+            return codePoint;
+        }
+
+        return toLowerCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native int toLowerCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Converts the character argument to uppercase using case mapping
+     * information from the UnicodeData file.
+     * <p>
+     * Note that
+     * {@code Character.isUpperCase(Character.toUpperCase(ch))}
+     * does not always return {@code true} for some ranges of
+     * characters, particularly those that are symbols or ideographs.
+     *
+     * <p>In general, {@link String#toUpperCase()} should be used to map
+     * characters to uppercase. {@code String} case mapping methods
+     * have several benefits over {@code Character} case mapping methods.
+     * {@code String} case mapping methods can perform locale-sensitive
+     * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+     * the {@code Character} case mapping methods cannot.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #toUpperCase(int)} method.
+     *
+     * @param   ch   the character to be converted.
+     * @return  the uppercase equivalent of the character, if any;
+     *          otherwise, the character itself.
+     * @see     Character#isUpperCase(char)
+     * @see     String#toUpperCase()
+     */
+    public static char toUpperCase(char ch) {
+        return (char)toUpperCase((int)ch);
+    }
+
+    /**
+     * Converts the character (Unicode code point) argument to
+     * uppercase using case mapping information from the UnicodeData
+     * file.
+     *
+     * <p>Note that
+     * {@code Character.isUpperCase(Character.toUpperCase(codePoint))}
+     * does not always return {@code true} for some ranges of
+     * characters, particularly those that are symbols or ideographs.
+     *
+     * <p>In general, {@link String#toUpperCase()} should be used to map
+     * characters to uppercase. {@code String} case mapping methods
+     * have several benefits over {@code Character} case mapping methods.
+     * {@code String} case mapping methods can perform locale-sensitive
+     * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+     * the {@code Character} case mapping methods cannot.
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return  the uppercase equivalent of the character, if any;
+     *          otherwise, the character itself.
+     * @see     Character#isUpperCase(int)
+     * @see     String#toUpperCase()
+     *
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toUpperCase(int codePoint) {
+        return CharacterData.of(codePoint).toUpperCase(codePoint);
+    }
+    */
+    public static int toUpperCase(int codePoint) {
+        if (codePoint >= 'a' && codePoint <= 'z') {
+            return codePoint - ('a' - 'A');
+        }
+
+        // All ASCII codepoints except the ones above remain unchanged.
+        if (codePoint < 0x80) {
+            return codePoint;
+        }
+
+        return toUpperCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native int toUpperCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Converts the character argument to titlecase using case mapping
+     * information from the UnicodeData file. If a character has no
+     * explicit titlecase mapping and is not itself a titlecase char
+     * according to UnicodeData, then the uppercase mapping is
+     * returned as an equivalent titlecase mapping. If the
+     * {@code char} argument is already a titlecase
+     * {@code char}, the same {@code char} value will be
+     * returned.
+     * <p>
+     * Note that
+     * {@code Character.isTitleCase(Character.toTitleCase(ch))}
+     * does not always return {@code true} for some ranges of
+     * characters.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #toTitleCase(int)} method.
+     *
+     * @param   ch   the character to be converted.
+     * @return  the titlecase equivalent of the character, if any;
+     *          otherwise, the character itself.
+     * @see     Character#isTitleCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#toUpperCase(char)
+     * @since   1.0.2
+     */
+    public static char toTitleCase(char ch) {
+        return (char)toTitleCase((int)ch);
+    }
+
+    /**
+     * Converts the character (Unicode code point) argument to titlecase using case mapping
+     * information from the UnicodeData file. If a character has no
+     * explicit titlecase mapping and is not itself a titlecase char
+     * according to UnicodeData, then the uppercase mapping is
+     * returned as an equivalent titlecase mapping. If the
+     * character argument is already a titlecase
+     * character, the same character value will be
+     * returned.
+     *
+     * <p>Note that
+     * {@code Character.isTitleCase(Character.toTitleCase(codePoint))}
+     * does not always return {@code true} for some ranges of
+     * characters.
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return  the titlecase equivalent of the character, if any;
+     *          otherwise, the character itself.
+     * @see     Character#isTitleCase(int)
+     * @see     Character#toLowerCase(int)
+     * @see     Character#toUpperCase(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int toTitleCase(int codePoint) {
+        return CharacterData.of(codePoint).toTitleCase(codePoint);
+    }
+    */
+    public static int toTitleCase(int codePoint) {
+        return toTitleCaseImpl(codePoint);
+    }
+
+    @FastNative
+    static native int toTitleCaseImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Returns the numeric value of the character {@code ch} in the
+     * specified radix.
+     * <p>
+     * If the radix is not in the range {@code MIN_RADIX} &le;
+     * {@code radix} &le; {@code MAX_RADIX} or if the
+     * value of {@code ch} is not a valid digit in the specified
+     * radix, {@code -1} is returned. A character is a valid digit
+     * if at least one of the following is true:
+     * <ul>
+     * <li>The method {@code isDigit} is {@code true} of the character
+     *     and the Unicode decimal digit value of the character (or its
+     *     single-character decomposition) is less than the specified radix.
+     *     In this case the decimal digit value is returned.
+     * <li>The character is one of the uppercase Latin letters
+     *     {@code 'A'} through {@code 'Z'} and its code is less than
+     *     {@code radix + 'A' - 10}.
+     *     In this case, {@code ch - 'A' + 10}
+     *     is returned.
+     * <li>The character is one of the lowercase Latin letters
+     *     {@code 'a'} through {@code 'z'} and its code is less than
+     *     {@code radix + 'a' - 10}.
+     *     In this case, {@code ch - 'a' + 10}
+     *     is returned.
+     * <li>The character is one of the fullwidth uppercase Latin letters A
+     *     ({@code '\u005CuFF21'}) through Z ({@code '\u005CuFF3A'})
+     *     and its code is less than
+     *     {@code radix + '\u005CuFF21' - 10}.
+     *     In this case, {@code ch - '\u005CuFF21' + 10}
+     *     is returned.
+     * <li>The character is one of the fullwidth lowercase Latin letters a
+     *     ({@code '\u005CuFF41'}) through z ({@code '\u005CuFF5A'})
+     *     and its code is less than
+     *     {@code radix + '\u005CuFF41' - 10}.
+     *     In this case, {@code ch - '\u005CuFF41' + 10}
+     *     is returned.
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #digit(int, int)} method.
+     *
+     * @param   ch      the character to be converted.
+     * @param   radix   the radix.
+     * @return  the numeric value represented by the character in the
+     *          specified radix.
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(char)
+     */
+    public static int digit(char ch, int radix) {
+        return digit((int)ch, radix);
+    }
+
+    /**
+     * Returns the numeric value of the specified character (Unicode
+     * code point) in the specified radix.
+     *
+     * <p>If the radix is not in the range {@code MIN_RADIX} &le;
+     * {@code radix} &le; {@code MAX_RADIX} or if the
+     * character is not a valid digit in the specified
+     * radix, {@code -1} is returned. A character is a valid digit
+     * if at least one of the following is true:
+     * <ul>
+     * <li>The method {@link #isDigit(int) isDigit(codePoint)} is {@code true} of the character
+     *     and the Unicode decimal digit value of the character (or its
+     *     single-character decomposition) is less than the specified radix.
+     *     In this case the decimal digit value is returned.
+     * <li>The character is one of the uppercase Latin letters
+     *     {@code 'A'} through {@code 'Z'} and its code is less than
+     *     {@code radix + 'A' - 10}.
+     *     In this case, {@code codePoint - 'A' + 10}
+     *     is returned.
+     * <li>The character is one of the lowercase Latin letters
+     *     {@code 'a'} through {@code 'z'} and its code is less than
+     *     {@code radix + 'a' - 10}.
+     *     In this case, {@code codePoint - 'a' + 10}
+     *     is returned.
+     * <li>The character is one of the fullwidth uppercase Latin letters A
+     *     ({@code '\u005CuFF21'}) through Z ({@code '\u005CuFF3A'})
+     *     and its code is less than
+     *     {@code radix + '\u005CuFF21' - 10}.
+     *     In this case,
+     *     {@code codePoint - '\u005CuFF21' + 10}
+     *     is returned.
+     * <li>The character is one of the fullwidth lowercase Latin letters a
+     *     ({@code '\u005CuFF41'}) through z ({@code '\u005CuFF5A'})
+     *     and its code is less than
+     *     {@code radix + '\u005CuFF41'- 10}.
+     *     In this case,
+     *     {@code codePoint - '\u005CuFF41' + 10}
+     *     is returned.
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be converted.
+     * @param   radix   the radix.
+     * @return  the numeric value represented by the character in the
+     *          specified radix.
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int digit(int codePoint, int radix) {
+        return CharacterData.of(codePoint).digit(codePoint, radix);
+    }
+    */
+    public static int digit(int codePoint, int radix) {
+        if (radix < MIN_RADIX || radix > MAX_RADIX) {
+            return -1;
+        }
+        if (codePoint < 128) {
+            // Optimized for ASCII
+            int result = -1;
+            if ('0' <= codePoint && codePoint <= '9') {
+                result = codePoint - '0';
+            } else if ('a' <= codePoint && codePoint <= 'z') {
+                result = 10 + (codePoint - 'a');
+            } else if ('A' <= codePoint && codePoint <= 'Z') {
+                result = 10 + (codePoint - 'A');
+            }
+            return result < radix ? result : -1;
+        }
+        return digitImpl(codePoint, radix);
+    }
+
+    @FastNative
+    native static int digitImpl(int codePoint, int radix);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Returns the {@code int} value that the specified Unicode
+     * character represents. For example, the character
+     * {@code '\u005Cu216C'} (the roman numeral fifty) will return
+     * an int with a value of 50.
+     * <p>
+     * The letters A-Z in their uppercase ({@code '\u005Cu0041'} through
+     * {@code '\u005Cu005A'}), lowercase
+     * ({@code '\u005Cu0061'} through {@code '\u005Cu007A'}), and
+     * full width variant ({@code '\u005CuFF21'} through
+     * {@code '\u005CuFF3A'} and {@code '\u005CuFF41'} through
+     * {@code '\u005CuFF5A'}) forms have numeric values from 10
+     * through 35. This is independent of the Unicode specification,
+     * which does not assign numeric values to these {@code char}
+     * values.
+     * <p>
+     * If the character does not have a numeric value, then -1 is returned.
+     * If the character has a numeric value that cannot be represented as a
+     * nonnegative integer (for example, a fractional value), then -2
+     * is returned.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #getNumericValue(int)} method.
+     *
+     * @param   ch      the character to be converted.
+     * @return  the numeric value of the character, as a nonnegative {@code int}
+     *           value; -2 if the character has a numeric value that is not a
+     *          nonnegative integer; -1 if the character has no numeric value.
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(char)
+     * @since   1.1
+     */
+    public static int getNumericValue(char ch) {
+        return getNumericValue((int)ch);
+    }
+
+    /**
+     * Returns the {@code int} value that the specified
+     * character (Unicode code point) represents. For example, the character
+     * {@code '\u005Cu216C'} (the Roman numeral fifty) will return
+     * an {@code int} with a value of 50.
+     * <p>
+     * The letters A-Z in their uppercase ({@code '\u005Cu0041'} through
+     * {@code '\u005Cu005A'}), lowercase
+     * ({@code '\u005Cu0061'} through {@code '\u005Cu007A'}), and
+     * full width variant ({@code '\u005CuFF21'} through
+     * {@code '\u005CuFF3A'} and {@code '\u005CuFF41'} through
+     * {@code '\u005CuFF5A'}) forms have numeric values from 10
+     * through 35. This is independent of the Unicode specification,
+     * which does not assign numeric values to these {@code char}
+     * values.
+     * <p>
+     * If the character does not have a numeric value, then -1 is returned.
+     * If the character has a numeric value that cannot be represented as a
+     * nonnegative integer (for example, a fractional value), then -2
+     * is returned.
+     *
+     * @param   codePoint the character (Unicode code point) to be converted.
+     * @return  the numeric value of the character, as a nonnegative {@code int}
+     *          value; -2 if the character has a numeric value that is not a
+     *          nonnegative integer; -1 if the character has no numeric value.
+     * @see     Character#forDigit(int, int)
+     * @see     Character#isDigit(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int getNumericValue(int codePoint) {
+        return CharacterData.of(codePoint).getNumericValue(codePoint);
+    }
+    */
+    public static int getNumericValue(int codePoint) {
+        // This is both an optimization and papers over differences between Java and ICU.
+        if (codePoint < 128) {
+            if (codePoint >= '0' && codePoint <= '9') {
+                return codePoint - '0';
+            }
+            if (codePoint >= 'a' && codePoint <= 'z') {
+                return codePoint - ('a' - 10);
+            }
+            if (codePoint >= 'A' && codePoint <= 'Z') {
+                return codePoint - ('A' - 10);
+            }
+            return -1;
+        }
+        // Full-width uppercase A-Z.
+        if (codePoint >= 0xff21 && codePoint <= 0xff3a) {
+            return codePoint - 0xff17;
+        }
+        // Full-width lowercase a-z.
+        if (codePoint >= 0xff41 && codePoint <= 0xff5a) {
+            return codePoint - 0xff37;
+        }
+        return getNumericValueImpl(codePoint);
+    }
+
+    @FastNative
+    native static int getNumericValueImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is ISO-LATIN-1 white space.
+     * This method returns {@code true} for the following five
+     * characters only:
+     * <table summary="truechars">
+     * <tr><td>{@code '\t'}</td>            <td>{@code U+0009}</td>
+     *     <td>{@code HORIZONTAL TABULATION}</td></tr>
+     * <tr><td>{@code '\n'}</td>            <td>{@code U+000A}</td>
+     *     <td>{@code NEW LINE}</td></tr>
+     * <tr><td>{@code '\f'}</td>            <td>{@code U+000C}</td>
+     *     <td>{@code FORM FEED}</td></tr>
+     * <tr><td>{@code '\r'}</td>            <td>{@code U+000D}</td>
+     *     <td>{@code CARRIAGE RETURN}</td></tr>
+     * <tr><td>{@code ' '}</td>             <td>{@code U+0020}</td>
+     *     <td>{@code SPACE}</td></tr>
+     * </table>
+     *
+     * @param      ch   the character to be tested.
+     * @return     {@code true} if the character is ISO-LATIN-1 white
+     *             space; {@code false} otherwise.
+     * @see        Character#isSpaceChar(char)
+     * @see        Character#isWhitespace(char)
+     * @deprecated Replaced by isWhitespace(char).
+     */
+    @Deprecated
+    public static boolean isSpace(char ch) {
+        return (ch <= 0x0020) &&
+            (((((1L << 0x0009) |
+            (1L << 0x000A) |
+            (1L << 0x000C) |
+            (1L << 0x000D) |
+            (1L << 0x0020)) >> ch) & 1L) != 0);
+    }
+
+
+    /**
+     * Determines if the specified character is a Unicode space character.
+     * A character is considered to be a space character if and only if
+     * it is specified to be a space character by the Unicode Standard. This
+     * method returns true if the character's general category type is any of
+     * the following:
+     * <ul>
+     * <li> {@code SPACE_SEPARATOR}
+     * <li> {@code LINE_SEPARATOR}
+     * <li> {@code PARAGRAPH_SEPARATOR}
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isSpaceChar(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  {@code true} if the character is a space character;
+     *          {@code false} otherwise.
+     * @see     Character#isWhitespace(char)
+     * @since   1.1
+     */
+    public static boolean isSpaceChar(char ch) {
+        return isSpaceChar((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is a
+     * Unicode space character.  A character is considered to be a
+     * space character if and only if it is specified to be a space
+     * character by the Unicode Standard. This method returns true if
+     * the character's general category type is any of the following:
+     *
+     * <ul>
+     * <li> {@link #SPACE_SEPARATOR}
+     * <li> {@link #LINE_SEPARATOR}
+     * <li> {@link #PARAGRAPH_SEPARATOR}
+     * </ul>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is a space character;
+     *          {@code false} otherwise.
+     * @see     Character#isWhitespace(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isSpaceChar(int codePoint) {
+        return ((((1 << Character.SPACE_SEPARATOR) |
+                  (1 << Character.LINE_SEPARATOR) |
+                  (1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
+            != 0;
+    }
+    */
+    public static boolean isSpaceChar(int codePoint) {
+        // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
+        // SPACE or NO-BREAK SPACE?
+        if (codePoint == 0x20 || codePoint == 0xa0) {
+            return true;
+        }
+        if (codePoint < 0x1000) {
+            return false;
+        }
+        // OGHAM SPACE MARK or MONGOLIAN VOWEL SEPARATOR?
+        if (codePoint == 0x1680 || codePoint == 0x180e) {
+            return true;
+        }
+        if (codePoint < 0x2000) {
+            return false;
+        }
+        if (codePoint <= 0xffff) {
+            // Other whitespace from General Punctuation...
+            return codePoint <= 0x200a || codePoint == 0x2028 || codePoint == 0x2029 || codePoint == 0x202f || codePoint == 0x205f ||
+                codePoint == 0x3000; // ...or CJK Symbols and Punctuation?
+        }
+        // Let icu4c worry about non-BMP code points.
+        return isSpaceCharImpl(codePoint);
+    }
+
+    @FastNative
+    static native boolean isSpaceCharImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is white space according to Java.
+     * A character is a Java whitespace character if and only if it satisfies
+     * one of the following criteria:
+     * <ul>
+     * <li> It is a Unicode space character ({@code SPACE_SEPARATOR},
+     *      {@code LINE_SEPARATOR}, or {@code PARAGRAPH_SEPARATOR})
+     *      but is not also a non-breaking space ({@code '\u005Cu00A0'},
+     *      {@code '\u005Cu2007'}, {@code '\u005Cu202F'}).
+     * <li> It is {@code '\u005Ct'}, U+0009 HORIZONTAL TABULATION.
+     * <li> It is {@code '\u005Cn'}, U+000A LINE FEED.
+     * <li> It is {@code '\u005Cu000B'}, U+000B VERTICAL TABULATION.
+     * <li> It is {@code '\u005Cf'}, U+000C FORM FEED.
+     * <li> It is {@code '\u005Cr'}, U+000D CARRIAGE RETURN.
+     * <li> It is {@code '\u005Cu001C'}, U+001C FILE SEPARATOR.
+     * <li> It is {@code '\u005Cu001D'}, U+001D GROUP SEPARATOR.
+     * <li> It is {@code '\u005Cu001E'}, U+001E RECORD SEPARATOR.
+     * <li> It is {@code '\u005Cu001F'}, U+001F UNIT SEPARATOR.
+     * </ul>
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isWhitespace(int)} method.
+     *
+     * @param   ch the character to be tested.
+     * @return  {@code true} if the character is a Java whitespace
+     *          character; {@code false} otherwise.
+     * @see     Character#isSpaceChar(char)
+     * @since   1.1
+     */
+    public static boolean isWhitespace(char ch) {
+        return isWhitespace((int)ch);
+    }
+
+    /**
+     * Determines if the specified character (Unicode code point) is
+     * white space according to Java.  A character is a Java
+     * whitespace character if and only if it satisfies one of the
+     * following criteria:
+     * <ul>
+     * <li> It is a Unicode space character ({@link #SPACE_SEPARATOR},
+     *      {@link #LINE_SEPARATOR}, or {@link #PARAGRAPH_SEPARATOR})
+     *      but is not also a non-breaking space ({@code '\u005Cu00A0'},
+     *      {@code '\u005Cu2007'}, {@code '\u005Cu202F'}).
+     * <li> It is {@code '\u005Ct'}, U+0009 HORIZONTAL TABULATION.
+     * <li> It is {@code '\u005Cn'}, U+000A LINE FEED.
+     * <li> It is {@code '\u005Cu000B'}, U+000B VERTICAL TABULATION.
+     * <li> It is {@code '\u005Cf'}, U+000C FORM FEED.
+     * <li> It is {@code '\u005Cr'}, U+000D CARRIAGE RETURN.
+     * <li> It is {@code '\u005Cu001C'}, U+001C FILE SEPARATOR.
+     * <li> It is {@code '\u005Cu001D'}, U+001D GROUP SEPARATOR.
+     * <li> It is {@code '\u005Cu001E'}, U+001E RECORD SEPARATOR.
+     * <li> It is {@code '\u005Cu001F'}, U+001F UNIT SEPARATOR.
+     * </ul>
+     * <p>
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is a Java whitespace
+     *          character; {@code false} otherwise.
+     * @see     Character#isSpaceChar(int)
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isWhitespace(int codePoint) {
+        return CharacterData.of(codePoint).isWhitespace(codePoint);
+    }
+    */
+    public static boolean isWhitespace(int codePoint) {
+        // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
+        // Any ASCII whitespace character?
+        if ((codePoint >= 0x1c && codePoint <= 0x20) || (codePoint >= 0x09 && codePoint <= 0x0d)) {
+            return true;
+        }
+        if (codePoint < 0x1000) {
+            return false;
+        }
+        // OGHAM SPACE MARK or MONGOLIAN VOWEL SEPARATOR?
+        if (codePoint == 0x1680 || codePoint == 0x180e) {
+            return true;
+        }
+        if (codePoint < 0x2000) {
+            return false;
+        }
+        // Exclude General Punctuation's non-breaking spaces (which includes FIGURE SPACE).
+        if (codePoint == 0x2007 || codePoint == 0x202f) {
+            return false;
+        }
+        if (codePoint <= 0xffff) {
+            // Other whitespace from General Punctuation...
+            return codePoint <= 0x200a || codePoint == 0x2028 || codePoint == 0x2029 || codePoint == 0x205f ||
+                codePoint == 0x3000; // ...or CJK Symbols and Punctuation?
+        }
+        // Let icu4c worry about non-BMP code points.
+        return isWhitespaceImpl(codePoint);
+    }
+
+    @FastNative
+    native static boolean isWhitespaceImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines if the specified character is an ISO control
+     * character.  A character is considered to be an ISO control
+     * character if its code is in the range {@code '\u005Cu0000'}
+     * through {@code '\u005Cu001F'} or in the range
+     * {@code '\u005Cu007F'} through {@code '\u005Cu009F'}.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isISOControl(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  {@code true} if the character is an ISO control character;
+     *          {@code false} otherwise.
+     *
+     * @see     Character#isSpaceChar(char)
+     * @see     Character#isWhitespace(char)
+     * @since   1.1
+     */
+    public static boolean isISOControl(char ch) {
+        return isISOControl((int)ch);
+    }
+
+    /**
+     * Determines if the referenced character (Unicode code point) is an ISO control
+     * character.  A character is considered to be an ISO control
+     * character if its code is in the range {@code '\u005Cu0000'}
+     * through {@code '\u005Cu001F'} or in the range
+     * {@code '\u005Cu007F'} through {@code '\u005Cu009F'}.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is an ISO control character;
+     *          {@code false} otherwise.
+     * @see     Character#isSpaceChar(int)
+     * @see     Character#isWhitespace(int)
+     * @since   1.5
+     */
+    public static boolean isISOControl(int codePoint) {
+        // Optimized form of:
+        //     (codePoint >= 0x00 && codePoint <= 0x1F) ||
+        //     (codePoint >= 0x7F && codePoint <= 0x9F);
+        return codePoint <= 0x9F &&
+            (codePoint >= 0x7F || (codePoint >>> 5 == 0));
+    }
+
+    /**
+     * Returns a value indicating a character's general category.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #getType(int)} method.
+     *
+     * @param   ch      the character to be tested.
+     * @return  a value of type {@code int} representing the
+     *          character's general category.
+     * @see     Character#COMBINING_SPACING_MARK
+     * @see     Character#CONNECTOR_PUNCTUATION
+     * @see     Character#CONTROL
+     * @see     Character#CURRENCY_SYMBOL
+     * @see     Character#DASH_PUNCTUATION
+     * @see     Character#DECIMAL_DIGIT_NUMBER
+     * @see     Character#ENCLOSING_MARK
+     * @see     Character#END_PUNCTUATION
+     * @see     Character#FINAL_QUOTE_PUNCTUATION
+     * @see     Character#FORMAT
+     * @see     Character#INITIAL_QUOTE_PUNCTUATION
+     * @see     Character#LETTER_NUMBER
+     * @see     Character#LINE_SEPARATOR
+     * @see     Character#LOWERCASE_LETTER
+     * @see     Character#MATH_SYMBOL
+     * @see     Character#MODIFIER_LETTER
+     * @see     Character#MODIFIER_SYMBOL
+     * @see     Character#NON_SPACING_MARK
+     * @see     Character#OTHER_LETTER
+     * @see     Character#OTHER_NUMBER
+     * @see     Character#OTHER_PUNCTUATION
+     * @see     Character#OTHER_SYMBOL
+     * @see     Character#PARAGRAPH_SEPARATOR
+     * @see     Character#PRIVATE_USE
+     * @see     Character#SPACE_SEPARATOR
+     * @see     Character#START_PUNCTUATION
+     * @see     Character#SURROGATE
+     * @see     Character#TITLECASE_LETTER
+     * @see     Character#UNASSIGNED
+     * @see     Character#UPPERCASE_LETTER
+     * @since   1.1
+     */
+    public static int getType(char ch) {
+        return getType((int)ch);
+    }
+
+    /**
+     * Returns a value indicating a character's general category.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  a value of type {@code int} representing the
+     *          character's general category.
+     * @see     Character#COMBINING_SPACING_MARK COMBINING_SPACING_MARK
+     * @see     Character#CONNECTOR_PUNCTUATION CONNECTOR_PUNCTUATION
+     * @see     Character#CONTROL CONTROL
+     * @see     Character#CURRENCY_SYMBOL CURRENCY_SYMBOL
+     * @see     Character#DASH_PUNCTUATION DASH_PUNCTUATION
+     * @see     Character#DECIMAL_DIGIT_NUMBER DECIMAL_DIGIT_NUMBER
+     * @see     Character#ENCLOSING_MARK ENCLOSING_MARK
+     * @see     Character#END_PUNCTUATION END_PUNCTUATION
+     * @see     Character#FINAL_QUOTE_PUNCTUATION FINAL_QUOTE_PUNCTUATION
+     * @see     Character#FORMAT FORMAT
+     * @see     Character#INITIAL_QUOTE_PUNCTUATION INITIAL_QUOTE_PUNCTUATION
+     * @see     Character#LETTER_NUMBER LETTER_NUMBER
+     * @see     Character#LINE_SEPARATOR LINE_SEPARATOR
+     * @see     Character#LOWERCASE_LETTER LOWERCASE_LETTER
+     * @see     Character#MATH_SYMBOL MATH_SYMBOL
+     * @see     Character#MODIFIER_LETTER MODIFIER_LETTER
+     * @see     Character#MODIFIER_SYMBOL MODIFIER_SYMBOL
+     * @see     Character#NON_SPACING_MARK NON_SPACING_MARK
+     * @see     Character#OTHER_LETTER OTHER_LETTER
+     * @see     Character#OTHER_NUMBER OTHER_NUMBER
+     * @see     Character#OTHER_PUNCTUATION OTHER_PUNCTUATION
+     * @see     Character#OTHER_SYMBOL OTHER_SYMBOL
+     * @see     Character#PARAGRAPH_SEPARATOR PARAGRAPH_SEPARATOR
+     * @see     Character#PRIVATE_USE PRIVATE_USE
+     * @see     Character#SPACE_SEPARATOR SPACE_SEPARATOR
+     * @see     Character#START_PUNCTUATION START_PUNCTUATION
+     * @see     Character#SURROGATE SURROGATE
+     * @see     Character#TITLECASE_LETTER TITLECASE_LETTER
+     * @see     Character#UNASSIGNED UNASSIGNED
+     * @see     Character#UPPERCASE_LETTER UPPERCASE_LETTER
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static int getType(int codePoint) {
+        return CharacterData.of(codePoint).getType(codePoint);
+    }
+    */
+    public static int getType(int codePoint) {
+        int type = getTypeImpl(codePoint);
+        // The type values returned by ICU are not RI-compatible. The RI skips the value 17.
+        if (type <= Character.FORMAT) {
+            return type;
+        }
+        return (type + 1);
+    }
+
+    @FastNative
+    static native int getTypeImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines the character representation for a specific digit in
+     * the specified radix. If the value of {@code radix} is not a
+     * valid radix, or the value of {@code digit} is not a valid
+     * digit in the specified radix, the null character
+     * ({@code '\u005Cu0000'}) is returned.
+     * <p>
+     * The {@code radix} argument is valid if it is greater than or
+     * equal to {@code MIN_RADIX} and less than or equal to
+     * {@code MAX_RADIX}. The {@code digit} argument is valid if
+     * {@code 0 <= digit < radix}.
+     * <p>
+     * If the digit is less than 10, then
+     * {@code '0' + digit} is returned. Otherwise, the value
+     * {@code 'a' + digit - 10} is returned.
+     *
+     * @param   digit   the number to convert to a character.
+     * @param   radix   the radix.
+     * @return  the {@code char} representation of the specified digit
+     *          in the specified radix.
+     * @see     Character#MIN_RADIX
+     * @see     Character#MAX_RADIX
+     * @see     Character#digit(char, int)
+     */
+    public static char forDigit(int digit, int radix) {
+        if ((digit >= radix) || (digit < 0)) {
+            return '\0';
+        }
+        if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
+            return '\0';
+        }
+        if (digit < 10) {
+            return (char)('0' + digit);
+        }
+        return (char)('a' - 10 + digit);
+    }
+
+    /**
+     * Returns the Unicode directionality property for the given
+     * character.  Character directionality is used to calculate the
+     * visual ordering of text. The directionality value of undefined
+     * {@code char} values is {@code DIRECTIONALITY_UNDEFINED}.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #getDirectionality(int)} method.
+     *
+     * @param  ch {@code char} for which the directionality property
+     *            is requested.
+     * @return the directionality property of the {@code char} value.
+     *
+     * @see Character#DIRECTIONALITY_UNDEFINED
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+     * @see Character#DIRECTIONALITY_ARABIC_NUMBER
+     * @see Character#DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+     * @see Character#DIRECTIONALITY_NONSPACING_MARK
+     * @see Character#DIRECTIONALITY_BOUNDARY_NEUTRAL
+     * @see Character#DIRECTIONALITY_PARAGRAPH_SEPARATOR
+     * @see Character#DIRECTIONALITY_SEGMENT_SEPARATOR
+     * @see Character#DIRECTIONALITY_WHITESPACE
+     * @see Character#DIRECTIONALITY_OTHER_NEUTRALS
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+     * @see Character#DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+     * @since 1.4
+     */
+    public static byte getDirectionality(char ch) {
+        return getDirectionality((int)ch);
+    }
+
+    /**
+     * Returns the Unicode directionality property for the given
+     * character (Unicode code point).  Character directionality is
+     * used to calculate the visual ordering of text. The
+     * directionality value of undefined character is {@link
+     * #DIRECTIONALITY_UNDEFINED}.
+     *
+     * @param   codePoint the character (Unicode code point) for which
+     *          the directionality property is requested.
+     * @return the directionality property of the character.
+     *
+     * @see Character#DIRECTIONALITY_UNDEFINED DIRECTIONALITY_UNDEFINED
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT DIRECTIONALITY_LEFT_TO_RIGHT
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT DIRECTIONALITY_RIGHT_TO_LEFT
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER DIRECTIONALITY_EUROPEAN_NUMBER
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+     * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+     * @see Character#DIRECTIONALITY_ARABIC_NUMBER DIRECTIONALITY_ARABIC_NUMBER
+     * @see Character#DIRECTIONALITY_COMMON_NUMBER_SEPARATOR DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+     * @see Character#DIRECTIONALITY_NONSPACING_MARK DIRECTIONALITY_NONSPACING_MARK
+     * @see Character#DIRECTIONALITY_BOUNDARY_NEUTRAL DIRECTIONALITY_BOUNDARY_NEUTRAL
+     * @see Character#DIRECTIONALITY_PARAGRAPH_SEPARATOR DIRECTIONALITY_PARAGRAPH_SEPARATOR
+     * @see Character#DIRECTIONALITY_SEGMENT_SEPARATOR DIRECTIONALITY_SEGMENT_SEPARATOR
+     * @see Character#DIRECTIONALITY_WHITESPACE DIRECTIONALITY_WHITESPACE
+     * @see Character#DIRECTIONALITY_OTHER_NEUTRALS DIRECTIONALITY_OTHER_NEUTRALS
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+     * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+     * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+     * @see Character#DIRECTIONALITY_POP_DIRECTIONAL_FORMAT DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+     * @since    1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static byte getDirectionality(int codePoint) {
+        return CharacterData.of(codePoint).getDirectionality(codePoint);
+    }
+    */
+    public static byte getDirectionality(int codePoint) {
+        if (getType(codePoint) == Character.UNASSIGNED) {
+            return Character.DIRECTIONALITY_UNDEFINED;
+        }
+
+        byte directionality = getDirectionalityImpl(codePoint);
+        if (directionality >= 0 && directionality < DIRECTIONALITY.length) {
+            return DIRECTIONALITY[directionality];
+        }
+        return Character.DIRECTIONALITY_UNDEFINED;
+    }
+
+    @FastNative
+    native static byte getDirectionalityImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Determines whether the character is mirrored according to the
+     * Unicode specification.  Mirrored characters should have their
+     * glyphs horizontally mirrored when displayed in text that is
+     * right-to-left.  For example, {@code '\u005Cu0028'} LEFT
+     * PARENTHESIS is semantically defined to be an <i>opening
+     * parenthesis</i>.  This will appear as a "(" in text that is
+     * left-to-right but as a ")" in text that is right-to-left.
+     *
+     * <p><b>Note:</b> This method cannot handle <a
+     * href="#supplementary"> supplementary characters</a>. To support
+     * all Unicode characters, including supplementary characters, use
+     * the {@link #isMirrored(int)} method.
+     *
+     * @param  ch {@code char} for which the mirrored property is requested
+     * @return {@code true} if the char is mirrored, {@code false}
+     *         if the {@code char} is not mirrored or is not defined.
+     * @since 1.4
+     */
+    public static boolean isMirrored(char ch) {
+        return isMirrored((int)ch);
+    }
+
+    /**
+     * Determines whether the specified character (Unicode code point)
+     * is mirrored according to the Unicode specification.  Mirrored
+     * characters should have their glyphs horizontally mirrored when
+     * displayed in text that is right-to-left.  For example,
+     * {@code '\u005Cu0028'} LEFT PARENTHESIS is semantically
+     * defined to be an <i>opening parenthesis</i>.  This will appear
+     * as a "(" in text that is left-to-right but as a ")" in text
+     * that is right-to-left.
+     *
+     * @param   codePoint the character (Unicode code point) to be tested.
+     * @return  {@code true} if the character is mirrored, {@code false}
+     *          if the character is not mirrored or is not defined.
+     * @since   1.5
+     */
+    // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+    /*
+    public static boolean isMirrored(int codePoint) {
+        return CharacterData.of(codePoint).isMirrored(codePoint);
+    }
+    */
+    public static boolean isMirrored(int codePoint) {
+        return isMirroredImpl(codePoint);
+    }
+
+    @FastNative
+    native static boolean isMirroredImpl(int codePoint);
+    // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+    /**
+     * Compares two {@code Character} objects numerically.
+     *
+     * @param   anotherCharacter   the {@code Character} to be compared.
+
+     * @return  the value {@code 0} if the argument {@code Character}
+     *          is equal to this {@code Character}; a value less than
+     *          {@code 0} if this {@code Character} is numerically less
+     *          than the {@code Character} argument; and a value greater than
+     *          {@code 0} if this {@code Character} is numerically greater
+     *          than the {@code Character} argument (unsigned comparison).
+     *          Note that this is strictly a numerical comparison; it is not
+     *          locale-dependent.
+     * @since   1.2
+     */
+    public int compareTo(Character anotherCharacter) {
+        return compare(this.value, anotherCharacter.value);
+    }
+
+    /**
+     * Compares two {@code char} values numerically.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Character.valueOf(x).compareTo(Character.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code char} to compare
+     * @param  y the second {@code char} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code x < y}; and
+     *         a value greater than {@code 0} if {@code x > y}
+     * @since 1.7
+     */
+    public static int compare(char x, char y) {
+        return x - y;
+    }
+
+    // BEGIN Android-removed: Use ICU.
+    /**
+     * Converts the character (Unicode code point) argument to uppercase using
+     * information from the UnicodeData file.
+     * <p>
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return  either the uppercase equivalent of the character, if
+     *          any, or an error flag ({@code Character.ERROR})
+     *          that indicates that a 1:M {@code char} mapping exists.
+     * @see     Character#isLowerCase(char)
+     * @see     Character#isUpperCase(char)
+     * @see     Character#toLowerCase(char)
+     * @see     Character#toTitleCase(char)
+     * @since 1.4
+     *
+    static int toUpperCaseEx(int codePoint) {
+        assert isValidCodePoint(codePoint);
+        return CharacterData.of(codePoint).toUpperCaseEx(codePoint);
+    }
+
+    /**
+     * Converts the character (Unicode code point) argument to uppercase using case
+     * mapping information from the SpecialCasing file in the Unicode
+     * specification. If a character has no explicit uppercase
+     * mapping, then the {@code char} itself is returned in the
+     * {@code char[]}.
+     *
+     * @param   codePoint   the character (Unicode code point) to be converted.
+     * @return a {@code char[]} with the uppercased character.
+     * @since 1.4
+     *
+    static char[] toUpperCaseCharArray(int codePoint) {
+        // As of Unicode 6.0, 1:M uppercasings only happen in the BMP.
+        assert isBmpCodePoint(codePoint);
+        return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
+    }
+    */
+    // END Android-removed: Use ICU.
+
+    /**
+     * The number of bits used to represent a <tt>char</tt> value in unsigned
+     * binary form, constant {@code 16}.
+     *
+     * @since 1.5
+     */
+    public static final int SIZE = 16;
+
+    /**
+     * The number of bytes used to represent a {@code char} value in unsigned
+     * binary form.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * Returns the value obtained by reversing the order of the bytes in the
+     * specified <tt>char</tt> value.
+     *
+     * @param ch The {@code char} of which to reverse the byte order.
+     * @return the value obtained by reversing (or, equivalently, swapping)
+     *     the bytes in the specified <tt>char</tt> value.
+     * @since 1.5
+     */
+    public static char reverseBytes(char ch) {
+        return (char) (((ch & 0xFF00) >> 8) | (ch << 8));
+    }
+
+    /**
+     * Returns the Unicode name of the specified character
+     * {@code codePoint}, or null if the code point is
+     * {@link #UNASSIGNED unassigned}.
+     * <p>
+     * Note: if the specified character is not assigned a name by
+     * the <i>UnicodeData</i> file (part of the Unicode Character
+     * Database maintained by the Unicode Consortium), the returned
+     * name is the same as the result of expression.
+     *
+     * <blockquote>{@code
+     *     Character.UnicodeBlock.of(codePoint).toString().replace('_', ' ')
+     *     + " "
+     *     + Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+     *
+     * }</blockquote>
+     *
+     * @param  codePoint the character (Unicode code point)
+     *
+     * @return the Unicode name of the specified character, or null if
+     *         the code point is unassigned.
+     *
+     * @exception IllegalArgumentException if the specified
+     *            {@code codePoint} is not a valid Unicode
+     *            code point.
+     *
+     * @since 1.7
+     */
+    public static String getName(int codePoint) {
+        if (!isValidCodePoint(codePoint)) {
+            throw new IllegalArgumentException();
+        }
+        // Android-changed: Use ICU.
+        // String name = CharacterName.get(codePoint);
+        String name = getNameImpl(codePoint);
+        if (name != null)
+            return name;
+        if (getType(codePoint) == UNASSIGNED)
+            return null;
+        UnicodeBlock block = UnicodeBlock.of(codePoint);
+        if (block != null)
+            return block.toString().replace('_', ' ') + " "
+                   + Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+        // should never come here
+        return Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+    }
+
+    // Android-added: Use ICU.
+    // Implement getNameImpl() natively.
+    private static native String getNameImpl(int codePoint);
+}
diff --git a/java/lang/Class.annotated.java b/java/lang/Class.annotated.java
new file mode 100644
index 0000000..fd80abb
--- /dev/null
+++ b/java/lang/Class.annotated.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2014, 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.TypeVariable;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.io.InputStream;
+import java.util.HashMap;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Class<T> implements java.io.Serializable, java.lang.reflect.GenericDeclaration, java.lang.reflect.Type, java.lang.reflect.AnnotatedElement {
+
+Class() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String className) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String name, boolean initialize, java.lang.ClassLoader loader) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public native T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+public boolean isInstance(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isAssignableFrom(java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); }
+
+public boolean isInterface() { throw new RuntimeException("Stub!"); }
+
+public boolean isArray() { throw new RuntimeException("Stub!"); }
+
+public boolean isPrimitive() { throw new RuntimeException("Stub!"); }
+
+public boolean isFinalizable() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotation() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getClassLoader() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<? super T> getSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type getGenericSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public java.lang.String getPackageName$() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?>[] getInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?> getComponentType() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object[] getSigners() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getEnclosingMethod() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?> getEnclosingConstructor() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?> getDeclaringClass();
+
+public native java.lang.Class<?> getEnclosingClass();
+
+public java.lang.String getSimpleName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getCanonicalName() { throw new RuntimeException("Stub!"); }
+
+public native boolean isAnonymousClass();
+
+public boolean isLocalClass() { throw new RuntimeException("Stub!"); }
+
+public boolean isMemberClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?>[] getClasses() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field getField(java.lang.String name) throws java.lang.NoSuchFieldException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getDeclaredClasses();
+
+public native java.lang.reflect.Field[] getDeclaredFields();
+
[email protected]
+public native java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
[email protected]
+public native java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.reflect.Field getDeclaredField(java.lang.String name) throws java.lang.NoSuchFieldException;
+
+public java.lang.reflect.Method getDeclaredMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getInstanceMethod(java.lang.String name, java.lang.Class<?>[] parameterTypes) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getDeclaredConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.io.InputStream getResourceAsStream(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.net.URL getResource(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.security.ProtectionDomain getProtectionDomain() { throw new RuntimeException("Stub!"); }
+
+public boolean desiredAssertionStatus() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnum() { throw new RuntimeException("Stub!"); }
+
+public T[] getEnumConstants() { throw new RuntimeException("Stub!"); }
+
+public T[] getEnumConstantsShared() { throw new RuntimeException("Stub!"); }
+
+public T cast(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public <U> java.lang.Class<? extends U> asSubclass(java.lang.Class<U> clazz) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public native <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(java.lang.Class<A> annotationClass);
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+
+public boolean isProxy() { throw new RuntimeException("Stub!"); }
+
+public int getAccessFlags() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/Class.java b/java/lang/Class.java
new file mode 100644
index 0000000..f792248
--- /dev/null
+++ b/java/lang/Class.java
@@ -0,0 +1,2675 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2014, 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;
+
+import dalvik.annotation.optimization.FastNative;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.InternalNames;
+import libcore.reflect.Types;
+import libcore.util.BasicLruCache;
+import libcore.util.CollectionUtils;
+import libcore.util.EmptyArray;
+
+import dalvik.system.ClassExt;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+
+/**
+ * Instances of the class {@code Class} represent classes and
+ * interfaces in a running Java application.  An enum is a kind of
+ * class and an annotation is a kind of interface.  Every array also
+ * belongs to a class that is reflected as a {@code Class} object
+ * that is shared by all arrays with the same element type and number
+ * of dimensions.  The primitive Java types ({@code boolean},
+ * {@code byte}, {@code char}, {@code short},
+ * {@code int}, {@code long}, {@code float}, and
+ * {@code double}), and the keyword {@code void} are also
+ * represented as {@code Class} objects.
+ *
+ * <p> {@code Class} has no public constructor. Instead {@code Class}
+ * objects are constructed automatically by the Java Virtual Machine as classes
+ * are loaded and by calls to the {@code defineClass} method in the class
+ * loader.
+ *
+ * <p> The following example uses a {@code Class} object to print the
+ * class name of an object:
+ *
+ * <blockquote><pre>
+ *     void printClassName(Object obj) {
+ *         System.out.println("The class of " + obj +
+ *                            " is " + obj.getClass().getName());
+ *     }
+ * </pre></blockquote>
+ *
+ * <p> It is also possible to get the {@code Class} object for a named
+ * type (or for void) using a class literal.  See Section 15.8.2 of
+ * <cite>The Java&trade; Language Specification</cite>.
+ * For example:
+ *
+ * <blockquote>
+ *     {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
+ * </blockquote>
+ *
+ * @param <T> the type of the class modeled by this {@code Class}
+ * object.  For example, the type of {@code String.class} is {@code
+ * Class<String>}.  Use {@code Class<?>} if the class being modeled is
+ * unknown.
+ *
+ * @author  unascribed
+ * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
+ * @since   JDK1.0
+ */
+public final class Class<T> implements java.io.Serializable,
+                              GenericDeclaration,
+                              Type,
+                              AnnotatedElement {
+    private static final int ANNOTATION= 0x00002000;
+    private static final int ENUM      = 0x00004000;
+    private static final int SYNTHETIC = 0x00001000;
+    private static final int FINALIZABLE = 0x80000000;
+
+    /** defining class loader, or null for the "bootstrap" system loader. */
+    private transient ClassLoader classLoader;
+
+    /**
+     * For array classes, the component class object for instanceof/checkcast (for String[][][],
+     * this will be String[][]). null for non-array classes.
+     */
+    private transient Class<?> componentType;
+
+    /**
+     * DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
+     * e.g. arrays and primitive classes.
+     */
+    private transient Object dexCache;
+
+    /**
+     * Extra data that only some classes possess. This is allocated lazily as needed.
+     */
+    private transient ClassExt extData;
+
+    /**
+     * The interface table (iftable_) contains pairs of a interface class and an array of the
+     * interface methods. There is one pair per interface supported by this class.  That
+     * means one pair for each interface we support directly, indirectly via superclass, or
+     * indirectly via a superinterface.  This will be null if neither we nor our superclass
+     * implement any interfaces.
+     *
+     * Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
+     * Invoke faceObj.blah(), where "blah" is part of the Face interface.  We can't easily use a
+     * single vtable.
+     *
+     * For every interface a concrete class implements, we create an array of the concrete vtable_
+     * methods for the methods in the interface.
+     */
+    private transient Object[] ifTable;
+
+    /** Lazily computed name of this class; always prefer calling getName(). */
+    private transient String name;
+
+    /** The superclass, or null if this is java.lang.Object, an interface or primitive type. */
+    private transient Class<? super T> superClass;
+
+    /**
+     * Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass
+     * is copied in, and virtual methods from our class either replace those from the super or are
+     * appended. For abstract classes, methods may be created in the vtable that aren't in
+     * virtual_ methods_ for miranda methods.
+     */
+    private transient Object vtable;
+
+    /**
+     * Instance fields. These describe the layout of the contents of an Object. Note that only the
+     * fields directly declared by this class are listed in iFields; fields declared by a
+     * superclass are listed in the superclass's Class.iFields.
+     *
+     * All instance fields that refer to objects are guaranteed to be at the beginning of the field
+     * list.  {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
+     */
+    private transient long iFields;
+
+    /** All methods with this class as the base for virtual dispatch. */
+    private transient long methods;
+
+    /** Static fields */
+    private transient long sFields;
+
+    /** access flags; low 16 bits are defined by VM spec */
+    private transient int accessFlags;
+
+    /** Class flags to help the GC with object scanning. */
+    private transient int classFlags;
+
+    /**
+     * Total size of the Class instance; used when allocating storage on GC heap.
+     * See also {@link Class#objectSize}.
+     */
+    private transient int classSize;
+
+    /**
+     * tid used to check for recursive static initializer invocation.
+     */
+    private transient int clinitThreadId;
+
+    /**
+     * Class def index from dex file. An index of 65535 indicates that there is no class definition,
+     * for example for an array type.
+     * TODO: really 16bits as type indices are 16bit.
+     */
+    private transient int dexClassDefIndex;
+
+    /**
+     * Class type index from dex file, lazily computed. An index of 65535 indicates that the type
+     * index isn't known. Volatile to avoid double-checked locking bugs.
+     * TODO: really 16bits as type indices are 16bit.
+     */
+    private transient volatile int dexTypeIndex;
+
+    /** Number of instance fields that are object references. */
+    private transient int numReferenceInstanceFields;
+
+    /** Number of static fields that are object references. */
+    private transient int numReferenceStaticFields;
+
+    /**
+     * Total object size; used when allocating storage on GC heap. For interfaces and abstract
+     * classes this will be zero. See also {@link Class#classSize}.
+     */
+    private transient int objectSize;
+
+    /**
+     * Aligned object size for allocation fast path. The value is max int if the object is
+     * uninitialized or finalizable, otherwise the aligned object size.
+     */
+    private transient int objectSizeAllocFastPath;
+
+    /**
+     * The lower 16 bits is the primitive type value, or 0 if not a primitive type; set for
+     * generated primitive classes.
+     */
+    private transient int primitiveType;
+
+    /** Bitmap of offsets of iFields. */
+    private transient int referenceInstanceOffsets;
+
+    /** State of class initialization */
+    private transient int status;
+
+    /** Offset of the first virtual method copied from an interface in the methods array. */
+    private transient short copiedMethodsOffset;
+
+    /** Offset of the first virtual method defined in this class in the methods array. */
+    private transient short virtualMethodsOffset;
+
+    /*
+     * Private constructor. Only the Java Virtual Machine creates Class objects.
+     * This constructor is not used and prevents the default constructor being
+     * generated.
+     */
+    private Class() {}
+
+
+    /**
+     * Converts the object to a string. The string representation is the
+     * string "class" or "interface", followed by a space, and then by the
+     * fully qualified name of the class in the format returned by
+     * {@code getName}.  If this {@code Class} object represents a
+     * primitive type, this method returns the name of the primitive type.  If
+     * this {@code Class} object represents void this method returns
+     * "void".
+     *
+     * @return a string representation of this class object.
+     */
+    public String toString() {
+        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+            + getName();
+    }
+
+    /**
+     * Returns a string describing this {@code Class}, including
+     * information about modifiers and type parameters.
+     *
+     * The string is formatted as a list of type modifiers, if any,
+     * followed by the kind of type (empty string for primitive types
+     * and {@code class}, {@code enum}, {@code interface}, or
+     * <code>&#64;</code>{@code interface}, as appropriate), followed
+     * by the type's name, followed by an angle-bracketed
+     * comma-separated list of the type's type parameters, if any.
+     *
+     * A space is used to separate modifiers from one another and to
+     * separate any modifiers from the kind of type. The modifiers
+     * occur in canonical order. If there are no type parameters, the
+     * type parameter list is elided.
+     *
+     * <p>Note that since information about the runtime representation
+     * of a type is being generated, modifiers not present on the
+     * originating source code or illegal on the originating source
+     * code may be present.
+     *
+     * @return a string describing this {@code Class}, including
+     * information about modifiers and type parameters
+     *
+     * @since 1.8
+     */
+    public String toGenericString() {
+        if (isPrimitive()) {
+            return toString();
+        } else {
+            StringBuilder sb = new StringBuilder();
+
+            // Class modifiers are a superset of interface modifiers
+            int modifiers = getModifiers() & Modifier.classModifiers();
+            if (modifiers != 0) {
+                sb.append(Modifier.toString(modifiers));
+                sb.append(' ');
+            }
+
+            if (isAnnotation()) {
+                sb.append('@');
+            }
+            if (isInterface()) { // Note: all annotation types are interfaces
+                sb.append("interface");
+            } else {
+                if (isEnum())
+                    sb.append("enum");
+                else
+                    sb.append("class");
+            }
+            sb.append(' ');
+            sb.append(getName());
+
+            TypeVariable<?>[] typeparms = getTypeParameters();
+            if (typeparms.length > 0) {
+                boolean first = true;
+                sb.append('<');
+                for(TypeVariable<?> typeparm: typeparms) {
+                    if (!first)
+                        sb.append(',');
+                    sb.append(typeparm.getTypeName());
+                    first = false;
+                }
+                sb.append('>');
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Returns the {@code Class} object associated with the class or
+     * interface with the given string name.  Invoking this method is
+     * equivalent to:
+     *
+     * <blockquote>
+     *  {@code Class.forName(className, true, currentLoader)}
+     * </blockquote>
+     *
+     * where {@code currentLoader} denotes the defining class loader of
+     * the current class.
+     *
+     * <p> For example, the following code fragment returns the
+     * runtime {@code Class} descriptor for the class named
+     * {@code java.lang.Thread}:
+     *
+     * <blockquote>
+     *   {@code Class t = Class.forName("java.lang.Thread")}
+     * </blockquote>
+     * <p>
+     * A call to {@code forName("X")} causes the class named
+     * {@code X} to be initialized.
+     *
+     * @param      className   the fully qualified name of the desired class.
+     * @return     the {@code Class} object for the class with the
+     *             specified name.
+     * @exception LinkageError if the linkage fails
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *            by this method fails
+     * @exception ClassNotFoundException if the class cannot be located
+     */
+    @CallerSensitive
+    public static Class<?> forName(String className)
+                throws ClassNotFoundException {
+        Class<?> caller = Reflection.getCallerClass();
+        return forName(className, true, ClassLoader.getClassLoader(caller));
+    }
+
+
+    /**
+     * Returns the {@code Class} object associated with the class or
+     * interface with the given string name, using the given class loader.
+     * Given the fully qualified name for a class or interface (in the same
+     * format returned by {@code getName}) this method attempts to
+     * locate, load, and link the class or interface.  The specified class
+     * loader is used to load the class or interface.  If the parameter
+     * {@code loader} is null, the class is loaded through the bootstrap
+     * class loader.  The class is initialized only if the
+     * {@code initialize} parameter is {@code true} and if it has
+     * not been initialized earlier.
+     *
+     * <p> If {@code name} denotes a primitive type or void, an attempt
+     * will be made to locate a user-defined class in the unnamed package whose
+     * name is {@code name}. Therefore, this method cannot be used to
+     * obtain any of the {@code Class} objects representing primitive
+     * types or void.
+     *
+     * <p> If {@code name} denotes an array class, the component type of
+     * the array class is loaded but not initialized.
+     *
+     * <p> For example, in an instance method the expression:
+     *
+     * <blockquote>
+     *  {@code Class.forName("Foo")}
+     * </blockquote>
+     *
+     * is equivalent to:
+     *
+     * <blockquote>
+     *  {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
+     * </blockquote>
+     *
+     * Note that this method throws errors related to loading, linking or
+     * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
+     * Java Language Specification</em>.
+     * Note that this method does not check whether the requested class
+     * is accessible to its caller.
+     *
+     * <p> If the {@code loader} is {@code null}, and a security
+     * manager is present, and the caller's class loader is not null, then this
+     * method calls the security manager's {@code checkPermission} method
+     * with a {@code RuntimePermission("getClassLoader")} permission to
+     * ensure it's ok to access the bootstrap class loader.
+     *
+     * @param name       fully qualified name of the desired class
+     * @param initialize if {@code true} the class will be initialized.
+     *                   See Section 12.4 of <em>The Java Language Specification</em>.
+     * @param loader     class loader from which the class must be loaded
+     * @return           class object representing the desired class
+     *
+     * @exception LinkageError if the linkage fails
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *            by this method fails
+     * @exception ClassNotFoundException if the class cannot be located by
+     *            the specified class loader
+     *
+     * @see       java.lang.Class#forName(String)
+     * @see       java.lang.ClassLoader
+     * @since     1.2
+     */
+    @CallerSensitive
+    public static Class<?> forName(String name, boolean initialize,
+                                   ClassLoader loader)
+        throws ClassNotFoundException
+    {
+        if (loader == null) {
+            loader = BootClassLoader.getInstance();
+        }
+        Class<?> result;
+        try {
+            result = classForName(name, initialize, loader);
+        } catch (ClassNotFoundException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof LinkageError) {
+                throw (LinkageError) cause;
+            }
+            throw e;
+        }
+        return result;
+    }
+
+    /** Called after security checks have been made. */
+    @FastNative
+    static native Class<?> classForName(String className, boolean shouldInitialize,
+            ClassLoader classLoader) throws ClassNotFoundException;
+
+    /**
+     * Creates a new instance of the class represented by this {@code Class}
+     * object.  The class is instantiated as if by a {@code new}
+     * expression with an empty argument list.  The class is initialized if it
+     * has not already been initialized.
+     *
+     * <p>Note that this method propagates any exception thrown by the
+     * nullary constructor, including a checked exception.  Use of
+     * this method effectively bypasses the compile-time exception
+     * checking that would otherwise be performed by the compiler.
+     * The {@link
+     * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
+     * Constructor.newInstance} method avoids this problem by wrapping
+     * any exception thrown by the constructor in a (checked) {@link
+     * java.lang.reflect.InvocationTargetException}.
+     *
+     * @return  a newly allocated instance of the class represented by this
+     *          object.
+     * @throws  IllegalAccessException  if the class or its nullary
+     *          constructor is not accessible.
+     * @throws  InstantiationException
+     *          if this {@code Class} represents an abstract class,
+     *          an interface, an array class, a primitive type, or void;
+     *          or if the class has no nullary constructor;
+     *          or if the instantiation fails for some other reason.
+     * @throws  ExceptionInInitializerError if the initialization
+     *          provoked by this method fails.
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and
+     *          the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class.
+     */
+    @FastNative
+    public native T newInstance() throws InstantiationException, IllegalAccessException;
+
+    /**
+     * Determines if the specified {@code Object} is assignment-compatible
+     * with the object represented by this {@code Class}.  This method is
+     * the dynamic equivalent of the Java language {@code instanceof}
+     * operator. The method returns {@code true} if the specified
+     * {@code Object} argument is non-null and can be cast to the
+     * reference type represented by this {@code Class} object without
+     * raising a {@code ClassCastException.} It returns {@code false}
+     * otherwise.
+     *
+     * <p> Specifically, if this {@code Class} object represents a
+     * declared class, this method returns {@code true} if the specified
+     * {@code Object} argument is an instance of the represented class (or
+     * of any of its subclasses); it returns {@code false} otherwise. If
+     * this {@code Class} object represents an array class, this method
+     * returns {@code true} if the specified {@code Object} argument
+     * can be converted to an object of the array class by an identity
+     * conversion or by a widening reference conversion; it returns
+     * {@code false} otherwise. If this {@code Class} object
+     * represents an interface, this method returns {@code true} if the
+     * class or any superclass of the specified {@code Object} argument
+     * implements this interface; it returns {@code false} otherwise. If
+     * this {@code Class} object represents a primitive type, this method
+     * returns {@code false}.
+     *
+     * @param   obj the object to check
+     * @return  true if {@code obj} is an instance of this class
+     *
+     * @since JDK1.1
+     */
+    public boolean isInstance(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        return isAssignableFrom(obj.getClass());
+    }
+
+
+    /**
+     * Determines if the class or interface represented by this
+     * {@code Class} object is either the same as, or is a superclass or
+     * superinterface of, the class or interface represented by the specified
+     * {@code Class} parameter. It returns {@code true} if so;
+     * otherwise it returns {@code false}. If this {@code Class}
+     * object represents a primitive type, this method returns
+     * {@code true} if the specified {@code Class} parameter is
+     * exactly this {@code Class} object; otherwise it returns
+     * {@code false}.
+     *
+     * <p> Specifically, this method tests whether the type represented by the
+     * specified {@code Class} parameter can be converted to the type
+     * represented by this {@code Class} object via an identity conversion
+     * or via a widening reference conversion. See <em>The Java Language
+     * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
+     *
+     * @param cls the {@code Class} object to be checked
+     * @return the {@code boolean} value indicating whether objects of the
+     * type {@code cls} can be assigned to objects of this class
+     * @exception NullPointerException if the specified Class parameter is
+     *            null.
+     * @since JDK1.1
+     */
+    public boolean isAssignableFrom(Class<?> cls) {
+        if (this == cls) {
+            return true;  // Can always assign to things of the same type.
+        } else if (this == Object.class) {
+            return !cls.isPrimitive();  // Can assign any reference to java.lang.Object.
+        } else if (isArray()) {
+            return cls.isArray() && componentType.isAssignableFrom(cls.componentType);
+        } else if (isInterface()) {
+            // Search iftable which has a flattened and uniqued list of interfaces.
+            Object[] iftable = cls.ifTable;
+            if (iftable != null) {
+                for (int i = 0; i < iftable.length; i += 2) {
+                    if (iftable[i] == this) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } else {
+            if (!cls.isInterface()) {
+                for (cls = cls.superClass; cls != null; cls = cls.superClass) {
+                    if (cls == this) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Determines if the specified {@code Class} object represents an
+     * interface type.
+     *
+     * @return  {@code true} if this object represents an interface;
+     *          {@code false} otherwise.
+     */
+    public boolean isInterface() {
+        return (accessFlags & Modifier.INTERFACE) != 0;
+    }
+
+    /**
+     * Determines if this {@code Class} object represents an array class.
+     *
+     * @return  {@code true} if this object represents an array class;
+     *          {@code false} otherwise.
+     * @since   JDK1.1
+     */
+    public boolean isArray() {
+        return getComponentType() != null;
+    }
+
+    /**
+     * Determines if the specified {@code Class} object represents a
+     * primitive type.
+     *
+     * <p> There are nine predefined {@code Class} objects to represent
+     * the eight primitive types and void.  These are created by the Java
+     * Virtual Machine, and have the same names as the primitive types that
+     * they represent, namely {@code boolean}, {@code byte},
+     * {@code char}, {@code short}, {@code int},
+     * {@code long}, {@code float}, and {@code double}.
+     *
+     * <p> These objects may only be accessed via the following public static
+     * final variables, and are the only {@code Class} objects for which
+     * this method returns {@code true}.
+     *
+     * @return true if and only if this class represents a primitive type
+     *
+     * @see     java.lang.Boolean#TYPE
+     * @see     java.lang.Character#TYPE
+     * @see     java.lang.Byte#TYPE
+     * @see     java.lang.Short#TYPE
+     * @see     java.lang.Integer#TYPE
+     * @see     java.lang.Long#TYPE
+     * @see     java.lang.Float#TYPE
+     * @see     java.lang.Double#TYPE
+     * @see     java.lang.Void#TYPE
+     * @since JDK1.1
+     */
+    public boolean isPrimitive() {
+      return (primitiveType & 0xFFFF) != 0;
+    }
+
+    /**
+     * Indicates whether this {@code Class} or its parents override finalize.
+     *
+     * @return {@code true} if and if this class or its parents override
+     *         finalize;
+     *
+     * @hide
+     */
+    public boolean isFinalizable() {
+        return (getModifiers() & FINALIZABLE) != 0;
+    }
+
+    /**
+     * Returns true if this {@code Class} object represents an annotation
+     * type.  Note that if this method returns true, {@link #isInterface()}
+     * would also return true, as all annotation types are also interfaces.
+     *
+     * @return {@code true} if this class object represents an annotation
+     *      type; {@code false} otherwise
+     * @since 1.5
+     */
+    public boolean isAnnotation() {
+        return (getModifiers() & ANNOTATION) != 0;
+    }
+
+    /**
+     * Returns {@code true} if this class is a synthetic class;
+     * returns {@code false} otherwise.
+     * @return {@code true} if and only if this class is a synthetic class as
+     *         defined by the Java Language Specification.
+     * @jls 13.1 The Form of a Binary
+     * @since 1.5
+     */
+    public boolean isSynthetic() {
+        return (getModifiers() & SYNTHETIC) != 0;
+    }
+
+    /**
+     * Returns the  name of the entity (class, interface, array class,
+     * primitive type, or void) represented by this {@code Class} object,
+     * as a {@code String}.
+     *
+     * <p> If this class object represents a reference type that is not an
+     * array type then the binary name of the class is returned, as specified
+     * by
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * <p> If this class object represents a primitive type or void, then the
+     * name returned is a {@code String} equal to the Java language
+     * keyword corresponding to the primitive type or void.
+     *
+     * <p> If this class object represents a class of arrays, then the internal
+     * form of the name consists of the name of the element type preceded by
+     * one or more '{@code [}' characters representing the depth of the array
+     * nesting.  The encoding of element type names is as follows:
+     *
+     * <blockquote><table summary="Element types and encodings">
+     * <tr><th> Element Type <th> &nbsp;&nbsp;&nbsp; <th> Encoding
+     * <tr><td> boolean      <td> &nbsp;&nbsp;&nbsp; <td align=center> Z
+     * <tr><td> byte         <td> &nbsp;&nbsp;&nbsp; <td align=center> B
+     * <tr><td> char         <td> &nbsp;&nbsp;&nbsp; <td align=center> C
+     * <tr><td> class or interface
+     *                       <td> &nbsp;&nbsp;&nbsp; <td align=center> L<i>classname</i>;
+     * <tr><td> double       <td> &nbsp;&nbsp;&nbsp; <td align=center> D
+     * <tr><td> float        <td> &nbsp;&nbsp;&nbsp; <td align=center> F
+     * <tr><td> int          <td> &nbsp;&nbsp;&nbsp; <td align=center> I
+     * <tr><td> long         <td> &nbsp;&nbsp;&nbsp; <td align=center> J
+     * <tr><td> short        <td> &nbsp;&nbsp;&nbsp; <td align=center> S
+     * </table></blockquote>
+     *
+     * <p> The class or interface name <i>classname</i> is the binary name of
+     * the class specified above.
+     *
+     * <p> Examples:
+     * <blockquote><pre>
+     * String.class.getName()
+     *     returns "java.lang.String"
+     * byte.class.getName()
+     *     returns "byte"
+     * (new Object[3]).getClass().getName()
+     *     returns "[Ljava.lang.Object;"
+     * (new int[3][4][5][6][7][8][9]).getClass().getName()
+     *     returns "[[[[[[[I"
+     * </pre></blockquote>
+     *
+     * @return  the name of the class or interface
+     *          represented by this object.
+     */
+    public String getName() {
+        String name = this.name;
+        if (name == null)
+            this.name = name = getNameNative();
+        return name;
+    }
+
+    @FastNative
+    private native String getNameNative();
+
+    /**
+     * Returns the class loader for the class.  Some implementations may use
+     * null to represent the bootstrap class loader. This method will return
+     * null in such implementations if this class was loaded by the bootstrap
+     * class loader.
+     *
+     * <p> If a security manager is present, and the caller's class loader is
+     * not null and the caller's class loader is not the same as or an ancestor of
+     * the class loader for the class whose class loader is requested, then
+     * this method calls the security manager's {@code checkPermission}
+     * method with a {@code RuntimePermission("getClassLoader")}
+     * permission to ensure it's ok to access the class loader for the class.
+     *
+     * <p>If this object
+     * represents a primitive type or void, null is returned.
+     *
+     * @return  the class loader that loaded the class or interface
+     *          represented by this object.
+     * @throws SecurityException
+     *    if a security manager exists and its
+     *    {@code checkPermission} method denies
+     *    access to the class loader for the class.
+     * @see java.lang.ClassLoader
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     */
+    public ClassLoader getClassLoader() {
+        if (isPrimitive()) {
+            return null;
+        }
+        // Android-note: The RI returns null in the case where Android returns BootClassLoader.
+        // Noted in http://b/111850480#comment3
+        return (classLoader == null) ? BootClassLoader.getInstance() : classLoader;
+    }
+
+    /**
+     * Returns an array of {@code TypeVariable} objects that represent the
+     * type variables declared by the generic declaration represented by this
+     * {@code GenericDeclaration} object, in declaration order.  Returns an
+     * array of length 0 if the underlying generic declaration declares no type
+     * variables.
+     *
+     * @return an array of {@code TypeVariable} objects that represent
+     *     the type variables declared by this generic declaration
+     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
+     *     signature of this generic declaration does not conform to
+     *     the format specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @since 1.5
+     */
+    @Override
+    public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
+        String annotationSignature = getSignatureAttribute();
+        if (annotationSignature == null) {
+            return EmptyArray.TYPE_VARIABLE;
+        }
+        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+        parser.parseForClass(this, annotationSignature);
+        return parser.formalTypeParameters;
+    }
+
+
+    /**
+     * Returns the {@code Class} representing the superclass of the entity
+     * (class, interface, primitive type or void) represented by this
+     * {@code Class}.  If this {@code Class} represents either the
+     * {@code Object} class, an interface, a primitive type, or void, then
+     * null is returned.  If this object represents an array class then the
+     * {@code Class} object representing the {@code Object} class is
+     * returned.
+     *
+     * @return the superclass of the class represented by this object.
+     */
+    public Class<? super T> getSuperclass() {
+        // For interfaces superClass is Object (which agrees with the JNI spec)
+        // but not with the expected behavior here.
+        if (isInterface()) {
+            return null;
+        } else {
+            return superClass;
+        }
+    }
+
+    /**
+     * Returns the {@code Type} representing the direct superclass of
+     * the entity (class, interface, primitive type or void) represented by
+     * this {@code Class}.
+     *
+     * <p>If the superclass is a parameterized type, the {@code Type}
+     * object returned must accurately reflect the actual type
+     * parameters used in the source code. The parameterized type
+     * representing the superclass is created if it had not been
+     * created before. See the declaration of {@link
+     * java.lang.reflect.ParameterizedType ParameterizedType} for the
+     * semantics of the creation process for parameterized types.  If
+     * this {@code Class} represents either the {@code Object}
+     * class, an interface, a primitive type, or void, then null is
+     * returned.  If this object represents an array class then the
+     * {@code Class} object representing the {@code Object} class is
+     * returned.
+     *
+     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
+     *     class signature does not conform to the format specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if the generic superclass
+     *     refers to a non-existent type declaration
+     * @throws java.lang.reflect.MalformedParameterizedTypeException if the
+     *     generic superclass refers to a parameterized type that cannot be
+     *     instantiated  for any reason
+     * @return the superclass of the class represented by this object
+     * @since 1.5
+     */
+    public Type getGenericSuperclass() {
+        Type genericSuperclass = getSuperclass();
+        // This method is specified to return null for all cases where getSuperclass
+        // returns null, i.e, for primitives, interfaces, void and java.lang.Object.
+        if (genericSuperclass == null) {
+            return null;
+        }
+
+        String annotationSignature = getSignatureAttribute();
+        if (annotationSignature != null) {
+            GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+            parser.parseForClass(this, annotationSignature);
+            genericSuperclass = parser.superclassType;
+        }
+        return Types.getType(genericSuperclass);
+    }
+
+    /**
+     * Gets the package for this class.  The class loader of this class is used
+     * to find the package.  If the class was loaded by the bootstrap class
+     * loader the set of packages loaded from CLASSPATH is searched to find the
+     * package of the class. Null is returned if no package object was created
+     * by the class loader of this class.
+     *
+     * <p> Packages have attributes for versions and specifications only if the
+     * information was defined in the manifests that accompany the classes, and
+     * if the class loader created the package instance with the attributes
+     * from the manifest.
+     *
+     * @return the package of the class, or null if no package
+     *         information is available from the archive or codebase.
+     */
+    public Package getPackage() {
+        ClassLoader loader = getClassLoader();
+        if (loader != null) {
+            String packageName = getPackageName$();
+            return packageName != null ? loader.getPackage(packageName) : null;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the package name of this class. This returns null for classes in
+     * the default package.
+     *
+     * @hide
+     */
+    public String getPackageName$() {
+        String name = getName();
+        int last = name.lastIndexOf('.');
+        return last == -1 ? null : name.substring(0, last);
+    }
+
+
+    /**
+     * Determines the interfaces implemented by the class or interface
+     * represented by this object.
+     *
+     * <p> If this object represents a class, the return value is an array
+     * containing objects representing all interfaces implemented by the
+     * class. The order of the interface objects in the array corresponds to
+     * the order of the interface names in the {@code implements} clause
+     * of the declaration of the class represented by this object. For
+     * example, given the declaration:
+     * <blockquote>
+     * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
+     * </blockquote>
+     * suppose the value of {@code s} is an instance of
+     * {@code Shimmer}; the value of the expression:
+     * <blockquote>
+     * {@code s.getClass().getInterfaces()[0]}
+     * </blockquote>
+     * is the {@code Class} object that represents interface
+     * {@code FloorWax}; and the value of:
+     * <blockquote>
+     * {@code s.getClass().getInterfaces()[1]}
+     * </blockquote>
+     * is the {@code Class} object that represents interface
+     * {@code DessertTopping}.
+     *
+     * <p> If this object represents an interface, the array contains objects
+     * representing all interfaces extended by the interface. The order of the
+     * interface objects in the array corresponds to the order of the interface
+     * names in the {@code extends} clause of the declaration of the
+     * interface represented by this object.
+     *
+     * <p> If this object represents a class or interface that implements no
+     * interfaces, the method returns an array of length 0.
+     *
+     * <p> If this object represents a primitive type or void, the method
+     * returns an array of length 0.
+     *
+     * <p> If this {@code Class} object represents an array type, the
+     * interfaces {@code Cloneable} and {@code java.io.Serializable} are
+     * returned in that order.
+     *
+     * @return an array of interfaces implemented by this class.
+     */
+    public Class<?>[] getInterfaces() {
+        if (isArray()) {
+            return new Class<?>[] { Cloneable.class, Serializable.class };
+        }
+
+        final Class<?>[] ifaces = getInterfacesInternal();
+        if (ifaces == null) {
+            return EmptyArray.CLASS;
+        }
+
+        return ifaces;
+    }
+
+    @FastNative
+    private native Class<?>[] getInterfacesInternal();
+
+
+    /**
+     * Returns the {@code Type}s representing the interfaces
+     * directly implemented by the class or interface represented by
+     * this object.
+     *
+     * <p>If a superinterface is a parameterized type, the
+     * {@code Type} object returned for it must accurately reflect
+     * the actual type parameters used in the source code. The
+     * parameterized type representing each superinterface is created
+     * if it had not been created before. See the declaration of
+     * {@link java.lang.reflect.ParameterizedType ParameterizedType}
+     * for the semantics of the creation process for parameterized
+     * types.
+     *
+     * <p> If this object represents a class, the return value is an
+     * array containing objects representing all interfaces
+     * implemented by the class. The order of the interface objects in
+     * the array corresponds to the order of the interface names in
+     * the {@code implements} clause of the declaration of the class
+     * represented by this object.  In the case of an array class, the
+     * interfaces {@code Cloneable} and {@code Serializable} are
+     * returned in that order.
+     *
+     * <p>If this object represents an interface, the array contains
+     * objects representing all interfaces directly extended by the
+     * interface.  The order of the interface objects in the array
+     * corresponds to the order of the interface names in the
+     * {@code extends} clause of the declaration of the interface
+     * represented by this object.
+     *
+     * <p>If this object represents a class or interface that
+     * implements no interfaces, the method returns an array of length
+     * 0.
+     *
+     * <p>If this object represents a primitive type or void, the
+     * method returns an array of length 0.
+     *
+     * @throws java.lang.reflect.GenericSignatureFormatError
+     *     if the generic class signature does not conform to the format
+     *     specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if any of the generic
+     *     superinterfaces refers to a non-existent type declaration
+     * @throws java.lang.reflect.MalformedParameterizedTypeException
+     *     if any of the generic superinterfaces refer to a parameterized
+     *     type that cannot be instantiated for any reason
+     * @return an array of interfaces implemented by this class
+     * @since 1.5
+     */
+    public Type[] getGenericInterfaces() {
+        Type[] result;
+        synchronized (Caches.genericInterfaces) {
+            result = Caches.genericInterfaces.get(this);
+            if (result == null) {
+                String annotationSignature = getSignatureAttribute();
+                if (annotationSignature == null) {
+                    result = getInterfaces();
+                } else {
+                    GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+                    parser.parseForClass(this, annotationSignature);
+                    result = Types.getTypeArray(parser.interfaceTypes, false);
+                }
+                Caches.genericInterfaces.put(this, result);
+            }
+        }
+        return (result.length == 0) ? result : result.clone();
+    }
+
+
+    /**
+     * Returns the {@code Class} representing the component type of an
+     * array.  If this class does not represent an array class this method
+     * returns null.
+     *
+     * @return the {@code Class} representing the component type of this
+     * class if this class is an array
+     * @see     java.lang.reflect.Array
+     * @since JDK1.1
+     */
+    public Class<?> getComponentType() {
+      return componentType;
+    }
+
+    /**
+     * Returns the Java language modifiers for this class or interface, encoded
+     * in an integer. The modifiers consist of the Java Virtual Machine's
+     * constants for {@code public}, {@code protected},
+     * {@code private}, {@code final}, {@code static},
+     * {@code abstract} and {@code interface}; they should be decoded
+     * using the methods of class {@code Modifier}.
+     *
+     * <p> If the underlying class is an array class, then its
+     * {@code public}, {@code private} and {@code protected}
+     * modifiers are the same as those of its component type.  If this
+     * {@code Class} represents a primitive type or void, its
+     * {@code public} modifier is always {@code true}, and its
+     * {@code protected} and {@code private} modifiers are always
+     * {@code false}. If this object represents an array class, a
+     * primitive type or void, then its {@code final} modifier is always
+     * {@code true} and its interface modifier is always
+     * {@code false}. The values of its other modifiers are not determined
+     * by this specification.
+     *
+     * <p> The modifier encodings are defined in <em>The Java Virtual Machine
+     * Specification</em>, table 4.1.
+     *
+     * @return the {@code int} representing the modifiers for this class
+     * @see     java.lang.reflect.Modifier
+     * @since JDK1.1
+     */
+    public int getModifiers() {
+        // Array classes inherit modifiers from their component types, but in the case of arrays
+        // of an inner class, the class file may contain "fake" access flags because it's not valid
+        // for a top-level class to private, say. The real access flags are stored in the InnerClass
+        // attribute, so we need to make sure we drill down to the inner class: the accessFlags
+        // field is not the value we want to return, and the synthesized array class does not itself
+        // have an InnerClass attribute. https://code.google.com/p/android/issues/detail?id=56267
+        if (isArray()) {
+            int componentModifiers = getComponentType().getModifiers();
+            if ((componentModifiers & Modifier.INTERFACE) != 0) {
+                componentModifiers &= ~(Modifier.INTERFACE | Modifier.STATIC);
+            }
+            return Modifier.ABSTRACT | Modifier.FINAL | componentModifiers;
+        }
+        int JAVA_FLAGS_MASK = 0xffff;
+        int modifiers = this.getInnerClassFlags(accessFlags & JAVA_FLAGS_MASK);
+        return modifiers & JAVA_FLAGS_MASK;
+    }
+
+    /**
+     * Gets the signers of this class.
+     *
+     * @return  the signers of this class, or null if there are no signers.  In
+     *          particular, this method returns null if this object represents
+     *          a primitive type or void.
+     * @since   JDK1.1
+     */
+    public Object[] getSigners() {
+        return null;
+    }
+
+    @FastNative
+    private native Method getEnclosingMethodNative();
+
+    /**
+     * If this {@code Class} object represents a local or anonymous
+     * class within a method, returns a {@link
+     * java.lang.reflect.Method Method} object representing the
+     * immediately enclosing method of the underlying class. Returns
+     * {@code null} otherwise.
+     *
+     * In particular, this method returns {@code null} if the underlying
+     * class is a local or anonymous class immediately enclosed by a type
+     * declaration, instance initializer or static initializer.
+     *
+     * @return the immediately enclosing method of the underlying class, if
+     *     that class is a local or anonymous class; otherwise {@code null}.
+     * @since 1.5
+     */
+    // Android-changed: Removed SecurityException
+    public Method getEnclosingMethod() {
+        if (classNameImpliesTopLevel()) {
+            return null;
+        }
+        return getEnclosingMethodNative();
+    }
+
+    /**
+     * If this {@code Class} object represents a local or anonymous
+     * class within a constructor, returns a {@link
+     * java.lang.reflect.Constructor Constructor} object representing
+     * the immediately enclosing constructor of the underlying
+     * class. Returns {@code null} otherwise.  In particular, this
+     * method returns {@code null} if the underlying class is a local
+     * or anonymous class immediately enclosed by a type declaration,
+     * instance initializer or static initializer.
+     *
+     * @return the immediately enclosing constructor of the underlying class, if
+     *     that class is a local or anonymous class; otherwise {@code null}.
+     * @since 1.5
+     */
+    // Android-changed: Removed SecurityException
+    public Constructor<?> getEnclosingConstructor() {
+        if (classNameImpliesTopLevel()) {
+            return null;
+        }
+        return getEnclosingConstructorNative();
+    }
+
+    @FastNative
+    private native Constructor<?> getEnclosingConstructorNative();
+
+    private boolean classNameImpliesTopLevel() {
+        return !getName().contains("$");
+    }
+
+
+    /**
+     * If the class or interface represented by this {@code Class} object
+     * is a member of another class, returns the {@code Class} object
+     * representing the class in which it was declared.  This method returns
+     * null if this class or interface is not a member of any other class.  If
+     * this {@code Class} object represents an array class, a primitive
+     * type, or void,then this method returns null.
+     *
+     * @return the declaring class for this class
+     * @since JDK1.1
+     */
+    // Android-changed: Removed SecurityException
+    @FastNative
+    public native Class<?> getDeclaringClass();
+
+    /**
+     * Returns the immediately enclosing class of the underlying
+     * class.  If the underlying class is a top level class this
+     * method returns {@code null}.
+     * @return the immediately enclosing class of the underlying class
+     * @since 1.5
+     */
+    // Android-changed: Removed SecurityException
+    @FastNative
+    public native Class<?> getEnclosingClass();
+
+    /**
+     * Returns the simple name of the underlying class as given in the
+     * source code. Returns an empty string if the underlying class is
+     * anonymous.
+     *
+     * <p>The simple name of an array is the simple name of the
+     * component type with "[]" appended.  In particular the simple
+     * name of an array whose component type is anonymous is "[]".
+     *
+     * @return the simple name of the underlying class
+     * @since 1.5
+     */
+    public String getSimpleName() {
+        if (isArray())
+            return getComponentType().getSimpleName()+"[]";
+
+        if (isAnonymousClass()) {
+            return "";
+        }
+
+        if (isMemberClass() || isLocalClass()) {
+            // Note that we obtain this information from getInnerClassName(), which uses
+            // dex system annotations to obtain the name. It is possible for this information
+            // to disagree with the actual enclosing class name. For example, if dex
+            // manipulation tools have renamed the enclosing class without adjusting
+            // the system annotation to match. See http://b/28800927.
+            return getInnerClassName();
+        }
+
+        String simpleName = getName();
+        final int dot = simpleName.lastIndexOf(".");
+        if (dot > 0) {
+            return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
+        }
+
+        return simpleName;
+    }
+
+    /**
+     * Return an informative string for the name of this type.
+     *
+     * @return an informative string for the name of this type
+     * @since 1.8
+     */
+    public String getTypeName() {
+        if (isArray()) {
+            try {
+                Class<?> cl = this;
+                int dimensions = 0;
+                while (cl.isArray()) {
+                    dimensions++;
+                    cl = cl.getComponentType();
+                }
+                StringBuilder sb = new StringBuilder();
+                sb.append(cl.getName());
+                for (int i = 0; i < dimensions; i++) {
+                    sb.append("[]");
+                }
+                return sb.toString();
+            } catch (Throwable e) { /*FALLTHRU*/ }
+        }
+        return getName();
+    }
+
+    /**
+     * Returns the canonical name of the underlying class as
+     * defined by the Java Language Specification.  Returns null if
+     * the underlying class does not have a canonical name (i.e., if
+     * it is a local or anonymous class or an array whose component
+     * type does not have a canonical name).
+     * @return the canonical name of the underlying class if it exists, and
+     * {@code null} otherwise.
+     * @since 1.5
+     */
+    public String getCanonicalName() {
+        if (isArray()) {
+            String canonicalName = getComponentType().getCanonicalName();
+            if (canonicalName != null)
+                return canonicalName + "[]";
+            else
+                return null;
+        }
+        if (isLocalOrAnonymousClass())
+            return null;
+        Class<?> enclosingClass = getEnclosingClass();
+        if (enclosingClass == null) { // top level class
+            return getName();
+        } else {
+            String enclosingName = enclosingClass.getCanonicalName();
+            if (enclosingName == null)
+                return null;
+            return enclosingName + "." + getSimpleName();
+        }
+    }
+
+    /**
+     * Returns {@code true} if and only if the underlying class
+     * is an anonymous class.
+     *
+     * @return {@code true} if and only if this class is an anonymous class.
+     * @since 1.5
+     */
+    @FastNative
+    public native boolean isAnonymousClass();
+
+    /**
+     * Returns {@code true} if and only if the underlying class
+     * is a local class.
+     *
+     * @return {@code true} if and only if this class is a local class.
+     * @since 1.5
+     */
+    public boolean isLocalClass() {
+        return (getEnclosingMethod() != null || getEnclosingConstructor() != null)
+                && !isAnonymousClass();
+    }
+
+    /**
+     * Returns {@code true} if and only if the underlying class
+     * is a member class.
+     *
+     * @return {@code true} if and only if this class is a member class.
+     * @since 1.5
+     */
+    public boolean isMemberClass() {
+        return getDeclaringClass() != null;
+    }
+
+    /**
+     * Returns {@code true} if this is a local class or an anonymous
+     * class.  Returns {@code false} otherwise.
+     */
+    private boolean isLocalOrAnonymousClass() {
+        // JVM Spec 4.8.6: A class must have an EnclosingMethod
+        // attribute if and only if it is a local class or an
+        // anonymous class.
+        return isLocalClass() || isAnonymousClass();
+    }
+
+    /**
+     * Returns an array containing {@code Class} objects representing all
+     * the public classes and interfaces that are members of the class
+     * represented by this {@code Class} object.  This includes public
+     * class and interface members inherited from superclasses and public class
+     * and interface members declared by the class.  This method returns an
+     * array of length 0 if this {@code Class} object has no public member
+     * classes or interfaces.  This method also returns an array of length 0 if
+     * this {@code Class} object represents a primitive type, an array
+     * class, or void.
+     *
+     * @return the array of {@code Class} objects representing the public
+     *         members of this class
+     *
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Class<?>[] getClasses() {
+        List<Class<?>> result = new ArrayList<Class<?>>();
+        for (Class<?> c = this; c != null; c = c.superClass) {
+            for (Class<?> member : c.getDeclaredClasses()) {
+                if (Modifier.isPublic(member.getModifiers())) {
+                    result.add(member);
+                }
+            }
+        }
+        return result.toArray(new Class[result.size()]);
+    }
+
+
+    /**
+     * Returns an array containing {@code Field} objects reflecting all
+     * the accessible public fields of the class or interface represented by
+     * this {@code Class} object.
+     *
+     * <p> If this {@code Class} object represents a class or interface with no
+     * no accessible public fields, then this method returns an array of length
+     * 0.
+     *
+     * <p> If this {@code Class} object represents a class, then this method
+     * returns the public fields of the class and of all its superclasses.
+     *
+     * <p> If this {@code Class} object represents an interface, then this
+     * method returns the fields of the interface and of all its
+     * superinterfaces.
+     *
+     * <p> If this {@code Class} object represents an array type, a primitive
+     * type, or void, then this method returns an array of length 0.
+     *
+     * <p> The elements in the returned array are not sorted and are not in any
+     * particular order.
+     *
+     * @return the array of {@code Field} objects representing the
+     *         public fields
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @since JDK1.1
+     * @jls 8.2 Class Members
+     * @jls 8.3 Field Declarations
+     */
+    @CallerSensitive
+    public Field[] getFields() throws SecurityException {
+        List<Field> fields = new ArrayList<Field>();
+        getPublicFieldsRecursive(fields);
+        return fields.toArray(new Field[fields.size()]);
+    }
+
+    /**
+     * Populates {@code result} with public fields defined by this class, its
+     * superclasses, and all implemented interfaces.
+     */
+    private void getPublicFieldsRecursive(List<Field> result) {
+        // search superclasses
+        for (Class<?> c = this; c != null; c = c.superClass) {
+            Collections.addAll(result, c.getPublicDeclaredFields());
+        }
+
+        // search iftable which has a flattened and uniqued list of interfaces
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            for (int i = 0; i < iftable.length; i += 2) {
+                Collections.addAll(result, ((Class<?>) iftable[i]).getPublicDeclaredFields());
+            }
+        }
+    }
+
+    /**
+     * Returns an array containing {@code Method} objects reflecting all the
+     * public methods of the class or interface represented by this {@code
+     * Class} object, including those declared by the class or interface and
+     * those inherited from superclasses and superinterfaces.
+     *
+     * <p> If this {@code Class} object represents a type that has multiple
+     * public methods with the same name and parameter types, but different
+     * return types, then the returned array has a {@code Method} object for
+     * each such method.
+     *
+     * <p> If this {@code Class} object represents a type with a class
+     * initialization method {@code <clinit>}, then the returned array does
+     * <em>not</em> have a corresponding {@code Method} object.
+     *
+     * <p> If this {@code Class} object represents an array type, then the
+     * returned array has a {@code Method} object for each of the public
+     * methods inherited by the array type from {@code Object}. It does not
+     * contain a {@code Method} object for {@code clone()}.
+     *
+     * <p> If this {@code Class} object represents an interface then the
+     * returned array does not contain any implicitly declared methods from
+     * {@code Object}. Therefore, if no methods are explicitly declared in
+     * this interface or any of its superinterfaces then the returned array
+     * has length 0. (Note that a {@code Class} object which represents a class
+     * always has public methods, inherited from {@code Object}.)
+     *
+     * <p> If this {@code Class} object represents a primitive type or void,
+     * then the returned array has length 0.
+     *
+     * <p> Static methods declared in superinterfaces of the class or interface
+     * represented by this {@code Class} object are not considered members of
+     * the class or interface.
+     *
+     * <p> The elements in the returned array are not sorted and are not in any
+     * particular order.
+     *
+     * @return the array of {@code Method} objects representing the
+     *         public methods of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @jls 8.2 Class Members
+     * @jls 8.4 Method Declarations
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Method[] getMethods() throws SecurityException {
+        List<Method> methods = new ArrayList<Method>();
+        getPublicMethodsInternal(methods);
+        /*
+         * Remove duplicate methods defined by superclasses and
+         * interfaces, preferring to keep methods declared by derived
+         * types.
+         */
+        CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
+        return methods.toArray(new Method[methods.size()]);
+    }
+
+    /**
+     * Populates {@code result} with public methods defined by this class, its
+     * superclasses, and all implemented interfaces, including overridden methods.
+     */
+    private void getPublicMethodsInternal(List<Method> result) {
+        Collections.addAll(result, getDeclaredMethodsUnchecked(true));
+        if (!isInterface()) {
+            // Search superclasses, for interfaces don't search java.lang.Object.
+            for (Class<?> c = superClass; c != null; c = c.superClass) {
+                Collections.addAll(result, c.getDeclaredMethodsUnchecked(true));
+            }
+        }
+        // Search iftable which has a flattened and uniqued list of interfaces.
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            for (int i = 0; i < iftable.length; i += 2) {
+                Class<?> ifc = (Class<?>) iftable[i];
+                Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true));
+            }
+        }
+    }
+
+    /**
+     * Returns an array containing {@code Constructor} objects reflecting
+     * all the public constructors of the class represented by this
+     * {@code Class} object.  An array of length 0 is returned if the
+     * class has no public constructors, or if the class is an array class, or
+     * if the class reflects a primitive type or void.
+     *
+     * Note that while this method returns an array of {@code
+     * Constructor<T>} objects (that is an array of constructors from
+     * this class), the return type of this method is {@code
+     * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
+     * might be expected.  This less informative return type is
+     * necessary since after being returned from this method, the
+     * array could be modified to hold {@code Constructor} objects for
+     * different classes, which would violate the type guarantees of
+     * {@code Constructor<T>[]}.
+     *
+     * @return the array of {@code Constructor} objects representing the
+     *         public constructors of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Constructor<?>[] getConstructors() throws SecurityException {
+        return getDeclaredConstructorsInternal(true);
+    }
+
+
+    /**
+     * Returns a {@code Field} object that reflects the specified public member
+     * field of the class or interface represented by this {@code Class}
+     * object. The {@code name} parameter is a {@code String} specifying the
+     * simple name of the desired field.
+     *
+     * <p> The field to be reflected is determined by the algorithm that
+     * follows.  Let C be the class or interface represented by this object:
+     *
+     * <OL>
+     * <LI> If C declares a public field with the name specified, that is the
+     *      field to be reflected.</LI>
+     * <LI> If no field was found in step 1 above, this algorithm is applied
+     *      recursively to each direct superinterface of C. The direct
+     *      superinterfaces are searched in the order they were declared.</LI>
+     * <LI> If no field was found in steps 1 and 2 above, and C has a
+     *      superclass S, then this algorithm is invoked recursively upon S.
+     *      If C has no superclass, then a {@code NoSuchFieldException}
+     *      is thrown.</LI>
+     * </OL>
+     *
+     * <p> If this {@code Class} object represents an array type, then this
+     * method does not find the {@code length} field of the array type.
+     *
+     * @param name the field name
+     * @return the {@code Field} object of this class specified by
+     *         {@code name}
+     * @throws NoSuchFieldException if a field with the specified name is
+     *         not found.
+     * @throws NullPointerException if {@code name} is {@code null}
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @since JDK1.1
+     * @jls 8.2 Class Members
+     * @jls 8.3 Field Declarations
+     */
+    // Android-changed: Removed SecurityException
+    public Field getField(String name)
+        throws NoSuchFieldException {
+        if (name == null) {
+            throw new NullPointerException("name == null");
+        }
+        Field result = getPublicFieldRecursive(name);
+        if (result == null) {
+            throw new NoSuchFieldException(name);
+        }
+        return result;
+    }
+
+    /**
+     * The native implementation of the {@code getField} method.
+     *
+     * @throws NullPointerException
+     *            if name is null.
+     * @see #getField(String)
+     */
+    @FastNative
+    private native Field getPublicFieldRecursive(String name);
+
+    /**
+     * Returns a {@code Method} object that reflects the specified public
+     * member method of the class or interface represented by this
+     * {@code Class} object. The {@code name} parameter is a
+     * {@code String} specifying the simple name of the desired method. The
+     * {@code parameterTypes} parameter is an array of {@code Class}
+     * objects that identify the method's formal parameter types, in declared
+     * order. If {@code parameterTypes} is {@code null}, it is
+     * treated as if it were an empty array.
+     *
+     * <p> If the {@code name} is "{@code <init>}" or "{@code <clinit>}" a
+     * {@code NoSuchMethodException} is raised. Otherwise, the method to
+     * be reflected is determined by the algorithm that follows.  Let C be the
+     * class or interface represented by this object:
+     * <OL>
+     * <LI> C is searched for a <I>matching method</I>, as defined below. If a
+     *      matching method is found, it is reflected.</LI>
+     * <LI> If no matching method is found by step 1 then:
+     *   <OL TYPE="a">
+     *   <LI> If C is a class other than {@code Object}, then this algorithm is
+     *        invoked recursively on the superclass of C.</LI>
+     *   <LI> If C is the class {@code Object}, or if C is an interface, then
+     *        the superinterfaces of C (if any) are searched for a matching
+     *        method. If any such method is found, it is reflected.</LI>
+     *   </OL></LI>
+     * </OL>
+     *
+     * <p> To find a matching method in a class or interface C:&nbsp; If C
+     * declares exactly one public method with the specified name and exactly
+     * the same formal parameter types, that is the method reflected. If more
+     * than one such method is found in C, and one of these methods has a
+     * return type that is more specific than any of the others, that method is
+     * reflected; otherwise one of the methods is chosen arbitrarily.
+     *
+     * <p>Note that there may be more than one matching method in a
+     * class because while the Java language forbids a class to
+     * declare multiple methods with the same signature but different
+     * return types, the Java virtual machine does not.  This
+     * increased flexibility in the virtual machine can be used to
+     * implement various language features.  For example, covariant
+     * returns can be implemented with {@linkplain
+     * java.lang.reflect.Method#isBridge bridge methods}; the bridge
+     * method and the method being overridden would have the same
+     * signature but different return types.
+     *
+     * <p> If this {@code Class} object represents an array type, then this
+     * method does not find the {@code clone()} method.
+     *
+     * <p> Static methods declared in superinterfaces of the class or interface
+     * represented by this {@code Class} object are not considered members of
+     * the class or interface.
+     *
+     * @param name the name of the method
+     * @param parameterTypes the list of parameters
+     * @return the {@code Method} object that matches the specified
+     *         {@code name} and {@code parameterTypes}
+     * @throws NoSuchMethodException if a matching method is not found
+     *         or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
+     * @throws NullPointerException if {@code name} is {@code null}
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @jls 8.2 Class Members
+     * @jls 8.4 Method Declarations
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Method getMethod(String name, Class<?>... parameterTypes)
+        throws NoSuchMethodException, SecurityException {
+        return getMethod(name, parameterTypes, true);
+    }
+
+
+    /**
+     * Returns a {@code Constructor} object that reflects the specified
+     * public constructor of the class represented by this {@code Class}
+     * object. The {@code parameterTypes} parameter is an array of
+     * {@code Class} objects that identify the constructor's formal
+     * parameter types, in declared order.
+     *
+     * If this {@code Class} object represents an inner class
+     * declared in a non-static context, the formal parameter types
+     * include the explicit enclosing instance as the first parameter.
+     *
+     * <p> The constructor to reflect is the public constructor of the class
+     * represented by this {@code Class} object whose formal parameter
+     * types match those specified by {@code parameterTypes}.
+     *
+     * @param parameterTypes the parameter array
+     * @return the {@code Constructor} object of the public constructor that
+     *         matches the specified {@code parameterTypes}
+     * @throws NoSuchMethodException if a matching method is not found.
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
+     *
+     * @since JDK1.1
+     */
+    public Constructor<T> getConstructor(Class<?>... parameterTypes)
+        throws NoSuchMethodException, SecurityException {
+        return getConstructor0(parameterTypes, Member.PUBLIC);
+    }
+
+
+    /**
+     * Returns an array of {@code Class} objects reflecting all the
+     * classes and interfaces declared as members of the class represented by
+     * this {@code Class} object. This includes public, protected, default
+     * (package) access, and private classes and interfaces declared by the
+     * class, but excludes inherited classes and interfaces.  This method
+     * returns an array of length 0 if the class declares no classes or
+     * interfaces as members, or if this {@code Class} object represents a
+     * primitive type, an array class, or void.
+     *
+     * @return the array of {@code Class} objects representing all the
+     *         declared members of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and any of the
+     *         following conditions is met:
+     *
+     *         <ul>
+     *
+     *         <li> the caller's class loader is not the same as the
+     *         class loader of this class and invocation of
+     *         {@link SecurityManager#checkPermission
+     *         s.checkPermission} method with
+     *         {@code RuntimePermission("accessDeclaredMembers")}
+     *         denies access to the declared classes within this class
+     *
+     *         <li> the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class
+     *
+     *         </ul>
+     *
+     * @since JDK1.1
+     */
+    // Android-changed: Removed SecurityException
+    @FastNative
+    public native Class<?>[] getDeclaredClasses();
+
+    /**
+     * Returns an array of {@code Field} objects reflecting all the fields
+     * declared by the class or interface represented by this
+     * {@code Class} object. This includes public, protected, default
+     * (package) access, and private fields, but excludes inherited fields.
+     *
+     * <p> If this {@code Class} object represents a class or interface with no
+     * declared fields, then this method returns an array of length 0.
+     *
+     * <p> If this {@code Class} object represents an array type, a primitive
+     * type, or void, then this method returns an array of length 0.
+     *
+     * <p> The elements in the returned array are not sorted and are not in any
+     * particular order.
+     *
+     * @return  the array of {@code Field} objects representing all the
+     *          declared fields of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared fields within this class
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @since JDK1.1
+     * @jls 8.2 Class Members
+     * @jls 8.3 Field Declarations
+     */
+    // Android-changed: Removed SecurityException
+    @FastNative
+    public native Field[] getDeclaredFields();
+
+    /**
+     * Populates a list of fields without performing any security or type
+     * resolution checks first. If no fields exist, the list is not modified.
+     *
+     * @param publicOnly Whether to return only public fields.
+     * @hide
+     */
+    @FastNative
+    public native Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+    /**
+     *
+     * Returns an array containing {@code Method} objects reflecting all the
+     * declared methods of the class or interface represented by this {@code
+     * Class} object, including public, protected, default (package)
+     * access, and private methods, but excluding inherited methods.
+     *
+     * <p> If this {@code Class} object represents a type that has multiple
+     * declared methods with the same name and parameter types, but different
+     * return types, then the returned array has a {@code Method} object for
+     * each such method.
+     *
+     * <p> If this {@code Class} object represents a type that has a class
+     * initialization method {@code <clinit>}, then the returned array does
+     * <em>not</em> have a corresponding {@code Method} object.
+     *
+     * <p> If this {@code Class} object represents a class or interface with no
+     * declared methods, then the returned array has length 0.
+     *
+     * <p> If this {@code Class} object represents an array type, a primitive
+     * type, or void, then the returned array has length 0.
+     *
+     * <p> The elements in the returned array are not sorted and are not in any
+     * particular order.
+     *
+     * @return  the array of {@code Method} objects representing all the
+     *          declared methods of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared methods within this class
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @jls 8.2 Class Members
+     * @jls 8.4 Method Declarations
+     * @since JDK1.1
+     */
+    public Method[] getDeclaredMethods() throws SecurityException {
+        Method[] result = getDeclaredMethodsUnchecked(false);
+        for (Method m : result) {
+            // Throw NoClassDefFoundError if types cannot be resolved.
+            m.getReturnType();
+            m.getParameterTypes();
+        }
+        return result;
+    }
+
+    /**
+     * Populates a list of methods without performing any security or type
+     * resolution checks first. If no methods exist, the list is not modified.
+     *
+     * @param publicOnly Whether to return only public methods.
+     * @hide
+     */
+    @FastNative
+    public native Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+    /**
+     * Returns an array of {@code Constructor} objects reflecting all the
+     * constructors declared by the class represented by this
+     * {@code Class} object. These are public, protected, default
+     * (package) access, and private constructors.  The elements in the array
+     * returned are not sorted and are not in any particular order.  If the
+     * class has a default constructor, it is included in the returned array.
+     * This method returns an array of length 0 if this {@code Class}
+     * object represents an interface, a primitive type, an array class, or
+     * void.
+     *
+     * <p> See <em>The Java Language Specification</em>, section 8.2.
+     *
+     * @return  the array of {@code Constructor} objects representing all the
+     *          declared constructors of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared constructors within this class
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @since JDK1.1
+     */
+    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
+        return getDeclaredConstructorsInternal(false);
+    }
+
+
+    /**
+     * Returns the constructor with the given parameters if it is defined by this class;
+     * {@code null} otherwise. This may return a non-public member.
+     */
+    @FastNative
+    private native Constructor<?>[] getDeclaredConstructorsInternal(boolean publicOnly);
+
+    /**
+     * Returns a {@code Field} object that reflects the specified declared
+     * field of the class or interface represented by this {@code Class}
+     * object. The {@code name} parameter is a {@code String} that specifies
+     * the simple name of the desired field.
+     *
+     * <p> If this {@code Class} object represents an array type, then this
+     * method does not find the {@code length} field of the array type.
+     *
+     * @param name the name of the field
+     * @return  the {@code Field} object for the specified field in this
+     *          class
+     * @throws  NoSuchFieldException if a field with the specified name is
+     *          not found.
+     * @throws  NullPointerException if {@code name} is {@code null}
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared field
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @since JDK1.1
+     * @jls 8.2 Class Members
+     * @jls 8.3 Field Declarations
+     */
+    // Android-changed: Removed SecurityException
+    @FastNative
+    public native Field getDeclaredField(String name) throws NoSuchFieldException;
+
+    /**
+     * Returns the subset of getDeclaredFields which are public.
+     */
+    @FastNative
+    private native Field[] getPublicDeclaredFields();
+
+    /**
+     * Returns a {@code Method} object that reflects the specified
+     * declared method of the class or interface represented by this
+     * {@code Class} object. The {@code name} parameter is a
+     * {@code String} that specifies the simple name of the desired
+     * method, and the {@code parameterTypes} parameter is an array of
+     * {@code Class} objects that identify the method's formal parameter
+     * types, in declared order.  If more than one method with the same
+     * parameter types is declared in a class, and one of these methods has a
+     * return type that is more specific than any of the others, that method is
+     * returned; otherwise one of the methods is chosen arbitrarily.  If the
+     * name is "&lt;init&gt;"or "&lt;clinit&gt;" a {@code NoSuchMethodException}
+     * is raised.
+     *
+     * <p> If this {@code Class} object represents an array type, then this
+     * method does not find the {@code clone()} method.
+     *
+     * @param name the name of the method
+     * @param parameterTypes the parameter array
+     * @return  the {@code Method} object for the method of this class
+     *          matching the specified name and parameters
+     * @throws  NoSuchMethodException if a matching method is not found.
+     * @throws  NullPointerException if {@code name} is {@code null}
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared method
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @jls 8.2 Class Members
+     * @jls 8.4 Method Declarations
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
+        throws NoSuchMethodException, SecurityException {
+        return getMethod(name, parameterTypes, false);
+    }
+
+    private Method getMethod(String name, Class<?>[] parameterTypes, boolean recursivePublicMethods)
+            throws NoSuchMethodException {
+        if (name == null) {
+            throw new NullPointerException("name == null");
+        }
+        if (parameterTypes == null) {
+            parameterTypes = EmptyArray.CLASS;
+        }
+        for (Class<?> c : parameterTypes) {
+            if (c == null) {
+                throw new NoSuchMethodException("parameter type is null");
+            }
+        }
+        Method result = recursivePublicMethods ? getPublicMethodRecursive(name, parameterTypes)
+                                               : getDeclaredMethodInternal(name, parameterTypes);
+        // Fail if we didn't find the method or it was expected to be public.
+        if (result == null ||
+            (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
+            throw new NoSuchMethodException(getName() + "." + name + " "
+                    + Arrays.toString(parameterTypes));
+        }
+        return result;
+    }
+    private Method getPublicMethodRecursive(String name, Class<?>[] parameterTypes) {
+        // search superclasses
+        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
+            Method result = c.getDeclaredMethodInternal(name, parameterTypes);
+            if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+                return result;
+            }
+        }
+
+        return findInterfaceMethod(name, parameterTypes);
+    }
+
+    /**
+     * Returns an instance method that's defined on this class or any super classes, regardless
+     * of its access flags. Constructors are excluded.
+     *
+     * This function does not perform access checks and its semantics don't match any dex byte code
+     * instruction or public reflection API. This is used by {@code MethodHandles.findVirtual}
+     * which will perform access checks on the returned method.
+     *
+     * @hide
+     */
+    public Method getInstanceMethod(String name, Class<?>[] parameterTypes)
+            throws NoSuchMethodException, IllegalAccessException {
+        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
+            Method result = c.getDeclaredMethodInternal(name, parameterTypes);
+            if (result != null && !Modifier.isStatic(result.getModifiers())) {
+                return result;
+            }
+        }
+
+        return findInterfaceMethod(name, parameterTypes);
+    }
+
+    private Method findInterfaceMethod(String name, Class<?>[] parameterTypes) {
+        Object[] iftable = ifTable;
+        if (iftable != null) {
+            // Search backwards so more specific interfaces are searched first. This ensures that
+            // the method we return is not overridden by one of it's subtypes that this class also
+            // implements.
+            for (int i = iftable.length - 2; i >= 0; i -= 2) {
+                Class<?> ifc = (Class<?>) iftable[i];
+                Method result = ifc.getPublicMethodRecursive(name, parameterTypes);
+                if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+                    return result;
+                }
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Returns a {@code Constructor} object that reflects the specified
+     * constructor of the class or interface represented by this
+     * {@code Class} object.  The {@code parameterTypes} parameter is
+     * an array of {@code Class} objects that identify the constructor's
+     * formal parameter types, in declared order.
+     *
+     * If this {@code Class} object represents an inner class
+     * declared in a non-static context, the formal parameter types
+     * include the explicit enclosing instance as the first parameter.
+     *
+     * @param parameterTypes the parameter array
+     * @return  The {@code Constructor} object for the constructor with the
+     *          specified parameter list
+     * @throws  NoSuchMethodException if a matching method is not found.
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
+     *
+     *          <ul>
+     *
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared constructor
+     *
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
+     *
+     *          </ul>
+     *
+     * @since JDK1.1
+     */
+    @CallerSensitive
+    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
+        throws NoSuchMethodException, SecurityException {
+        return getConstructor0(parameterTypes, Member.DECLARED);
+    }
+
+    /**
+     * Finds a resource with a given name.  The rules for searching resources
+     * associated with a given class are implemented by the defining
+     * {@linkplain ClassLoader class loader} of the class.  This method
+     * delegates to this object's class loader.  If this object was loaded by
+     * the bootstrap class loader, the method delegates to {@link
+     * ClassLoader#getSystemResourceAsStream}.
+     *
+     * <p> Before delegation, an absolute resource name is constructed from the
+     * given resource name using this algorithm:
+     *
+     * <ul>
+     *
+     * <li> If the {@code name} begins with a {@code '/'}
+     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
+     * portion of the {@code name} following the {@code '/'}.
+     *
+     * <li> Otherwise, the absolute name is of the following form:
+     *
+     * <blockquote>
+     *   {@code modified_package_name/name}
+     * </blockquote>
+     *
+     * <p> Where the {@code modified_package_name} is the package name of this
+     * object with {@code '/'} substituted for {@code '.'}
+     * (<tt>'&#92;u002e'</tt>).
+     *
+     * </ul>
+     *
+     * @param  name name of the desired resource
+     * @return      A {@link java.io.InputStream} object or {@code null} if
+     *              no resource with this name is found
+     * @throws  NullPointerException If {@code name} is {@code null}
+     * @since  JDK1.1
+     */
+     public InputStream getResourceAsStream(String name) {
+        name = resolveName(name);
+        ClassLoader cl = getClassLoader();
+        if (cl==null) {
+            // A system class.
+            return ClassLoader.getSystemResourceAsStream(name);
+        }
+        return cl.getResourceAsStream(name);
+    }
+
+    /**
+     * Finds a resource with a given name.  The rules for searching resources
+     * associated with a given class are implemented by the defining
+     * {@linkplain ClassLoader class loader} of the class.  This method
+     * delegates to this object's class loader.  If this object was loaded by
+     * the bootstrap class loader, the method delegates to {@link
+     * ClassLoader#getSystemResource}.
+     *
+     * <p> Before delegation, an absolute resource name is constructed from the
+     * given resource name using this algorithm:
+     *
+     * <ul>
+     *
+     * <li> If the {@code name} begins with a {@code '/'}
+     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
+     * portion of the {@code name} following the {@code '/'}.
+     *
+     * <li> Otherwise, the absolute name is of the following form:
+     *
+     * <blockquote>
+     *   {@code modified_package_name/name}
+     * </blockquote>
+     *
+     * <p> Where the {@code modified_package_name} is the package name of this
+     * object with {@code '/'} substituted for {@code '.'}
+     * (<tt>'&#92;u002e'</tt>).
+     *
+     * </ul>
+     *
+     * @param  name name of the desired resource
+     * @return      A  {@link java.net.URL} object or {@code null} if no
+     *              resource with this name is found
+     * @since  JDK1.1
+     */
+    public java.net.URL getResource(String name) {
+        name = resolveName(name);
+        ClassLoader cl = getClassLoader();
+        if (cl==null) {
+            // A system class.
+            return ClassLoader.getSystemResource(name);
+        }
+        return cl.getResource(name);
+    }
+
+    /**
+     * Returns the {@code ProtectionDomain} of this class.  If there is a
+     * security manager installed, this method first calls the security
+     * manager's {@code checkPermission} method with a
+     * {@code RuntimePermission("getProtectionDomain")} permission to
+     * ensure it's ok to get the
+     * {@code ProtectionDomain}.
+     *
+     * @return the ProtectionDomain of this class
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        getting the ProtectionDomain.
+     *
+     * @see java.security.ProtectionDomain
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     * @since 1.2
+     */
+    public java.security.ProtectionDomain getProtectionDomain() {
+        return null;
+    }
+
+    /*
+     * Return the runtime's Class object for the named
+     * primitive type.
+     */
+    @FastNative
+    static native Class<?> getPrimitiveClass(String name);
+
+    /**
+     * Add a package name prefix if the name is not absolute Remove leading "/"
+     * if name is absolute
+     */
+    private String resolveName(String name) {
+        if (name == null) {
+            return name;
+        }
+        if (!name.startsWith("/")) {
+            Class<?> c = this;
+            while (c.isArray()) {
+                c = c.getComponentType();
+            }
+            String baseName = c.getName();
+            int index = baseName.lastIndexOf('.');
+            if (index != -1) {
+                name = baseName.substring(0, index).replace('.', '/')
+                    +"/"+name;
+            }
+        } else {
+            name = name.substring(1);
+        }
+        return name;
+    }
+
+    private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
+                                        int which) throws NoSuchMethodException
+    {
+        if (parameterTypes == null) {
+            parameterTypes = EmptyArray.CLASS;
+        }
+        for (Class<?> c : parameterTypes) {
+            if (c == null) {
+                throw new NoSuchMethodException("parameter type is null");
+            }
+        }
+        Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
+        if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) {
+            throw new NoSuchMethodException(getName() + ".<init> "
+                    + Arrays.toString(parameterTypes));
+        }
+        return result;
+    }
+
+    /** use serialVersionUID from JDK 1.1 for interoperability */
+    private static final long serialVersionUID = 3206093459760846163L;
+
+
+    /**
+     * Returns the constructor with the given parameters if it is defined by this class;
+     * {@code null} otherwise. This may return a non-public member.
+     *
+     * @param args the types of the parameters to the constructor.
+     */
+    @FastNative
+    private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
+
+    /**
+     * Returns the assertion status that would be assigned to this
+     * class if it were to be initialized at the time this method is invoked.
+     * If this class has had its assertion status set, the most recent
+     * setting will be returned; otherwise, if any package default assertion
+     * status pertains to this class, the most recent setting for the most
+     * specific pertinent package default assertion status is returned;
+     * otherwise, if this class is not a system class (i.e., it has a
+     * class loader) its class loader's default assertion status is returned;
+     * otherwise, the system class default assertion status is returned.
+     * <p>
+     * Few programmers will have any need for this method; it is provided
+     * for the benefit of the JRE itself.  (It allows a class to determine at
+     * the time that it is initialized whether assertions should be enabled.)
+     * Note that this method is not guaranteed to return the actual
+     * assertion status that was (or will be) associated with the specified
+     * class when it was (or will be) initialized.
+     *
+     * @return the desired assertion status of the specified class.
+     * @see    java.lang.ClassLoader#setClassAssertionStatus
+     * @see    java.lang.ClassLoader#setPackageAssertionStatus
+     * @see    java.lang.ClassLoader#setDefaultAssertionStatus
+     * @since  1.4
+     */
+    public boolean desiredAssertionStatus() {
+        return false;
+    }
+
+    /**
+     * Returns the simple name of a member or local class, or {@code null} otherwise.
+     */
+    @FastNative
+    private native String getInnerClassName();
+
+    @FastNative
+    private native int getInnerClassFlags(int defaultValue);
+
+    /**
+     * Returns true if and only if this class was declared as an enum in the
+     * source code.
+     *
+     * @return true if and only if this class was declared as an enum in the
+     *     source code
+     * @since 1.5
+     */
+    public boolean isEnum() {
+        // An enum must both directly extend java.lang.Enum and have
+        // the ENUM bit set; classes for specialized enum constants
+        // don't do the former.
+        return (this.getModifiers() & ENUM) != 0 &&
+        this.getSuperclass() == java.lang.Enum.class;
+    }
+
+    /**
+     * Returns the elements of this enum class or null if this
+     * Class object does not represent an enum type.
+     *
+     * @return an array containing the values comprising the enum class
+     *     represented by this Class object in the order they're
+     *     declared, or null if this Class object does not
+     *     represent an enum type
+     * @since 1.5
+     */
+    public T[] getEnumConstants() {
+        T[] values = getEnumConstantsShared();
+        return (values != null) ? values.clone() : null;
+    }
+
+    // Android-changed: Made public/hidden instead of using sun.misc.SharedSecrets.
+    /**
+     * Returns the elements of this enum class or null if this
+     * Class object does not represent an enum type;
+     * identical to getEnumConstants except that the result is
+     * uncloned, cached, and shared by all callers.
+     * @hide
+     */
+    public T[] getEnumConstantsShared() {
+        if (!isEnum()) return null;
+        return (T[]) Enum.getSharedConstants((Class) this);
+    }
+
+    /**
+     * Casts an object to the class or interface represented
+     * by this {@code Class} object.
+     *
+     * @param obj the object to be cast
+     * @return the object after casting, or null if obj is null
+     *
+     * @throws ClassCastException if the object is not
+     * null and is not assignable to the type T.
+     *
+     * @since 1.5
+     */
+    @SuppressWarnings("unchecked")
+    public T cast(Object obj) {
+        if (obj != null && !isInstance(obj))
+            throw new ClassCastException(cannotCastMsg(obj));
+        return (T) obj;
+    }
+
+    private String cannotCastMsg(Object obj) {
+        return "Cannot cast " + obj.getClass().getName() + " to " + getName();
+    }
+
+    /**
+     * Casts this {@code Class} object to represent a subclass of the class
+     * represented by the specified class object.  Checks that the cast
+     * is valid, and throws a {@code ClassCastException} if it is not.  If
+     * this method succeeds, it always returns a reference to this class object.
+     *
+     * <p>This method is useful when a client needs to "narrow" the type of
+     * a {@code Class} object to pass it to an API that restricts the
+     * {@code Class} objects that it is willing to accept.  A cast would
+     * generate a compile-time warning, as the correctness of the cast
+     * could not be checked at runtime (because generic types are implemented
+     * by erasure).
+     *
+     * @param <U> the type to cast this class object to
+     * @param clazz the class of the type to cast this class object to
+     * @return this {@code Class} object, cast to represent a subclass of
+     *    the specified class object.
+     * @throws ClassCastException if this {@code Class} object does not
+     *    represent a subclass of the specified class (here "subclass" includes
+     *    the class itself).
+     * @since 1.5
+     */
+    @SuppressWarnings("unchecked")
+    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
+        if (clazz.isAssignableFrom(this))
+            return (Class<? extends U>) this;
+        else
+            throw new ClassCastException(this.toString() +
+                " cannot be cast to " + clazz.getName());
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    @SuppressWarnings("unchecked")
+    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+        Objects.requireNonNull(annotationClass);
+
+        A annotation = getDeclaredAnnotation(annotationClass);
+        if (annotation != null) {
+            return annotation;
+        }
+
+        if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+                annotation = sup.getDeclaredAnnotation(annotationClass);
+                if (annotation != null) {
+                    return annotation;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        if (annotationClass == null) {
+            throw new NullPointerException("annotationClass == null");
+        }
+
+        if (isDeclaredAnnotationPresent(annotationClass)) {
+            return true;
+        }
+
+        if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+                if (sup.isDeclaredAnnotationPresent(annotationClass)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
+      // Find any associated annotations [directly or repeatably (indirectly) present on this].
+      A[] annotations = GenericDeclaration.super.getAnnotationsByType(annotationClass);
+
+      if (annotations.length != 0) {
+        return annotations;
+      }
+
+      // Nothing was found, attempt looking for associated annotations recursively up to the root
+      // class if and only if:
+      // * The annotation class was marked with @Inherited.
+      //
+      // Inherited annotations are not coalesced into a single set: the first declaration found is
+      // returned.
+
+      if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+        Class<?> superClass = getSuperclass();  // Returns null if klass's base is Object.
+
+        if (superClass != null) {
+          return superClass.getAnnotationsByType(annotationClass);
+        }
+      }
+
+      // Annotated was not marked with @Inherited, or no superclass.
+      return (A[]) Array.newInstance(annotationClass, 0);  // Safe by construction.
+    }
+
+    /**
+     * @since 1.5
+     */
+    @Override
+    public Annotation[] getAnnotations() {
+        /*
+         * We need to get the annotations declared on this class, plus the
+         * annotations from superclasses that have the "@Inherited" annotation
+         * set.  We create a temporary map to use while we accumulate the
+         * annotations and convert it to an array at the end.
+         *
+         * It's possible to have duplicates when annotations are inherited.
+         * We use a Map to filter those out.
+         *
+         * HashMap might be overkill here.
+         */
+        HashMap<Class<?>, Annotation> map = new HashMap<Class<?>, Annotation>();
+        for (Annotation declaredAnnotation : getDeclaredAnnotations()) {
+            map.put(declaredAnnotation.annotationType(), declaredAnnotation);
+        }
+        for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+            for (Annotation declaredAnnotation : sup.getDeclaredAnnotations()) {
+                Class<? extends Annotation> clazz = declaredAnnotation.annotationType();
+                if (!map.containsKey(clazz) && clazz.isDeclaredAnnotationPresent(Inherited.class)) {
+                    map.put(clazz, declaredAnnotation);
+                }
+            }
+        }
+
+        /* Convert annotation values from HashMap to array. */
+        Collection<Annotation> coll = map.values();
+        return coll.toArray(new Annotation[coll.size()]);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    @FastNative
+    public native <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass);
+
+    /**
+     * @since 1.5
+     */
+    @Override
+    @FastNative
+    public native Annotation[] getDeclaredAnnotations();
+
+    /**
+     * Returns true if the annotation exists.
+     */
+    @FastNative
+    private native boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass);
+
+    private String getSignatureAttribute() {
+        String[] annotation = getSignatureAnnotation();
+        if (annotation == null) {
+            return null;
+        }
+        StringBuilder result = new StringBuilder();
+        for (String s : annotation) {
+            result.append(s);
+        }
+        return result.toString();
+    }
+
+    @FastNative
+    private native String[] getSignatureAnnotation();
+
+    /**
+     * Is this a runtime created proxy class?
+     *
+     * @hide
+     */
+    public boolean isProxy() {
+        return (accessFlags & 0x00040000) != 0;
+    }
+
+    /**
+     * @hide
+     */
+    public int getAccessFlags() {
+        return accessFlags;
+    }
+
+
+    /**
+     * Returns the method if it is defined by this class; {@code null} otherwise. This may return a
+     * non-public member.
+     *
+     * @param name the method name
+     * @param args the method's parameter types
+     */
+    @FastNative
+    private native Method getDeclaredMethodInternal(String name, Class<?>[] args);
+
+    private static class Caches {
+        /**
+         * Cache to avoid frequent recalculation of generic interfaces, which is generally uncommon.
+         * Sized sufficient to allow ConcurrentHashMapTest to run without recalculating its generic
+         * interfaces (required to avoid time outs). Validated by running reflection heavy code
+         * such as applications using Guice-like frameworks.
+         */
+        private static final BasicLruCache<Class, Type[]> genericInterfaces
+            = new BasicLruCache<Class, Type[]>(8);
+    }
+}
diff --git a/java/lang/ClassCastException.java b/java/lang/ClassCastException.java
new file mode 100644
index 0000000..e4ca76c
--- /dev/null
+++ b/java/lang/ClassCastException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 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;
+
+/**
+ * Thrown to indicate that the code has attempted to cast an object
+ * to a subclass of which it is not an instance. For example, the
+ * following code generates a <code>ClassCastException</code>:
+ * <blockquote><pre>
+ *     Object x = new Integer(0);
+ *     System.out.println((String)x);
+ * </pre></blockquote>
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class ClassCastException extends RuntimeException {
+    private static final long serialVersionUID = -9223365651070458532L;
+
+    /**
+     * Constructs a <code>ClassCastException</code> with no detail message.
+     */
+    public ClassCastException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>ClassCastException</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ClassCastException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/ClassCircularityError.java b/java/lang/ClassCircularityError.java
new file mode 100644
index 0000000..64e5361
--- /dev/null
+++ b/java/lang/ClassCircularityError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine detects a circularity in the
+ * superclass hierarchy of a class being loaded.
+ *
+ * @author     unascribed
+ * @since      JDK1.0
+ */
+public class ClassCircularityError extends LinkageError {
+    private static final long serialVersionUID = 1054362542914539689L;
+
+    /**
+     * Constructs a {@code ClassCircularityError} with no detail message.
+     */
+    public ClassCircularityError() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code ClassCircularityError} with the specified detail
+     * message.
+     *
+     * @param  s
+     *         The detail message
+     */
+    public ClassCircularityError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/ClassFormatError.java b/java/lang/ClassFormatError.java
new file mode 100644
index 0000000..2dc81db
--- /dev/null
+++ b/java/lang/ClassFormatError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine attempts to read a class
+ * file and determines that the file is malformed or otherwise cannot
+ * be interpreted as a class file.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class ClassFormatError extends LinkageError {
+    private static final long serialVersionUID = -8420114879011949195L;
+
+    /**
+     * Constructs a <code>ClassFormatError</code> with no detail message.
+     */
+    public ClassFormatError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>ClassFormatError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ClassFormatError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/ClassLoader.java b/java/lang/ClassLoader.java
new file mode 100644
index 0000000..0a8b08a
--- /dev/null
+++ b/java/lang/ClassLoader.java
@@ -0,0 +1,1428 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013, 2015, 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;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.CodeSource;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import dalvik.system.PathClassLoader;
+import java.util.List;
+import sun.misc.CompoundEnumeration;
+import sun.misc.Resource;
+import sun.misc.URLClassPath;
+import sun.misc.VM;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.security.util.SecurityConstants;
+
+/**
+ * A class loader is an object that is responsible for loading classes. The
+ * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
+ * href="#name">binary name</a> of a class, a class loader should attempt to
+ * locate or generate data that constitutes a definition for the class.  A
+ * typical strategy is to transform the name into a file name and then read a
+ * "class file" of that name from a file system.
+ *
+ * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
+ * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
+ * it.
+ *
+ * <p> <tt>Class</tt> objects for array classes are not created by class
+ * loaders, but are created automatically as required by the Java runtime.
+ * The class loader for an array class, as returned by {@link
+ * Class#getClassLoader()} is the same as the class loader for its element
+ * type; if the element type is a primitive type, then the array class has no
+ * class loader.
+ *
+ * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
+ * extend the manner in which the Java virtual machine dynamically loads
+ * classes.
+ *
+ * <p> Class loaders may typically be used by security managers to indicate
+ * security domains.
+ *
+ * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
+ * classes and resources.  Each instance of <tt>ClassLoader</tt> has an
+ * associated parent class loader.  When requested to find a class or
+ * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
+ * class or resource to its parent class loader before attempting to find the
+ * class or resource itself.  The virtual machine's built-in class loader,
+ * called the "bootstrap class loader", does not itself have a parent but may
+ * serve as the parent of a <tt>ClassLoader</tt> instance.
+ *
+ * <p> Class loaders that support concurrent loading of classes are known as
+ * <em>parallel capable</em> class loaders and are required to register
+ * themselves at their class initialization time by invoking the
+ * {@link
+ * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
+ * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
+ * capable by default. However, its subclasses still need to register themselves
+ * if they are parallel capable. <br>
+ * In environments in which the delegation model is not strictly
+ * hierarchical, class loaders need to be parallel capable, otherwise class
+ * loading can lead to deadlocks because the loader lock is held for the
+ * duration of the class loading process (see {@link #loadClass
+ * <tt>loadClass</tt>} methods).
+ *
+ * <p> Normally, the Java virtual machine loads classes from the local file
+ * system in a platform-dependent manner.  For example, on UNIX systems, the
+ * virtual machine loads classes from the directory defined by the
+ * <tt>CLASSPATH</tt> environment variable.
+ *
+ * <p> However, some classes may not originate from a file; they may originate
+ * from other sources, such as the network, or they could be constructed by an
+ * application.  The method {@link #defineClass(String, byte[], int, int)
+ * <tt>defineClass</tt>} converts an array of bytes into an instance of class
+ * <tt>Class</tt>. Instances of this newly defined class can be created using
+ * {@link Class#newInstance <tt>Class.newInstance</tt>}.
+ *
+ * <p> The methods and constructors of objects created by a class loader may
+ * reference other classes.  To determine the class(es) referred to, the Java
+ * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
+ * the class loader that originally created the class.
+ *
+ * <p> For example, an application could create a network class loader to
+ * download class files from a server.  Sample code might look like:
+ *
+ * <blockquote><pre>
+ *   ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
+ *   Object main&nbsp;= loader.loadClass("Main", true).newInstance();
+ *       &nbsp;.&nbsp;.&nbsp;.
+ * </pre></blockquote>
+ *
+ * <p> The network class loader subclass must define the methods {@link
+ * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
+ * from the network.  Once it has downloaded the bytes that make up the class,
+ * it should use the method {@link #defineClass <tt>defineClass</tt>} to
+ * create a class instance.  A sample implementation is:
+ *
+ * <blockquote><pre>
+ *     class NetworkClassLoader extends ClassLoader {
+ *         String host;
+ *         int port;
+ *
+ *         public Class findClass(String name) {
+ *             byte[] b = loadClassData(name);
+ *             return defineClass(name, b, 0, b.length);
+ *         }
+ *
+ *         private byte[] loadClassData(String name) {
+ *             // load the class data from the connection
+ *             &nbsp;.&nbsp;.&nbsp;.
+ *         }
+ *     }
+ * </pre></blockquote>
+ *
+ * <h3> <a name="name">Binary names</a> </h3>
+ *
+ * <p> Any class name provided as a {@link String} parameter to methods in
+ * <tt>ClassLoader</tt> must be a binary name as defined by
+ * <cite>The Java&trade; Language Specification</cite>.
+ *
+ * <p> Examples of valid class names include:
+ * <blockquote><pre>
+ *   "java.lang.String"
+ *   "javax.swing.JSpinner$DefaultEditor"
+ *   "java.security.KeyStore$Builder$FileBuilder$1"
+ *   "java.net.URLClassLoader$3$1"
+ * </pre></blockquote>
+ *
+ * @see      #resolveClass(Class)
+ * @since 1.0
+ */
+public abstract class ClassLoader {
+
+    static private class SystemClassLoader {
+        public static ClassLoader loader = ClassLoader.createSystemClassLoader();
+    }
+
+    /**
+     * To avoid unloading individual classes, {@link java.lang.reflect.Proxy}
+     * only generates one class for each set of interfaces. This maps sets of
+     * interfaces to the proxy class that implements all of them. It is declared
+     * here so that these generated classes can be unloaded with their class
+     * loader.
+     *
+     * @hide
+     */
+    public final Map<List<Class<?>>, Class<?>> proxyCache =
+            new HashMap<List<Class<?>>, Class<?>>();
+
+    // The parent class loader for delegation
+    // Note: VM hardcoded the offset of this field, thus all new fields
+    // must be added *after* it.
+    private final ClassLoader parent;
+
+    /**
+     * Encapsulates the set of parallel capable loader types.
+     */
+    private static ClassLoader createSystemClassLoader() {
+        String classPath = System.getProperty("java.class.path", ".");
+        String librarySearchPath = System.getProperty("java.library.path", "");
+
+        // String[] paths = classPath.split(":");
+        // URL[] urls = new URL[paths.length];
+        // for (int i = 0; i < paths.length; i++) {
+        // try {
+        // urls[i] = new URL("file://" + paths[i]);
+        // }
+        // catch (Exception ex) {
+        // ex.printStackTrace();
+        // }
+        // }
+        //
+        // return new java.net.URLClassLoader(urls, null);
+
+        // TODO Make this a java.net.URLClassLoader once we have those?
+        return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());
+    }
+
+    // The packages defined in this class loader.  Each package name is mapped
+    // to its corresponding Package object.
+    // @GuardedBy("itself")
+    private final HashMap<String, Package> packages = new HashMap<>();
+
+    /**
+     * Pointer to the allocator used by the runtime to allocate metadata such
+     * as ArtFields and ArtMethods.
+     */
+    private transient long allocator;
+
+    /**
+     * Pointer to the class table, only used from within the runtime.
+     */
+    private transient long classTable;
+
+    private static Void checkCreateClassLoader() {
+        return null;
+    }
+
+    private ClassLoader(Void unused, ClassLoader parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Creates a new class loader using the specified parent class loader for
+     * delegation.
+     *
+     * <p> If there is a security manager, its {@link
+     * SecurityManager#checkCreateClassLoader()
+     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
+     * a security exception.  </p>
+     *
+     * @param  parent
+     *         The parent class loader
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
+     *          of a new class loader.
+     *
+     * @since  1.2
+     */
+    protected ClassLoader(ClassLoader parent) {
+        this(checkCreateClassLoader(), parent);
+    }
+
+    /**
+     * Creates a new class loader using the <tt>ClassLoader</tt> returned by
+     * the method {@link #getSystemClassLoader()
+     * <tt>getSystemClassLoader()</tt>} as the parent class loader.
+     *
+     * <p> If there is a security manager, its {@link
+     * SecurityManager#checkCreateClassLoader()
+     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
+     * a security exception.  </p>
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
+     *          of a new class loader.
+     */
+    protected ClassLoader() {
+        this(checkCreateClassLoader(), getSystemClassLoader());
+    }
+
+    // -- Class --
+
+    /**
+     * Loads the class with the specified <a href="#name">binary name</a>.
+     * This method searches for classes in the same manner as the {@link
+     * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
+     * machine to resolve class references.  Invoking this method is equivalent
+     * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
+     * false)</tt>}.
+     *
+     * @param  name
+     *         The <a href="#name">binary name</a> of the class
+     *
+     * @return  The resulting <tt>Class</tt> object
+     *
+     * @throws  ClassNotFoundException
+     *          If the class was not found
+     */
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        return loadClass(name, false);
+    }
+
+    /**
+     * Loads the class with the specified <a href="#name">binary name</a>.  The
+     * default implementation of this method searches for classes in the
+     * following order:
+     *
+     * <ol>
+     *
+     *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
+     *   has already been loaded.  </p></li>
+     *
+     *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
+     *   on the parent class loader.  If the parent is <tt>null</tt> the class
+     *   loader built-in to the virtual machine is used, instead.  </p></li>
+     *
+     *   <li><p> Invoke the {@link #findClass(String)} method to find the
+     *   class.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> If the class was found using the above steps, and the
+     * <tt>resolve</tt> flag is true, this method will then invoke the {@link
+     * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
+     *
+     * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
+     * #findClass(String)}, rather than this method.  </p>
+     *
+     *
+     * @param  name
+     *         The <a href="#name">binary name</a> of the class
+     *
+     * @param  resolve
+     *         If <tt>true</tt> then resolve the class
+     *
+     * @return  The resulting <tt>Class</tt> object
+     *
+     * @throws  ClassNotFoundException
+     *          If the class could not be found
+     */
+    // Android-removed: Remove references to getClassLoadingLock
+    //                   Remove perf counters.
+    //
+    // <p> Unless overridden, this method synchronizes on the result of
+    // {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
+    // during the entire class loading process.
+    protected Class<?> loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+            // First, check if the class has already been loaded
+            Class<?> c = findLoadedClass(name);
+            if (c == null) {
+                try {
+                    if (parent != null) {
+                        c = parent.loadClass(name, false);
+                    } else {
+                        c = findBootstrapClassOrNull(name);
+                    }
+                } catch (ClassNotFoundException e) {
+                    // ClassNotFoundException thrown if class not found
+                    // from the non-null parent class loader
+                }
+
+                if (c == null) {
+                    // If still not found, then invoke findClass in order
+                    // to find the class.
+                    c = findClass(name);
+                }
+            }
+            return c;
+    }
+
+
+    /**
+     * Finds the class with the specified <a href="#name">binary name</a>.
+     * This method should be overridden by class loader implementations that
+     * follow the delegation model for loading classes, and will be invoked by
+     * the {@link #loadClass <tt>loadClass</tt>} method after checking the
+     * parent class loader for the requested class.  The default implementation
+     * throws a <tt>ClassNotFoundException</tt>.
+     *
+     * @param  name
+     *         The <a href="#name">binary name</a> of the class
+     *
+     * @return  The resulting <tt>Class</tt> object
+     *
+     * @throws  ClassNotFoundException
+     *          If the class could not be found
+     *
+     * @since  1.2
+     */
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        throw new ClassNotFoundException(name);
+    }
+
+    /**
+     * Converts an array of bytes into an instance of class <tt>Class</tt>.
+     * Before the <tt>Class</tt> can be used it must be resolved.  This method
+     * is deprecated in favor of the version that takes a <a
+     * href="#name">binary name</a> as its first argument, and is more secure.
+     *
+     * @param  b
+     *         The bytes that make up the class data.  The bytes in positions
+     *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
+     *         of a valid class file as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *
+     * @param  off
+     *         The start offset in <tt>b</tt> of the class data
+     *
+     * @param  len
+     *         The length of the class data
+     *
+     * @return  The <tt>Class</tt> object that was created from the specified
+     *          class data
+     *
+     * @throws  ClassFormatError
+     *          If the data did not contain a valid class
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
+     *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
+     *
+     * @throws  SecurityException
+     *          If an attempt is made to add this class to a package that
+     *          contains classes that were signed by a different set of
+     *          certificates than this class, or if an attempt is made
+     *          to define a class in a package with a fully-qualified name
+     *          that starts with "{@code java.}".
+     *
+     * @see  #loadClass(String, boolean)
+     * @see  #resolveClass(Class)
+     *
+     * @deprecated  Replaced by {@link #defineClass(String, byte[], int, int)
+     * defineClass(String, byte[], int, int)}
+     */
+    @Deprecated
+    protected final Class<?> defineClass(byte[] b, int off, int len)
+        throws ClassFormatError
+    {
+        throw new UnsupportedOperationException("can't load this type of class file");
+    }
+
+    /**
+     * Converts an array of bytes into an instance of class <tt>Class</tt>.
+     * Before the <tt>Class</tt> can be used it must be resolved.
+     *
+     * <p> This method assigns a default {@link java.security.ProtectionDomain
+     * <tt>ProtectionDomain</tt>} to the newly defined class.  The
+     * <tt>ProtectionDomain</tt> is effectively granted the same set of
+     * permissions returned when {@link
+     * java.security.Policy#getPermissions(java.security.CodeSource)
+     * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
+     * is invoked.  The default domain is created on the first invocation of
+     * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
+     * and re-used on subsequent invocations.
+     *
+     * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
+     * the {@link #defineClass(String, byte[], int, int,
+     * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
+     * <tt>ProtectionDomain</tt> as one of its arguments.  </p>
+     *
+     * @param  name
+     *         The expected <a href="#name">binary name</a> of the class, or
+     *         <tt>null</tt> if not known
+     *
+     * @param  b
+     *         The bytes that make up the class data.  The bytes in positions
+     *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
+     *         of a valid class file as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *
+     * @param  off
+     *         The start offset in <tt>b</tt> of the class data
+     *
+     * @param  len
+     *         The length of the class data
+     *
+     * @return  The <tt>Class</tt> object that was created from the specified
+     *          class data.
+     *
+     * @throws  ClassFormatError
+     *          If the data did not contain a valid class
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
+     *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
+     *
+     * @throws  SecurityException
+     *          If an attempt is made to add this class to a package that
+     *          contains classes that were signed by a different set of
+     *          certificates than this class (which is unsigned), or if
+     *          <tt>name</tt> begins with "<tt>java.</tt>".
+     *
+     * @see  #loadClass(String, boolean)
+     * @see  #resolveClass(Class)
+     * @see  java.security.CodeSource
+     * @see  java.security.SecureClassLoader
+     *
+     * @since  1.1
+     */
+    protected final Class<?> defineClass(String name, byte[] b, int off, int len)
+        throws ClassFormatError
+    {
+        throw new UnsupportedOperationException("can't load this type of class file");
+    }
+
+
+    /**
+     * Converts an array of bytes into an instance of class <tt>Class</tt>,
+     * with an optional <tt>ProtectionDomain</tt>.  If the domain is
+     * <tt>null</tt>, then a default domain will be assigned to the class as
+     * specified in the documentation for {@link #defineClass(String, byte[],
+     * int, int)}.  Before the class can be used it must be resolved.
+     *
+     * <p> The first class defined in a package determines the exact set of
+     * certificates that all subsequent classes defined in that package must
+     * contain.  The set of certificates for a class is obtained from the
+     * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
+     * <tt>ProtectionDomain</tt> of the class.  Any classes added to that
+     * package must contain the same set of certificates or a
+     * <tt>SecurityException</tt> will be thrown.  Note that if
+     * <tt>name</tt> is <tt>null</tt>, this check is not performed.
+     * You should always pass in the <a href="#name">binary name</a> of the
+     * class you are defining as well as the bytes.  This ensures that the
+     * class you are defining is indeed the class you think it is.
+     *
+     * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
+     * all classes in the "<tt>java.*</tt> packages can only be defined by the
+     * bootstrap class loader.  If <tt>name</tt> is not <tt>null</tt>, it
+     * must be equal to the <a href="#name">binary name</a> of the class
+     * specified by the byte array "<tt>b</tt>", otherwise a {@link
+     * NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>
+     *
+     * @param  name
+     *         The expected <a href="#name">binary name</a> of the class, or
+     *         <tt>null</tt> if not known
+     *
+     * @param  b
+     *         The bytes that make up the class data. The bytes in positions
+     *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
+     *         of a valid class file as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *
+     * @param  off
+     *         The start offset in <tt>b</tt> of the class data
+     *
+     * @param  len
+     *         The length of the class data
+     *
+     * @param  protectionDomain
+     *         The ProtectionDomain of the class
+     *
+     * @return  The <tt>Class</tt> object created from the data,
+     *          and optional <tt>ProtectionDomain</tt>.
+     *
+     * @throws  ClassFormatError
+     *          If the data did not contain a valid class
+     *
+     * @throws  NoClassDefFoundError
+     *          If <tt>name</tt> is not equal to the <a href="#name">binary
+     *          name</a> of the class specified by <tt>b</tt>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
+     *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
+     *
+     * @throws  SecurityException
+     *          If an attempt is made to add this class to a package that
+     *          contains classes that were signed by a different set of
+     *          certificates than this class, or if <tt>name</tt> begins with
+     *          "<tt>java.</tt>".
+     */
+    // Android-changed: Remove <tt> from link for NoClassDefFoundError
+    protected final Class<?> defineClass(String name, byte[] b, int off, int len,
+                                         ProtectionDomain protectionDomain)
+        throws ClassFormatError
+    {
+        throw new UnsupportedOperationException("can't load this type of class file");
+    }
+
+    /**
+     * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
+     * into an instance of class <tt>Class</tt>,
+     * with an optional <tt>ProtectionDomain</tt>.  If the domain is
+     * <tt>null</tt>, then a default domain will be assigned to the class as
+     * specified in the documentation for {@link #defineClass(String, byte[],
+     * int, int)}.  Before the class can be used it must be resolved.
+     *
+     * <p>The rules about the first class defined in a package determining the
+     * set of certificates for the package, and the restrictions on class names
+     * are identical to those specified in the documentation for {@link
+     * #defineClass(String, byte[], int, int, ProtectionDomain)}.
+     *
+     * <p> An invocation of this method of the form
+     * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
+     * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
+     * result as the statements
+     *
+     *<p> <tt>
+     * ...<br>
+     * byte[] temp = new byte[bBuffer.{@link
+     * java.nio.ByteBuffer#remaining remaining}()];<br>
+     *     bBuffer.{@link java.nio.ByteBuffer#get(byte[])
+     * get}(temp);<br>
+     *     return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
+     * cl.defineClass}(name, temp, 0,
+     * temp.length, pd);<br>
+     * </tt></p>
+     *
+     * @param  name
+     *         The expected <a href="#name">binary name</a>. of the class, or
+     *         <tt>null</tt> if not known
+     *
+     * @param  b
+     *         The bytes that make up the class data. The bytes from positions
+     *         <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
+     *         </tt> should have the format of a valid class file as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *
+     * @param  protectionDomain
+     *         The ProtectionDomain of the class, or <tt>null</tt>.
+     *
+     * @return  The <tt>Class</tt> object created from the data,
+     *          and optional <tt>ProtectionDomain</tt>.
+     *
+     * @throws  ClassFormatError
+     *          If the data did not contain a valid class.
+     *
+     * @throws  NoClassDefFoundError
+     *          If <tt>name</tt> is not equal to the <a href="#name">binary
+     *          name</a> of the class specified by <tt>b</tt>
+     *
+     * @throws  SecurityException
+     *          If an attempt is made to add this class to a package that
+     *          contains classes that were signed by a different set of
+     *          certificates than this class, or if <tt>name</tt> begins with
+     *          "<tt>java.</tt>".
+     *
+     * @see      #defineClass(String, byte[], int, int, ProtectionDomain)
+     *
+     * @since  1.5
+     */
+    protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
+                                         ProtectionDomain protectionDomain)
+        throws ClassFormatError
+    {
+        throw new UnsupportedOperationException("can't load this type of class file");
+    }
+
+    /**
+     * Links the specified class.  This (misleadingly named) method may be
+     * used by a class loader to link a class.  If the class <tt>c</tt> has
+     * already been linked, then this method simply returns. Otherwise, the
+     * class is linked as described in the "Execution" chapter of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @param  c
+     *         The class to link
+     *
+     * @throws  NullPointerException
+     *          If <tt>c</tt> is <tt>null</tt>.
+     *
+     * @see  #defineClass(String, byte[], int, int)
+     */
+    protected final void resolveClass(Class<?> c) {
+    }
+
+    /**
+     * Finds a class with the specified <a href="#name">binary name</a>,
+     * loading it if necessary.
+     *
+     * <p> This method loads the class through the system class loader (see
+     * {@link #getSystemClassLoader()}).  The <tt>Class</tt> object returned
+     * might have more than one <tt>ClassLoader</tt> associated with it.
+     * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
+     * because most class loaders need to override just {@link
+     * #findClass(String)}.  </p>
+     *
+     * @param  name
+     *         The <a href="#name">binary name</a> of the class
+     *
+     * @return  The <tt>Class</tt> object for the specified <tt>name</tt>
+     *
+     * @throws  ClassNotFoundException
+     *          If the class could not be found
+     *
+     * @see  #ClassLoader(ClassLoader)
+     * @see  #getParent()
+     */
+    protected final Class<?> findSystemClass(String name)
+        throws ClassNotFoundException
+    {
+        return Class.forName(name, false, getSystemClassLoader());
+    }
+
+    /**
+     * Returns a class loaded by the bootstrap class loader;
+     * or return null if not found.
+     */
+    private Class<?> findBootstrapClassOrNull(String name)
+    {
+        return null;
+    }
+
+    /**
+     * Returns the class with the given <a href="#name">binary name</a> if this
+     * loader has been recorded by the Java virtual machine as an initiating
+     * loader of a class with that <a href="#name">binary name</a>.  Otherwise
+     * <tt>null</tt> is returned.
+     *
+     * @param  name
+     *         The <a href="#name">binary name</a> of the class
+     *
+     * @return  The <tt>Class</tt> object, or <tt>null</tt> if the class has
+     *          not been loaded
+     *
+     * @since  1.1
+     */
+    protected final Class<?> findLoadedClass(String name) {
+        ClassLoader loader;
+        if (this == BootClassLoader.getInstance())
+            loader = null;
+        else
+            loader = this;
+        return VMClassLoader.findLoadedClass(loader, name);
+    }
+
+    /**
+     * Sets the signers of a class.  This should be invoked after defining a
+     * class.
+     *
+     * @param  c
+     *         The <tt>Class</tt> object
+     *
+     * @param  signers
+     *         The signers for the class
+     *
+     * @since  1.1
+     */
+    protected final void setSigners(Class<?> c, Object[] signers) {
+    }
+
+
+    // -- Resource --
+
+    /**
+     * Finds the resource with the given name.  A resource is some data
+     * (images, audio, text, etc) that can be accessed by class code in a way
+     * that is independent of the location of the code.
+     *
+     * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
+     * identifies the resource.
+     *
+     * <p> This method will first search the parent class loader for the
+     * resource; if the parent is <tt>null</tt> the path of the class loader
+     * built-in to the virtual machine is searched.  That failing, this method
+     * will invoke {@link #findResource(String)} to find the resource.  </p>
+     *
+     * @apiNote When overriding this method it is recommended that an
+     * implementation ensures that any delegation is consistent with the {@link
+     * #getResources(java.lang.String) getResources(String)} method.
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  A <tt>URL</tt> object for reading the resource, or
+     *          <tt>null</tt> if the resource could not be found or the invoker
+     *          doesn't have adequate  privileges to get the resource.
+     *
+     * @since  1.1
+     */
+    public URL getResource(String name) {
+        URL url;
+        if (parent != null) {
+            url = parent.getResource(name);
+        } else {
+            url = getBootstrapResource(name);
+        }
+        if (url == null) {
+            url = findResource(name);
+        }
+        return url;
+    }
+
+    /**
+     * Finds all the resources with the given name. A resource is some data
+     * (images, audio, text, etc) that can be accessed by class code in a way
+     * that is independent of the location of the code.
+     *
+     * <p>The name of a resource is a <tt>/</tt>-separated path name that
+     * identifies the resource.
+     *
+     * <p> The search order is described in the documentation for {@link
+     * #getResource(String)}.  </p>
+     *
+     * @apiNote When overriding this method it is recommended that an
+     * implementation ensures that any delegation is consistent with the {@link
+     * #getResource(java.lang.String) getResource(String)} method. This should
+     * ensure that the first element returned by the Enumeration's
+     * {@code nextElement} method is the same resource that the
+     * {@code getResource(String)} method would return.
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+     *          the resource.  If no resources could  be found, the enumeration
+     *          will be empty.  Resources that the class loader doesn't have
+     *          access to will not be in the enumeration.
+     *
+     * @throws  IOException
+     *          If I/O errors occur
+     *
+     * @see  #findResources(String)
+     *
+     * @since  1.2
+     */
+    public Enumeration<URL> getResources(String name) throws IOException {
+        @SuppressWarnings("unchecked")
+        Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
+        if (parent != null) {
+            tmp[0] = parent.getResources(name);
+        } else {
+            tmp[0] = getBootstrapResources(name);
+        }
+        tmp[1] = findResources(name);
+
+        return new CompoundEnumeration<>(tmp);
+    }
+
+    /**
+     * Finds the resource with the given name. Class loader implementations
+     * should override this method to specify where to find resources.
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  A <tt>URL</tt> object for reading the resource, or
+     *          <tt>null</tt> if the resource could not be found
+     *
+     * @since  1.2
+     */
+    protected URL findResource(String name) {
+        return null;
+    }
+
+    /**
+     * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
+     * representing all the resources with the given name. Class loader
+     * implementations should override this method to specify where to load
+     * resources from.
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+     *          the resources
+     *
+     * @throws  IOException
+     *          If I/O errors occur
+     *
+     * @since  1.2
+     */
+    protected Enumeration<URL> findResources(String name) throws IOException {
+        return java.util.Collections.emptyEnumeration();
+    }
+
+    /**
+     * Registers the caller as parallel capable.
+     * The registration succeeds if and only if all of the following
+     * conditions are met:
+     * <ol>
+     * <li> no instance of the caller has been created</li>
+     * <li> all of the super classes (except class Object) of the caller are
+     * registered as parallel capable</li>
+     * </ol>
+     * <p>Note that once a class loader is registered as parallel capable, there
+     * is no way to change it back.</p>
+     *
+     * @return  true if the caller is successfully registered as
+     *          parallel capable and false if otherwise.
+     *
+     * @since   1.7
+     */
+    @CallerSensitive
+    protected static boolean registerAsParallelCapable() {
+        return true;
+    }
+
+    /**
+     * Find a resource of the specified name from the search path used to load
+     * classes.  This method locates the resource through the system class
+     * loader (see {@link #getSystemClassLoader()}).
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
+     *          resource, or <tt>null</tt> if the resource could not be found
+     *
+     * @since  1.1
+     */
+    public static URL getSystemResource(String name) {
+        ClassLoader system = getSystemClassLoader();
+        if (system == null) {
+            return getBootstrapResource(name);
+        }
+        return system.getResource(name);
+    }
+
+    /**
+     * Finds all resources of the specified name from the search path used to
+     * load classes.  The resources thus found are returned as an
+     * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
+     * java.net.URL <tt>URL</tt>} objects.
+     *
+     * <p> The search order is described in the documentation for {@link
+     * #getSystemResource(String)}.  </p>
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An enumeration of resource {@link java.net.URL <tt>URL</tt>}
+     *          objects
+     *
+     * @throws  IOException
+     *          If I/O errors occur
+
+     * @since  1.2
+     */
+    public static Enumeration<URL> getSystemResources(String name)
+        throws IOException
+    {
+        ClassLoader system = getSystemClassLoader();
+        if (system == null) {
+            return getBootstrapResources(name);
+        }
+        return system.getResources(name);
+    }
+
+    /**
+     * Find resources from the VM's built-in classloader.
+     */
+    private static URL getBootstrapResource(String name) {
+        return null;
+    }
+
+    /**
+     * Find resources from the VM's built-in classloader.
+     */
+    private static Enumeration<URL> getBootstrapResources(String name)
+        throws IOException
+    {
+        return null;
+    }
+
+
+
+    /**
+     * Returns an input stream for reading the specified resource.
+     *
+     * <p> The search order is described in the documentation for {@link
+     * #getResource(String)}.  </p>
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An input stream for reading the resource, or <tt>null</tt>
+     *          if the resource could not be found
+     *
+     * @since  1.1
+     */
+    public InputStream getResourceAsStream(String name) {
+        URL url = getResource(name);
+        try {
+            return url != null ? url.openStream() : null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Open for reading, a resource of the specified name from the search path
+     * used to load classes.  This method locates the resource through the
+     * system class loader (see {@link #getSystemClassLoader()}).
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An input stream for reading the resource, or <tt>null</tt>
+     *          if the resource could not be found
+     *
+     * @since  1.1
+     */
+    public static InputStream getSystemResourceAsStream(String name) {
+        URL url = getSystemResource(name);
+        try {
+            return url != null ? url.openStream() : null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+
+    // -- Hierarchy --
+
+    /**
+     * Returns the parent class loader for delegation. Some implementations may
+     * use <tt>null</tt> to represent the bootstrap class loader. This method
+     * will return <tt>null</tt> in such implementations if this class loader's
+     * parent is the bootstrap class loader.
+     *
+     * <p> If a security manager is present, and the invoker's class loader is
+     * not <tt>null</tt> and is not an ancestor of this class loader, then this
+     * method invokes the security manager's {@link
+     * SecurityManager#checkPermission(java.security.Permission)
+     * <tt>checkPermission</tt>} method with a {@link
+     * RuntimePermission#RuntimePermission(String)
+     * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
+     * access to the parent class loader is permitted.  If not, a
+     * <tt>SecurityException</tt> will be thrown.  </p>
+     *
+     * @return  The parent <tt>ClassLoader</tt>
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its <tt>checkPermission</tt>
+     *          method doesn't allow access to this class loader's parent class
+     *          loader.
+     *
+     * @since  1.2
+     */
+    @CallerSensitive
+    public final ClassLoader getParent() {
+        return parent;
+    }
+
+    // Android-changed: Removed "java.system.class.loader" paragraph.
+    /**
+     * Returns the system class loader for delegation.  This is the default
+     * delegation parent for new <tt>ClassLoader</tt> instances, and is
+     * typically the class loader used to start the application.
+     *
+     * <p> This method is first invoked early in the runtime's startup
+     * sequence, at which point it creates the system class loader and sets it
+     * as the context class loader of the invoking <tt>Thread</tt>.
+     *
+     * <p> The default system class loader is an implementation-dependent
+     * instance of this class.
+     *
+     * <p> If a security manager is present, and the invoker's class loader is
+     * not <tt>null</tt> and the invoker's class loader is not the same as or
+     * an ancestor of the system class loader, then this method invokes the
+     * security manager's {@link
+     * SecurityManager#checkPermission(java.security.Permission)
+     * <tt>checkPermission</tt>} method with a {@link
+     * RuntimePermission#RuntimePermission(String)
+     * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
+     * access to the system class loader.  If not, a
+     * <tt>SecurityException</tt> will be thrown.  </p>
+     *
+     * @return  The system <tt>ClassLoader</tt> for delegation, or
+     *          <tt>null</tt> if none
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its <tt>checkPermission</tt>
+     *          method doesn't allow access to the system class loader.
+     *
+     * @throws  IllegalStateException
+     *          If invoked recursively during the construction of the class
+     *          loader specified by the "<tt>java.system.class.loader</tt>"
+     *          property.
+     *
+     * @throws  Error
+     *          If the system property "<tt>java.system.class.loader</tt>"
+     *          is defined but the named class could not be loaded, the
+     *          provider class does not define the required constructor, or an
+     *          exception is thrown by that constructor when it is invoked. The
+     *          underlying cause of the error can be retrieved via the
+     *          {@link Throwable#getCause()} method.
+     *
+     * @revised  1.4
+     */
+    @CallerSensitive
+    public static ClassLoader getSystemClassLoader() {
+        return SystemClassLoader.loader;
+    }
+
+    // Returns the class's class loader, or null if none.
+    static ClassLoader getClassLoader(Class<?> caller) {
+        // This can be null if the VM is requesting it
+        if (caller == null) {
+            return null;
+        }
+        // Android-changed: Use Class.getClassLoader(); there is no Class.getClassLoader0().
+        // // Circumvent security check since this is package-private
+        // return caller.getClassLoader0();
+        return caller.getClassLoader();
+    }
+
+    // -- Package --
+
+    /**
+     * Defines a package by name in this <tt>ClassLoader</tt>.  This allows
+     * class loaders to define the packages for their classes. Packages must
+     * be created before the class is defined, and package names must be
+     * unique within a class loader and cannot be redefined or changed once
+     * created.
+     *
+     * @param  name
+     *         The package name
+     *
+     * @param  specTitle
+     *         The specification title
+     *
+     * @param  specVersion
+     *         The specification version
+     *
+     * @param  specVendor
+     *         The specification vendor
+     *
+     * @param  implTitle
+     *         The implementation title
+     *
+     * @param  implVersion
+     *         The implementation version
+     *
+     * @param  implVendor
+     *         The implementation vendor
+     *
+     * @param  sealBase
+     *         If not <tt>null</tt>, then this package is sealed with
+     *         respect to the given code source {@link java.net.URL
+     *         <tt>URL</tt>}  object.  Otherwise, the package is not sealed.
+     *
+     * @return  The newly defined <tt>Package</tt> object
+     *
+     * @throws  IllegalArgumentException
+     *          If package name duplicates an existing package either in this
+     *          class loader or one of its ancestors
+     *
+     * @since  1.2
+     */
+    protected Package definePackage(String name, String specTitle,
+                                    String specVersion, String specVendor,
+                                    String implTitle, String implVersion,
+                                    String implVendor, URL sealBase)
+        throws IllegalArgumentException
+    {
+        synchronized (packages) {
+            Package pkg = packages.get(name);
+            if (pkg != null) {
+                throw new IllegalArgumentException(name);
+            }
+            pkg = new Package(name, specTitle, specVersion, specVendor,
+                              implTitle, implVersion, implVendor,
+                              sealBase, this);
+            packages.put(name, pkg);
+            return pkg;
+        }
+    }
+
+    /**
+     * Returns a <tt>Package</tt> that has been defined by this class loader
+     * or any of its ancestors.
+     *
+     * @param  name
+     *         The package name
+     *
+     * @return  The <tt>Package</tt> corresponding to the given name, or
+     *          <tt>null</tt> if not found
+     *
+     * @since  1.2
+     */
+    protected Package getPackage(String name) {
+        Package pkg;
+        synchronized (packages) {
+            pkg = packages.get(name);
+        }
+        return pkg;
+    }
+
+    /**
+     * Returns all of the <tt>Packages</tt> defined by this class loader and
+     * its ancestors.
+     *
+     * @return  The array of <tt>Package</tt> objects defined by this
+     *          <tt>ClassLoader</tt>
+     *
+     * @since  1.2
+     */
+    protected Package[] getPackages() {
+        Map<String, Package> map;
+        synchronized (packages) {
+            map = new HashMap<>(packages);
+        }
+        Package[] pkgs;
+        return map.values().toArray(new Package[map.size()]);
+    }
+
+
+    // -- Native library access --
+
+    /**
+     * Returns the absolute path name of a native library.  The VM invokes this
+     * method to locate the native libraries that belong to classes loaded with
+     * this class loader. If this method returns <tt>null</tt>, the VM
+     * searches the library along the path specified as the
+     * "<tt>java.library.path</tt>" property.
+     *
+     * @param  libname
+     *         The library name
+     *
+     * @return  The absolute path of the native library
+     *
+     * @see  System#loadLibrary(String)
+     * @see  System#mapLibraryName(String)
+     *
+     * @since  1.2
+     */
+    protected String findLibrary(String libname) {
+        return null;
+    }
+
+    /**
+     * Sets the default assertion status for this class loader.  This setting
+     * determines whether classes loaded by this class loader and initialized
+     * in the future will have assertions enabled or disabled by default.
+     * This setting may be overridden on a per-package or per-class basis by
+     * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
+     * #setClassAssertionStatus(String, boolean)}.
+     *
+     * @param  enabled
+     *         <tt>true</tt> if classes loaded by this class loader will
+     *         henceforth have assertions enabled by default, <tt>false</tt>
+     *         if they will have assertions disabled by default.
+     *
+     * @since  1.4
+     */
+    public void setDefaultAssertionStatus(boolean enabled) {
+    }
+
+    /**
+     * Sets the package default assertion status for the named package.  The
+     * package default assertion status determines the assertion status for
+     * classes initialized in the future that belong to the named package or
+     * any of its "subpackages".
+     *
+     * <p> A subpackage of a package named p is any package whose name begins
+     * with "<tt>p.</tt>".  For example, <tt>javax.swing.text</tt> is a
+     * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
+     * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
+     *
+     * <p> In the event that multiple package defaults apply to a given class,
+     * the package default pertaining to the most specific package takes
+     * precedence over the others.  For example, if <tt>javax.lang</tt> and
+     * <tt>javax.lang.reflect</tt> both have package defaults associated with
+     * them, the latter package default applies to classes in
+     * <tt>javax.lang.reflect</tt>.
+     *
+     * <p> Package defaults take precedence over the class loader's default
+     * assertion status, and may be overridden on a per-class basis by invoking
+     * {@link #setClassAssertionStatus(String, boolean)}.  </p>
+     *
+     * @param  packageName
+     *         The name of the package whose package default assertion status
+     *         is to be set. A <tt>null</tt> value indicates the unnamed
+     *         package that is "current"
+     *         (see section 7.4.2 of
+     *         <cite>The Java&trade; Language Specification</cite>.)
+     *
+     * @param  enabled
+     *         <tt>true</tt> if classes loaded by this classloader and
+     *         belonging to the named package or any of its subpackages will
+     *         have assertions enabled by default, <tt>false</tt> if they will
+     *         have assertions disabled by default.
+     *
+     * @since  1.4
+     */
+    public void setPackageAssertionStatus(String packageName,
+                                          boolean enabled) {
+    }
+
+    /**
+     * Sets the desired assertion status for the named top-level class in this
+     * class loader and any nested classes contained therein.  This setting
+     * takes precedence over the class loader's default assertion status, and
+     * over any applicable per-package default.  This method has no effect if
+     * the named class has already been initialized.  (Once a class is
+     * initialized, its assertion status cannot change.)
+     *
+     * <p> If the named class is not a top-level class, this invocation will
+     * have no effect on the actual assertion status of any class. </p>
+     *
+     * @param  className
+     *         The fully qualified class name of the top-level class whose
+     *         assertion status is to be set.
+     *
+     * @param  enabled
+     *         <tt>true</tt> if the named class is to have assertions
+     *         enabled when (and if) it is initialized, <tt>false</tt> if the
+     *         class is to have assertions disabled.
+     *
+     * @since  1.4
+     */
+    public void setClassAssertionStatus(String className, boolean enabled) {
+    }
+
+    /**
+     * Sets the default assertion status for this class loader to
+     * <tt>false</tt> and discards any package defaults or class assertion
+     * status settings associated with the class loader.  This method is
+     * provided so that class loaders can be made to ignore any command line or
+     * persistent assertion status settings and "start with a clean slate."
+     *
+     * @since  1.4
+     */
+    public void clearAssertionStatus() {
+        /*
+         * Whether or not "Java assertion maps" are initialized, set
+         * them to empty maps, effectively ignoring any present settings.
+         */
+    }
+}
+
+
+class BootClassLoader extends ClassLoader {
+
+    private static BootClassLoader instance;
+
+    @FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
+    public static synchronized BootClassLoader getInstance() {
+        if (instance == null) {
+            instance = new BootClassLoader();
+        }
+
+        return instance;
+    }
+
+    public BootClassLoader() {
+        super(null);
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        return Class.classForName(name, false, null);
+    }
+
+    @Override
+    protected URL findResource(String name) {
+        return VMClassLoader.getResource(name);
+    }
+
+    @SuppressWarnings("unused")
+    @Override
+    protected Enumeration<URL> findResources(String resName) throws IOException {
+        return Collections.enumeration(VMClassLoader.getResources(resName));
+    }
+
+    /**
+     * Returns package information for the given package. Unfortunately, the
+     * Android BootClassLoader doesn't really have this information, and as a
+     * non-secure ClassLoader, it isn't even required to, according to the spec.
+     * Yet, we want to provide it, in order to make all those hopeful callers of
+     * {@code myClass.getPackage().getName()} happy. Thus we construct a Package
+     * object the first time it is being requested and fill most of the fields
+     * with dummy values. The Package object is then put into the ClassLoader's
+     * Package cache, so we see the same one next time. We don't create Package
+     * objects for null arguments or for the default package.
+     * <p>
+     * There a limited chance that we end up with multiple Package objects
+     * representing the same package: It can happen when when a package is
+     * scattered across different JAR files being loaded by different
+     * ClassLoaders. Rather unlikely, and given that this whole thing is more or
+     * less a workaround, probably not worth the effort.
+     */
+    @Override
+    protected Package getPackage(String name) {
+        if (name != null && !name.isEmpty()) {
+            synchronized (this) {
+                Package pack = super.getPackage(name);
+
+                if (pack == null) {
+                    pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0",
+                            "Unknown", null);
+                }
+
+                return pack;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public URL getResource(String resName) {
+        return findResource(resName);
+    }
+
+    @Override
+    protected Class<?> loadClass(String className, boolean resolve)
+           throws ClassNotFoundException {
+        Class<?> clazz = findLoadedClass(className);
+
+        if (clazz == null) {
+            clazz = findClass(className);
+        }
+
+        return clazz;
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resName) throws IOException {
+        return findResources(resName);
+    }
+}
diff --git a/java/lang/ClassNotFoundException.java b/java/lang/ClassNotFoundException.java
new file mode 100644
index 0000000..1211e9f
--- /dev/null
+++ b/java/lang/ClassNotFoundException.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1995, 2004, 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;
+
+/**
+ * Thrown when an application tries to load in a class through its
+ * string name using:
+ * <ul>
+ * <li>The <code>forName</code> method in class <code>Class</code>.
+ * <li>The <code>findSystemClass</code> method in class
+ *     <code>ClassLoader</code> .
+ * <li>The <code>loadClass</code> method in class <code>ClassLoader</code>.
+ * </ul>
+ * <p>
+ * but no definition for the class with the specified name could be found.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism.  The "optional exception
+ * that was raised while loading the class" that may be provided at
+ * construction time and accessed via the {@link #getException()} method is
+ * now known as the <i>cause</i>, and may be accessed via the {@link
+ * Throwable#getCause()} method, as well as the aforementioned "legacy method."
+ *
+ * @author  unascribed
+ * @see     java.lang.Class#forName(java.lang.String)
+ * @see     java.lang.ClassLoader#findSystemClass(java.lang.String)
+ * @see     java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ * @since   JDK1.0
+ */
+public class ClassNotFoundException extends ReflectiveOperationException {
+    /**
+     * use serialVersionUID from JDK 1.1.X for interoperability
+     */
+     private static final long serialVersionUID = 9176873029745254542L;
+
+    /**
+     * This field holds the exception ex if the
+     * ClassNotFoundException(String s, Throwable ex) constructor was
+     * used to instantiate the object
+     * @serial
+     * @since 1.2
+     */
+    private Throwable ex;
+
+    /**
+     * Constructs a <code>ClassNotFoundException</code> with no detail message.
+     */
+    public ClassNotFoundException() {
+        super((Throwable)null);  // Disallow initCause
+    }
+
+    /**
+     * Constructs a <code>ClassNotFoundException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public ClassNotFoundException(String s) {
+        super(s, null);  //  Disallow initCause
+    }
+
+    /**
+     * Constructs a <code>ClassNotFoundException</code> with the
+     * specified detail message and optional exception that was
+     * raised while loading the class.
+     *
+     * @param s the detail message
+     * @param ex the exception that was raised while loading the class
+     * @since 1.2
+     */
+    public ClassNotFoundException(String s, Throwable ex) {
+        super(s, null);  //  Disallow initCause
+        this.ex = ex;
+    }
+
+    /**
+     * Returns the exception that was raised if an error occurred while
+     * attempting to load the class. Otherwise, returns <tt>null</tt>.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the <code>Exception</code> that was raised while loading a class
+     * @since 1.2
+     */
+    public Throwable getException() {
+        return ex;
+    }
+
+    /**
+     * Returns the cause of this exception (the exception that was raised
+     * if an error occurred while attempting to load the class; otherwise
+     * <tt>null</tt>).
+     *
+     * @return  the cause of this exception.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return ex;
+    }
+}
diff --git a/java/lang/CloneNotSupportedException.java b/java/lang/CloneNotSupportedException.java
new file mode 100644
index 0000000..e43901c
--- /dev/null
+++ b/java/lang/CloneNotSupportedException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that the <code>clone</code> method in class
+ * <code>Object</code> has been called to clone an object, but that
+ * the object's class does not implement the <code>Cloneable</code>
+ * interface.
+ * <p>
+ * Applications that override the <code>clone</code> method can also
+ * throw this exception to indicate that an object could not or
+ * should not be cloned.
+ *
+ * @author  unascribed
+ * @see     java.lang.Cloneable
+ * @see     java.lang.Object#clone()
+ * @since   JDK1.0
+ */
+
+public
+class CloneNotSupportedException extends Exception {
+    private static final long serialVersionUID = 5195511250079656443L;
+
+    /**
+     * Constructs a <code>CloneNotSupportedException</code> with no
+     * detail message.
+     */
+    public CloneNotSupportedException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>CloneNotSupportedException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public CloneNotSupportedException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/Cloneable.java b/java/lang/Cloneable.java
new file mode 100644
index 0000000..14cf2a9
--- /dev/null
+++ b/java/lang/Cloneable.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 2004, 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;
+
+/**
+ * A class implements the <code>Cloneable</code> interface to
+ * indicate to the {@link java.lang.Object#clone()} method that it
+ * is legal for that method to make a
+ * field-for-field copy of instances of that class.
+ * <p>
+ * Invoking Object's clone method on an instance that does not implement the
+ * <code>Cloneable</code> interface results in the exception
+ * <code>CloneNotSupportedException</code> being thrown.
+ * <p>
+ * By convention, classes that implement this interface should override
+ * <tt>Object.clone</tt> (which is protected) with a public method.
+ * See {@link java.lang.Object#clone()} for details on overriding this
+ * method.
+ * <p>
+ * Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
+ * Therefore, it is not possible to clone an object merely by virtue of the
+ * fact that it implements this interface.  Even if the clone method is invoked
+ * reflectively, there is no guarantee that it will succeed.
+ *
+ * @author  unascribed
+ * @see     java.lang.CloneNotSupportedException
+ * @see     java.lang.Object#clone()
+ * @since   JDK1.0
+ */
+public interface Cloneable {
+}
diff --git a/java/lang/Comparable.java b/java/lang/Comparable.java
new file mode 100644
index 0000000..a88cf16
--- /dev/null
+++ b/java/lang/Comparable.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1997, 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;
+import java.util.*;
+
+/**
+ * This interface imposes a total ordering on the objects of each class that
+ * implements it.  This ordering is referred to as the class's <i>natural
+ * ordering</i>, and the class's <tt>compareTo</tt> method is referred to as
+ * its <i>natural comparison method</i>.<p>
+ *
+ * Lists (and arrays) of objects that implement this interface can be sorted
+ * automatically by {@link Collections#sort(List) Collections.sort} (and
+ * {@link Arrays#sort(Object[]) Arrays.sort}).  Objects that implement this
+ * interface can be used as keys in a {@linkplain SortedMap sorted map} or as
+ * elements in a {@linkplain SortedSet sorted set}, without the need to
+ * specify a {@linkplain Comparator comparator}.<p>
+ *
+ * The natural ordering for a class <tt>C</tt> is said to be <i>consistent
+ * with equals</i> if and only if <tt>e1.compareTo(e2) == 0</tt> has
+ * the same boolean value as <tt>e1.equals(e2)</tt> for every
+ * <tt>e1</tt> and <tt>e2</tt> of class <tt>C</tt>.  Note that <tt>null</tt>
+ * is not an instance of any class, and <tt>e.compareTo(null)</tt> should
+ * throw a <tt>NullPointerException</tt> even though <tt>e.equals(null)</tt>
+ * returns <tt>false</tt>.<p>
+ *
+ * It is strongly recommended (though not required) that natural orderings be
+ * consistent with equals.  This is so because sorted sets (and sorted maps)
+ * without explicit comparators behave "strangely" when they are used with
+ * elements (or keys) whose natural ordering is inconsistent with equals.  In
+ * particular, such a sorted set (or sorted map) violates the general contract
+ * for set (or map), which is defined in terms of the <tt>equals</tt>
+ * method.<p>
+ *
+ * For example, if one adds two keys <tt>a</tt> and <tt>b</tt> such that
+ * {@code (!a.equals(b) && a.compareTo(b) == 0)} to a sorted
+ * set that does not use an explicit comparator, the second <tt>add</tt>
+ * operation returns false (and the size of the sorted set does not increase)
+ * because <tt>a</tt> and <tt>b</tt> are equivalent from the sorted set's
+ * perspective.<p>
+ *
+ * Virtually all Java core classes that implement <tt>Comparable</tt> have natural
+ * orderings that are consistent with equals.  One exception is
+ * <tt>java.math.BigDecimal</tt>, whose natural ordering equates
+ * <tt>BigDecimal</tt> objects with equal values and different precisions
+ * (such as 4.0 and 4.00).<p>
+ *
+ * For the mathematically inclined, the <i>relation</i> that defines
+ * the natural ordering on a given class C is:<pre>
+ *       {(x, y) such that x.compareTo(y) &lt;= 0}.
+ * </pre> The <i>quotient</i> for this total order is: <pre>
+ *       {(x, y) such that x.compareTo(y) == 0}.
+ * </pre>
+ *
+ * It follows immediately from the contract for <tt>compareTo</tt> that the
+ * quotient is an <i>equivalence relation</i> on <tt>C</tt>, and that the
+ * natural ordering is a <i>total order</i> on <tt>C</tt>.  When we say that a
+ * class's natural ordering is <i>consistent with equals</i>, we mean that the
+ * quotient for the natural ordering is the equivalence relation defined by
+ * the class's {@link Object#equals(Object) equals(Object)} method:<pre>
+ *     {(x, y) such that x.equals(y)}. </pre><p>
+ *
+ * This interface is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @param <T> the type of objects that this object may be compared to
+ *
+ * @author  Josh Bloch
+ * @see java.util.Comparator
+ * @since 1.2
+ */
+public interface Comparable<T> {
+    /**
+     * Compares this object with the specified object for order.  Returns a
+     * negative integer, zero, or a positive integer as this object is less
+     * than, equal to, or greater than the specified object.
+     *
+     * <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
+     * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This
+     * implies that <tt>x.compareTo(y)</tt> must throw an exception iff
+     * <tt>y.compareTo(x)</tt> throws an exception.)
+     *
+     * <p>The implementor must also ensure that the relation is transitive:
+     * <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt> implies
+     * <tt>x.compareTo(z)&gt;0</tt>.
+     *
+     * <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
+     * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
+     * all <tt>z</tt>.
+     *
+     * <p>It is strongly recommended, but <i>not</i> strictly required that
+     * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any
+     * class that implements the <tt>Comparable</tt> interface and violates
+     * this condition should clearly indicate this fact.  The recommended
+     * language is "Note: this class has a natural ordering that is
+     * inconsistent with equals."
+     *
+     * <p>In the foregoing description, the notation
+     * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
+     * <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
+     * <tt>0</tt>, or <tt>1</tt> according to whether the value of
+     * <i>expression</i> is negative, zero or positive.
+     *
+     * @param   o the object to be compared.
+     * @return  a negative integer, zero, or a positive integer as this object
+     *          is less than, equal to, or greater than the specified object.
+     *
+     * @throws NullPointerException if the specified object is null
+     * @throws ClassCastException if the specified object's type prevents it
+     *         from being compared to this object.
+     */
+    public int compareTo(T o);
+}
diff --git a/java/lang/Compiler.java b/java/lang/Compiler.java
new file mode 100644
index 0000000..def9a83
--- /dev/null
+++ b/java/lang/Compiler.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Does nothing on Android.
+ */
+public final class Compiler  {
+    /**
+     * Prevent this class from being instantiated.
+     */
+    private Compiler() {}               // don't make instances
+
+    /**
+     * Compiles the specified class using the JIT compiler and indicates if
+     * compilation has been successful. Does nothing and returns false on
+     * Android.
+     *
+     * @param classToCompile
+     *            java.lang.Class the class to JIT compile
+     * @return {@code true} if the compilation has been successful;
+     *         {@code false} if it has failed or if there is no JIT compiler
+     *         available.
+     */
+    public static boolean compileClass(Class<?> classToCompile) {
+        return false;
+    }
+
+    /**
+     * Compiles all classes whose name matches the specified name using the JIT
+     * compiler and indicates if compilation has been successful. Does nothing
+     * and returns false on Android.
+     *
+     * @param nameRoot
+     *            the string to match class names with.
+     * @return {@code true} if the compilation has been successful;
+     *         {@code false} if it has failed or if there is no JIT compiler
+     *         available.
+     */
+    public static boolean compileClasses(String nameRoot) {
+        return false;
+    }
+
+    /**
+     * Executes an operation according to the specified command object. This
+     * method is the low-level interface to the JIT compiler. It may return any
+     * object or {@code null} if no JIT compiler is available. Returns null
+     * on Android, whether or not the system has a JIT.
+     *
+     * @param cmd
+     *            the command object for the JIT compiler.
+     * @return the result of executing command or {@code null}.
+     */
+    public static Object command(Object cmd) {
+        return null;
+    }
+
+    /**
+     * Enables the JIT compiler. Does nothing on Android.
+     */
+    public static void enable() {
+
+    }
+
+    /**
+     * Disables the JIT compiler. Does nothing on Android.
+     */
+    public static void disable() {
+
+    }
+}
diff --git a/java/lang/Daemons.java b/java/lang/Daemons.java
new file mode 100644
index 0000000..568614f
--- /dev/null
+++ b/java/lang/Daemons.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.lang.ref.FinalizerReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import libcore.util.EmptyArray;
+
+import dalvik.system.VMRuntime;
+import dalvik.system.VMDebug;
+
+/**
+ * Calls Object.finalize() on objects in the finalizer reference queue. The VM
+ * will abort if any finalize() call takes more than the maximum finalize time
+ * to complete.
+ *
+ * @hide
+ */
+public final class Daemons {
+    private static final int NANOS_PER_MILLI = 1000 * 1000;
+
+    // This used to be final. IT IS NOW ONLY WRITTEN. We now update it when we look at the command
+    // line argument, for the benefit of mis-behaved apps that might read it.  SLATED FOR REMOVAL.
+    // There is no reason to use this: Finalizers should not rely on the value. If a finalizer takes
+    // appreciable time, the work should be done elsewhere.  Based on disassembly of Daemons.class,
+    // the value is effectively inlined, so changing the field never did have an effect.
+    // DO NOT USE. FOR ANYTHING. THIS WILL BE REMOVED SHORTLY.
+    @UnsupportedAppUsage
+    private static long MAX_FINALIZE_NANOS = 10L * 1000 * NANOS_PER_MILLI;
+
+    private static final Daemon[] DAEMONS = new Daemon[] {
+            HeapTaskDaemon.INSTANCE,
+            ReferenceQueueDaemon.INSTANCE,
+            FinalizerDaemon.INSTANCE,
+            FinalizerWatchdogDaemon.INSTANCE,
+    };
+    private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+    private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+
+    private static boolean postZygoteFork = false;
+
+    @UnsupportedAppUsage
+    public static void start() {
+        for (Daemon daemon : DAEMONS) {
+            daemon.start();
+        }
+    }
+
+    public static void startPostZygoteFork() {
+        postZygoteFork = true;
+        for (Daemon daemon : DAEMONS) {
+            daemon.startPostZygoteFork();
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static void stop() {
+        for (Daemon daemon : DAEMONS) {
+            daemon.stop();
+        }
+    }
+
+    private static void waitForDaemonStart() throws Exception {
+        if (postZygoteFork) {
+            POST_ZYGOTE_START_LATCH.await();
+        } else {
+            PRE_ZYGOTE_START_LATCH.await();
+        }
+    }
+
+    /**
+     * A background task that provides runtime support to the application.
+     * Daemons can be stopped and started, but only so that the zygote can be a
+     * single-threaded process when it forks.
+     */
+    private static abstract class Daemon implements Runnable {
+        @UnsupportedAppUsage
+        private Thread thread;
+        private String name;
+        private boolean postZygoteFork;
+
+        protected Daemon(String name) {
+            this.name = name;
+        }
+
+        @UnsupportedAppUsage
+        public synchronized void start() {
+            startInternal();
+        }
+
+        public synchronized void startPostZygoteFork() {
+            postZygoteFork = true;
+            startInternal();
+        }
+
+        public void startInternal() {
+            if (thread != null) {
+                throw new IllegalStateException("already running");
+            }
+            thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
+            thread.setDaemon(true);
+            thread.setSystemDaemon(true);
+            thread.start();
+        }
+
+        public final void run() {
+            if (postZygoteFork) {
+                // We don't set the priority before the Thread.start() call above because
+                // Thread.start() will call SetNativePriority and overwrite the desired native
+                // priority. We (may) use a native priority that doesn't have a corresponding
+                // java.lang.Thread-level priority (native priorities are more coarse-grained.)
+                VMRuntime.getRuntime().setSystemDaemonThreadPriority();
+                POST_ZYGOTE_START_LATCH.countDown();
+            } else {
+                PRE_ZYGOTE_START_LATCH.countDown();
+            }
+            runInternal();
+        }
+
+        public abstract void runInternal();
+
+        /**
+         * Returns true while the current thread should continue to run; false
+         * when it should return.
+         */
+        @UnsupportedAppUsage
+        protected synchronized boolean isRunning() {
+            return thread != null;
+        }
+
+        public synchronized void interrupt() {
+            interrupt(thread);
+        }
+
+        public synchronized void interrupt(Thread thread) {
+            if (thread == null) {
+                throw new IllegalStateException("not running");
+            }
+            thread.interrupt();
+        }
+
+        /**
+         * Waits for the runtime thread to stop. This interrupts the thread
+         * currently running the runnable and then waits for it to exit.
+         */
+        @UnsupportedAppUsage
+        public void stop() {
+            Thread threadToStop;
+            synchronized (this) {
+                threadToStop = thread;
+                thread = null;
+            }
+            if (threadToStop == null) {
+                throw new IllegalStateException("not running");
+            }
+            interrupt(threadToStop);
+            while (true) {
+                try {
+                    threadToStop.join();
+                    return;
+                } catch (InterruptedException ignored) {
+                } catch (OutOfMemoryError ignored) {
+                    // An OOME may be thrown if allocating the InterruptedException failed.
+                }
+            }
+        }
+
+        /**
+         * Returns the current stack trace of the thread, or an empty stack trace
+         * if the thread is not currently running.
+         */
+        public synchronized StackTraceElement[] getStackTrace() {
+            return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
+        }
+    }
+
+    /**
+     * This heap management thread moves elements from the garbage collector's
+     * pending list to the managed reference queue.
+     */
+    private static class ReferenceQueueDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
+
+        ReferenceQueueDaemon() {
+            super("ReferenceQueueDaemon");
+        }
+
+        @Override public void runInternal() {
+            while (isRunning()) {
+                Reference<?> list;
+                try {
+                    synchronized (ReferenceQueue.class) {
+                        while (ReferenceQueue.unenqueued == null) {
+                            ReferenceQueue.class.wait();
+                        }
+                        list = ReferenceQueue.unenqueued;
+                        ReferenceQueue.unenqueued = null;
+                    }
+                } catch (InterruptedException e) {
+                    continue;
+                } catch (OutOfMemoryError e) {
+                    continue;
+                }
+                ReferenceQueue.enqueuePending(list);
+            }
+        }
+    }
+
+    private static class FinalizerDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
+        private final ReferenceQueue<Object> queue = FinalizerReference.queue;
+        private final AtomicInteger progressCounter = new AtomicInteger(0);
+        // Object (not reference!) being finalized. Accesses may race!
+        @UnsupportedAppUsage
+        private Object finalizingObject = null;
+
+        FinalizerDaemon() {
+            super("FinalizerDaemon");
+        }
+
+        @Override public void runInternal() {
+            // This loop may be performance critical, since we need to keep up with mutator
+            // generation of finalizable objects.
+            // We minimize the amount of work we do per finalizable object. For example, we avoid
+            // reading the current time here, since that involves a kernel call per object.  We
+            // limit fast path communication with FinalizerWatchDogDaemon to what's unavoidable: A
+            // non-volatile store to communicate the current finalizable object, e.g. for
+            // reporting, and a release store (lazySet) to a counter.
+            // We do stop the  FinalizerWatchDogDaemon if we have nothing to do for a
+            // potentially extended period.  This prevents the device from waking up regularly
+            // during idle times.
+
+            // Local copy of progressCounter; saves a fence per increment on ARM and MIPS.
+            int localProgressCounter = progressCounter.get();
+
+            while (isRunning()) {
+                try {
+                    // Use non-blocking poll to avoid FinalizerWatchdogDaemon communication
+                    // when busy.
+                    FinalizerReference<?> finalizingReference = (FinalizerReference<?>)queue.poll();
+                    if (finalizingReference != null) {
+                        finalizingObject = finalizingReference.get();
+                        progressCounter.lazySet(++localProgressCounter);
+                    } else {
+                        finalizingObject = null;
+                        progressCounter.lazySet(++localProgressCounter);
+                        // Slow path; block.
+                        FinalizerWatchdogDaemon.INSTANCE.goToSleep();
+                        finalizingReference = (FinalizerReference<?>)queue.remove();
+                        finalizingObject = finalizingReference.get();
+                        progressCounter.set(++localProgressCounter);
+                        FinalizerWatchdogDaemon.INSTANCE.wakeUp();
+                    }
+                    doFinalize(finalizingReference);
+                } catch (InterruptedException ignored) {
+                } catch (OutOfMemoryError ignored) {
+                }
+            }
+        }
+
+        @FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")
+        private void doFinalize(FinalizerReference<?> reference) {
+            FinalizerReference.remove(reference);
+            Object object = reference.get();
+            reference.clear();
+            try {
+                object.finalize();
+            } catch (Throwable ex) {
+                // The RI silently swallows these, but Android has always logged.
+                System.logE("Uncaught exception thrown by finalizer", ex);
+            } finally {
+                // Done finalizing, stop holding the object as live.
+                finalizingObject = null;
+            }
+        }
+    }
+
+    /**
+     * The watchdog exits the VM if the finalizer ever gets stuck. We consider
+     * the finalizer to be stuck if it spends more than MAX_FINALIZATION_MILLIS
+     * on one instance.
+     */
+    private static class FinalizerWatchdogDaemon extends Daemon {
+        @UnsupportedAppUsage
+        private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
+
+        private boolean needToWork = true;  // Only accessed in synchronized methods.
+
+        private long finalizerTimeoutMs = 0;  // Lazily initialized.
+
+        FinalizerWatchdogDaemon() {
+            super("FinalizerWatchdogDaemon");
+        }
+
+        @Override public void runInternal() {
+            while (isRunning()) {
+                if (!sleepUntilNeeded()) {
+                    // We have been interrupted, need to see if this daemon has been stopped.
+                    continue;
+                }
+                final Object finalizing = waitForFinalization();
+                if (finalizing != null && !VMDebug.isDebuggerConnected()) {
+                    finalizerTimedOut(finalizing);
+                    break;
+                }
+            }
+        }
+
+        /**
+         * Wait until something is ready to be finalized.
+         * Return false if we have been interrupted
+         * See also http://code.google.com/p/android/issues/detail?id=22778.
+         */
+        private synchronized boolean sleepUntilNeeded() {
+            while (!needToWork) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    // Daemon.stop may have interrupted us.
+                    return false;
+                } catch (OutOfMemoryError e) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Notify daemon that it's OK to sleep until notified that something is ready to be
+         * finalized.
+         */
+        private synchronized void goToSleep() {
+            needToWork = false;
+        }
+
+        /**
+         * Notify daemon that there is something ready to be finalized.
+         */
+        private synchronized void wakeUp() {
+            needToWork = true;
+            notify();
+        }
+
+        private synchronized boolean getNeedToWork() {
+            return needToWork;
+        }
+
+        /**
+         * Sleep for the given number of milliseconds.
+         * @return false if we were interrupted.
+         */
+        private boolean sleepForMillis(long durationMillis) {
+            long startMillis = System.currentTimeMillis();
+            while (true) {
+                long elapsedMillis = System.currentTimeMillis() - startMillis;
+                long sleepMillis = durationMillis - elapsedMillis;
+                if (sleepMillis <= 0) {
+                    return true;
+                }
+                try {
+                    Thread.sleep(sleepMillis);
+                } catch (InterruptedException e) {
+                    if (!isRunning()) {
+                        return false;
+                    }
+                } catch (OutOfMemoryError ignored) {
+                    if (!isRunning()) {
+                        return false;
+                    }
+                }
+            }
+        }
+
+
+        /**
+         * Return an object that took too long to finalize or return null.
+         * Wait VMRuntime.getFinalizerTimeoutMs.  If the FinalizerDaemon took essentially the
+         * whole time processing a single reference, return that reference.  Otherwise return
+         * null.  Only called from a single thread.
+         */
+        private Object waitForFinalization() {
+            if (finalizerTimeoutMs == 0) {
+                finalizerTimeoutMs = VMRuntime.getRuntime().getFinalizerTimeoutMs();
+                // Temporary app backward compatibility. Remove eventually.
+                MAX_FINALIZE_NANOS = NANOS_PER_MILLI * finalizerTimeoutMs;
+            }
+            long startCount = FinalizerDaemon.INSTANCE.progressCounter.get();
+            // Avoid remembering object being finalized, so as not to keep it alive.
+            if (!sleepForMillis(finalizerTimeoutMs)) {
+                // Don't report possibly spurious timeout if we are interrupted.
+                return null;
+            }
+            if (getNeedToWork() && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+                // We assume that only remove() and doFinalize() may take time comparable to
+                // the finalizer timeout.
+                // We observed neither the effect of the gotoSleep() nor the increment preceding a
+                // later wakeUp. Any remove() call by the FinalizerDaemon during our sleep
+                // interval must have been followed by a wakeUp call before we checked needToWork.
+                // But then we would have seen the counter increment.  Thus there cannot have
+                // been such a remove() call.
+                // The FinalizerDaemon must not have progressed (from either the beginning or the
+                // last progressCounter increment) to either the next increment or gotoSleep()
+                // call.  Thus we must have taken essentially the whole finalizerTimeoutMs in a
+                // single doFinalize() call.  Thus it's OK to time out.  finalizingObject was set
+                // just before the counter increment, which preceded the doFinalize call.  Thus we
+                // are guaranteed to get the correct finalizing value below, unless doFinalize()
+                // just finished as we were timing out, in which case we may get null or a later
+                // one.  In this last case, we are very likely to discard it below.
+                Object finalizing = FinalizerDaemon.INSTANCE.finalizingObject;
+                sleepForMillis(500);
+                // Recheck to make it even less likely we report the wrong finalizing object in
+                // the case which a very slow finalization just finished as we were timing out.
+                if (getNeedToWork()
+                        && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+                    return finalizing;
+                }
+            }
+            return null;
+        }
+
+        private static void finalizerTimedOut(Object object) {
+            // The current object has exceeded the finalization deadline; abort!
+            String message = object.getClass().getName() + ".finalize() timed out after "
+                    + VMRuntime.getRuntime().getFinalizerTimeoutMs() / 1000 + " seconds";
+            Exception syntheticException = new TimeoutException(message);
+            // We use the stack from where finalize() was running to show where it was stuck.
+            syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
+
+            // Send SIGQUIT to get native stack traces.
+            try {
+                Os.kill(Os.getpid(), OsConstants.SIGQUIT);
+                // Sleep a few seconds to let the stack traces print.
+                Thread.sleep(5000);
+            } catch (Exception e) {
+                System.logE("failed to send SIGQUIT", e);
+            } catch (OutOfMemoryError ignored) {
+                // May occur while trying to allocate the exception.
+            }
+
+            // Ideally, we'd want to do this if this Thread had no handler to dispatch to.
+            // Unfortunately, it's extremely to messy to query whether a given Thread has *some*
+            // handler to dispatch to, either via a handler set on itself, via its ThreadGroup
+            // object or via the defaultUncaughtExceptionHandler.
+            //
+            // As an approximation, we log by hand an exit if there's no pre-exception handler nor
+            // a default uncaught exception handler.
+            //
+            // Note that this condition will only ever be hit by ART host tests and standalone
+            // dalvikvm invocations. All zygote forked process *will* have a pre-handler set
+            // in RuntimeInit and they cannot subsequently override it.
+            if (Thread.getUncaughtExceptionPreHandler() == null &&
+                    Thread.getDefaultUncaughtExceptionHandler() == null) {
+                // If we have no handler, log and exit.
+                System.logE(message, syntheticException);
+                System.exit(2);
+            }
+
+            // Otherwise call the handler to do crash reporting.
+            // We don't just throw because we're not the thread that
+            // timed out; we're the thread that detected it.
+            Thread.currentThread().dispatchUncaughtException(syntheticException);
+        }
+    }
+
+    // Adds a heap trim task to the heap event processor, not called from java. Left for
+    // compatibility purposes due to reflection.
+    @UnsupportedAppUsage
+    public static void requestHeapTrim() {
+        VMRuntime.getRuntime().requestHeapTrim();
+    }
+
+    // Adds a concurrent GC request task ot the heap event processor, not called from java. Left
+    // for compatibility purposes due to reflection.
+    public static void requestGC() {
+        VMRuntime.getRuntime().requestConcurrentGC();
+    }
+
+    private static class HeapTaskDaemon extends Daemon {
+        private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();
+
+        HeapTaskDaemon() {
+            super("HeapTaskDaemon");
+        }
+
+        // Overrides the Daemon.interupt method which is called from Daemons.stop.
+        public synchronized void interrupt(Thread thread) {
+            VMRuntime.getRuntime().stopHeapTaskProcessor();
+        }
+
+        @Override public void runInternal() {
+            synchronized (this) {
+                if (isRunning()) {
+                  // Needs to be synchronized or else we there is a race condition where we start
+                  // the thread, call stopHeapTaskProcessor before we start the heap task
+                  // processor, resulting in a deadlock since startHeapTaskProcessor restarts it
+                  // while the other thread is waiting in Daemons.stop().
+                  VMRuntime.getRuntime().startHeapTaskProcessor();
+                }
+            }
+            // This runs tasks until we are stopped and there is no more pending task.
+            VMRuntime.getRuntime().runHeapTasks();
+        }
+    }
+}
diff --git a/java/lang/Deprecated.java b/java/lang/Deprecated.java
new file mode 100644
index 0000000..58a0691
--- /dev/null
+++ b/java/lang/Deprecated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * A program element annotated &#64;Deprecated is one that programmers
+ * are discouraged from using, typically because it is dangerous,
+ * or because a better alternative exists.  Compilers warn when a
+ * deprecated program element is used or overridden in non-deprecated code.
+ *
+ * @author  Neal Gafter
+ * @since 1.5
+ * @jls 9.6.3.6 @Deprecated
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
+public @interface Deprecated {
+}
diff --git a/java/lang/DexCache.java b/java/lang/DexCache.java
new file mode 100644
index 0000000..e35a69d
--- /dev/null
+++ b/java/lang/DexCache.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
+ */
+final class DexCache {
+    /** The classloader this dex cache is for. */
+    private ClassLoader classLoader;
+
+    /** The location of the associated dex file. */
+    private String location;
+
+    /** Holds C pointer to dexFile. */
+    @UnsupportedAppUsage
+    private long dexFile;
+
+    /**
+     * References to pre resolved strings.
+     */
+    private long preResolvedStrings;
+
+    /**
+     * References to CallSite (C array pointer) as they become resolved following
+     * interpreter semantics.
+     */
+    private long resolvedCallSites;
+
+    /**
+     * References to fields (C array pointer) as they become resolved following
+     * interpreter semantics. May refer to fields defined in other dex files.
+     */
+    private long resolvedFields;
+
+    /**
+     * References to MethodType (C array pointer) as they become resolved following
+     * interpreter semantics.
+     */
+    private long resolvedMethodTypes;
+
+    /**
+     * References to methods (C array pointer) as they become resolved following
+     * interpreter semantics. May refer to methods defined in other dex files.
+     */
+    private long resolvedMethods;
+
+    /**
+     * References to types (C array pointer) as they become resolved following
+     * interpreter semantics. May refer to types defined in other dex files.
+     */
+    private long resolvedTypes;
+
+    /**
+     * References to strings (C array pointer) as they become resolved following
+     * interpreter semantics. All strings are interned.
+     */
+    private long strings;
+
+    /**
+     * The number of elements in the native pre resolved strings array.
+     */
+    private int numPreResolvedStrings;
+
+    /**
+     * The number of elements in the native call sites array.
+     */
+    private int numResolvedCallSites;
+
+    /**
+     * The number of elements in the native resolvedFields array.
+     */
+    private int numResolvedFields;
+
+    /**
+     * The number of elements in the native method types array.
+     */
+    private int numResolvedMethodTypes;
+
+    /**
+     * The number of elements in the native resolvedMethods array.
+     */
+    private int numResolvedMethods;
+
+    /**
+     * The number of elements in the native resolvedTypes array.
+     */
+    private int numResolvedTypes;
+
+    /**
+     * The number of elements in the native strings array.
+     */
+    private int numStrings;
+
+    // Only created by the VM.
+    private DexCache() {}
+}
diff --git a/java/lang/Double.annotated.java b/java/lang/Double.annotated.java
new file mode 100644
index 0000000..8f565fc
--- /dev/null
+++ b/java/lang/Double.annotated.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
+
+public Double(double value) { throw new RuntimeException("Stub!"); }
+
+public Double(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Double valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Double valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+public static double parseDouble(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(double d) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(double value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static long doubleToLongBits(double value) { throw new RuntimeException("Stub!"); }
+
+public static native long doubleToRawLongBits(double value);
+
+public static native double longBitsToDouble(long bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Double anotherDouble) { throw new RuntimeException("Stub!"); }
+
+public static int compare(double d1, double d2) { throw new RuntimeException("Stub!"); }
+
+public static double sum(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final int MAX_EXPONENT = 1023; // 0x3ff
+
+public static final double MAX_VALUE = 1.7976931348623157E308;
+
+public static final int MIN_EXPONENT = -1022; // 0xfffffc02
+
+public static final double MIN_NORMAL = 2.2250738585072014E-308;
+
+public static final double MIN_VALUE = 4.9E-324;
+
+public static final double NEGATIVE_INFINITY = (-1.0/0.0);
+
+public static final double NaN = (0.0/0.0);
+
+public static final double POSITIVE_INFINITY = (1.0/0.0);
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Double> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Double.java b/java/lang/Double.java
new file mode 100644
index 0000000..690ca6a
--- /dev/null
+++ b/java/lang/Double.java
@@ -0,0 +1,1058 @@
+/*
+ * Copyright (c) 1994, 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;
+
+import sun.misc.FloatingDecimal;
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+/**
+ * The {@code Double} class wraps a value of the primitive type
+ * {@code double} in an object. An object of type
+ * {@code Double} contains a single field whose type is
+ * {@code double}.
+ *
+ * <p>In addition, this class provides several methods for converting a
+ * {@code double} to a {@code String} and a
+ * {@code String} to a {@code double}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code double}.
+ *
+ * @author  Lee Boynton
+ * @author  Arthur van Hoff
+ * @author  Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Double extends Number implements Comparable<Double> {
+    /**
+     * A constant holding the positive infinity of type
+     * {@code double}. It is equal to the value returned by
+     * {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
+     */
+    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
+
+    /**
+     * A constant holding the negative infinity of type
+     * {@code double}. It is equal to the value returned by
+     * {@code Double.longBitsToDouble(0xfff0000000000000L)}.
+     */
+    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
+
+    /**
+     * A constant holding a Not-a-Number (NaN) value of type
+     * {@code double}. It is equivalent to the value returned by
+     * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
+     */
+    public static final double NaN = 0.0d / 0.0;
+
+    /**
+     * A constant holding the largest positive finite value of type
+     * {@code double},
+     * (2-2<sup>-52</sup>)&middot;2<sup>1023</sup>.  It is equal to
+     * the hexadecimal floating-point literal
+     * {@code 0x1.fffffffffffffP+1023} and also equal to
+     * {@code Double.longBitsToDouble(0x7fefffffffffffffL)}.
+     */
+    public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
+
+    /**
+     * A constant holding the smallest positive normal value of type
+     * {@code double}, 2<sup>-1022</sup>.  It is equal to the
+     * hexadecimal floating-point literal {@code 0x1.0p-1022} and also
+     * equal to {@code Double.longBitsToDouble(0x0010000000000000L)}.
+     *
+     * @since 1.6
+     */
+    public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
+
+    /**
+     * A constant holding the smallest positive nonzero value of type
+     * {@code double}, 2<sup>-1074</sup>. It is equal to the
+     * hexadecimal floating-point literal
+     * {@code 0x0.0000000000001P-1022} and also equal to
+     * {@code Double.longBitsToDouble(0x1L)}.
+     */
+    public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
+
+    /**
+     * Maximum exponent a finite {@code double} variable may have.
+     * It is equal to the value returned by
+     * {@code Math.getExponent(Double.MAX_VALUE)}.
+     *
+     * @since 1.6
+     */
+    public static final int MAX_EXPONENT = 1023;
+
+    /**
+     * Minimum exponent a normalized {@code double} variable may
+     * have.  It is equal to the value returned by
+     * {@code Math.getExponent(Double.MIN_NORMAL)}.
+     *
+     * @since 1.6
+     */
+    public static final int MIN_EXPONENT = -1022;
+
+    /**
+     * The number of bits used to represent a {@code double} value.
+     *
+     * @since 1.5
+     */
+    public static final int SIZE = 64;
+
+    /**
+     * The number of bytes used to represent a {@code double} value.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code double}.
+     *
+     * @since JDK1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");
+
+    /**
+     * Returns a string representation of the {@code double}
+     * argument. All characters mentioned below are ASCII characters.
+     * <ul>
+     * <li>If the argument is NaN, the result is the string
+     *     "{@code NaN}".
+     * <li>Otherwise, the result is a string that represents the sign and
+     * magnitude (absolute value) of the argument. If the sign is negative,
+     * the first character of the result is '{@code -}'
+     * ({@code '\u005Cu002D'}); if the sign is positive, no sign character
+     * appears in the result. As for the magnitude <i>m</i>:
+     * <ul>
+     * <li>If <i>m</i> is infinity, it is represented by the characters
+     * {@code "Infinity"}; thus, positive infinity produces the result
+     * {@code "Infinity"} and negative infinity produces the result
+     * {@code "-Infinity"}.
+     *
+     * <li>If <i>m</i> is zero, it is represented by the characters
+     * {@code "0.0"}; thus, negative zero produces the result
+     * {@code "-0.0"} and positive zero produces the result
+     * {@code "0.0"}.
+     *
+     * <li>If <i>m</i> is greater than or equal to 10<sup>-3</sup> but less
+     * than 10<sup>7</sup>, then it is represented as the integer part of
+     * <i>m</i>, in decimal form with no leading zeroes, followed by
+     * '{@code .}' ({@code '\u005Cu002E'}), followed by one or
+     * more decimal digits representing the fractional part of <i>m</i>.
+     *
+     * <li>If <i>m</i> is less than 10<sup>-3</sup> or greater than or
+     * equal to 10<sup>7</sup>, then it is represented in so-called
+     * "computerized scientific notation." Let <i>n</i> be the unique
+     * integer such that 10<sup><i>n</i></sup> &le; <i>m</i> {@literal <}
+     * 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
+     * mathematically exact quotient of <i>m</i> and
+     * 10<sup><i>n</i></sup> so that 1 &le; <i>a</i> {@literal <} 10. The
+     * magnitude is then represented as the integer part of <i>a</i>,
+     * as a single decimal digit, followed by '{@code .}'
+     * ({@code '\u005Cu002E'}), followed by decimal digits
+     * representing the fractional part of <i>a</i>, followed by the
+     * letter '{@code E}' ({@code '\u005Cu0045'}), followed
+     * by a representation of <i>n</i> as a decimal integer, as
+     * produced by the method {@link Integer#toString(int)}.
+     * </ul>
+     * </ul>
+     * How many digits must be printed for the fractional part of
+     * <i>m</i> or <i>a</i>? There must be at least one digit to represent
+     * the fractional part, and beyond that as many, but only as many, more
+     * digits as are needed to uniquely distinguish the argument value from
+     * adjacent values of type {@code double}. That is, suppose that
+     * <i>x</i> is the exact mathematical value represented by the decimal
+     * representation produced by this method for a finite nonzero argument
+     * <i>d</i>. Then <i>d</i> must be the {@code double} value nearest
+     * to <i>x</i>; or if two {@code double} values are equally close
+     * to <i>x</i>, then <i>d</i> must be one of them and the least
+     * significant bit of the significand of <i>d</i> must be {@code 0}.
+     *
+     * <p>To create localized string representations of a floating-point
+     * value, use subclasses of {@link java.text.NumberFormat}.
+     *
+     * @param   d   the {@code double} to be converted.
+     * @return a string representation of the argument.
+     */
+    public static String toString(double d) {
+        return FloatingDecimal.toJavaFormatString(d);
+    }
+
+    /**
+     * Returns a hexadecimal string representation of the
+     * {@code double} argument. All characters mentioned below
+     * are ASCII characters.
+     *
+     * <ul>
+     * <li>If the argument is NaN, the result is the string
+     *     "{@code NaN}".
+     * <li>Otherwise, the result is a string that represents the sign
+     * and magnitude of the argument. If the sign is negative, the
+     * first character of the result is '{@code -}'
+     * ({@code '\u005Cu002D'}); if the sign is positive, no sign
+     * character appears in the result. As for the magnitude <i>m</i>:
+     *
+     * <ul>
+     * <li>If <i>m</i> is infinity, it is represented by the string
+     * {@code "Infinity"}; thus, positive infinity produces the
+     * result {@code "Infinity"} and negative infinity produces
+     * the result {@code "-Infinity"}.
+     *
+     * <li>If <i>m</i> is zero, it is represented by the string
+     * {@code "0x0.0p0"}; thus, negative zero produces the result
+     * {@code "-0x0.0p0"} and positive zero produces the result
+     * {@code "0x0.0p0"}.
+     *
+     * <li>If <i>m</i> is a {@code double} value with a
+     * normalized representation, substrings are used to represent the
+     * significand and exponent fields.  The significand is
+     * represented by the characters {@code "0x1."}
+     * followed by a lowercase hexadecimal representation of the rest
+     * of the significand as a fraction.  Trailing zeros in the
+     * hexadecimal representation are removed unless all the digits
+     * are zero, in which case a single zero is used. Next, the
+     * exponent is represented by {@code "p"} followed
+     * by a decimal string of the unbiased exponent as if produced by
+     * a call to {@link Integer#toString(int) Integer.toString} on the
+     * exponent value.
+     *
+     * <li>If <i>m</i> is a {@code double} value with a subnormal
+     * representation, the significand is represented by the
+     * characters {@code "0x0."} followed by a
+     * hexadecimal representation of the rest of the significand as a
+     * fraction.  Trailing zeros in the hexadecimal representation are
+     * removed. Next, the exponent is represented by
+     * {@code "p-1022"}.  Note that there must be at
+     * least one nonzero digit in a subnormal significand.
+     *
+     * </ul>
+     *
+     * </ul>
+     *
+     * <table border>
+     * <caption>Examples</caption>
+     * <tr><th>Floating-point Value</th><th>Hexadecimal String</th>
+     * <tr><td>{@code 1.0}</td> <td>{@code 0x1.0p0}</td>
+     * <tr><td>{@code -1.0}</td>        <td>{@code -0x1.0p0}</td>
+     * <tr><td>{@code 2.0}</td> <td>{@code 0x1.0p1}</td>
+     * <tr><td>{@code 3.0}</td> <td>{@code 0x1.8p1}</td>
+     * <tr><td>{@code 0.5}</td> <td>{@code 0x1.0p-1}</td>
+     * <tr><td>{@code 0.25}</td>        <td>{@code 0x1.0p-2}</td>
+     * <tr><td>{@code Double.MAX_VALUE}</td>
+     *     <td>{@code 0x1.fffffffffffffp1023}</td>
+     * <tr><td>{@code Minimum Normal Value}</td>
+     *     <td>{@code 0x1.0p-1022}</td>
+     * <tr><td>{@code Maximum Subnormal Value}</td>
+     *     <td>{@code 0x0.fffffffffffffp-1022}</td>
+     * <tr><td>{@code Double.MIN_VALUE}</td>
+     *     <td>{@code 0x0.0000000000001p-1022}</td>
+     * </table>
+     * @param   d   the {@code double} to be converted.
+     * @return a hex string representation of the argument.
+     * @since 1.5
+     * @author Joseph D. Darcy
+     */
+    public static String toHexString(double d) {
+        /*
+         * Modeled after the "a" conversion specifier in C99, section
+         * 7.19.6.1; however, the output of this method is more
+         * tightly specified.
+         */
+        if (!isFinite(d) )
+            // For infinity and NaN, use the decimal output.
+            return Double.toString(d);
+        else {
+            // Initialized to maximum size of output.
+            StringBuilder answer = new StringBuilder(24);
+
+            if (Math.copySign(1.0, d) == -1.0)    // value is negative,
+                answer.append("-");                  // so append sign info
+
+            answer.append("0x");
+
+            d = Math.abs(d);
+
+            if(d == 0.0) {
+                answer.append("0.0p0");
+            } else {
+                boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
+
+                // Isolate significand bits and OR in a high-order bit
+                // so that the string representation has a known
+                // length.
+                long signifBits = (Double.doubleToLongBits(d)
+                                   & DoubleConsts.SIGNIF_BIT_MASK) |
+                    0x1000000000000000L;
+
+                // Subnormal values have a 0 implicit bit; normal
+                // values have a 1 implicit bit.
+                answer.append(subnormal ? "0." : "1.");
+
+                // Isolate the low-order 13 digits of the hex
+                // representation.  If all the digits are zero,
+                // replace with a single 0; otherwise, remove all
+                // trailing zeros.
+                String signif = Long.toHexString(signifBits).substring(3,16);
+                answer.append(signif.equals("0000000000000") ? // 13 zeros
+                              "0":
+                              signif.replaceFirst("0{1,12}$", ""));
+
+                answer.append('p');
+                // If the value is subnormal, use the E_min exponent
+                // value for double; otherwise, extract and report d's
+                // exponent (the representation of a subnormal uses
+                // E_min -1).
+                answer.append(subnormal ?
+                              DoubleConsts.MIN_EXPONENT:
+                              Math.getExponent(d));
+            }
+            return answer.toString();
+        }
+    }
+
+    /**
+     * Returns a {@code Double} object holding the
+     * {@code double} value represented by the argument string
+     * {@code s}.
+     *
+     * <p>If {@code s} is {@code null}, then a
+     * {@code NullPointerException} is thrown.
+     *
+     * <p>Leading and trailing whitespace characters in {@code s}
+     * are ignored.  Whitespace is removed as if by the {@link
+     * String#trim} method; that is, both ASCII space and control
+     * characters are removed. The rest of {@code s} should
+     * constitute a <i>FloatValue</i> as described by the lexical
+     * syntax rules:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>FloatValue:</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code NaN}
+     * <dd><i>Sign<sub>opt</sub></i> {@code Infinity}
+     * <dd><i>Sign<sub>opt</sub> FloatingPointLiteral</i>
+     * <dd><i>Sign<sub>opt</sub> HexFloatingPointLiteral</i>
+     * <dd><i>SignedInteger</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>HexFloatingPointLiteral</i>:
+     * <dd> <i>HexSignificand BinaryExponent FloatTypeSuffix<sub>opt</sub></i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>HexSignificand:</i>
+     * <dd><i>HexNumeral</i>
+     * <dd><i>HexNumeral</i> {@code .}
+     * <dd>{@code 0x} <i>HexDigits<sub>opt</sub>
+     *     </i>{@code .}<i> HexDigits</i>
+     * <dd>{@code 0X}<i> HexDigits<sub>opt</sub>
+     *     </i>{@code .} <i>HexDigits</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>BinaryExponent:</i>
+     * <dd><i>BinaryExponentIndicator SignedInteger</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>BinaryExponentIndicator:</i>
+     * <dd>{@code p}
+     * <dd>{@code P}
+     * </dl>
+     *
+     * </blockquote>
+     *
+     * where <i>Sign</i>, <i>FloatingPointLiteral</i>,
+     * <i>HexNumeral</i>, <i>HexDigits</i>, <i>SignedInteger</i> and
+     * <i>FloatTypeSuffix</i> are as defined in the lexical structure
+     * sections of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     * If {@code s} does not have the form of
+     * a <i>FloatValue</i>, then a {@code NumberFormatException}
+     * is thrown. Otherwise, {@code s} is regarded as
+     * representing an exact decimal value in the usual
+     * "computerized scientific notation" or as an exact
+     * hexadecimal value; this exact numerical value is then
+     * conceptually converted to an "infinitely precise"
+     * binary value that is then rounded to type {@code double}
+     * by the usual round-to-nearest rule of IEEE 754 floating-point
+     * arithmetic, which includes preserving the sign of a zero
+     * value.
+     *
+     * Note that the round-to-nearest rule also implies overflow and
+     * underflow behaviour; if the exact value of {@code s} is large
+     * enough in magnitude (greater than or equal to ({@link
+     * #MAX_VALUE} + {@link Math#ulp(double) ulp(MAX_VALUE)}/2),
+     * rounding to {@code double} will result in an infinity and if the
+     * exact value of {@code s} is small enough in magnitude (less
+     * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+     * result in a zero.
+     *
+     * Finally, after rounding a {@code Double} object representing
+     * this {@code double} value is returned.
+     *
+     * <p> To interpret localized string representations of a
+     * floating-point value, use subclasses of {@link
+     * java.text.NumberFormat}.
+     *
+     * <p>Note that trailing format specifiers, specifiers that
+     * determine the type of a floating-point literal
+     * ({@code 1.0f} is a {@code float} value;
+     * {@code 1.0d} is a {@code double} value), do
+     * <em>not</em> influence the results of this method.  In other
+     * words, the numerical value of the input string is converted
+     * directly to the target floating-point type.  The two-step
+     * sequence of conversions, string to {@code float} followed
+     * by {@code float} to {@code double}, is <em>not</em>
+     * equivalent to converting a string directly to
+     * {@code double}. For example, the {@code float}
+     * literal {@code 0.1f} is equal to the {@code double}
+     * value {@code 0.10000000149011612}; the {@code float}
+     * literal {@code 0.1f} represents a different numerical
+     * value than the {@code double} literal
+     * {@code 0.1}. (The numerical value 0.1 cannot be exactly
+     * represented in a binary floating-point number.)
+     *
+     * <p>To avoid calling this method on an invalid string and having
+     * a {@code NumberFormatException} be thrown, the regular
+     * expression below can be used to screen the input string:
+     *
+     * <pre>{@code
+     *  final String Digits     = "(\\p{Digit}+)";
+     *  final String HexDigits  = "(\\p{XDigit}+)";
+     *  // an exponent is 'e' or 'E' followed by an optionally
+     *  // signed decimal integer.
+     *  final String Exp        = "[eE][+-]?"+Digits;
+     *  final String fpRegex    =
+     *      ("[\\x00-\\x20]*"+  // Optional leading "whitespace"
+     *       "[+-]?(" + // Optional sign character
+     *       "NaN|" +           // "NaN" string
+     *       "Infinity|" +      // "Infinity" string
+     *
+     *       // A decimal floating-point string representing a finite positive
+     *       // number without a leading sign has at most five basic pieces:
+     *       // Digits . Digits ExponentPart FloatTypeSuffix
+     *       //
+     *       // Since this method allows integer-only strings as input
+     *       // in addition to strings of floating-point literals, the
+     *       // two sub-patterns below are simplifications of the grammar
+     *       // productions from section 3.10.2 of
+     *       // The Java Language Specification.
+     *
+     *       // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
+     *       "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
+     *
+     *       // . Digits ExponentPart_opt FloatTypeSuffix_opt
+     *       "(\\.("+Digits+")("+Exp+")?)|"+
+     *
+     *       // Hexadecimal strings
+     *       "((" +
+     *        // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
+     *        "(0[xX]" + HexDigits + "(\\.)?)|" +
+     *
+     *        // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
+     *        "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
+     *
+     *        ")[pP][+-]?" + Digits + "))" +
+     *       "[fFdD]?))" +
+     *       "[\\x00-\\x20]*");// Optional trailing "whitespace"
+     *
+     *  if (Pattern.matches(fpRegex, myString))
+     *      Double.valueOf(myString); // Will not throw NumberFormatException
+     *  else {
+     *      // Perform suitable alternative action
+     *  }
+     * }</pre>
+     *
+     * @param      s   the string to be parsed.
+     * @return     a {@code Double} object holding the value
+     *             represented by the {@code String} argument.
+     * @throws     NumberFormatException  if the string does not contain a
+     *             parsable number.
+     */
+    public static Double valueOf(String s) throws NumberFormatException {
+        return new Double(parseDouble(s));
+    }
+
+    /**
+     * Returns a {@code Double} instance representing the specified
+     * {@code double} value.
+     * If a new {@code Double} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Double(double)}, as this method is likely to yield
+     * significantly better space and time performance by caching
+     * frequently requested values.
+     *
+     * @param  d a double value.
+     * @return a {@code Double} instance representing {@code d}.
+     * @since  1.5
+     */
+    public static Double valueOf(double d) {
+        return new Double(d);
+    }
+
+    /**
+     * Returns a new {@code double} initialized to the value
+     * represented by the specified {@code String}, as performed
+     * by the {@code valueOf} method of class
+     * {@code Double}.
+     *
+     * @param  s   the string to be parsed.
+     * @return the {@code double} value represented by the string
+     *         argument.
+     * @throws NullPointerException  if the string is null
+     * @throws NumberFormatException if the string does not contain
+     *         a parsable {@code double}.
+     * @see    java.lang.Double#valueOf(String)
+     * @since 1.2
+     */
+    public static double parseDouble(String s) throws NumberFormatException {
+        return FloatingDecimal.parseDouble(s);
+    }
+
+    /**
+     * Returns {@code true} if the specified number is a
+     * Not-a-Number (NaN) value, {@code false} otherwise.
+     *
+     * @param   v   the value to be tested.
+     * @return  {@code true} if the value of the argument is NaN;
+     *          {@code false} otherwise.
+     */
+    public static boolean isNaN(double v) {
+        return (v != v);
+    }
+
+    /**
+     * Returns {@code true} if the specified number is infinitely
+     * large in magnitude, {@code false} otherwise.
+     *
+     * @param   v   the value to be tested.
+     * @return  {@code true} if the value of the argument is positive
+     *          infinity or negative infinity; {@code false} otherwise.
+     */
+    public static boolean isInfinite(double v) {
+        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
+    }
+
+    /**
+     * Returns {@code true} if the argument is a finite floating-point
+     * value; returns {@code false} otherwise (for NaN and infinity
+     * arguments).
+     *
+     * @param d the {@code double} value to be tested
+     * @return {@code true} if the argument is a finite
+     * floating-point value, {@code false} otherwise.
+     * @since 1.8
+     */
+    public static boolean isFinite(double d) {
+        return Math.abs(d) <= DoubleConsts.MAX_VALUE;
+    }
+
+    /**
+     * The value of the Double.
+     *
+     * @serial
+     */
+    private final double value;
+
+    /**
+     * Constructs a newly allocated {@code Double} object that
+     * represents the primitive {@code double} argument.
+     *
+     * @param   value   the value to be represented by the {@code Double}.
+     */
+    public Double(double value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Double} object that
+     * represents the floating-point value of type {@code double}
+     * represented by the string. The string is converted to a
+     * {@code double} value as if by the {@code valueOf} method.
+     *
+     * @param  s  a string to be converted to a {@code Double}.
+     * @throws    NumberFormatException  if the string does not contain a
+     *            parsable number.
+     * @see       java.lang.Double#valueOf(java.lang.String)
+     */
+    public Double(String s) throws NumberFormatException {
+        value = parseDouble(s);
+    }
+
+    /**
+     * Returns {@code true} if this {@code Double} value is
+     * a Not-a-Number (NaN), {@code false} otherwise.
+     *
+     * @return  {@code true} if the value represented by this object is
+     *          NaN; {@code false} otherwise.
+     */
+    public boolean isNaN() {
+        return isNaN(value);
+    }
+
+    /**
+     * Returns {@code true} if this {@code Double} value is
+     * infinitely large in magnitude, {@code false} otherwise.
+     *
+     * @return  {@code true} if the value represented by this object is
+     *          positive infinity or negative infinity;
+     *          {@code false} otherwise.
+     */
+    public boolean isInfinite() {
+        return isInfinite(value);
+    }
+
+    /**
+     * Returns a string representation of this {@code Double} object.
+     * The primitive {@code double} value represented by this
+     * object is converted to a string exactly as if by the method
+     * {@code toString} of one argument.
+     *
+     * @return  a {@code String} representation of this object.
+     * @see java.lang.Double#toString(double)
+     */
+    public String toString() {
+        return toString(value);
+    }
+
+    /**
+     * Returns the value of this {@code Double} as a {@code byte}
+     * after a narrowing primitive conversion.
+     *
+     * @return  the {@code double} value represented by this object
+     *          converted to type {@code byte}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @since JDK1.1
+     */
+    public byte byteValue() {
+        return (byte)value;
+    }
+
+    /**
+     * Returns the value of this {@code Double} as a {@code short}
+     * after a narrowing primitive conversion.
+     *
+     * @return  the {@code double} value represented by this object
+     *          converted to type {@code short}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @since JDK1.1
+     */
+    public short shortValue() {
+        return (short)value;
+    }
+
+    /**
+     * Returns the value of this {@code Double} as an {@code int}
+     * after a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     *
+     * @return  the {@code double} value represented by this object
+     *          converted to type {@code int}
+     */
+    public int intValue() {
+        return (int)value;
+    }
+
+    /**
+     * Returns the value of this {@code Double} as a {@code long}
+     * after a narrowing primitive conversion.
+     *
+     * @return  the {@code double} value represented by this object
+     *          converted to type {@code long}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public long longValue() {
+        return (long)value;
+    }
+
+    /**
+     * Returns the value of this {@code Double} as a {@code float}
+     * after a narrowing primitive conversion.
+     *
+     * @return  the {@code double} value represented by this object
+     *          converted to type {@code float}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @since JDK1.0
+     */
+    public float floatValue() {
+        return (float)value;
+    }
+
+    /**
+     * Returns the {@code double} value of this {@code Double} object.
+     *
+     * @return the {@code double} value represented by this object
+     */
+    public double doubleValue() {
+        return value;
+    }
+
+    /**
+     * Returns a hash code for this {@code Double} object. The
+     * result is the exclusive OR of the two halves of the
+     * {@code long} integer bit representation, exactly as
+     * produced by the method {@link #doubleToLongBits(double)}, of
+     * the primitive {@code double} value represented by this
+     * {@code Double} object. That is, the hash code is the value
+     * of the expression:
+     *
+     * <blockquote>
+     *  {@code (int)(v^(v>>>32))}
+     * </blockquote>
+     *
+     * where {@code v} is defined by:
+     *
+     * <blockquote>
+     *  {@code long v = Double.doubleToLongBits(this.doubleValue());}
+     * </blockquote>
+     *
+     * @return  a {@code hash code} value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return Double.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code double} value; compatible with
+     * {@code Double.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code double} value.
+     * @since 1.8
+     */
+    public static int hashCode(double value) {
+        long bits = doubleToLongBits(value);
+        return (int)(bits ^ (bits >>> 32));
+    }
+
+    /**
+     * Compares this object against the specified object.  The result
+     * is {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Double} object that
+     * represents a {@code double} that has the same value as the
+     * {@code double} represented by this object. For this
+     * purpose, two {@code double} values are considered to be
+     * the same if and only if the method {@link
+     * #doubleToLongBits(double)} returns the identical
+     * {@code long} value when applied to each.
+     *
+     * <p>Note that in most cases, for two instances of class
+     * {@code Double}, {@code d1} and {@code d2}, the
+     * value of {@code d1.equals(d2)} is {@code true} if and
+     * only if
+     *
+     * <blockquote>
+     *  {@code d1.doubleValue() == d2.doubleValue()}
+     * </blockquote>
+     *
+     * <p>also has the value {@code true}. However, there are two
+     * exceptions:
+     * <ul>
+     * <li>If {@code d1} and {@code d2} both represent
+     *     {@code Double.NaN}, then the {@code equals} method
+     *     returns {@code true}, even though
+     *     {@code Double.NaN==Double.NaN} has the value
+     *     {@code false}.
+     * <li>If {@code d1} represents {@code +0.0} while
+     *     {@code d2} represents {@code -0.0}, or vice versa,
+     *     the {@code equal} test has the value {@code false},
+     *     even though {@code +0.0==-0.0} has the value {@code true}.
+     * </ul>
+     * This definition allows hash tables to operate properly.
+     * @param   obj   the object to compare with.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see java.lang.Double#doubleToLongBits(double)
+     */
+    public boolean equals(Object obj) {
+        return (obj instanceof Double)
+               && (doubleToLongBits(((Double)obj).value) ==
+                      doubleToLongBits(value));
+    }
+
+    /**
+     * Returns a representation of the specified floating-point value
+     * according to the IEEE 754 floating-point "double
+     * format" bit layout.
+     *
+     * <p>Bit 63 (the bit that is selected by the mask
+     * {@code 0x8000000000000000L}) represents the sign of the
+     * floating-point number. Bits
+     * 62-52 (the bits that are selected by the mask
+     * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
+     * (the bits that are selected by the mask
+     * {@code 0x000fffffffffffffL}) represent the significand
+     * (sometimes called the mantissa) of the floating-point number.
+     *
+     * <p>If the argument is positive infinity, the result is
+     * {@code 0x7ff0000000000000L}.
+     *
+     * <p>If the argument is negative infinity, the result is
+     * {@code 0xfff0000000000000L}.
+     *
+     * <p>If the argument is NaN, the result is
+     * {@code 0x7ff8000000000000L}.
+     *
+     * <p>In all cases, the result is a {@code long} integer that, when
+     * given to the {@link #longBitsToDouble(long)} method, will produce a
+     * floating-point value the same as the argument to
+     * {@code doubleToLongBits} (except all NaN values are
+     * collapsed to a single "canonical" NaN value).
+     *
+     * @param   value   a {@code double} precision floating-point number.
+     * @return the bits that represent the floating-point number.
+     */
+    public static long doubleToLongBits(double value) {
+        long result = doubleToRawLongBits(value);
+        // Check for NaN based on values of bit fields, maximum
+        // exponent and nonzero significand.
+        if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
+              DoubleConsts.EXP_BIT_MASK) &&
+             (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
+            result = 0x7ff8000000000000L;
+        return result;
+    }
+
+    /**
+     * Returns a representation of the specified floating-point value
+     * according to the IEEE 754 floating-point "double
+     * format" bit layout, preserving Not-a-Number (NaN) values.
+     *
+     * <p>Bit 63 (the bit that is selected by the mask
+     * {@code 0x8000000000000000L}) represents the sign of the
+     * floating-point number. Bits
+     * 62-52 (the bits that are selected by the mask
+     * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
+     * (the bits that are selected by the mask
+     * {@code 0x000fffffffffffffL}) represent the significand
+     * (sometimes called the mantissa) of the floating-point number.
+     *
+     * <p>If the argument is positive infinity, the result is
+     * {@code 0x7ff0000000000000L}.
+     *
+     * <p>If the argument is negative infinity, the result is
+     * {@code 0xfff0000000000000L}.
+     *
+     * <p>If the argument is NaN, the result is the {@code long}
+     * integer representing the actual NaN value.  Unlike the
+     * {@code doubleToLongBits} method,
+     * {@code doubleToRawLongBits} does not collapse all the bit
+     * patterns encoding a NaN to a single "canonical" NaN
+     * value.
+     *
+     * <p>In all cases, the result is a {@code long} integer that,
+     * when given to the {@link #longBitsToDouble(long)} method, will
+     * produce a floating-point value the same as the argument to
+     * {@code doubleToRawLongBits}.
+     *
+     * @param   value   a {@code double} precision floating-point number.
+     * @return the bits that represent the floating-point number.
+     * @since 1.3
+     */
+    public static native long doubleToRawLongBits(double value);
+
+    /**
+     * Returns the {@code double} value corresponding to a given
+     * bit representation.
+     * The argument is considered to be a representation of a
+     * floating-point value according to the IEEE 754 floating-point
+     * "double format" bit layout.
+     *
+     * <p>If the argument is {@code 0x7ff0000000000000L}, the result
+     * is positive infinity.
+     *
+     * <p>If the argument is {@code 0xfff0000000000000L}, the result
+     * is negative infinity.
+     *
+     * <p>If the argument is any value in the range
+     * {@code 0x7ff0000000000001L} through
+     * {@code 0x7fffffffffffffffL} or in the range
+     * {@code 0xfff0000000000001L} through
+     * {@code 0xffffffffffffffffL}, the result is a NaN.  No IEEE
+     * 754 floating-point operation provided by Java can distinguish
+     * between two NaN values of the same type with different bit
+     * patterns.  Distinct values of NaN are only distinguishable by
+     * use of the {@code Double.doubleToRawLongBits} method.
+     *
+     * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
+     * values that can be computed from the argument:
+     *
+     * <blockquote><pre>{@code
+     * int s = ((bits >> 63) == 0) ? 1 : -1;
+     * int e = (int)((bits >> 52) & 0x7ffL);
+     * long m = (e == 0) ?
+     *                 (bits & 0xfffffffffffffL) << 1 :
+     *                 (bits & 0xfffffffffffffL) | 0x10000000000000L;
+     * }</pre></blockquote>
+     *
+     * Then the floating-point result equals the value of the mathematical
+     * expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-1075</sup>.
+     *
+     * <p>Note that this method may not be able to return a
+     * {@code double} NaN with exactly same bit pattern as the
+     * {@code long} argument.  IEEE 754 distinguishes between two
+     * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>.  The
+     * differences between the two kinds of NaN are generally not
+     * visible in Java.  Arithmetic operations on signaling NaNs turn
+     * them into quiet NaNs with a different, but often similar, bit
+     * pattern.  However, on some processors merely copying a
+     * signaling NaN also performs that conversion.  In particular,
+     * copying a signaling NaN to return it to the calling method
+     * may perform this conversion.  So {@code longBitsToDouble}
+     * may not be able to return a {@code double} with a
+     * signaling NaN bit pattern.  Consequently, for some
+     * {@code long} values,
+     * {@code doubleToRawLongBits(longBitsToDouble(start))} may
+     * <i>not</i> equal {@code start}.  Moreover, which
+     * particular bit patterns represent signaling NaNs is platform
+     * dependent; although all NaN bit patterns, quiet or signaling,
+     * must be in the NaN range identified above.
+     *
+     * @param   bits   any {@code long} integer.
+     * @return  the {@code double} floating-point value with the same
+     *          bit pattern.
+     */
+    public static native double longBitsToDouble(long bits);
+
+    /**
+     * Compares two {@code Double} objects numerically.  There
+     * are two ways in which comparisons performed by this method
+     * differ from those performed by the Java language numerical
+     * comparison operators ({@code <, <=, ==, >=, >})
+     * when applied to primitive {@code double} values:
+     * <ul><li>
+     *          {@code Double.NaN} is considered by this method
+     *          to be equal to itself and greater than all other
+     *          {@code double} values (including
+     *          {@code Double.POSITIVE_INFINITY}).
+     * <li>
+     *          {@code 0.0d} is considered by this method to be greater
+     *          than {@code -0.0d}.
+     * </ul>
+     * This ensures that the <i>natural ordering</i> of
+     * {@code Double} objects imposed by this method is <i>consistent
+     * with equals</i>.
+     *
+     * @param   anotherDouble   the {@code Double} to be compared.
+     * @return  the value {@code 0} if {@code anotherDouble} is
+     *          numerically equal to this {@code Double}; a value
+     *          less than {@code 0} if this {@code Double}
+     *          is numerically less than {@code anotherDouble};
+     *          and a value greater than {@code 0} if this
+     *          {@code Double} is numerically greater than
+     *          {@code anotherDouble}.
+     *
+     * @since   1.2
+     */
+    public int compareTo(Double anotherDouble) {
+        return Double.compare(value, anotherDouble.value);
+    }
+
+    /**
+     * Compares the two specified {@code double} values. The sign
+     * of the integer value returned is the same as that of the
+     * integer that would be returned by the call:
+     * <pre>
+     *    new Double(d1).compareTo(new Double(d2))
+     * </pre>
+     *
+     * @param   d1        the first {@code double} to compare
+     * @param   d2        the second {@code double} to compare
+     * @return  the value {@code 0} if {@code d1} is
+     *          numerically equal to {@code d2}; a value less than
+     *          {@code 0} if {@code d1} is numerically less than
+     *          {@code d2}; and a value greater than {@code 0}
+     *          if {@code d1} is numerically greater than
+     *          {@code d2}.
+     * @since 1.4
+     */
+    public static int compare(double d1, double d2) {
+        if (d1 < d2)
+            return -1;           // Neither val is NaN, thisVal is smaller
+        if (d1 > d2)
+            return 1;            // Neither val is NaN, thisVal is larger
+
+        // Cannot use doubleToRawLongBits because of possibility of NaNs.
+        long thisBits    = Double.doubleToLongBits(d1);
+        long anotherBits = Double.doubleToLongBits(d2);
+
+        return (thisBits == anotherBits ?  0 : // Values are equal
+                (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
+                 1));                          // (0.0, -0.0) or (NaN, !NaN)
+    }
+
+    /**
+     * Adds two {@code double} values together as per the + operator.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the sum of {@code a} and {@code b}
+     * @jls 4.2.4 Floating-Point Operations
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static double sum(double a, double b) {
+        return a + b;
+    }
+
+    /**
+     * Returns the greater of two {@code double} values
+     * as if by calling {@link Math#max(double, double) Math.max}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the greater of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static double max(double a, double b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code double} values
+     * as if by calling {@link Math#min(double, double) Math.min}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the smaller of {@code a} and {@code b}.
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static double min(double a, double b) {
+        return Math.min(a, b);
+    }
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -9172774392245257468L;
+}
diff --git a/java/lang/Enum.annotated.java b/java/lang/Enum.annotated.java
new file mode 100644
index 0000000..b49785e
--- /dev/null
+++ b/java/lang/Enum.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 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 java.lang;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E>, java.io.Serializable {
+
+protected Enum(@libcore.util.NonNull java.lang.String name, int ordinal) { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.String name() { throw new RuntimeException("Stub!"); }
+
+public final int ordinal() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object other) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public final int compareTo(@libcore.util.NullFromTypeParam E o) { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.Class<E> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public static <T extends java.lang.Enum<T>> T valueOf(@libcore.util.NonNull java.lang.Class<T> enumType, @libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+protected final void finalize() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Enum.java b/java/lang/Enum.java
new file mode 100644
index 0000000..988c133
--- /dev/null
+++ b/java/lang/Enum.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 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 java.lang;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import libcore.util.BasicLruCache;
+import libcore.util.EmptyArray;
+
+/**
+ * This is the common base class of all Java language enumeration types.
+ *
+ * More information about enums, including descriptions of the
+ * implicitly declared methods synthesized by the compiler, can be
+ * found in section 8.9 of
+ * <cite>The Java&trade; Language Specification</cite>.
+ *
+ * <p> Note that when using an enumeration type as the type of a set
+ * or as the type of the keys in a map, specialized and efficient
+ * {@linkplain java.util.EnumSet set} and {@linkplain
+ * java.util.EnumMap map} implementations are available.
+ *
+ * @param <E> The enum type subclass
+ * @author  Josh Bloch
+ * @author  Neal Gafter
+ * @see     Class#getEnumConstants()
+ * @see     java.util.EnumSet
+ * @see     java.util.EnumMap
+ * @since   1.5
+ */
+public abstract class Enum<E extends Enum<E>>
+        implements Comparable<E>, Serializable {
+    /**
+     * The name of this enum constant, as declared in the enum declaration.
+     * Most programmers should use the {@link #toString} method rather than
+     * accessing this field.
+     */
+    private final String name;
+
+    /**
+     * Returns the name of this enum constant, exactly as declared in its
+     * enum declaration.
+     *
+     * <b>Most programmers should use the {@link #toString} method in
+     * preference to this one, as the toString method may return
+     * a more user-friendly name.</b>  This method is designed primarily for
+     * use in specialized situations where correctness depends on getting the
+     * exact name, which will not vary from release to release.
+     *
+     * @return the name of this enum constant
+     */
+    public final String name() {
+        return name;
+    }
+
+    /**
+     * The ordinal of this enumeration constant (its position
+     * in the enum declaration, where the initial constant is assigned
+     * an ordinal of zero).
+     *
+     * Most programmers will have no use for this field.  It is designed
+     * for use by sophisticated enum-based data structures, such as
+     * {@link java.util.EnumSet} and {@link java.util.EnumMap}.
+     */
+    private final int ordinal;
+
+    /**
+     * Returns the ordinal of this enumeration constant (its position
+     * in its enum declaration, where the initial constant is assigned
+     * an ordinal of zero).
+     *
+     * Most programmers will have no use for this method.  It is
+     * designed for use by sophisticated enum-based data structures, such
+     * as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
+     *
+     * @return the ordinal of this enumeration constant
+     */
+    public final int ordinal() {
+        return ordinal;
+    }
+
+    /**
+     * Sole constructor.  Programmers cannot invoke this constructor.
+     * It is for use by code emitted by the compiler in response to
+     * enum type declarations.
+     *
+     * @param name - The name of this enum constant, which is the identifier
+     *               used to declare it.
+     * @param ordinal - The ordinal of this enumeration constant (its position
+     *         in the enum declaration, where the initial constant is assigned
+     *         an ordinal of zero).
+     */
+    protected Enum(String name, int ordinal) {
+        this.name = name;
+        this.ordinal = ordinal;
+    }
+
+    /**
+     * Returns the name of this enum constant, as contained in the
+     * declaration.  This method may be overridden, though it typically
+     * isn't necessary or desirable.  An enum type should override this
+     * method when a more "programmer-friendly" string form exists.
+     *
+     * @return the name of this enum constant
+     */
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Returns true if the specified object is equal to this
+     * enum constant.
+     *
+     * @param other the object to be compared for equality with this object.
+     * @return  true if the specified object is equal to this
+     *          enum constant.
+     */
+    public final boolean equals(Object other) {
+        return this==other;
+    }
+
+    /**
+     * Returns a hash code for this enum constant.
+     *
+     * @return a hash code for this enum constant.
+     */
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * Throws CloneNotSupportedException.  This guarantees that enums
+     * are never cloned, which is necessary to preserve their "singleton"
+     * status.
+     *
+     * @return (never returns)
+     */
+    protected final Object clone() throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+    /**
+     * Compares this enum with the specified object for order.  Returns a
+     * negative integer, zero, or a positive integer as this object is less
+     * than, equal to, or greater than the specified object.
+     *
+     * Enum constants are only comparable to other enum constants of the
+     * same enum type.  The natural order implemented by this
+     * method is the order in which the constants are declared.
+     */
+    public final int compareTo(E o) {
+        Enum<?> other = (Enum<?>)o;
+        Enum<E> self = this;
+        if (self.getClass() != other.getClass() && // optimization
+            self.getDeclaringClass() != other.getDeclaringClass())
+            throw new ClassCastException();
+        return self.ordinal - other.ordinal;
+    }
+
+    /**
+     * Returns the Class object corresponding to this enum constant's
+     * enum type.  Two enum constants e1 and  e2 are of the
+     * same enum type if and only if
+     *   e1.getDeclaringClass() == e2.getDeclaringClass().
+     * (The value returned by this method may differ from the one returned
+     * by the {@link Object#getClass} method for enum constants with
+     * constant-specific class bodies.)
+     *
+     * @return the Class object corresponding to this enum constant's
+     *     enum type
+     */
+    @SuppressWarnings("unchecked")
+    public final Class<E> getDeclaringClass() {
+        Class<?> clazz = getClass();
+        Class<?> zuper = clazz.getSuperclass();
+        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
+    }
+
+    /**
+     * Returns the enum constant of the specified enum type with the
+     * specified name.  The name must match exactly an identifier used
+     * to declare an enum constant in this type.  (Extraneous whitespace
+     * characters are not permitted.)
+     *
+     * <p>Note that for a particular enum type {@code T}, the
+     * implicitly declared {@code public static T valueOf(String)}
+     * method on that enum may be used instead of this method to map
+     * from a name to the corresponding enum constant.  All the
+     * constants of an enum type can be obtained by calling the
+     * implicit {@code public static T[] values()} method of that
+     * type.
+     *
+     * @param <T> The enum type whose constant is to be returned
+     * @param enumType the {@code Class} object of the enum type from which
+     *      to return a constant
+     * @param name the name of the constant to return
+     * @return the enum constant of the specified enum type with the
+     *      specified name
+     * @throws IllegalArgumentException if the specified enum type has
+     *         no constant with the specified name, or the specified
+     *         class object does not represent an enum type
+     * @throws NullPointerException if {@code enumType} or {@code name}
+     *         is null
+     * @since 1.5
+     */
+    // BEGIN Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+    // This change was made to fix a performance regression. See b/4087759 and b/109791362 for more
+    // background information.
+    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
+                                                String name) {
+        Objects.requireNonNull(enumType, "enumType == null");
+        Objects.requireNonNull(enumType, "name == null");
+        T[] values = getSharedConstants(enumType);
+        if (values == null) {
+            throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
+        }
+
+        // Iterate backwards through the array to retain historic Android behavior in the
+        // unexpected / likely invalid case where there are multiple values with the same name.
+        for (int i = values.length - 1; i >= 0; --i) {
+            T value = values[i];
+            if (name.equals(value.name())) {
+                return value;
+            }
+        }
+        throw new IllegalArgumentException(
+                "No enum constant " + enumType.getCanonicalName() + "." + name);
+    }
+
+    private static Object[] enumValues(Class<? extends Enum> clazz) {
+        if (!clazz.isEnum()) {
+            // Either clazz is Enum.class itself, or it is not an enum class and the method was
+            // called unsafely e.g. using an unchecked cast or via reflection.
+            return null;
+        }
+        try {
+            Method valueMethod = clazz.getDeclaredMethod("values");
+            return (Object[]) valueMethod.invoke(null);
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
+            = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
+        @Override protected Object[] create(Class<? extends Enum> enumType) {
+            return enumValues(enumType);
+        }
+    };
+
+    /**
+     * Returns a shared, mutable array containing the constants of this enum. It
+     * is an error to modify the returned array.
+     *
+     * @hide
+     */
+    @SuppressWarnings("unchecked") // the cache always returns the type matching enumType
+    public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
+        return (T[]) sharedConstantsCache.get(enumType);
+    }
+    // END Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+
+    /**
+     * enum classes cannot have finalize methods.
+     */
+    protected final void finalize() { }
+
+    /**
+     * prevent default deserialization
+     */
+    private void readObject(ObjectInputStream in) throws IOException,
+        ClassNotFoundException {
+        throw new InvalidObjectException("can't deserialize enum");
+    }
+
+    private void readObjectNoData() throws ObjectStreamException {
+        throw new InvalidObjectException("can't deserialize enum");
+    }
+}
diff --git a/java/lang/EnumConstantNotPresentException.java b/java/lang/EnumConstantNotPresentException.java
new file mode 100644
index 0000000..1773160
--- /dev/null
+++ b/java/lang/EnumConstantNotPresentException.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2004, 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 java.lang;
+
+/**
+ * Thrown when an application tries to access an enum constant by name
+ * and the enum type contains no constant with the specified name.
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author  Josh Bloch
+ * @see     java.lang.reflect.AnnotatedElement
+ * @since   1.5
+ */
+@SuppressWarnings("rawtypes") /* rawtypes are part of the public api */
+public class EnumConstantNotPresentException extends RuntimeException {
+    private static final long serialVersionUID = -6046998521960521108L;
+
+    /**
+     * The type of the missing enum constant.
+     */
+    private Class<? extends Enum> enumType;
+
+    /**
+     * The name of the missing enum constant.
+     */
+    private String constantName;
+
+    /**
+     * Constructs an <tt>EnumConstantNotPresentException</tt> for the
+     * specified constant.
+     *
+     * @param enumType the type of the missing enum constant
+     * @param constantName the name of the missing enum constant
+     */
+    public EnumConstantNotPresentException(Class<? extends Enum> enumType,
+                                           String constantName) {
+        super(enumType.getName() + "." + constantName);
+        this.enumType = enumType;
+        this.constantName  = constantName;
+    }
+
+    /**
+     * Returns the type of the missing enum constant.
+     *
+     * @return the type of the missing enum constant
+     */
+    public Class<? extends Enum> enumType() { return enumType; }
+
+    /**
+     * Returns the name of the missing enum constant.
+     *
+     * @return the name of the missing enum constant
+     */
+    public String constantName() { return constantName; }
+}
diff --git a/java/lang/Error.java b/java/lang/Error.java
new file mode 100644
index 0000000..d18c15f
--- /dev/null
+++ b/java/lang/Error.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1995, 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 java.lang;
+
+/**
+ * An {@code Error} is a subclass of {@code Throwable}
+ * that indicates serious problems that a reasonable application
+ * should not try to catch. Most such errors are abnormal conditions.
+ * The {@code ThreadDeath} error, though a "normal" condition,
+ * is also a subclass of {@code Error} because most applications
+ * should not try to catch it.
+ * <p>
+ * A method is not required to declare in its {@code throws}
+ * clause any subclasses of {@code Error} that might be thrown
+ * during the execution of the method but not caught, since these
+ * errors are abnormal conditions that should never occur.
+ *
+ * That is, {@code Error} and its subclasses are regarded as unchecked
+ * exceptions for the purposes of compile-time checking of exceptions.
+ *
+ * @author  Frank Yellin
+ * @see     java.lang.ThreadDeath
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since   JDK1.0
+ */
+public class Error extends Throwable {
+    static final long serialVersionUID = 4980196508277280342L;
+
+    /**
+     * Constructs a new error with {@code null} as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     */
+    public Error() {
+        super();
+    }
+
+    /**
+     * Constructs a new error with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * @param   message   the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public Error(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new error with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this error's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Error(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new error with the specified cause and a detail
+     * message of {@code (cause==null ? null : cause.toString())} (which
+     * typically contains the class and detail message of {@code cause}).
+     * This constructor is useful for errors that are little more than
+     * wrappers for other throwables.
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Error(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new error with the specified detail message,
+     * cause, suppression enabled or disabled, and writable stack
+     * trace enabled or disabled.
+     *
+     * @param  message the detail message.
+     * @param cause the cause.  (A {@code null} value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @param enableSuppression whether or not suppression is enabled
+     *                          or disabled
+     * @param writableStackTrace whether or not the stack trace should
+     *                           be writable
+     *
+     * @since 1.7
+     */
+    protected Error(String message, Throwable cause,
+                    boolean enableSuppression,
+                    boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/java/lang/Exception.java b/java/lang/Exception.java
new file mode 100644
index 0000000..0bcbf9c
--- /dev/null
+++ b/java/lang/Exception.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * The class {@code Exception} and its subclasses are a form of
+ * {@code Throwable} that indicates conditions that a reasonable
+ * application might want to catch.
+ *
+ * <p>The class {@code Exception} and any subclasses that are not also
+ * subclasses of {@link RuntimeException} are <em>checked
+ * exceptions</em>.  Checked exceptions need to be declared in a
+ * method or constructor's {@code throws} clause if they can be thrown
+ * by the execution of the method or constructor and propagate outside
+ * the method or constructor boundary.
+ *
+ * @author  Frank Yellin
+ * @see     java.lang.Error
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since   JDK1.0
+ */
+public class Exception extends Throwable {
+    static final long serialVersionUID = -3387516993124229948L;
+
+    /**
+     * Constructs a new exception with {@code null} as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     */
+    public Exception() {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * @param   message   the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public Exception(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Exception(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Exception(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message,
+     * cause, suppression enabled or disabled, and writable stack
+     * trace enabled or disabled.
+     *
+     * @param  message the detail message.
+     * @param cause the cause.  (A {@code null} value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @param enableSuppression whether or not suppression is enabled
+     *                          or disabled
+     * @param writableStackTrace whether or not the stack trace should
+     *                           be writable
+     * @since 1.7
+     */
+    protected Exception(String message, Throwable cause,
+                        boolean enableSuppression,
+                        boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/java/lang/ExceptionInInitializerError.java b/java/lang/ExceptionInInitializerError.java
new file mode 100644
index 0000000..0259766
--- /dev/null
+++ b/java/lang/ExceptionInInitializerError.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1996, 2000, 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;
+
+/**
+ * Signals that an unexpected exception has occurred in a static initializer.
+ * An <code>ExceptionInInitializerError</code> is thrown to indicate that an
+ * exception occurred during evaluation of a static initializer or the
+ * initializer for a static variable.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism.  The "saved throwable
+ * object" that may be provided at construction time and accessed via
+ * the {@link #getException()} method is now known as the <i>cause</i>,
+ * and may be accessed via the {@link Throwable#getCause()} method, as well
+ * as the aforementioned "legacy method."
+ *
+ * @author  Frank Yellin
+ * @since   JDK1.1
+ */
+public class ExceptionInInitializerError extends LinkageError {
+    /**
+     * Use serialVersionUID from JDK 1.1.X for interoperability
+     */
+    private static final long serialVersionUID = 1521711792217232256L;
+
+    /**
+     * This field holds the exception if the
+     * ExceptionInInitializerError(Throwable thrown) constructor was
+     * used to instantiate the object
+     *
+     * @serial
+     *
+     */
+    private Throwable exception;
+
+    /**
+     * Constructs an <code>ExceptionInInitializerError</code> with
+     * <code>null</code> as its detail message string and with no saved
+     * throwable object.
+     * A detail message is a String that describes this particular exception.
+     */
+    public ExceptionInInitializerError() {
+        initCause(null);  // Disallow subsequent initCause
+    }
+
+    /**
+     * Constructs a new <code>ExceptionInInitializerError</code> class by
+     * saving a reference to the <code>Throwable</code> object thrown for
+     * later retrieval by the {@link #getException()} method. The detail
+     * message string is set to <code>null</code>.
+     *
+     * @param thrown The exception thrown
+     */
+    public ExceptionInInitializerError(Throwable thrown) {
+        initCause(null);  // Disallow subsequent initCause
+        this.exception = thrown;
+    }
+
+    /**
+     * Constructs an ExceptionInInitializerError with the specified detail
+     * message string.  A detail message is a String that describes this
+     * particular exception. The detail message string is saved for later
+     * retrieval by the {@link Throwable#getMessage()} method. There is no
+     * saved throwable object.
+     *
+     *
+     * @param s the detail message
+     */
+    public ExceptionInInitializerError(String s) {
+        super(s);
+        initCause(null);  // Disallow subsequent initCause
+    }
+
+    /**
+     * Returns the exception that occurred during a static initialization that
+     * caused this error to be created.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the saved throwable object of this
+     *         <code>ExceptionInInitializerError</code>, or <code>null</code>
+     *         if this <code>ExceptionInInitializerError</code> has no saved
+     *         throwable object.
+     */
+    public Throwable getException() {
+        return exception;
+    }
+
+    /**
+     * Returns the cause of this error (the exception that occurred
+     * during a static initialization that caused this error to be created).
+     *
+     * @return  the cause of this error or <code>null</code> if the
+     *          cause is nonexistent or unknown.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return exception;
+    }
+}
diff --git a/java/lang/FindBugsSuppressWarnings.java b/java/lang/FindBugsSuppressWarnings.java
new file mode 100644
index 0000000..ac753bd
--- /dev/null
+++ b/java/lang/FindBugsSuppressWarnings.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+import java.lang.annotation.Target;
+
+/**
+ * Suppress FindBugs warnings on the annotated element. FindBugs will recognize
+ * any annotation that has class retention and whose name ends with
+ * "SuppressWarnings".
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(CLASS)
+public @interface FindBugsSuppressWarnings {
+
+    /**
+     * The <a href="http://findbugs.sourceforge.net/bugDescriptions.html">FindBugs
+     * Patterns</a> to suppress, such as {@code SE_TRANSIENT_FIELD_NOT_RESTORED}
+     * or {@code Se}. Full, upper case names are preferred.
+     */
+    String[] value();
+}
diff --git a/java/lang/Float.annotated.java b/java/lang/Float.annotated.java
new file mode 100644
index 0000000..a459ec1
--- /dev/null
+++ b/java/lang/Float.annotated.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
+
+public Float(float value) { throw new RuntimeException("Stub!"); }
+
+public Float(double value) { throw new RuntimeException("Stub!"); }
+
+public Float(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Float valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Float valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+public static float parseFloat(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(float f) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(float value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static int floatToIntBits(float value) { throw new RuntimeException("Stub!"); }
+
+public static native int floatToRawIntBits(float value);
+
+public static native float intBitsToFloat(int bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Float anotherFloat) { throw new RuntimeException("Stub!"); }
+
+public static int compare(float f1, float f2) { throw new RuntimeException("Stub!"); }
+
+public static float sum(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_EXPONENT = 127; // 0x7f
+
+public static final float MAX_VALUE = 3.4028235E38f;
+
+public static final int MIN_EXPONENT = -126; // 0xffffff82
+
+public static final float MIN_NORMAL = 1.17549435E-38f;
+
+public static final float MIN_VALUE = 1.4E-45f;
+
+public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
+
+public static final float NaN = (0.0f/0.0f);
+
+public static final float POSITIVE_INFINITY = (1.0f/0.0f);
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Float> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Float.java b/java/lang/Float.java
new file mode 100644
index 0000000..5cc28f9
--- /dev/null
+++ b/java/lang/Float.java
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 1994, 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;
+
+import sun.misc.FloatingDecimal;
+import sun.misc.FloatConsts;
+import sun.misc.DoubleConsts;
+
+/**
+ * The {@code Float} class wraps a value of primitive type
+ * {@code float} in an object. An object of type
+ * {@code Float} contains a single field whose type is
+ * {@code float}.
+ *
+ * <p>In addition, this class provides several methods for converting a
+ * {@code float} to a {@code String} and a
+ * {@code String} to a {@code float}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code float}.
+ *
+ * @author  Lee Boynton
+ * @author  Arthur van Hoff
+ * @author  Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Float extends Number implements Comparable<Float> {
+    /**
+     * A constant holding the positive infinity of type
+     * {@code float}. It is equal to the value returned by
+     * {@code Float.intBitsToFloat(0x7f800000)}.
+     */
+    public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
+
+    /**
+     * A constant holding the negative infinity of type
+     * {@code float}. It is equal to the value returned by
+     * {@code Float.intBitsToFloat(0xff800000)}.
+     */
+    public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
+
+    /**
+     * A constant holding a Not-a-Number (NaN) value of type
+     * {@code float}.  It is equivalent to the value returned by
+     * {@code Float.intBitsToFloat(0x7fc00000)}.
+     */
+    public static final float NaN = 0.0f / 0.0f;
+
+    /**
+     * A constant holding the largest positive finite value of type
+     * {@code float}, (2-2<sup>-23</sup>)&middot;2<sup>127</sup>.
+     * It is equal to the hexadecimal floating-point literal
+     * {@code 0x1.fffffeP+127f} and also equal to
+     * {@code Float.intBitsToFloat(0x7f7fffff)}.
+     */
+    public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
+
+    /**
+     * A constant holding the smallest positive normal value of type
+     * {@code float}, 2<sup>-126</sup>.  It is equal to the
+     * hexadecimal floating-point literal {@code 0x1.0p-126f} and also
+     * equal to {@code Float.intBitsToFloat(0x00800000)}.
+     *
+     * @since 1.6
+     */
+    public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
+
+    /**
+     * A constant holding the smallest positive nonzero value of type
+     * {@code float}, 2<sup>-149</sup>. It is equal to the
+     * hexadecimal floating-point literal {@code 0x0.000002P-126f}
+     * and also equal to {@code Float.intBitsToFloat(0x1)}.
+     */
+    public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
+
+    /**
+     * Maximum exponent a finite {@code float} variable may have.  It
+     * is equal to the value returned by {@code
+     * Math.getExponent(Float.MAX_VALUE)}.
+     *
+     * @since 1.6
+     */
+    public static final int MAX_EXPONENT = 127;
+
+    /**
+     * Minimum exponent a normalized {@code float} variable may have.
+     * It is equal to the value returned by {@code
+     * Math.getExponent(Float.MIN_NORMAL)}.
+     *
+     * @since 1.6
+     */
+    public static final int MIN_EXPONENT = -126;
+
+    /**
+     * The number of bits used to represent a {@code float} value.
+     *
+     * @since 1.5
+     */
+    public static final int SIZE = 32;
+
+    /**
+     * The number of bytes used to represent a {@code float} value.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code float}.
+     *
+     * @since JDK1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
+
+    /**
+     * Returns a string representation of the {@code float}
+     * argument. All characters mentioned below are ASCII characters.
+     * <ul>
+     * <li>If the argument is NaN, the result is the string
+     * "{@code NaN}".
+     * <li>Otherwise, the result is a string that represents the sign and
+     *     magnitude (absolute value) of the argument. If the sign is
+     *     negative, the first character of the result is
+     *     '{@code -}' ({@code '\u005Cu002D'}); if the sign is
+     *     positive, no sign character appears in the result. As for
+     *     the magnitude <i>m</i>:
+     * <ul>
+     * <li>If <i>m</i> is infinity, it is represented by the characters
+     *     {@code "Infinity"}; thus, positive infinity produces
+     *     the result {@code "Infinity"} and negative infinity
+     *     produces the result {@code "-Infinity"}.
+     * <li>If <i>m</i> is zero, it is represented by the characters
+     *     {@code "0.0"}; thus, negative zero produces the result
+     *     {@code "-0.0"} and positive zero produces the result
+     *     {@code "0.0"}.
+     * <li> If <i>m</i> is greater than or equal to 10<sup>-3</sup> but
+     *      less than 10<sup>7</sup>, then it is represented as the
+     *      integer part of <i>m</i>, in decimal form with no leading
+     *      zeroes, followed by '{@code .}'
+     *      ({@code '\u005Cu002E'}), followed by one or more
+     *      decimal digits representing the fractional part of
+     *      <i>m</i>.
+     * <li> If <i>m</i> is less than 10<sup>-3</sup> or greater than or
+     *      equal to 10<sup>7</sup>, then it is represented in
+     *      so-called "computerized scientific notation." Let <i>n</i>
+     *      be the unique integer such that 10<sup><i>n</i> </sup>&le;
+     *      <i>m</i> {@literal <} 10<sup><i>n</i>+1</sup>; then let <i>a</i>
+     *      be the mathematically exact quotient of <i>m</i> and
+     *      10<sup><i>n</i></sup> so that 1 &le; <i>a</i> {@literal <} 10.
+     *      The magnitude is then represented as the integer part of
+     *      <i>a</i>, as a single decimal digit, followed by
+     *      '{@code .}' ({@code '\u005Cu002E'}), followed by
+     *      decimal digits representing the fractional part of
+     *      <i>a</i>, followed by the letter '{@code E}'
+     *      ({@code '\u005Cu0045'}), followed by a representation
+     *      of <i>n</i> as a decimal integer, as produced by the
+     *      method {@link java.lang.Integer#toString(int)}.
+     *
+     * </ul>
+     * </ul>
+     * How many digits must be printed for the fractional part of
+     * <i>m</i> or <i>a</i>? There must be at least one digit
+     * to represent the fractional part, and beyond that as many, but
+     * only as many, more digits as are needed to uniquely distinguish
+     * the argument value from adjacent values of type
+     * {@code float}. That is, suppose that <i>x</i> is the
+     * exact mathematical value represented by the decimal
+     * representation produced by this method for a finite nonzero
+     * argument <i>f</i>. Then <i>f</i> must be the {@code float}
+     * value nearest to <i>x</i>; or, if two {@code float} values are
+     * equally close to <i>x</i>, then <i>f</i> must be one of
+     * them and the least significant bit of the significand of
+     * <i>f</i> must be {@code 0}.
+     *
+     * <p>To create localized string representations of a floating-point
+     * value, use subclasses of {@link java.text.NumberFormat}.
+     *
+     * @param   f   the float to be converted.
+     * @return a string representation of the argument.
+     */
+    public static String toString(float f) {
+        return FloatingDecimal.toJavaFormatString(f);
+    }
+
+    /**
+     * Returns a hexadecimal string representation of the
+     * {@code float} argument. All characters mentioned below are
+     * ASCII characters.
+     *
+     * <ul>
+     * <li>If the argument is NaN, the result is the string
+     *     "{@code NaN}".
+     * <li>Otherwise, the result is a string that represents the sign and
+     * magnitude (absolute value) of the argument. If the sign is negative,
+     * the first character of the result is '{@code -}'
+     * ({@code '\u005Cu002D'}); if the sign is positive, no sign character
+     * appears in the result. As for the magnitude <i>m</i>:
+     *
+     * <ul>
+     * <li>If <i>m</i> is infinity, it is represented by the string
+     * {@code "Infinity"}; thus, positive infinity produces the
+     * result {@code "Infinity"} and negative infinity produces
+     * the result {@code "-Infinity"}.
+     *
+     * <li>If <i>m</i> is zero, it is represented by the string
+     * {@code "0x0.0p0"}; thus, negative zero produces the result
+     * {@code "-0x0.0p0"} and positive zero produces the result
+     * {@code "0x0.0p0"}.
+     *
+     * <li>If <i>m</i> is a {@code float} value with a
+     * normalized representation, substrings are used to represent the
+     * significand and exponent fields.  The significand is
+     * represented by the characters {@code "0x1."}
+     * followed by a lowercase hexadecimal representation of the rest
+     * of the significand as a fraction.  Trailing zeros in the
+     * hexadecimal representation are removed unless all the digits
+     * are zero, in which case a single zero is used. Next, the
+     * exponent is represented by {@code "p"} followed
+     * by a decimal string of the unbiased exponent as if produced by
+     * a call to {@link Integer#toString(int) Integer.toString} on the
+     * exponent value.
+     *
+     * <li>If <i>m</i> is a {@code float} value with a subnormal
+     * representation, the significand is represented by the
+     * characters {@code "0x0."} followed by a
+     * hexadecimal representation of the rest of the significand as a
+     * fraction.  Trailing zeros in the hexadecimal representation are
+     * removed. Next, the exponent is represented by
+     * {@code "p-126"}.  Note that there must be at
+     * least one nonzero digit in a subnormal significand.
+     *
+     * </ul>
+     *
+     * </ul>
+     *
+     * <table border>
+     * <caption>Examples</caption>
+     * <tr><th>Floating-point Value</th><th>Hexadecimal String</th>
+     * <tr><td>{@code 1.0}</td> <td>{@code 0x1.0p0}</td>
+     * <tr><td>{@code -1.0}</td>        <td>{@code -0x1.0p0}</td>
+     * <tr><td>{@code 2.0}</td> <td>{@code 0x1.0p1}</td>
+     * <tr><td>{@code 3.0}</td> <td>{@code 0x1.8p1}</td>
+     * <tr><td>{@code 0.5}</td> <td>{@code 0x1.0p-1}</td>
+     * <tr><td>{@code 0.25}</td>        <td>{@code 0x1.0p-2}</td>
+     * <tr><td>{@code Float.MAX_VALUE}</td>
+     *     <td>{@code 0x1.fffffep127}</td>
+     * <tr><td>{@code Minimum Normal Value}</td>
+     *     <td>{@code 0x1.0p-126}</td>
+     * <tr><td>{@code Maximum Subnormal Value}</td>
+     *     <td>{@code 0x0.fffffep-126}</td>
+     * <tr><td>{@code Float.MIN_VALUE}</td>
+     *     <td>{@code 0x0.000002p-126}</td>
+     * </table>
+     * @param   f   the {@code float} to be converted.
+     * @return a hex string representation of the argument.
+     * @since 1.5
+     * @author Joseph D. Darcy
+     */
+    public static String toHexString(float f) {
+        if (Math.abs(f) < FloatConsts.MIN_NORMAL
+            &&  f != 0.0f ) {// float subnormal
+            // Adjust exponent to create subnormal double, then
+            // replace subnormal double exponent with subnormal float
+            // exponent
+            String s = Double.toHexString(Math.scalb((double)f,
+                                                     /* -1022+126 */
+                                                     DoubleConsts.MIN_EXPONENT-
+                                                     FloatConsts.MIN_EXPONENT));
+            return s.replaceFirst("p-1022$", "p-126");
+        }
+        else // double string will be the same as float string
+            return Double.toHexString(f);
+    }
+
+    /**
+     * Returns a {@code Float} object holding the
+     * {@code float} value represented by the argument string
+     * {@code s}.
+     *
+     * <p>If {@code s} is {@code null}, then a
+     * {@code NullPointerException} is thrown.
+     *
+     * <p>Leading and trailing whitespace characters in {@code s}
+     * are ignored.  Whitespace is removed as if by the {@link
+     * String#trim} method; that is, both ASCII space and control
+     * characters are removed. The rest of {@code s} should
+     * constitute a <i>FloatValue</i> as described by the lexical
+     * syntax rules:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>FloatValue:</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code NaN}
+     * <dd><i>Sign<sub>opt</sub></i> {@code Infinity}
+     * <dd><i>Sign<sub>opt</sub> FloatingPointLiteral</i>
+     * <dd><i>Sign<sub>opt</sub> HexFloatingPointLiteral</i>
+     * <dd><i>SignedInteger</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>HexFloatingPointLiteral</i>:
+     * <dd> <i>HexSignificand BinaryExponent FloatTypeSuffix<sub>opt</sub></i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>HexSignificand:</i>
+     * <dd><i>HexNumeral</i>
+     * <dd><i>HexNumeral</i> {@code .}
+     * <dd>{@code 0x} <i>HexDigits<sub>opt</sub>
+     *     </i>{@code .}<i> HexDigits</i>
+     * <dd>{@code 0X}<i> HexDigits<sub>opt</sub>
+     *     </i>{@code .} <i>HexDigits</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>BinaryExponent:</i>
+     * <dd><i>BinaryExponentIndicator SignedInteger</i>
+     * </dl>
+     *
+     * <dl>
+     * <dt><i>BinaryExponentIndicator:</i>
+     * <dd>{@code p}
+     * <dd>{@code P}
+     * </dl>
+     *
+     * </blockquote>
+     *
+     * where <i>Sign</i>, <i>FloatingPointLiteral</i>,
+     * <i>HexNumeral</i>, <i>HexDigits</i>, <i>SignedInteger</i> and
+     * <i>FloatTypeSuffix</i> are as defined in the lexical structure
+     * sections of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     * If {@code s} does not have the form of
+     * a <i>FloatValue</i>, then a {@code NumberFormatException}
+     * is thrown. Otherwise, {@code s} is regarded as
+     * representing an exact decimal value in the usual
+     * "computerized scientific notation" or as an exact
+     * hexadecimal value; this exact numerical value is then
+     * conceptually converted to an "infinitely precise"
+     * binary value that is then rounded to type {@code float}
+     * by the usual round-to-nearest rule of IEEE 754 floating-point
+     * arithmetic, which includes preserving the sign of a zero
+     * value.
+     *
+     * Note that the round-to-nearest rule also implies overflow and
+     * underflow behaviour; if the exact value of {@code s} is large
+     * enough in magnitude (greater than or equal to ({@link
+     * #MAX_VALUE} + {@link Math#ulp(float) ulp(MAX_VALUE)}/2),
+     * rounding to {@code float} will result in an infinity and if the
+     * exact value of {@code s} is small enough in magnitude (less
+     * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+     * result in a zero.
+     *
+     * Finally, after rounding a {@code Float} object representing
+     * this {@code float} value is returned.
+     *
+     * <p>To interpret localized string representations of a
+     * floating-point value, use subclasses of {@link
+     * java.text.NumberFormat}.
+     *
+     * <p>Note that trailing format specifiers, specifiers that
+     * determine the type of a floating-point literal
+     * ({@code 1.0f} is a {@code float} value;
+     * {@code 1.0d} is a {@code double} value), do
+     * <em>not</em> influence the results of this method.  In other
+     * words, the numerical value of the input string is converted
+     * directly to the target floating-point type.  In general, the
+     * two-step sequence of conversions, string to {@code double}
+     * followed by {@code double} to {@code float}, is
+     * <em>not</em> equivalent to converting a string directly to
+     * {@code float}.  For example, if first converted to an
+     * intermediate {@code double} and then to
+     * {@code float}, the string<br>
+     * {@code "1.00000017881393421514957253748434595763683319091796875001d"}<br>
+     * results in the {@code float} value
+     * {@code 1.0000002f}; if the string is converted directly to
+     * {@code float}, <code>1.000000<b>1</b>f</code> results.
+     *
+     * <p>To avoid calling this method on an invalid string and having
+     * a {@code NumberFormatException} be thrown, the documentation
+     * for {@link Double#valueOf Double.valueOf} lists a regular
+     * expression which can be used to screen the input.
+     *
+     * @param   s   the string to be parsed.
+     * @return  a {@code Float} object holding the value
+     *          represented by the {@code String} argument.
+     * @throws  NumberFormatException  if the string does not contain a
+     *          parsable number.
+     */
+    public static Float valueOf(String s) throws NumberFormatException {
+        return new Float(parseFloat(s));
+    }
+
+    /**
+     * Returns a {@code Float} instance representing the specified
+     * {@code float} value.
+     * If a new {@code Float} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Float(float)}, as this method is likely to yield
+     * significantly better space and time performance by caching
+     * frequently requested values.
+     *
+     * @param  f a float value.
+     * @return a {@code Float} instance representing {@code f}.
+     * @since  1.5
+     */
+    public static Float valueOf(float f) {
+        return new Float(f);
+    }
+
+    /**
+     * Returns a new {@code float} initialized to the value
+     * represented by the specified {@code String}, as performed
+     * by the {@code valueOf} method of class {@code Float}.
+     *
+     * @param  s the string to be parsed.
+     * @return the {@code float} value represented by the string
+     *         argument.
+     * @throws NullPointerException  if the string is null
+     * @throws NumberFormatException if the string does not contain a
+     *               parsable {@code float}.
+     * @see    java.lang.Float#valueOf(String)
+     * @since 1.2
+     */
+    public static float parseFloat(String s) throws NumberFormatException {
+        return FloatingDecimal.parseFloat(s);
+    }
+
+    /**
+     * Returns {@code true} if the specified number is a
+     * Not-a-Number (NaN) value, {@code false} otherwise.
+     *
+     * @param   v   the value to be tested.
+     * @return  {@code true} if the argument is NaN;
+     *          {@code false} otherwise.
+     */
+    public static boolean isNaN(float v) {
+        return (v != v);
+    }
+
+    /**
+     * Returns {@code true} if the specified number is infinitely
+     * large in magnitude, {@code false} otherwise.
+     *
+     * @param   v   the value to be tested.
+     * @return  {@code true} if the argument is positive infinity or
+     *          negative infinity; {@code false} otherwise.
+     */
+    public static boolean isInfinite(float v) {
+        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
+    }
+
+
+    /**
+     * Returns {@code true} if the argument is a finite floating-point
+     * value; returns {@code false} otherwise (for NaN and infinity
+     * arguments).
+     *
+     * @param f the {@code float} value to be tested
+     * @return {@code true} if the argument is a finite
+     * floating-point value, {@code false} otherwise.
+     * @since 1.8
+     */
+     public static boolean isFinite(float f) {
+        return Math.abs(f) <= FloatConsts.MAX_VALUE;
+    }
+
+    /**
+     * The value of the Float.
+     *
+     * @serial
+     */
+    private final float value;
+
+    /**
+     * Constructs a newly allocated {@code Float} object that
+     * represents the primitive {@code float} argument.
+     *
+     * @param   value   the value to be represented by the {@code Float}.
+     */
+    public Float(float value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Float} object that
+     * represents the argument converted to type {@code float}.
+     *
+     * @param   value   the value to be represented by the {@code Float}.
+     */
+    public Float(double value) {
+        this.value = (float)value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Float} object that
+     * represents the floating-point value of type {@code float}
+     * represented by the string. The string is converted to a
+     * {@code float} value as if by the {@code valueOf} method.
+     *
+     * @param      s   a string to be converted to a {@code Float}.
+     * @throws  NumberFormatException  if the string does not contain a
+     *               parsable number.
+     * @see        java.lang.Float#valueOf(java.lang.String)
+     */
+    public Float(String s) throws NumberFormatException {
+        value = parseFloat(s);
+    }
+
+    /**
+     * Returns {@code true} if this {@code Float} value is a
+     * Not-a-Number (NaN), {@code false} otherwise.
+     *
+     * @return  {@code true} if the value represented by this object is
+     *          NaN; {@code false} otherwise.
+     */
+    public boolean isNaN() {
+        return isNaN(value);
+    }
+
+    /**
+     * Returns {@code true} if this {@code Float} value is
+     * infinitely large in magnitude, {@code false} otherwise.
+     *
+     * @return  {@code true} if the value represented by this object is
+     *          positive infinity or negative infinity;
+     *          {@code false} otherwise.
+     */
+    public boolean isInfinite() {
+        return isInfinite(value);
+    }
+
+    /**
+     * Returns a string representation of this {@code Float} object.
+     * The primitive {@code float} value represented by this object
+     * is converted to a {@code String} exactly as if by the method
+     * {@code toString} of one argument.
+     *
+     * @return  a {@code String} representation of this object.
+     * @see java.lang.Float#toString(float)
+     */
+    public String toString() {
+        return Float.toString(value);
+    }
+
+    /**
+     * Returns the value of this {@code Float} as a {@code byte} after
+     * a narrowing primitive conversion.
+     *
+     * @return  the {@code float} value represented by this object
+     *          converted to type {@code byte}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public byte byteValue() {
+        return (byte)value;
+    }
+
+    /**
+     * Returns the value of this {@code Float} as a {@code short}
+     * after a narrowing primitive conversion.
+     *
+     * @return  the {@code float} value represented by this object
+     *          converted to type {@code short}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     * @since JDK1.1
+     */
+    public short shortValue() {
+        return (short)value;
+    }
+
+    /**
+     * Returns the value of this {@code Float} as an {@code int} after
+     * a narrowing primitive conversion.
+     *
+     * @return  the {@code float} value represented by this object
+     *          converted to type {@code int}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public int intValue() {
+        return (int)value;
+    }
+
+    /**
+     * Returns value of this {@code Float} as a {@code long} after a
+     * narrowing primitive conversion.
+     *
+     * @return  the {@code float} value represented by this object
+     *          converted to type {@code long}
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public long longValue() {
+        return (long)value;
+    }
+
+    /**
+     * Returns the {@code float} value of this {@code Float} object.
+     *
+     * @return the {@code float} value represented by this object
+     */
+    public float floatValue() {
+        return value;
+    }
+
+    /**
+     * Returns the value of this {@code Float} as a {@code double}
+     * after a widening primitive conversion.
+     *
+     * @return the {@code float} value represented by this
+     *         object converted to type {@code double}
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public double doubleValue() {
+        return (double)value;
+    }
+
+    /**
+     * Returns a hash code for this {@code Float} object. The
+     * result is the integer bit representation, exactly as produced
+     * by the method {@link #floatToIntBits(float)}, of the primitive
+     * {@code float} value represented by this {@code Float}
+     * object.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return Float.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code float} value; compatible with
+     * {@code Float.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code float} value.
+     * @since 1.8
+     */
+    public static int hashCode(float value) {
+        return floatToIntBits(value);
+    }
+
+    /**
+
+     * Compares this object against the specified object.  The result
+     * is {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Float} object that
+     * represents a {@code float} with the same value as the
+     * {@code float} represented by this object. For this
+     * purpose, two {@code float} values are considered to be the
+     * same if and only if the method {@link #floatToIntBits(float)}
+     * returns the identical {@code int} value when applied to
+     * each.
+     *
+     * <p>Note that in most cases, for two instances of class
+     * {@code Float}, {@code f1} and {@code f2}, the value
+     * of {@code f1.equals(f2)} is {@code true} if and only if
+     *
+     * <blockquote><pre>
+     *   f1.floatValue() == f2.floatValue()
+     * </pre></blockquote>
+     *
+     * <p>also has the value {@code true}. However, there are two exceptions:
+     * <ul>
+     * <li>If {@code f1} and {@code f2} both represent
+     *     {@code Float.NaN}, then the {@code equals} method returns
+     *     {@code true}, even though {@code Float.NaN==Float.NaN}
+     *     has the value {@code false}.
+     * <li>If {@code f1} represents {@code +0.0f} while
+     *     {@code f2} represents {@code -0.0f}, or vice
+     *     versa, the {@code equal} test has the value
+     *     {@code false}, even though {@code 0.0f==-0.0f}
+     *     has the value {@code true}.
+     * </ul>
+     *
+     * This definition allows hash tables to operate properly.
+     *
+     * @param obj the object to be compared
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see java.lang.Float#floatToIntBits(float)
+     */
+    public boolean equals(Object obj) {
+        return (obj instanceof Float)
+               && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
+    }
+
+    /**
+     * Returns a representation of the specified floating-point value
+     * according to the IEEE 754 floating-point "single format" bit
+     * layout.
+     *
+     * <p>Bit 31 (the bit that is selected by the mask
+     * {@code 0x80000000}) represents the sign of the floating-point
+     * number.
+     * Bits 30-23 (the bits that are selected by the mask
+     * {@code 0x7f800000}) represent the exponent.
+     * Bits 22-0 (the bits that are selected by the mask
+     * {@code 0x007fffff}) represent the significand (sometimes called
+     * the mantissa) of the floating-point number.
+     *
+     * <p>If the argument is positive infinity, the result is
+     * {@code 0x7f800000}.
+     *
+     * <p>If the argument is negative infinity, the result is
+     * {@code 0xff800000}.
+     *
+     * <p>If the argument is NaN, the result is {@code 0x7fc00000}.
+     *
+     * <p>In all cases, the result is an integer that, when given to the
+     * {@link #intBitsToFloat(int)} method, will produce a floating-point
+     * value the same as the argument to {@code floatToIntBits}
+     * (except all NaN values are collapsed to a single
+     * "canonical" NaN value).
+     *
+     * @param   value   a floating-point number.
+     * @return the bits that represent the floating-point number.
+     */
+    public static int floatToIntBits(float value) {
+        int result = floatToRawIntBits(value);
+        // Check for NaN based on values of bit fields, maximum
+        // exponent and nonzero significand.
+        if ( ((result & FloatConsts.EXP_BIT_MASK) ==
+              FloatConsts.EXP_BIT_MASK) &&
+             (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
+            result = 0x7fc00000;
+        return result;
+    }
+
+    /**
+     * Returns a representation of the specified floating-point value
+     * according to the IEEE 754 floating-point "single format" bit
+     * layout, preserving Not-a-Number (NaN) values.
+     *
+     * <p>Bit 31 (the bit that is selected by the mask
+     * {@code 0x80000000}) represents the sign of the floating-point
+     * number.
+     * Bits 30-23 (the bits that are selected by the mask
+     * {@code 0x7f800000}) represent the exponent.
+     * Bits 22-0 (the bits that are selected by the mask
+     * {@code 0x007fffff}) represent the significand (sometimes called
+     * the mantissa) of the floating-point number.
+     *
+     * <p>If the argument is positive infinity, the result is
+     * {@code 0x7f800000}.
+     *
+     * <p>If the argument is negative infinity, the result is
+     * {@code 0xff800000}.
+     *
+     * <p>If the argument is NaN, the result is the integer representing
+     * the actual NaN value.  Unlike the {@code floatToIntBits}
+     * method, {@code floatToRawIntBits} does not collapse all the
+     * bit patterns encoding a NaN to a single "canonical"
+     * NaN value.
+     *
+     * <p>In all cases, the result is an integer that, when given to the
+     * {@link #intBitsToFloat(int)} method, will produce a
+     * floating-point value the same as the argument to
+     * {@code floatToRawIntBits}.
+     *
+     * @param   value   a floating-point number.
+     * @return the bits that represent the floating-point number.
+     * @since 1.3
+     */
+    public static native int floatToRawIntBits(float value);
+
+    /**
+     * Returns the {@code float} value corresponding to a given
+     * bit representation.
+     * The argument is considered to be a representation of a
+     * floating-point value according to the IEEE 754 floating-point
+     * "single format" bit layout.
+     *
+     * <p>If the argument is {@code 0x7f800000}, the result is positive
+     * infinity.
+     *
+     * <p>If the argument is {@code 0xff800000}, the result is negative
+     * infinity.
+     *
+     * <p>If the argument is any value in the range
+     * {@code 0x7f800001} through {@code 0x7fffffff} or in
+     * the range {@code 0xff800001} through
+     * {@code 0xffffffff}, the result is a NaN.  No IEEE 754
+     * floating-point operation provided by Java can distinguish
+     * between two NaN values of the same type with different bit
+     * patterns.  Distinct values of NaN are only distinguishable by
+     * use of the {@code Float.floatToRawIntBits} method.
+     *
+     * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
+     * values that can be computed from the argument:
+     *
+     * <blockquote><pre>{@code
+     * int s = ((bits >> 31) == 0) ? 1 : -1;
+     * int e = ((bits >> 23) & 0xff);
+     * int m = (e == 0) ?
+     *                 (bits & 0x7fffff) << 1 :
+     *                 (bits & 0x7fffff) | 0x800000;
+     * }</pre></blockquote>
+     *
+     * Then the floating-point result equals the value of the mathematical
+     * expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-150</sup>.
+     *
+     * <p>Note that this method may not be able to return a
+     * {@code float} NaN with exactly same bit pattern as the
+     * {@code int} argument.  IEEE 754 distinguishes between two
+     * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>.  The
+     * differences between the two kinds of NaN are generally not
+     * visible in Java.  Arithmetic operations on signaling NaNs turn
+     * them into quiet NaNs with a different, but often similar, bit
+     * pattern.  However, on some processors merely copying a
+     * signaling NaN also performs that conversion.  In particular,
+     * copying a signaling NaN to return it to the calling method may
+     * perform this conversion.  So {@code intBitsToFloat} may
+     * not be able to return a {@code float} with a signaling NaN
+     * bit pattern.  Consequently, for some {@code int} values,
+     * {@code floatToRawIntBits(intBitsToFloat(start))} may
+     * <i>not</i> equal {@code start}.  Moreover, which
+     * particular bit patterns represent signaling NaNs is platform
+     * dependent; although all NaN bit patterns, quiet or signaling,
+     * must be in the NaN range identified above.
+     *
+     * @param   bits   an integer.
+     * @return  the {@code float} floating-point value with the same bit
+     *          pattern.
+     */
+    public static native float intBitsToFloat(int bits);
+
+    /**
+     * Compares two {@code Float} objects numerically.  There are
+     * two ways in which comparisons performed by this method differ
+     * from those performed by the Java language numerical comparison
+     * operators ({@code <, <=, ==, >=, >}) when
+     * applied to primitive {@code float} values:
+     *
+     * <ul><li>
+     *          {@code Float.NaN} is considered by this method to
+     *          be equal to itself and greater than all other
+     *          {@code float} values
+     *          (including {@code Float.POSITIVE_INFINITY}).
+     * <li>
+     *          {@code 0.0f} is considered by this method to be greater
+     *          than {@code -0.0f}.
+     * </ul>
+     *
+     * This ensures that the <i>natural ordering</i> of {@code Float}
+     * objects imposed by this method is <i>consistent with equals</i>.
+     *
+     * @param   anotherFloat   the {@code Float} to be compared.
+     * @return  the value {@code 0} if {@code anotherFloat} is
+     *          numerically equal to this {@code Float}; a value
+     *          less than {@code 0} if this {@code Float}
+     *          is numerically less than {@code anotherFloat};
+     *          and a value greater than {@code 0} if this
+     *          {@code Float} is numerically greater than
+     *          {@code anotherFloat}.
+     *
+     * @since   1.2
+     * @see Comparable#compareTo(Object)
+     */
+    public int compareTo(Float anotherFloat) {
+        return Float.compare(value, anotherFloat.value);
+    }
+
+    /**
+     * Compares the two specified {@code float} values. The sign
+     * of the integer value returned is the same as that of the
+     * integer that would be returned by the call:
+     * <pre>
+     *    new Float(f1).compareTo(new Float(f2))
+     * </pre>
+     *
+     * @param   f1        the first {@code float} to compare.
+     * @param   f2        the second {@code float} to compare.
+     * @return  the value {@code 0} if {@code f1} is
+     *          numerically equal to {@code f2}; a value less than
+     *          {@code 0} if {@code f1} is numerically less than
+     *          {@code f2}; and a value greater than {@code 0}
+     *          if {@code f1} is numerically greater than
+     *          {@code f2}.
+     * @since 1.4
+     */
+    public static int compare(float f1, float f2) {
+        if (f1 < f2)
+            return -1;           // Neither val is NaN, thisVal is smaller
+        if (f1 > f2)
+            return 1;            // Neither val is NaN, thisVal is larger
+
+        // Cannot use floatToRawIntBits because of possibility of NaNs.
+        int thisBits    = Float.floatToIntBits(f1);
+        int anotherBits = Float.floatToIntBits(f2);
+
+        return (thisBits == anotherBits ?  0 : // Values are equal
+                (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
+                 1));                          // (0.0, -0.0) or (NaN, !NaN)
+    }
+
+    /**
+     * Adds two {@code float} values together as per the + operator.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the sum of {@code a} and {@code b}
+     * @jls 4.2.4 Floating-Point Operations
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static float sum(float a, float b) {
+        return a + b;
+    }
+
+    /**
+     * Returns the greater of two {@code float} values
+     * as if by calling {@link Math#max(float, float) Math.max}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the greater of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static float max(float a, float b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code float} values
+     * as if by calling {@link Math#min(float, float) Math.min}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the smaller of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static float min(float a, float b) {
+        return Math.min(a, b);
+    }
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -2671257302660747028L;
+}
diff --git a/java/lang/FunctionalInterface.java b/java/lang/FunctionalInterface.java
new file mode 100644
index 0000000..a93ed51
--- /dev/null
+++ b/java/lang/FunctionalInterface.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import java.lang.annotation.*;
+
+/**
+ * An informative annotation type used to indicate that an interface
+ * type declaration is intended to be a <i>functional interface</i> as
+ * defined by the Java Language Specification.
+ *
+ * Conceptually, a functional interface has exactly one abstract
+ * method.  Since {@linkplain java.lang.reflect.Method#isDefault()
+ * default methods} have an implementation, they are not abstract.  If
+ * an interface declares an abstract method overriding one of the
+ * public methods of {@code java.lang.Object}, that also does
+ * <em>not</em> count toward the interface's abstract method count
+ * since any implementation of the interface will have an
+ * implementation from {@code java.lang.Object} or elsewhere.
+ *
+ * <p>Note that instances of functional interfaces can be created with
+ * lambda expressions, method references, or constructor references.
+ *
+ * <p>If a type is annotated with this annotation type, compilers are
+ * required to generate an error message unless:
+ *
+ * <ul>
+ * <li> The type is an interface type and not an annotation type, enum, or class.
+ * <li> The annotated type satisfies the requirements of a functional interface.
+ * </ul>
+ *
+ * <p>However, the compiler will treat any interface meeting the
+ * definition of a functional interface as a functional interface
+ * regardless of whether or not a {@code FunctionalInterface}
+ * annotation is present on the interface declaration.
+ *
+ * @jls 4.3.2. The Class Object
+ * @jls 9.8 Functional Interfaces
+ * @jls 9.4.3 Interface Method Body
+ * @since 1.8
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface FunctionalInterface {}
diff --git a/java/lang/IllegalAccessError.java b/java/lang/IllegalAccessError.java
new file mode 100644
index 0000000..ce045cd
--- /dev/null
+++ b/java/lang/IllegalAccessError.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown if an application attempts to access or modify a field, or
+ * to call a method that it does not have access to.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public class IllegalAccessError extends IncompatibleClassChangeError {
+    private static final long serialVersionUID = -8988904074992417891L;
+
+    /**
+     * Constructs an <code>IllegalAccessError</code> with no detail message.
+     */
+    public IllegalAccessError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IllegalAccessError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IllegalAccessError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/IllegalAccessException.java b/java/lang/IllegalAccessException.java
new file mode 100644
index 0000000..c7b1df8
--- /dev/null
+++ b/java/lang/IllegalAccessException.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * An IllegalAccessException is thrown when an application tries
+ * to reflectively create an instance (other than an array),
+ * set or get a field, or invoke a method, but the currently
+ * executing method does not have access to the definition of
+ * the specified class, field, method or constructor.
+ *
+ * @author  unascribed
+ * @see     Class#newInstance()
+ * @see     java.lang.reflect.Field#set(Object, Object)
+ * @see     java.lang.reflect.Field#setBoolean(Object, boolean)
+ * @see     java.lang.reflect.Field#setByte(Object, byte)
+ * @see     java.lang.reflect.Field#setShort(Object, short)
+ * @see     java.lang.reflect.Field#setChar(Object, char)
+ * @see     java.lang.reflect.Field#setInt(Object, int)
+ * @see     java.lang.reflect.Field#setLong(Object, long)
+ * @see     java.lang.reflect.Field#setFloat(Object, float)
+ * @see     java.lang.reflect.Field#setDouble(Object, double)
+ * @see     java.lang.reflect.Field#get(Object)
+ * @see     java.lang.reflect.Field#getBoolean(Object)
+ * @see     java.lang.reflect.Field#getByte(Object)
+ * @see     java.lang.reflect.Field#getShort(Object)
+ * @see     java.lang.reflect.Field#getChar(Object)
+ * @see     java.lang.reflect.Field#getInt(Object)
+ * @see     java.lang.reflect.Field#getLong(Object)
+ * @see     java.lang.reflect.Field#getFloat(Object)
+ * @see     java.lang.reflect.Field#getDouble(Object)
+ * @see     java.lang.reflect.Method#invoke(Object, Object[])
+ * @see     java.lang.reflect.Constructor#newInstance(Object[])
+ * @since   JDK1.0
+ */
+public class IllegalAccessException extends ReflectiveOperationException {
+    private static final long serialVersionUID = 6616958222490762034L;
+
+    /**
+     * Constructs an <code>IllegalAccessException</code> without a
+     * detail message.
+     */
+    public IllegalAccessException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IllegalAccessException</code> with a detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IllegalAccessException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/IllegalArgumentException.java b/java/lang/IllegalArgumentException.java
new file mode 100644
index 0000000..c29a9d5
--- /dev/null
+++ b/java/lang/IllegalArgumentException.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1994, 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;
+
+/**
+ * Thrown to indicate that a method has been passed an illegal or
+ * inappropriate argument.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class IllegalArgumentException extends RuntimeException {
+    /**
+     * Constructs an <code>IllegalArgumentException</code> with no
+     * detail message.
+     */
+    public IllegalArgumentException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IllegalArgumentException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IllegalArgumentException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.
+     *
+     * <p>Note that the detail message associated with <code>cause</code> is
+     * <i>not</i> automatically incorporated in this exception's detail
+     * message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link Throwable#getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value
+     *         is permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since 1.5
+     */
+    public IllegalArgumentException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.5
+     */
+    public IllegalArgumentException(Throwable cause) {
+        super(cause);
+    }
+
+    private static final long serialVersionUID = -5365630128856068164L;
+}
diff --git a/java/lang/IllegalMonitorStateException.java b/java/lang/IllegalMonitorStateException.java
new file mode 100644
index 0000000..3985066
--- /dev/null
+++ b/java/lang/IllegalMonitorStateException.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that a thread has attempted to wait on an
+ * object's monitor or to notify other threads waiting on an object's
+ * monitor without owning the specified monitor.
+ *
+ * @author  unascribed
+ * @see     java.lang.Object#notify()
+ * @see     java.lang.Object#notifyAll()
+ * @see     java.lang.Object#wait()
+ * @see     java.lang.Object#wait(long)
+ * @see     java.lang.Object#wait(long, int)
+ * @since   JDK1.0
+ */
+public
+class IllegalMonitorStateException extends RuntimeException {
+    private static final long serialVersionUID = 3713306369498869069L;
+
+    /**
+     * Constructs an <code>IllegalMonitorStateException</code> with no
+     * detail message.
+     */
+    public IllegalMonitorStateException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IllegalMonitorStateException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IllegalMonitorStateException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/IllegalStateException.java b/java/lang/IllegalStateException.java
new file mode 100644
index 0000000..9c0c06a
--- /dev/null
+++ b/java/lang/IllegalStateException.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1996, 2003, 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;
+
+/**
+ * Signals that a method has been invoked at an illegal or
+ * inappropriate time.  In other words, the Java environment or
+ * Java application is not in an appropriate state for the requested
+ * operation.
+ *
+ * @author  Jonni Kanerva
+ * @since   JDK1.1
+ */
+public
+class IllegalStateException extends RuntimeException {
+    /**
+     * Constructs an IllegalStateException with no detail message.
+     * A detail message is a String that describes this particular exception.
+     */
+    public IllegalStateException() {
+        super();
+    }
+
+    /**
+     * Constructs an IllegalStateException with the specified detail
+     * message.  A detail message is a String that describes this particular
+     * exception.
+     *
+     * @param s the String that contains a detailed message
+     */
+    public IllegalStateException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.
+     *
+     * <p>Note that the detail message associated with <code>cause</code> is
+     * <i>not</i> automatically incorporated in this exception's detail
+     * message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link Throwable#getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value
+     *         is permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since 1.5
+     */
+    public IllegalStateException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.5
+     */
+    public IllegalStateException(Throwable cause) {
+        super(cause);
+    }
+
+    static final long serialVersionUID = -1848914673093119416L;
+}
diff --git a/java/lang/IllegalThreadStateException.java b/java/lang/IllegalThreadStateException.java
new file mode 100644
index 0000000..c59ab59
--- /dev/null
+++ b/java/lang/IllegalThreadStateException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown to indicate that a thread is not in an appropriate state
+ * for the requested operation. See, for example, the
+ * <code>suspend</code> and <code>resume</code> methods in class
+ * <code>Thread</code>.
+ *
+ * @author  unascribed
+ * @see     java.lang.Thread#resume()
+ * @see     java.lang.Thread#suspend()
+ * @since   JDK1.0
+ */
+public class IllegalThreadStateException extends IllegalArgumentException {
+    private static final long serialVersionUID = -7626246362397460174L;
+
+    /**
+     * Constructs an <code>IllegalThreadStateException</code> with no
+     * detail message.
+     */
+    public IllegalThreadStateException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IllegalThreadStateException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IllegalThreadStateException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/IncompatibleClassChangeError.java b/java/lang/IncompatibleClassChangeError.java
new file mode 100644
index 0000000..edffaee
--- /dev/null
+++ b/java/lang/IncompatibleClassChangeError.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when an incompatible class change has occurred to some class
+ * definition. The definition of some class, on which the currently
+ * executing method depends, has since changed.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class IncompatibleClassChangeError extends LinkageError {
+    private static final long serialVersionUID = -4914975503642802119L;
+
+    /**
+     * Constructs an <code>IncompatibleClassChangeError</code> with no
+     * detail message.
+     */
+    public IncompatibleClassChangeError () {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IncompatibleClassChangeError</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IncompatibleClassChangeError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/IndexOutOfBoundsException.java b/java/lang/IndexOutOfBoundsException.java
new file mode 100644
index 0000000..4dc7948
--- /dev/null
+++ b/java/lang/IndexOutOfBoundsException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that an index of some sort (such as to an array, to a
+ * string, or to a vector) is out of range.
+ * <p>
+ * Applications can subclass this class to indicate similar exceptions.
+ *
+ * @author  Frank Yellin
+ * @since   JDK1.0
+ */
+public
+class IndexOutOfBoundsException extends RuntimeException {
+    private static final long serialVersionUID = 234122996006267687L;
+
+    /**
+     * Constructs an <code>IndexOutOfBoundsException</code> with no
+     * detail message.
+     */
+    public IndexOutOfBoundsException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>IndexOutOfBoundsException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public IndexOutOfBoundsException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/InheritableThreadLocal.java b/java/lang/InheritableThreadLocal.java
new file mode 100644
index 0000000..935c5f1
--- /dev/null
+++ b/java/lang/InheritableThreadLocal.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1998, 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;
+import java.lang.ref.*;
+
+/**
+ * This class extends <tt>ThreadLocal</tt> to provide inheritance of values
+ * from parent thread to child thread: when a child thread is created, the
+ * child receives initial values for all inheritable thread-local variables
+ * for which the parent has values.  Normally the child's values will be
+ * identical to the parent's; however, the child's value can be made an
+ * arbitrary function of the parent's by overriding the <tt>childValue</tt>
+ * method in this class.
+ *
+ * <p>Inheritable thread-local variables are used in preference to
+ * ordinary thread-local variables when the per-thread-attribute being
+ * maintained in the variable (e.g., User ID, Transaction ID) must be
+ * automatically transmitted to any child threads that are created.
+ *
+ * @author  Josh Bloch and Doug Lea
+ * @see     ThreadLocal
+ * @since   1.2
+ */
+
+public class InheritableThreadLocal<T> extends ThreadLocal<T> {
+    /**
+     * Computes the child's initial value for this inheritable thread-local
+     * variable as a function of the parent's value at the time the child
+     * thread is created.  This method is called from within the parent
+     * thread before the child is started.
+     * <p>
+     * This method merely returns its input argument, and should be overridden
+     * if a different behavior is desired.
+     *
+     * @param parentValue the parent thread's value
+     * @return the child thread's initial value
+     */
+    protected T childValue(T parentValue) {
+        return parentValue;
+    }
+
+    /**
+     * Get the map associated with a ThreadLocal.
+     *
+     * @param t the current thread
+     */
+    ThreadLocalMap getMap(Thread t) {
+       return t.inheritableThreadLocals;
+    }
+
+    /**
+     * Create the map associated with a ThreadLocal.
+     *
+     * @param t the current thread
+     * @param firstValue value for the initial entry of the table.
+     */
+    void createMap(Thread t, T firstValue) {
+        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
+    }
+}
diff --git a/java/lang/InstantiationError.java b/java/lang/InstantiationError.java
new file mode 100644
index 0000000..89c10b3
--- /dev/null
+++ b/java/lang/InstantiationError.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an application tries to use the Java <code>new</code>
+ * construct to instantiate an abstract class or an interface.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+
+
+public
+class InstantiationError extends IncompatibleClassChangeError {
+    private static final long serialVersionUID = -4885810657349421204L;
+
+    /**
+     * Constructs an <code>InstantiationError</code> with no detail  message.
+     */
+    public InstantiationError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>InstantiationError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public InstantiationError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/InstantiationException.java b/java/lang/InstantiationException.java
new file mode 100644
index 0000000..afeeb17
--- /dev/null
+++ b/java/lang/InstantiationException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an application tries to create an instance of a class
+ * using the {@code newInstance} method in class
+ * {@code Class}, but the specified class object cannot be
+ * instantiated.  The instantiation can fail for a variety of
+ * reasons including but not limited to:
+ *
+ * <ul>
+ * <li> the class object represents an abstract class, an interface,
+ *      an array class, a primitive type, or {@code void}
+ * <li> the class has no nullary constructor
+ *</ul>
+ *
+ * @author  unascribed
+ * @see     java.lang.Class#newInstance()
+ * @since   JDK1.0
+ */
+public
+class InstantiationException extends ReflectiveOperationException {
+    private static final long serialVersionUID = -8441929162975509110L;
+
+    /**
+     * Constructs an {@code InstantiationException} with no detail message.
+     */
+    public InstantiationException() {
+        super();
+    }
+
+    /**
+     * Constructs an {@code InstantiationException} with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public InstantiationException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/Integer.annotated.java b/java/lang/Integer.annotated.java
new file mode 100644
index 0000000..d3f6753
--- /dev/null
+++ b/java/lang/Integer.annotated.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
+
+public Integer(int value) { throw new RuntimeException("Stub!"); }
+
+public Integer(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toOctalString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toBinaryString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(int i) { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(int value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, int val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Integer val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Integer anotherInteger) { throw new RuntimeException("Stub!"); }
+
+public static int compare(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(int x) { throw new RuntimeException("Stub!"); }
+
+public static int divideUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int remainderUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int highestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int lowestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(int i) { throw new RuntimeException("Stub!"); }
+
+public static int rotateLeft(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int rotateRight(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int reverse(int i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(int i) { throw new RuntimeException("Stub!"); }
+
+public static int reverseBytes(int i) { throw new RuntimeException("Stub!"); }
+
+public static int sum(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+
+public static final int MIN_VALUE = -2147483648; // 0x80000000
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Integer> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Integer.java b/java/lang/Integer.java
new file mode 100644
index 0000000..93ae24c
--- /dev/null
+++ b/java/lang/Integer.java
@@ -0,0 +1,1630 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.lang.annotation.Native;
+
+/**
+ * The {@code Integer} class wraps a value of the primitive type
+ * {@code int} in an object. An object of type {@code Integer}
+ * contains a single field whose type is {@code int}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * an {@code int} to a {@code String} and a {@code String} to an
+ * {@code int}, as well as other constants and methods useful when
+ * dealing with an {@code int}.
+ *
+ * <p>Implementation note: The implementations of the "bit twiddling"
+ * methods (such as {@link #highestOneBit(int) highestOneBit} and
+ * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
+ * based on material from Henry S. Warren, Jr.'s <i>Hacker's
+ * Delight</i>, (Addison Wesley, 2002).
+ *
+ * @author  Lee Boynton
+ * @author  Arthur van Hoff
+ * @author  Josh Bloch
+ * @author  Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Integer extends Number implements Comparable<Integer> {
+    /**
+     * A constant holding the minimum value an {@code int} can
+     * have, -2<sup>31</sup>.
+     */
+    @Native public static final int   MIN_VALUE = 0x80000000;
+
+    /**
+     * A constant holding the maximum value an {@code int} can
+     * have, 2<sup>31</sup>-1.
+     */
+    @Native public static final int   MAX_VALUE = 0x7fffffff;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code int}.
+     *
+     * @since   JDK1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
+
+    /**
+     * All possible chars for representing a number as a String
+     */
+    final static char[] digits = {
+        '0' , '1' , '2' , '3' , '4' , '5' ,
+        '6' , '7' , '8' , '9' , 'a' , 'b' ,
+        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
+        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
+        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
+        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
+    };
+
+    /**
+     * Returns a string representation of the first argument in the
+     * radix specified by the second argument.
+     *
+     * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+     * or larger than {@code Character.MAX_RADIX}, then the radix
+     * {@code 10} is used instead.
+     *
+     * <p>If the first argument is negative, the first element of the
+     * result is the ASCII minus character {@code '-'}
+     * ({@code '\u005Cu002D'}). If the first argument is not
+     * negative, no sign character appears in the result.
+     *
+     * <p>The remaining characters of the result represent the magnitude
+     * of the first argument. If the magnitude is zero, it is
+     * represented by a single zero character {@code '0'}
+     * ({@code '\u005Cu0030'}); otherwise, the first character of
+     * the representation of the magnitude will not be the zero
+     * character.  The following ASCII characters are used as digits:
+     *
+     * <blockquote>
+     *   {@code 0123456789abcdefghijklmnopqrstuvwxyz}
+     * </blockquote>
+     *
+     * These are {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+     * {@code '\u005Cu007A'}. If {@code radix} is
+     * <var>N</var>, then the first <var>N</var> of these characters
+     * are used as radix-<var>N</var> digits in the order shown. Thus,
+     * the digits for hexadecimal (radix 16) are
+     * {@code 0123456789abcdef}. If uppercase letters are
+     * desired, the {@link java.lang.String#toUpperCase()} method may
+     * be called on the result:
+     *
+     * <blockquote>
+     *  {@code Integer.toString(n, 16).toUpperCase()}
+     * </blockquote>
+     *
+     * @param   i       an integer to be converted to a string.
+     * @param   radix   the radix to use in the string representation.
+     * @return  a string representation of the argument in the specified radix.
+     * @see     java.lang.Character#MAX_RADIX
+     * @see     java.lang.Character#MIN_RADIX
+     */
+    public static String toString(int i, int radix) {
+        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+            radix = 10;
+
+        /* Use the faster version */
+        if (radix == 10) {
+            return toString(i);
+        }
+
+        char buf[] = new char[33];
+        boolean negative = (i < 0);
+        int charPos = 32;
+
+        if (!negative) {
+            i = -i;
+        }
+
+        while (i <= -radix) {
+            buf[charPos--] = digits[-(i % radix)];
+            i = i / radix;
+        }
+        buf[charPos] = digits[-i];
+
+        if (negative) {
+            buf[--charPos] = '-';
+        }
+
+        return new String(buf, charPos, (33 - charPos));
+    }
+
+    /**
+     * Returns a string representation of the first argument as an
+     * unsigned integer value in the radix specified by the second
+     * argument.
+     *
+     * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+     * or larger than {@code Character.MAX_RADIX}, then the radix
+     * {@code 10} is used instead.
+     *
+     * <p>Note that since the first argument is treated as an unsigned
+     * value, no leading sign character is printed.
+     *
+     * <p>If the magnitude is zero, it is represented by a single zero
+     * character {@code '0'} ({@code '\u005Cu0030'}); otherwise,
+     * the first character of the representation of the magnitude will
+     * not be the zero character.
+     *
+     * <p>The behavior of radixes and the characters used as digits
+     * are the same as {@link #toString(int, int) toString}.
+     *
+     * @param   i       an integer to be converted to an unsigned string.
+     * @param   radix   the radix to use in the string representation.
+     * @return  an unsigned string representation of the argument in the specified radix.
+     * @see     #toString(int, int)
+     * @since 1.8
+     */
+    public static String toUnsignedString(int i, int radix) {
+        return Long.toUnsignedString(toUnsignedLong(i), radix);
+    }
+
+    /**
+     * Returns a string representation of the integer argument as an
+     * unsigned integer in base&nbsp;16.
+     *
+     * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+     * if the argument is negative; otherwise, it is equal to the
+     * argument.  This value is converted to a string of ASCII digits
+     * in hexadecimal (base&nbsp;16) with no extra leading
+     * {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Integer#parseUnsignedInt(String, int)
+     * Integer.parseUnsignedInt(s, 16)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * following characters are used as hexadecimal digits:
+     *
+     * <blockquote>
+     *  {@code 0123456789abcdef}
+     * </blockquote>
+     *
+     * These are the characters {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+     * {@code '\u005Cu0066'}. If uppercase letters are
+     * desired, the {@link java.lang.String#toUpperCase()} method may
+     * be called on the result:
+     *
+     * <blockquote>
+     *  {@code Integer.toHexString(n).toUpperCase()}
+     * </blockquote>
+     *
+     * @param   i   an integer to be converted to a string.
+     * @return  the string representation of the unsigned integer value
+     *          represented by the argument in hexadecimal (base&nbsp;16).
+     * @see #parseUnsignedInt(String, int)
+     * @see #toUnsignedString(int, int)
+     * @since   JDK1.0.2
+     */
+    public static String toHexString(int i) {
+        return toUnsignedString0(i, 4);
+    }
+
+    /**
+     * Returns a string representation of the integer argument as an
+     * unsigned integer in base&nbsp;8.
+     *
+     * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+     * if the argument is negative; otherwise, it is equal to the
+     * argument.  This value is converted to a string of ASCII digits
+     * in octal (base&nbsp;8) with no extra leading {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Integer#parseUnsignedInt(String, int)
+     * Integer.parseUnsignedInt(s, 8)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * following characters are used as octal digits:
+     *
+     * <blockquote>
+     * {@code 01234567}
+     * </blockquote>
+     *
+     * These are the characters {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0037'}.
+     *
+     * @param   i   an integer to be converted to a string.
+     * @return  the string representation of the unsigned integer value
+     *          represented by the argument in octal (base&nbsp;8).
+     * @see #parseUnsignedInt(String, int)
+     * @see #toUnsignedString(int, int)
+     * @since   JDK1.0.2
+     */
+    public static String toOctalString(int i) {
+        return toUnsignedString0(i, 3);
+    }
+
+    /**
+     * Returns a string representation of the integer argument as an
+     * unsigned integer in base&nbsp;2.
+     *
+     * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+     * if the argument is negative; otherwise it is equal to the
+     * argument.  This value is converted to a string of ASCII digits
+     * in binary (base&nbsp;2) with no extra leading {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Integer#parseUnsignedInt(String, int)
+     * Integer.parseUnsignedInt(s, 2)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code
+     * '1'} ({@code '\u005Cu0031'}) are used as binary digits.
+     *
+     * @param   i   an integer to be converted to a string.
+     * @return  the string representation of the unsigned integer value
+     *          represented by the argument in binary (base&nbsp;2).
+     * @see #parseUnsignedInt(String, int)
+     * @see #toUnsignedString(int, int)
+     * @since   JDK1.0.2
+     */
+    public static String toBinaryString(int i) {
+        return toUnsignedString0(i, 1);
+    }
+
+    /**
+     * Convert the integer to an unsigned number.
+     */
+    private static String toUnsignedString0(int val, int shift) {
+        // assert shift > 0 && shift <=5 : "Illegal shift value";
+        int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
+        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+        char[] buf = new char[chars];
+
+        formatUnsignedInt(val, shift, buf, 0, chars);
+
+        // Android-changed: Use regular constructor instead of one which takes over "buf".
+        // return new String(buf, true);
+        return new String(buf);
+    }
+
+    /**
+     * Format a long (treated as unsigned) into a character buffer.
+     * @param val the unsigned int to format
+     * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+     * @param buf the character buffer to write to
+     * @param offset the offset in the destination buffer to start at
+     * @param len the number of characters to write
+     * @return the lowest character  location used
+     */
+     static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+        int charPos = len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            buf[offset + --charPos] = Integer.digits[val & mask];
+            val >>>= shift;
+        } while (val != 0 && charPos > 0);
+
+        return charPos;
+    }
+
+    // BEGIN Android-changed: Cache the toString() result for small values.
+    private static final String[] SMALL_NEG_VALUES  = new String[100];
+    private static final String[] SMALL_NONNEG_VALUES = new String[100];
+    // END Android-changed: Cache the toString() result for small values.
+
+    final static char [] DigitTens = {
+        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
+        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
+        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
+        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
+        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
+        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
+        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
+        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
+        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
+        } ;
+
+    final static char [] DigitOnes = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        } ;
+
+        // I use the "invariant division by multiplication" trick to
+        // accelerate Integer.toString.  In particular we want to
+        // avoid division by 10.
+        //
+        // The "trick" has roughly the same performance characteristics
+        // as the "classic" Integer.toString code on a non-JIT VM.
+        // The trick avoids .rem and .div calls but has a longer code
+        // path and is thus dominated by dispatch overhead.  In the
+        // JIT case the dispatch overhead doesn't exist and the
+        // "trick" is considerably faster than the classic code.
+        //
+        // TODO-FIXME: convert (x * 52429) into the equiv shift-add
+        // sequence.
+        //
+        // RE:  Division by Invariant Integers using Multiplication
+        //      T Gralund, P Montgomery
+        //      ACM PLDI 1994
+        //
+
+    /**
+     * Returns a {@code String} object representing the
+     * specified integer. The argument is converted to signed decimal
+     * representation and returned as a string, exactly as if the
+     * argument and radix 10 were given as arguments to the {@link
+     * #toString(int, int)} method.
+     *
+     * @param   i   an integer to be converted.
+     * @return  a string representation of the argument in base&nbsp;10.
+     */
+    public static String toString(int i) {
+        if (i == Integer.MIN_VALUE)
+            return "-2147483648";
+
+        // BEGIN Android-changed: Cache the String for small values.
+        // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+        boolean negative = i < 0;
+        boolean small = negative ? i > -100 : i < 100;
+        if (small) {
+            final String[] smallValues = negative ? SMALL_NEG_VALUES : SMALL_NONNEG_VALUES;
+
+            if (negative) {
+                i = -i;
+                if (smallValues[i] == null) {
+                    smallValues[i] =
+                        i < 10 ? new String(new char[]{'-', DigitOnes[i]})
+                               : new String(new char[]{'-', DigitTens[i], DigitOnes[i]});
+                }
+            } else {
+                if (smallValues[i] == null) {
+                    smallValues[i] =
+                        i < 10 ? new String(new char[]{DigitOnes[i]})
+                               : new String(new char[]{DigitTens[i], DigitOnes[i]});
+                }
+            }
+            return smallValues[i];
+        }
+        int size = negative ? stringSize(-i) + 1 : stringSize(i);
+        // END Android-changed: Cache the String for small values.
+        char[] buf = new char[size];
+        getChars(i, size, buf);
+        // Android-changed: Use regular constructor instead of one which takes over "buf".
+        // return new String(buf, true);
+        return new String(buf);
+    }
+
+    /**
+     * Returns a string representation of the argument as an unsigned
+     * decimal value.
+     *
+     * The argument is converted to unsigned decimal representation
+     * and returned as a string exactly as if the argument and radix
+     * 10 were given as arguments to the {@link #toUnsignedString(int,
+     * int)} method.
+     *
+     * @param   i  an integer to be converted to an unsigned string.
+     * @return  an unsigned string representation of the argument.
+     * @see     #toUnsignedString(int, int)
+     * @since 1.8
+     */
+    public static String toUnsignedString(int i) {
+        return Long.toString(toUnsignedLong(i));
+    }
+
+    /**
+     * Places characters representing the integer i into the
+     * character array buf. The characters are placed into
+     * the buffer backwards starting with the least significant
+     * digit at the specified index (exclusive), and working
+     * backwards from there.
+     *
+     * Will fail if i == Integer.MIN_VALUE
+     */
+    static void getChars(int i, int index, char[] buf) {
+        int q, r;
+        int charPos = index;
+        char sign = 0;
+
+        if (i < 0) {
+            sign = '-';
+            i = -i;
+        }
+
+        // Generate two digits per iteration
+        while (i >= 65536) {
+            q = i / 100;
+        // really: r = i - (q * 100);
+            r = i - ((q << 6) + (q << 5) + (q << 2));
+            i = q;
+            buf [--charPos] = DigitOnes[r];
+            buf [--charPos] = DigitTens[r];
+        }
+
+        // Fall thru to fast mode for smaller numbers
+        // assert(i <= 65536, i);
+        for (;;) {
+            q = (i * 52429) >>> (16+3);
+            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
+            buf [--charPos] = digits [r];
+            i = q;
+            if (i == 0) break;
+        }
+        if (sign != 0) {
+            buf [--charPos] = sign;
+        }
+    }
+
+    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
+                                      99999999, 999999999, Integer.MAX_VALUE };
+
+    // Requires positive x
+    static int stringSize(int x) {
+        for (int i=0; ; i++)
+            if (x <= sizeTable[i])
+                return i+1;
+    }
+
+    /**
+     * Parses the string argument as a signed integer in the radix
+     * specified by the second argument. The characters in the string
+     * must all be digits of the specified radix (as determined by
+     * whether {@link java.lang.Character#digit(char, int)} returns a
+     * nonnegative value), except that the first character may be an
+     * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
+     * indicate a negative value or an ASCII plus sign {@code '+'}
+     * ({@code '\u005Cu002B'}) to indicate a positive value. The
+     * resulting integer value is returned.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     * <li>The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li>The radix is either smaller than
+     * {@link java.lang.Character#MIN_RADIX} or
+     * larger than {@link java.lang.Character#MAX_RADIX}.
+     *
+     * <li>Any character of the string is not a digit of the specified
+     * radix, except that the first character may be a minus sign
+     * {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+     * string is longer than length 1.
+     *
+     * <li>The value represented by the string is not a value of type
+     * {@code int}.
+     * </ul>
+     *
+     * <p>Examples:
+     * <blockquote><pre>
+     * parseInt("0", 10) returns 0
+     * parseInt("473", 10) returns 473
+     * parseInt("+42", 10) returns 42
+     * parseInt("-0", 10) returns 0
+     * parseInt("-FF", 16) returns -255
+     * parseInt("1100110", 2) returns 102
+     * parseInt("2147483647", 10) returns 2147483647
+     * parseInt("-2147483648", 10) returns -2147483648
+     * parseInt("2147483648", 10) throws a NumberFormatException
+     * parseInt("99", 8) throws a NumberFormatException
+     * parseInt("Kona", 10) throws a NumberFormatException
+     * parseInt("Kona", 27) returns 411787
+     * </pre></blockquote>
+     *
+     * @param      s   the {@code String} containing the integer
+     *                  representation to be parsed
+     * @param      radix   the radix to be used while parsing {@code s}.
+     * @return     the integer represented by the string argument in the
+     *             specified radix.
+     * @exception  NumberFormatException if the {@code String}
+     *             does not contain a parsable {@code int}.
+     */
+    public static int parseInt(String s, int radix)
+                throws NumberFormatException
+    {
+        /*
+         * WARNING: This method may be invoked early during VM initialization
+         * before IntegerCache is initialized. Care must be taken to not use
+         * the valueOf method.
+         */
+
+        if (s == null) {
+            // Android-changed: Improve exception message for parseInt.
+            throw new NumberFormatException("s == null");
+        }
+
+        if (radix < Character.MIN_RADIX) {
+            throw new NumberFormatException("radix " + radix +
+                                            " less than Character.MIN_RADIX");
+        }
+
+        if (radix > Character.MAX_RADIX) {
+            throw new NumberFormatException("radix " + radix +
+                                            " greater than Character.MAX_RADIX");
+        }
+
+        int result = 0;
+        boolean negative = false;
+        int i = 0, len = s.length();
+        int limit = -Integer.MAX_VALUE;
+        int multmin;
+        int digit;
+
+        if (len > 0) {
+            char firstChar = s.charAt(0);
+            if (firstChar < '0') { // Possible leading "+" or "-"
+                if (firstChar == '-') {
+                    negative = true;
+                    limit = Integer.MIN_VALUE;
+                } else if (firstChar != '+')
+                    throw NumberFormatException.forInputString(s);
+
+                if (len == 1) // Cannot have lone "+" or "-"
+                    throw NumberFormatException.forInputString(s);
+                i++;
+            }
+            multmin = limit / radix;
+            while (i < len) {
+                // Accumulating negatively avoids surprises near MAX_VALUE
+                digit = Character.digit(s.charAt(i++),radix);
+                if (digit < 0) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                if (result < multmin) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                result *= radix;
+                if (result < limit + digit) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                result -= digit;
+            }
+        } else {
+            throw NumberFormatException.forInputString(s);
+        }
+        return negative ? result : -result;
+    }
+
+    /**
+     * Parses the string argument as a signed decimal integer. The
+     * characters in the string must all be decimal digits, except
+     * that the first character may be an ASCII minus sign {@code '-'}
+     * ({@code '\u005Cu002D'}) to indicate a negative value or an
+     * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+     * indicate a positive value. The resulting integer value is
+     * returned, exactly as if the argument and the radix 10 were
+     * given as arguments to the {@link #parseInt(java.lang.String,
+     * int)} method.
+     *
+     * @param s    a {@code String} containing the {@code int}
+     *             representation to be parsed
+     * @return     the integer value represented by the argument in decimal.
+     * @exception  NumberFormatException  if the string does not contain a
+     *               parsable integer.
+     */
+    public static int parseInt(String s) throws NumberFormatException {
+        return parseInt(s,10);
+    }
+
+    /**
+     * Parses the string argument as an unsigned integer in the radix
+     * specified by the second argument.  An unsigned integer maps the
+     * values usually associated with negative numbers to positive
+     * numbers larger than {@code MAX_VALUE}.
+     *
+     * The characters in the string must all be digits of the
+     * specified radix (as determined by whether {@link
+     * java.lang.Character#digit(char, int)} returns a nonnegative
+     * value), except that the first character may be an ASCII plus
+     * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
+     * integer value is returned.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     * <li>The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li>The radix is either smaller than
+     * {@link java.lang.Character#MIN_RADIX} or
+     * larger than {@link java.lang.Character#MAX_RADIX}.
+     *
+     * <li>Any character of the string is not a digit of the specified
+     * radix, except that the first character may be a plus sign
+     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+     * string is longer than length 1.
+     *
+     * <li>The value represented by the string is larger than the
+     * largest unsigned {@code int}, 2<sup>32</sup>-1.
+     *
+     * </ul>
+     *
+     *
+     * @param      s   the {@code String} containing the unsigned integer
+     *                  representation to be parsed
+     * @param      radix   the radix to be used while parsing {@code s}.
+     * @return     the integer represented by the string argument in the
+     *             specified radix.
+     * @throws     NumberFormatException if the {@code String}
+     *             does not contain a parsable {@code int}.
+     * @since 1.8
+     */
+    public static int parseUnsignedInt(String s, int radix)
+                throws NumberFormatException {
+        if (s == null)  {
+            throw new NumberFormatException("null");
+        }
+
+        int len = s.length();
+        if (len > 0) {
+            char firstChar = s.charAt(0);
+            if (firstChar == '-') {
+                throw new
+                    NumberFormatException(String.format("Illegal leading minus sign " +
+                                                       "on unsigned string %s.", s));
+            } else {
+                if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
+                    (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
+                    return parseInt(s, radix);
+                } else {
+                    long ell = Long.parseLong(s, radix);
+                    if ((ell & 0xffff_ffff_0000_0000L) == 0) {
+                        return (int) ell;
+                    } else {
+                        throw new
+                            NumberFormatException(String.format("String value %s exceeds " +
+                                                                "range of unsigned int.", s));
+                    }
+                }
+            }
+        } else {
+            throw NumberFormatException.forInputString(s);
+        }
+    }
+
+    /**
+     * Parses the string argument as an unsigned decimal integer. The
+     * characters in the string must all be decimal digits, except
+     * that the first character may be an an ASCII plus sign {@code
+     * '+'} ({@code '\u005Cu002B'}). The resulting integer value
+     * is returned, exactly as if the argument and the radix 10 were
+     * given as arguments to the {@link
+     * #parseUnsignedInt(java.lang.String, int)} method.
+     *
+     * @param s   a {@code String} containing the unsigned {@code int}
+     *            representation to be parsed
+     * @return    the unsigned integer value represented by the argument in decimal.
+     * @throws    NumberFormatException  if the string does not contain a
+     *            parsable unsigned integer.
+     * @since 1.8
+     */
+    public static int parseUnsignedInt(String s) throws NumberFormatException {
+        return parseUnsignedInt(s, 10);
+    }
+
+    /**
+     * Returns an {@code Integer} object holding the value
+     * extracted from the specified {@code String} when parsed
+     * with the radix given by the second argument. The first argument
+     * is interpreted as representing a signed integer in the radix
+     * specified by the second argument, exactly as if the arguments
+     * were given to the {@link #parseInt(java.lang.String, int)}
+     * method. The result is an {@code Integer} object that
+     * represents the integer value specified by the string.
+     *
+     * <p>In other words, this method returns an {@code Integer}
+     * object equal to the value of:
+     *
+     * <blockquote>
+     *  {@code new Integer(Integer.parseInt(s, radix))}
+     * </blockquote>
+     *
+     * @param      s   the string to be parsed.
+     * @param      radix the radix to be used in interpreting {@code s}
+     * @return     an {@code Integer} object holding the value
+     *             represented by the string argument in the specified
+     *             radix.
+     * @exception NumberFormatException if the {@code String}
+     *            does not contain a parsable {@code int}.
+     */
+    public static Integer valueOf(String s, int radix) throws NumberFormatException {
+        return Integer.valueOf(parseInt(s,radix));
+    }
+
+    /**
+     * Returns an {@code Integer} object holding the
+     * value of the specified {@code String}. The argument is
+     * interpreted as representing a signed decimal integer, exactly
+     * as if the argument were given to the {@link
+     * #parseInt(java.lang.String)} method. The result is an
+     * {@code Integer} object that represents the integer value
+     * specified by the string.
+     *
+     * <p>In other words, this method returns an {@code Integer}
+     * object equal to the value of:
+     *
+     * <blockquote>
+     *  {@code new Integer(Integer.parseInt(s))}
+     * </blockquote>
+     *
+     * @param      s   the string to be parsed.
+     * @return     an {@code Integer} object holding the value
+     *             represented by the string argument.
+     * @exception  NumberFormatException  if the string cannot be parsed
+     *             as an integer.
+     */
+    public static Integer valueOf(String s) throws NumberFormatException {
+        return Integer.valueOf(parseInt(s, 10));
+    }
+
+    /**
+     * Cache to support the object identity semantics of autoboxing for values between
+     * -128 and 127 (inclusive) as required by JLS.
+     *
+     * The cache is initialized on first usage.  The size of the cache
+     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
+     * During VM initialization, java.lang.Integer.IntegerCache.high property
+     * may be set and saved in the private system properties in the
+     * sun.misc.VM class.
+     */
+
+    private static class IntegerCache {
+        static final int low = -128;
+        static final int high;
+        static final Integer cache[];
+
+        static {
+            // high value may be configured by property
+            int h = 127;
+            String integerCacheHighPropValue =
+                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
+            if (integerCacheHighPropValue != null) {
+                try {
+                    int i = parseInt(integerCacheHighPropValue);
+                    i = Math.max(i, 127);
+                    // Maximum array size is Integer.MAX_VALUE
+                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
+                } catch( NumberFormatException nfe) {
+                    // If the property cannot be parsed into an int, ignore it.
+                }
+            }
+            high = h;
+
+            cache = new Integer[(high - low) + 1];
+            int j = low;
+            for(int k = 0; k < cache.length; k++)
+                cache[k] = new Integer(j++);
+
+            // range [-128, 127] must be interned (JLS7 5.1.7)
+            assert IntegerCache.high >= 127;
+        }
+
+        private IntegerCache() {}
+    }
+
+    /**
+     * Returns an {@code Integer} instance representing the specified
+     * {@code int} value.  If a new {@code Integer} instance is not
+     * required, this method should generally be used in preference to
+     * the constructor {@link #Integer(int)}, as this method is likely
+     * to yield significantly better space and time performance by
+     * caching frequently requested values.
+     *
+     * This method will always cache values in the range -128 to 127,
+     * inclusive, and may cache other values outside of this range.
+     *
+     * @param  i an {@code int} value.
+     * @return an {@code Integer} instance representing {@code i}.
+     * @since  1.5
+     */
+    public static Integer valueOf(int i) {
+        if (i >= IntegerCache.low && i <= IntegerCache.high)
+            return IntegerCache.cache[i + (-IntegerCache.low)];
+        return new Integer(i);
+    }
+
+    /**
+     * The value of the {@code Integer}.
+     *
+     * @serial
+     */
+    private final int value;
+
+    /**
+     * Constructs a newly allocated {@code Integer} object that
+     * represents the specified {@code int} value.
+     *
+     * @param   value   the value to be represented by the
+     *                  {@code Integer} object.
+     */
+    public Integer(int value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Integer} object that
+     * represents the {@code int} value indicated by the
+     * {@code String} parameter. The string is converted to an
+     * {@code int} value in exactly the manner used by the
+     * {@code parseInt} method for radix 10.
+     *
+     * @param      s   the {@code String} to be converted to an
+     *                 {@code Integer}.
+     * @exception  NumberFormatException  if the {@code String} does not
+     *               contain a parsable integer.
+     * @see        java.lang.Integer#parseInt(java.lang.String, int)
+     */
+    public Integer(String s) throws NumberFormatException {
+        this.value = parseInt(s, 10);
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as a {@code byte}
+     * after a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public byte byteValue() {
+        return (byte)value;
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as a {@code short}
+     * after a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public short shortValue() {
+        return (short)value;
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as an
+     * {@code int}.
+     */
+    public int intValue() {
+        return value;
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as a {@code long}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     * @see Integer#toUnsignedLong(int)
+     */
+    public long longValue() {
+        return (long)value;
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as a {@code float}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public float floatValue() {
+        return (float)value;
+    }
+
+    /**
+     * Returns the value of this {@code Integer} as a {@code double}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public double doubleValue() {
+        return (double)value;
+    }
+
+    /**
+     * Returns a {@code String} object representing this
+     * {@code Integer}'s value. The value is converted to signed
+     * decimal representation and returned as a string, exactly as if
+     * the integer value were given as an argument to the {@link
+     * java.lang.Integer#toString(int)} method.
+     *
+     * @return  a string representation of the value of this object in
+     *          base&nbsp;10.
+     */
+    public String toString() {
+        return toString(value);
+    }
+
+    /**
+     * Returns a hash code for this {@code Integer}.
+     *
+     * @return  a hash code value for this object, equal to the
+     *          primitive {@code int} value represented by this
+     *          {@code Integer} object.
+     */
+    @Override
+    public int hashCode() {
+        return Integer.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code int} value; compatible with
+     * {@code Integer.hashCode()}.
+     *
+     * @param value the value to hash
+     * @since 1.8
+     *
+     * @return a hash code value for a {@code int} value.
+     */
+    public static int hashCode(int value) {
+        return value;
+    }
+
+    /**
+     * Compares this object to the specified object.  The result is
+     * {@code true} if and only if the argument is not
+     * {@code null} and is an {@code Integer} object that
+     * contains the same {@code int} value as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Integer) {
+            return value == ((Integer)obj).intValue();
+        }
+        return false;
+    }
+
+    /**
+     * Determines the integer value of the system property with the
+     * specified name.
+     *
+     * <p>The first argument is treated as the name of a system
+     * property.  System properties are accessible through the {@link
+     * java.lang.System#getProperty(java.lang.String)} method. The
+     * string value of this property is then interpreted as an integer
+     * value using the grammar supported by {@link Integer#decode decode} and
+     * an {@code Integer} object representing this value is returned.
+     *
+     * <p>If there is no property with the specified name, if the
+     * specified name is empty or {@code null}, or if the property
+     * does not have the correct numeric format, then {@code null} is
+     * returned.
+     *
+     * <p>In other words, this method returns an {@code Integer}
+     * object equal to the value of:
+     *
+     * <blockquote>
+     *  {@code getInteger(nm, null)}
+     * </blockquote>
+     *
+     * @param   nm   property name.
+     * @return  the {@code Integer} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     java.lang.System#getProperty(java.lang.String)
+     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Integer getInteger(String nm) {
+        return getInteger(nm, null);
+    }
+
+    /**
+     * Determines the integer value of the system property with the
+     * specified name.
+     *
+     * <p>The first argument is treated as the name of a system
+     * property.  System properties are accessible through the {@link
+     * java.lang.System#getProperty(java.lang.String)} method. The
+     * string value of this property is then interpreted as an integer
+     * value using the grammar supported by {@link Integer#decode decode} and
+     * an {@code Integer} object representing this value is returned.
+     *
+     * <p>The second argument is the default value. An {@code Integer} object
+     * that represents the value of the second argument is returned if there
+     * is no property of the specified name, if the property does not have
+     * the correct numeric format, or if the specified name is empty or
+     * {@code null}.
+     *
+     * <p>In other words, this method returns an {@code Integer} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     *  {@code getInteger(nm, new Integer(val))}
+     * </blockquote>
+     *
+     * but in practice it may be implemented in a manner such as:
+     *
+     * <blockquote><pre>
+     * Integer result = getInteger(nm, null);
+     * return (result == null) ? new Integer(val) : result;
+     * </pre></blockquote>
+     *
+     * to avoid the unnecessary allocation of an {@code Integer}
+     * object when the default value is not needed.
+     *
+     * @param   nm   property name.
+     * @param   val   default value.
+     * @return  the {@code Integer} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     java.lang.System#getProperty(java.lang.String)
+     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Integer getInteger(String nm, int val) {
+        Integer result = getInteger(nm, null);
+        return (result == null) ? Integer.valueOf(val) : result;
+    }
+
+    /**
+     * Returns the integer value of the system property with the
+     * specified name.  The first argument is treated as the name of a
+     * system property.  System properties are accessible through the
+     * {@link java.lang.System#getProperty(java.lang.String)} method.
+     * The string value of this property is then interpreted as an
+     * integer value, as per the {@link Integer#decode decode} method,
+     * and an {@code Integer} object representing this value is
+     * returned; in summary:
+     *
+     * <ul><li>If the property value begins with the two ASCII characters
+     *         {@code 0x} or the ASCII character {@code #}, not
+     *      followed by a minus sign, then the rest of it is parsed as a
+     *      hexadecimal integer exactly as by the method
+     *      {@link #valueOf(java.lang.String, int)} with radix 16.
+     * <li>If the property value begins with the ASCII character
+     *     {@code 0} followed by another character, it is parsed as an
+     *     octal integer exactly as by the method
+     *     {@link #valueOf(java.lang.String, int)} with radix 8.
+     * <li>Otherwise, the property value is parsed as a decimal integer
+     * exactly as by the method {@link #valueOf(java.lang.String, int)}
+     * with radix 10.
+     * </ul>
+     *
+     * <p>The second argument is the default value. The default value is
+     * returned if there is no property of the specified name, if the
+     * property does not have the correct numeric format, or if the
+     * specified name is empty or {@code null}.
+     *
+     * @param   nm   property name.
+     * @param   val   default value.
+     * @return  the {@code Integer} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     System#getProperty(java.lang.String)
+     * @see     System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Integer getInteger(String nm, Integer val) {
+        String v = null;
+        try {
+            v = System.getProperty(nm);
+        } catch (IllegalArgumentException | NullPointerException e) {
+        }
+        if (v != null) {
+            try {
+                return Integer.decode(v);
+            } catch (NumberFormatException e) {
+            }
+        }
+        return val;
+    }
+
+    /**
+     * Decodes a {@code String} into an {@code Integer}.
+     * Accepts decimal, hexadecimal, and octal numbers given
+     * by the following grammar:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>DecodableString:</i>
+     * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+     *
+     * <dt><i>Sign:</i>
+     * <dd>{@code -}
+     * <dd>{@code +}
+     * </dl>
+     * </blockquote>
+     *
+     * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+     * are as defined in section 3.10.1 of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     *
+     * <p>The sequence of characters following an optional
+     * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+     * "{@code #}", or leading zero) is parsed as by the {@code
+     * Integer.parseInt} method with the indicated radix (10, 16, or
+     * 8).  This sequence of characters must represent a positive
+     * value or a {@link NumberFormatException} will be thrown.  The
+     * result is negated if first character of the specified {@code
+     * String} is the minus sign.  No whitespace characters are
+     * permitted in the {@code String}.
+     *
+     * @param     nm the {@code String} to decode.
+     * @return    an {@code Integer} object holding the {@code int}
+     *             value represented by {@code nm}
+     * @exception NumberFormatException  if the {@code String} does not
+     *            contain a parsable integer.
+     * @see java.lang.Integer#parseInt(java.lang.String, int)
+     */
+    public static Integer decode(String nm) throws NumberFormatException {
+        int radix = 10;
+        int index = 0;
+        boolean negative = false;
+        Integer result;
+
+        if (nm.length() == 0)
+            throw new NumberFormatException("Zero length string");
+        char firstChar = nm.charAt(0);
+        // Handle sign, if present
+        if (firstChar == '-') {
+            negative = true;
+            index++;
+        } else if (firstChar == '+')
+            index++;
+
+        // Handle radix specifier, if present
+        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
+            index += 2;
+            radix = 16;
+        }
+        else if (nm.startsWith("#", index)) {
+            index ++;
+            radix = 16;
+        }
+        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
+            index ++;
+            radix = 8;
+        }
+
+        if (nm.startsWith("-", index) || nm.startsWith("+", index))
+            throw new NumberFormatException("Sign character in wrong position");
+
+        try {
+            result = Integer.valueOf(nm.substring(index), radix);
+            result = negative ? Integer.valueOf(-result.intValue()) : result;
+        } catch (NumberFormatException e) {
+            // If number is Integer.MIN_VALUE, we'll end up here. The next line
+            // handles this case, and causes any genuine format error to be
+            // rethrown.
+            String constant = negative ? ("-" + nm.substring(index))
+                                       : nm.substring(index);
+            result = Integer.valueOf(constant, radix);
+        }
+        return result;
+    }
+
+    /**
+     * Compares two {@code Integer} objects numerically.
+     *
+     * @param   anotherInteger   the {@code Integer} to be compared.
+     * @return  the value {@code 0} if this {@code Integer} is
+     *          equal to the argument {@code Integer}; a value less than
+     *          {@code 0} if this {@code Integer} is numerically less
+     *          than the argument {@code Integer}; and a value greater
+     *          than {@code 0} if this {@code Integer} is numerically
+     *           greater than the argument {@code Integer} (signed
+     *           comparison).
+     * @since   1.2
+     */
+    public int compareTo(Integer anotherInteger) {
+        return compare(this.value, anotherInteger.value);
+    }
+
+    /**
+     * Compares two {@code int} values numerically.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Integer.valueOf(x).compareTo(Integer.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code int} to compare
+     * @param  y the second {@code int} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code x < y}; and
+     *         a value greater than {@code 0} if {@code x > y}
+     * @since 1.7
+     */
+    public static int compare(int x, int y) {
+        return (x < y) ? -1 : ((x == y) ? 0 : 1);
+    }
+
+    /**
+     * Compares two {@code int} values numerically treating the values
+     * as unsigned.
+     *
+     * @param  x the first {@code int} to compare
+     * @param  y the second {@code int} to compare
+     * @return the value {@code 0} if {@code x == y}; a value less
+     *         than {@code 0} if {@code x < y} as unsigned values; and
+     *         a value greater than {@code 0} if {@code x > y} as
+     *         unsigned values
+     * @since 1.8
+     */
+    public static int compareUnsigned(int x, int y) {
+        return compare(x + MIN_VALUE, y + MIN_VALUE);
+    }
+
+    /**
+     * Converts the argument to a {@code long} by an unsigned
+     * conversion.  In an unsigned conversion to a {@code long}, the
+     * high-order 32 bits of the {@code long} are zero and the
+     * low-order 32 bits are equal to the bits of the integer
+     * argument.
+     *
+     * Consequently, zero and positive {@code int} values are mapped
+     * to a numerically equal {@code long} value and negative {@code
+     * int} values are mapped to a {@code long} value equal to the
+     * input plus 2<sup>32</sup>.
+     *
+     * @param  x the value to convert to an unsigned {@code long}
+     * @return the argument converted to {@code long} by an unsigned
+     *         conversion
+     * @since 1.8
+     */
+    public static long toUnsignedLong(int x) {
+        return ((long) x) & 0xffffffffL;
+    }
+
+    /**
+     * Returns the unsigned quotient of dividing the first argument by
+     * the second where each argument and the result is interpreted as
+     * an unsigned value.
+     *
+     * <p>Note that in two's complement arithmetic, the three other
+     * basic arithmetic operations of add, subtract, and multiply are
+     * bit-wise identical if the two operands are regarded as both
+     * being signed or both being unsigned.  Therefore separate {@code
+     * addUnsigned}, etc. methods are not provided.
+     *
+     * @param dividend the value to be divided
+     * @param divisor the value doing the dividing
+     * @return the unsigned quotient of the first argument divided by
+     * the second argument
+     * @see #remainderUnsigned
+     * @since 1.8
+     */
+    public static int divideUnsigned(int dividend, int divisor) {
+        // In lieu of tricky code, for now just use long arithmetic.
+        return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor));
+    }
+
+    /**
+     * Returns the unsigned remainder from dividing the first argument
+     * by the second where each argument and the result is interpreted
+     * as an unsigned value.
+     *
+     * @param dividend the value to be divided
+     * @param divisor the value doing the dividing
+     * @return the unsigned remainder of the first argument divided by
+     * the second argument
+     * @see #divideUnsigned
+     * @since 1.8
+     */
+    public static int remainderUnsigned(int dividend, int divisor) {
+        // In lieu of tricky code, for now just use long arithmetic.
+        return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor));
+    }
+
+
+    // Bit twiddling
+
+    /**
+     * The number of bits used to represent an {@code int} value in two's
+     * complement binary form.
+     *
+     * @since 1.5
+     */
+    @Native public static final int SIZE = 32;
+
+    /**
+     * The number of bytes used to represent a {@code int} value in two's
+     * complement binary form.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * Returns an {@code int} value with at most a single one-bit, in the
+     * position of the highest-order ("leftmost") one-bit in the specified
+     * {@code int} value.  Returns zero if the specified value has no
+     * one-bits in its two's complement binary representation, that is, if it
+     * is equal to zero.
+     *
+     * @param i the value whose highest one bit is to be computed
+     * @return an {@code int} value with a single one-bit, in the position
+     *     of the highest-order one-bit in the specified value, or zero if
+     *     the specified value is itself equal to zero.
+     * @since 1.5
+     */
+    public static int highestOneBit(int i) {
+        // HD, Figure 3-1
+        i |= (i >>  1);
+        i |= (i >>  2);
+        i |= (i >>  4);
+        i |= (i >>  8);
+        i |= (i >> 16);
+        return i - (i >>> 1);
+    }
+
+    /**
+     * Returns an {@code int} value with at most a single one-bit, in the
+     * position of the lowest-order ("rightmost") one-bit in the specified
+     * {@code int} value.  Returns zero if the specified value has no
+     * one-bits in its two's complement binary representation, that is, if it
+     * is equal to zero.
+     *
+     * @param i the value whose lowest one bit is to be computed
+     * @return an {@code int} value with a single one-bit, in the position
+     *     of the lowest-order one-bit in the specified value, or zero if
+     *     the specified value is itself equal to zero.
+     * @since 1.5
+     */
+    public static int lowestOneBit(int i) {
+        // HD, Section 2-1
+        return i & -i;
+    }
+
+    /**
+     * Returns the number of zero bits preceding the highest-order
+     * ("leftmost") one-bit in the two's complement binary representation
+     * of the specified {@code int} value.  Returns 32 if the
+     * specified value has no one-bits in its two's complement representation,
+     * in other words if it is equal to zero.
+     *
+     * <p>Note that this method is closely related to the logarithm base 2.
+     * For all positive {@code int} values x:
+     * <ul>
+     * <li>floor(log<sub>2</sub>(x)) = {@code 31 - numberOfLeadingZeros(x)}
+     * <li>ceil(log<sub>2</sub>(x)) = {@code 32 - numberOfLeadingZeros(x - 1)}
+     * </ul>
+     *
+     * @param i the value whose number of leading zeros is to be computed
+     * @return the number of zero bits preceding the highest-order
+     *     ("leftmost") one-bit in the two's complement binary representation
+     *     of the specified {@code int} value, or 32 if the value
+     *     is equal to zero.
+     * @since 1.5
+     */
+    public static int numberOfLeadingZeros(int i) {
+        // HD, Figure 5-6
+        if (i == 0)
+            return 32;
+        int n = 1;
+        if (i >>> 16 == 0) { n += 16; i <<= 16; }
+        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
+        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
+        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
+        n -= i >>> 31;
+        return n;
+    }
+
+    /**
+     * Returns the number of zero bits following the lowest-order ("rightmost")
+     * one-bit in the two's complement binary representation of the specified
+     * {@code int} value.  Returns 32 if the specified value has no
+     * one-bits in its two's complement representation, in other words if it is
+     * equal to zero.
+     *
+     * @param i the value whose number of trailing zeros is to be computed
+     * @return the number of zero bits following the lowest-order ("rightmost")
+     *     one-bit in the two's complement binary representation of the
+     *     specified {@code int} value, or 32 if the value is equal
+     *     to zero.
+     * @since 1.5
+     */
+    public static int numberOfTrailingZeros(int i) {
+        // HD, Figure 5-14
+        int y;
+        if (i == 0) return 32;
+        int n = 31;
+        y = i <<16; if (y != 0) { n = n -16; i = y; }
+        y = i << 8; if (y != 0) { n = n - 8; i = y; }
+        y = i << 4; if (y != 0) { n = n - 4; i = y; }
+        y = i << 2; if (y != 0) { n = n - 2; i = y; }
+        return n - ((i << 1) >>> 31);
+    }
+
+    /**
+     * Returns the number of one-bits in the two's complement binary
+     * representation of the specified {@code int} value.  This function is
+     * sometimes referred to as the <i>population count</i>.
+     *
+     * @param i the value whose bits are to be counted
+     * @return the number of one-bits in the two's complement binary
+     *     representation of the specified {@code int} value.
+     * @since 1.5
+     */
+    public static int bitCount(int i) {
+        // HD, Figure 5-2
+        i = i - ((i >>> 1) & 0x55555555);
+        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+        i = (i + (i >>> 4)) & 0x0f0f0f0f;
+        i = i + (i >>> 8);
+        i = i + (i >>> 16);
+        return i & 0x3f;
+    }
+
+    /**
+     * Returns the value obtained by rotating the two's complement binary
+     * representation of the specified {@code int} value left by the
+     * specified number of bits.  (Bits shifted out of the left hand, or
+     * high-order, side reenter on the right, or low-order.)
+     *
+     * <p>Note that left rotation with a negative distance is equivalent to
+     * right rotation: {@code rotateLeft(val, -distance) == rotateRight(val,
+     * distance)}.  Note also that rotation by any multiple of 32 is a
+     * no-op, so all but the last five bits of the rotation distance can be
+     * ignored, even if the distance is negative: {@code rotateLeft(val,
+     * distance) == rotateLeft(val, distance & 0x1F)}.
+     *
+     * @param i the value whose bits are to be rotated left
+     * @param distance the number of bit positions to rotate left
+     * @return the value obtained by rotating the two's complement binary
+     *     representation of the specified {@code int} value left by the
+     *     specified number of bits.
+     * @since 1.5
+     */
+    public static int rotateLeft(int i, int distance) {
+        return (i << distance) | (i >>> -distance);
+    }
+
+    /**
+     * Returns the value obtained by rotating the two's complement binary
+     * representation of the specified {@code int} value right by the
+     * specified number of bits.  (Bits shifted out of the right hand, or
+     * low-order, side reenter on the left, or high-order.)
+     *
+     * <p>Note that right rotation with a negative distance is equivalent to
+     * left rotation: {@code rotateRight(val, -distance) == rotateLeft(val,
+     * distance)}.  Note also that rotation by any multiple of 32 is a
+     * no-op, so all but the last five bits of the rotation distance can be
+     * ignored, even if the distance is negative: {@code rotateRight(val,
+     * distance) == rotateRight(val, distance & 0x1F)}.
+     *
+     * @param i the value whose bits are to be rotated right
+     * @param distance the number of bit positions to rotate right
+     * @return the value obtained by rotating the two's complement binary
+     *     representation of the specified {@code int} value right by the
+     *     specified number of bits.
+     * @since 1.5
+     */
+    public static int rotateRight(int i, int distance) {
+        return (i >>> distance) | (i << -distance);
+    }
+
+    /**
+     * Returns the value obtained by reversing the order of the bits in the
+     * two's complement binary representation of the specified {@code int}
+     * value.
+     *
+     * @param i the value to be reversed
+     * @return the value obtained by reversing order of the bits in the
+     *     specified {@code int} value.
+     * @since 1.5
+     */
+    public static int reverse(int i) {
+        // HD, Figure 7-1
+        i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
+        i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
+        i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
+        i = (i << 24) | ((i & 0xff00) << 8) |
+            ((i >>> 8) & 0xff00) | (i >>> 24);
+        return i;
+    }
+
+    /**
+     * Returns the signum function of the specified {@code int} value.  (The
+     * return value is -1 if the specified value is negative; 0 if the
+     * specified value is zero; and 1 if the specified value is positive.)
+     *
+     * @param i the value whose signum is to be computed
+     * @return the signum function of the specified {@code int} value.
+     * @since 1.5
+     */
+    public static int signum(int i) {
+        // HD, Section 2-7
+        return (i >> 31) | (-i >>> 31);
+    }
+
+    /**
+     * Returns the value obtained by reversing the order of the bytes in the
+     * two's complement representation of the specified {@code int} value.
+     *
+     * @param i the value whose bytes are to be reversed
+     * @return the value obtained by reversing the bytes in the specified
+     *     {@code int} value.
+     * @since 1.5
+     */
+    public static int reverseBytes(int i) {
+        return ((i >>> 24)           ) |
+               ((i >>   8) &   0xFF00) |
+               ((i <<   8) & 0xFF0000) |
+               ((i << 24));
+    }
+
+    /**
+     * Adds two integers together as per the + operator.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the sum of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static int sum(int a, int b) {
+        return a + b;
+    }
+
+    /**
+     * Returns the greater of two {@code int} values
+     * as if by calling {@link Math#max(int, int) Math.max}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the greater of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static int max(int a, int b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code int} values
+     * as if by calling {@link Math#min(int, int) Math.min}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the smaller of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static int min(int a, int b) {
+        return Math.min(a, b);
+    }
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    @Native private static final long serialVersionUID = 1360826667806852920L;
+}
diff --git a/java/lang/InternalError.java b/java/lang/InternalError.java
new file mode 100644
index 0000000..8d33821
--- /dev/null
+++ b/java/lang/InternalError.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * Thrown to indicate some unexpected internal error has occurred in
+ * the Java Virtual Machine.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public class InternalError extends VirtualMachineError {
+    private static final long serialVersionUID = -9062593416125562365L;
+
+    /**
+     * Constructs an <code>InternalError</code> with no detail message.
+     */
+    public InternalError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>InternalError</code> with the specified
+     * detail message.
+     *
+     * @param   message   the detail message.
+     */
+    public InternalError(String message) {
+        super(message);
+    }
+
+
+    /**
+     * Constructs an {@code InternalError} with the specified detail
+     * message and cause.  <p>Note that the detail message associated
+     * with {@code cause} is <i>not</i> automatically incorporated in
+     * this error's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.8
+     */
+    public InternalError(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs an {@code InternalError} with the specified cause
+     * and a detail message of {@code (cause==null ? null :
+     * cause.toString())} (which typically contains the class and
+     * detail message of {@code cause}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.8
+     */
+    public InternalError(Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/java/lang/InterruptedException.java b/java/lang/InterruptedException.java
new file mode 100644
index 0000000..27bc5a8
--- /dev/null
+++ b/java/lang/InterruptedException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when a thread is waiting, sleeping, or otherwise occupied,
+ * and the thread is interrupted, either before or during the activity.
+ * Occasionally a method may wish to test whether the current
+ * thread has been interrupted, and if so, to immediately throw
+ * this exception.  The following code can be used to achieve
+ * this effect:
+ * <pre>
+ *  if (Thread.interrupted())  // Clears interrupted status!
+ *      throw new InterruptedException();
+ * </pre>
+ *
+ * @author  Frank Yellin
+ * @see     java.lang.Object#wait()
+ * @see     java.lang.Object#wait(long)
+ * @see     java.lang.Object#wait(long, int)
+ * @see     java.lang.Thread#sleep(long)
+ * @see     java.lang.Thread#interrupt()
+ * @see     java.lang.Thread#interrupted()
+ * @since   JDK1.0
+ */
+public
+class InterruptedException extends Exception {
+    private static final long serialVersionUID = 6700697376100628473L;
+
+    /**
+     * Constructs an <code>InterruptedException</code> with no detail  message.
+     */
+    public InterruptedException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>InterruptedException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public InterruptedException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/Iterable.annotated.java b/java/lang/Iterable.annotated.java
new file mode 100644
index 0000000..8986b35
--- /dev/null
+++ b/java/lang/Iterable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import libcore.util.NonNull;
+import libcore.util.NullFromTypeParam;
+
+public interface Iterable<T> {
+
+  public @NonNull Iterator<@NullFromTypeParam T> iterator();
+  public default void forEach(@NonNull Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+  @NonNull public default Spliterator<T> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Iterable.java b/java/lang/Iterable.java
new file mode 100644
index 0000000..eed3938
--- /dev/null
+++ b/java/lang/Iterable.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+
+/**
+ * Implementing this interface allows an object to be the target of
+ * the "for-each loop" statement. See
+ * <strong>
+ * <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a>
+ * </strong>
+ *
+ * @param <T> the type of elements returned by the iterator
+ *
+ * @since 1.5
+ * @jls 14.14.2 The enhanced for statement
+ */
+public interface Iterable<T> {
+    /**
+     * Returns an iterator over elements of type {@code T}.
+     *
+     * @return an Iterator.
+     */
+    Iterator<T> iterator();
+
+    /**
+     * Performs the given action for each element of the {@code Iterable}
+     * until all elements have been processed or the action throws an
+     * exception.  Unless otherwise specified by the implementing class,
+     * actions are performed in the order of iteration (if an iteration order
+     * is specified).  Exceptions thrown by the action are relayed to the
+     * caller.
+     *
+     * @implSpec
+     * <p>The default implementation behaves as if:
+     * <pre>{@code
+     *     for (T t : this)
+     *         action.accept(t);
+     * }</pre>
+     *
+     * @param action The action to be performed for each element
+     * @throws NullPointerException if the specified action is null
+     * @since 1.8
+     */
+    default void forEach(Consumer<? super T> action) {
+        Objects.requireNonNull(action);
+        for (T t : this) {
+            action.accept(t);
+        }
+    }
+
+    /**
+     * Creates a {@link Spliterator} over the elements described by this
+     * {@code Iterable}.
+     *
+     * @implSpec
+     * The default implementation creates an
+     * <em><a href="Spliterator.html#binding">early-binding</a></em>
+     * spliterator from the iterable's {@code Iterator}.  The spliterator
+     * inherits the <em>fail-fast</em> properties of the iterable's iterator.
+     *
+     * @implNote
+     * The default implementation should usually be overridden.  The
+     * spliterator returned by the default implementation has poor splitting
+     * capabilities, is unsized, and does not report any spliterator
+     * characteristics. Implementing classes can nearly always provide a
+     * better implementation.
+     *
+     * @return a {@code Spliterator} over the elements described by this
+     * {@code Iterable}.
+     * @since 1.8
+     */
+    default Spliterator<T> spliterator() {
+        return Spliterators.spliteratorUnknownSize(iterator(), 0);
+    }
+}
diff --git a/java/lang/LinkageError.java b/java/lang/LinkageError.java
new file mode 100644
index 0000000..6b5f060
--- /dev/null
+++ b/java/lang/LinkageError.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 2010, 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;
+
+/**
+ * Subclasses of {@code LinkageError} indicate that a class has
+ * some dependency on another class; however, the latter class has
+ * incompatibly changed after the compilation of the former class.
+ *
+ *
+ * @author  Frank Yellin
+ * @since   JDK1.0
+ */
+public
+class LinkageError extends Error {
+    private static final long serialVersionUID = 3579600108157160122L;
+
+    /**
+     * Constructs a {@code LinkageError} with no detail message.
+     */
+    public LinkageError() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code LinkageError} with the specified detail
+     * message.
+     *
+     * @param   s   the detail message.
+     */
+    public LinkageError(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a {@code LinkageError} with the specified detail
+     * message and cause.
+     *
+     * @param s     the detail message.
+     * @param cause the cause, may be {@code null}
+     * @since 1.7
+     */
+    public LinkageError(String s, Throwable cause) {
+        super(s, cause);
+    }
+}
diff --git a/java/lang/Long.annotated.java b/java/lang/Long.annotated.java
new file mode 100644
index 0000000..b077ef5
--- /dev/null
+++ b/java/lang/Long.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.math.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
+
+public Long(long value) { throw new RuntimeException("Stub!"); }
+
+public Long(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toOctalString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toBinaryString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(long i) { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(long value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, long val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Long val) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Long anotherLong) { throw new RuntimeException("Stub!"); }
+
+public static int compare(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static long divideUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long remainderUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long highestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static long lowestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(long i) { throw new RuntimeException("Stub!"); }
+
+public static long rotateLeft(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long rotateRight(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long reverse(long i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(long i) { throw new RuntimeException("Stub!"); }
+
+public static long reverseBytes(long i) { throw new RuntimeException("Stub!"); }
+
+public static long sum(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
+
+public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Long> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Long.java b/java/lang/Long.java
new file mode 100644
index 0000000..0047125
--- /dev/null
+++ b/java/lang/Long.java
@@ -0,0 +1,1625 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.lang.annotation.Native;
+import java.math.*;
+
+
+/**
+ * The {@code Long} class wraps a value of the primitive type {@code
+ * long} in an object. An object of type {@code Long} contains a
+ * single field whose type is {@code long}.
+ *
+ * <p> In addition, this class provides several methods for converting
+ * a {@code long} to a {@code String} and a {@code String} to a {@code
+ * long}, as well as other constants and methods useful when dealing
+ * with a {@code long}.
+ *
+ * <p>Implementation note: The implementations of the "bit twiddling"
+ * methods (such as {@link #highestOneBit(long) highestOneBit} and
+ * {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are
+ * based on material from Henry S. Warren, Jr.'s <i>Hacker's
+ * Delight</i>, (Addison Wesley, 2002).
+ *
+ * @author  Lee Boynton
+ * @author  Arthur van Hoff
+ * @author  Josh Bloch
+ * @author  Joseph D. Darcy
+ * @since   JDK1.0
+ */
+public final class Long extends Number implements Comparable<Long> {
+    /**
+     * A constant holding the minimum value a {@code long} can
+     * have, -2<sup>63</sup>.
+     */
+    @Native public static final long MIN_VALUE = 0x8000000000000000L;
+
+    /**
+     * A constant holding the maximum value a {@code long} can
+     * have, 2<sup>63</sup>-1.
+     */
+    @Native public static final long MAX_VALUE = 0x7fffffffffffffffL;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code long}.
+     *
+     * @since   JDK1.1
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Long>     TYPE = (Class<Long>) Class.getPrimitiveClass("long");
+
+    /**
+     * Returns a string representation of the first argument in the
+     * radix specified by the second argument.
+     *
+     * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+     * or larger than {@code Character.MAX_RADIX}, then the radix
+     * {@code 10} is used instead.
+     *
+     * <p>If the first argument is negative, the first element of the
+     * result is the ASCII minus sign {@code '-'}
+     * ({@code '\u005Cu002d'}). If the first argument is not
+     * negative, no sign character appears in the result.
+     *
+     * <p>The remaining characters of the result represent the magnitude
+     * of the first argument. If the magnitude is zero, it is
+     * represented by a single zero character {@code '0'}
+     * ({@code '\u005Cu0030'}); otherwise, the first character of
+     * the representation of the magnitude will not be the zero
+     * character.  The following ASCII characters are used as digits:
+     *
+     * <blockquote>
+     *   {@code 0123456789abcdefghijklmnopqrstuvwxyz}
+     * </blockquote>
+     *
+     * These are {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+     * {@code '\u005Cu007a'}. If {@code radix} is
+     * <var>N</var>, then the first <var>N</var> of these characters
+     * are used as radix-<var>N</var> digits in the order shown. Thus,
+     * the digits for hexadecimal (radix 16) are
+     * {@code 0123456789abcdef}. If uppercase letters are
+     * desired, the {@link java.lang.String#toUpperCase()} method may
+     * be called on the result:
+     *
+     * <blockquote>
+     *  {@code Long.toString(n, 16).toUpperCase()}
+     * </blockquote>
+     *
+     * @param   i       a {@code long} to be converted to a string.
+     * @param   radix   the radix to use in the string representation.
+     * @return  a string representation of the argument in the specified radix.
+     * @see     java.lang.Character#MAX_RADIX
+     * @see     java.lang.Character#MIN_RADIX
+     */
+    public static String toString(long i, int radix) {
+        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+            radix = 10;
+        if (radix == 10)
+            return toString(i);
+        char[] buf = new char[65];
+        int charPos = 64;
+        boolean negative = (i < 0);
+
+        if (!negative) {
+            i = -i;
+        }
+
+        while (i <= -radix) {
+            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
+            i = i / radix;
+        }
+        buf[charPos] = Integer.digits[(int)(-i)];
+
+        if (negative) {
+            buf[--charPos] = '-';
+        }
+
+        return new String(buf, charPos, (65 - charPos));
+    }
+
+    /**
+     * Returns a string representation of the first argument as an
+     * unsigned integer value in the radix specified by the second
+     * argument.
+     *
+     * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+     * or larger than {@code Character.MAX_RADIX}, then the radix
+     * {@code 10} is used instead.
+     *
+     * <p>Note that since the first argument is treated as an unsigned
+     * value, no leading sign character is printed.
+     *
+     * <p>If the magnitude is zero, it is represented by a single zero
+     * character {@code '0'} ({@code '\u005Cu0030'}); otherwise,
+     * the first character of the representation of the magnitude will
+     * not be the zero character.
+     *
+     * <p>The behavior of radixes and the characters used as digits
+     * are the same as {@link #toString(long, int) toString}.
+     *
+     * @param   i       an integer to be converted to an unsigned string.
+     * @param   radix   the radix to use in the string representation.
+     * @return  an unsigned string representation of the argument in the specified radix.
+     * @see     #toString(long, int)
+     * @since 1.8
+     */
+    public static String toUnsignedString(long i, int radix) {
+        if (i >= 0)
+            return toString(i, radix);
+        else {
+            switch (radix) {
+            case 2:
+                return toBinaryString(i);
+
+            case 4:
+                return toUnsignedString0(i, 2);
+
+            case 8:
+                return toOctalString(i);
+
+            case 10:
+                /*
+                 * We can get the effect of an unsigned division by 10
+                 * on a long value by first shifting right, yielding a
+                 * positive value, and then dividing by 5.  This
+                 * allows the last digit and preceding digits to be
+                 * isolated more quickly than by an initial conversion
+                 * to BigInteger.
+                 */
+                long quot = (i >>> 1) / 5;
+                long rem = i - quot * 10;
+                return toString(quot) + rem;
+
+            case 16:
+                return toHexString(i);
+
+            case 32:
+                return toUnsignedString0(i, 5);
+
+            default:
+                return toUnsignedBigInteger(i).toString(radix);
+            }
+        }
+    }
+
+    /**
+     * Return a BigInteger equal to the unsigned value of the
+     * argument.
+     */
+    private static BigInteger toUnsignedBigInteger(long i) {
+        if (i >= 0L)
+            return BigInteger.valueOf(i);
+        else {
+            int upper = (int) (i >>> 32);
+            int lower = (int) i;
+
+            // return (upper << 32) + lower
+            return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
+                add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
+        }
+    }
+
+    /**
+     * Returns a string representation of the {@code long}
+     * argument as an unsigned integer in base&nbsp;16.
+     *
+     * <p>The unsigned {@code long} value is the argument plus
+     * 2<sup>64</sup> if the argument is negative; otherwise, it is
+     * equal to the argument.  This value is converted to a string of
+     * ASCII digits in hexadecimal (base&nbsp;16) with no extra
+     * leading {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+     * 16)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * following characters are used as hexadecimal digits:
+     *
+     * <blockquote>
+     *  {@code 0123456789abcdef}
+     * </blockquote>
+     *
+     * These are the characters {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0039'} and  {@code '\u005Cu0061'} through
+     * {@code '\u005Cu0066'}.  If uppercase letters are desired,
+     * the {@link java.lang.String#toUpperCase()} method may be called
+     * on the result:
+     *
+     * <blockquote>
+     *  {@code Long.toHexString(n).toUpperCase()}
+     * </blockquote>
+     *
+     * @param   i   a {@code long} to be converted to a string.
+     * @return  the string representation of the unsigned {@code long}
+     *          value represented by the argument in hexadecimal
+     *          (base&nbsp;16).
+     * @see #parseUnsignedLong(String, int)
+     * @see #toUnsignedString(long, int)
+     * @since   JDK 1.0.2
+     */
+    public static String toHexString(long i) {
+        return toUnsignedString0(i, 4);
+    }
+
+    /**
+     * Returns a string representation of the {@code long}
+     * argument as an unsigned integer in base&nbsp;8.
+     *
+     * <p>The unsigned {@code long} value is the argument plus
+     * 2<sup>64</sup> if the argument is negative; otherwise, it is
+     * equal to the argument.  This value is converted to a string of
+     * ASCII digits in octal (base&nbsp;8) with no extra leading
+     * {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+     * 8)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * following characters are used as octal digits:
+     *
+     * <blockquote>
+     *  {@code 01234567}
+     * </blockquote>
+     *
+     * These are the characters {@code '\u005Cu0030'} through
+     * {@code '\u005Cu0037'}.
+     *
+     * @param   i   a {@code long} to be converted to a string.
+     * @return  the string representation of the unsigned {@code long}
+     *          value represented by the argument in octal (base&nbsp;8).
+     * @see #parseUnsignedLong(String, int)
+     * @see #toUnsignedString(long, int)
+     * @since   JDK 1.0.2
+     */
+    public static String toOctalString(long i) {
+        return toUnsignedString0(i, 3);
+    }
+
+    /**
+     * Returns a string representation of the {@code long}
+     * argument as an unsigned integer in base&nbsp;2.
+     *
+     * <p>The unsigned {@code long} value is the argument plus
+     * 2<sup>64</sup> if the argument is negative; otherwise, it is
+     * equal to the argument.  This value is converted to a string of
+     * ASCII digits in binary (base&nbsp;2) with no extra leading
+     * {@code 0}s.
+     *
+     * <p>The value of the argument can be recovered from the returned
+     * string {@code s} by calling {@link
+     * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+     * 2)}.
+     *
+     * <p>If the unsigned magnitude is zero, it is represented by a
+     * single zero character {@code '0'} ({@code '\u005Cu0030'});
+     * otherwise, the first character of the representation of the
+     * unsigned magnitude will not be the zero character. The
+     * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code
+     * '1'} ({@code '\u005Cu0031'}) are used as binary digits.
+     *
+     * @param   i   a {@code long} to be converted to a string.
+     * @return  the string representation of the unsigned {@code long}
+     *          value represented by the argument in binary (base&nbsp;2).
+     * @see #parseUnsignedLong(String, int)
+     * @see #toUnsignedString(long, int)
+     * @since   JDK 1.0.2
+     */
+    public static String toBinaryString(long i) {
+        return toUnsignedString0(i, 1);
+    }
+
+    /**
+     * Format a long (treated as unsigned) into a String.
+     * @param val the value to format
+     * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+     */
+    static String toUnsignedString0(long val, int shift) {
+        // assert shift > 0 && shift <=5 : "Illegal shift value";
+        int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
+        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+        char[] buf = new char[chars];
+
+        formatUnsignedLong(val, shift, buf, 0, chars);
+        // Android-changed: Use regular constructor instead of one which takes over "buf".
+        // return new String(buf, true);
+        return new String(buf);
+    }
+
+    /**
+     * Format a long (treated as unsigned) into a character buffer.
+     * @param val the unsigned long to format
+     * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+     * @param buf the character buffer to write to
+     * @param offset the offset in the destination buffer to start at
+     * @param len the number of characters to write
+     * @return the lowest character location used
+     */
+     static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
+        int charPos = len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            buf[offset + --charPos] = Integer.digits[((int) val) & mask];
+            val >>>= shift;
+        } while (val != 0 && charPos > 0);
+
+        return charPos;
+    }
+
+    /**
+     * Returns a {@code String} object representing the specified
+     * {@code long}.  The argument is converted to signed decimal
+     * representation and returned as a string, exactly as if the
+     * argument and the radix 10 were given as arguments to the {@link
+     * #toString(long, int)} method.
+     *
+     * @param   i   a {@code long} to be converted.
+     * @return  a string representation of the argument in base&nbsp;10.
+     */
+    public static String toString(long i) {
+        if (i == Long.MIN_VALUE)
+            return "-9223372036854775808";
+        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+        char[] buf = new char[size];
+        getChars(i, size, buf);
+        // Android-changed: Use regular constructor instead of one which takes over "buf".
+        // return new String(buf, true);
+        return new String(buf);
+    }
+
+    /**
+     * Returns a string representation of the argument as an unsigned
+     * decimal value.
+     *
+     * The argument is converted to unsigned decimal representation
+     * and returned as a string exactly as if the argument and radix
+     * 10 were given as arguments to the {@link #toUnsignedString(long,
+     * int)} method.
+     *
+     * @param   i  an integer to be converted to an unsigned string.
+     * @return  an unsigned string representation of the argument.
+     * @see     #toUnsignedString(long, int)
+     * @since 1.8
+     */
+    public static String toUnsignedString(long i) {
+        return toUnsignedString(i, 10);
+    }
+
+    /**
+     * Places characters representing the integer i into the
+     * character array buf. The characters are placed into
+     * the buffer backwards starting with the least significant
+     * digit at the specified index (exclusive), and working
+     * backwards from there.
+     *
+     * Will fail if i == Long.MIN_VALUE
+     */
+    static void getChars(long i, int index, char[] buf) {
+        long q;
+        int r;
+        int charPos = index;
+        char sign = 0;
+
+        if (i < 0) {
+            sign = '-';
+            i = -i;
+        }
+
+        // Get 2 digits/iteration using longs until quotient fits into an int
+        while (i > Integer.MAX_VALUE) {
+            q = i / 100;
+            // really: r = i - (q * 100);
+            r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+            i = q;
+            buf[--charPos] = Integer.DigitOnes[r];
+            buf[--charPos] = Integer.DigitTens[r];
+        }
+
+        // Get 2 digits/iteration using ints
+        int q2;
+        int i2 = (int)i;
+        while (i2 >= 65536) {
+            q2 = i2 / 100;
+            // really: r = i2 - (q * 100);
+            r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+            i2 = q2;
+            buf[--charPos] = Integer.DigitOnes[r];
+            buf[--charPos] = Integer.DigitTens[r];
+        }
+
+        // Fall thru to fast mode for smaller numbers
+        // assert(i2 <= 65536, i2);
+        for (;;) {
+            q2 = (i2 * 52429) >>> (16+3);
+            r = i2 - ((q2 << 3) + (q2 << 1));  // r = i2-(q2*10) ...
+            buf[--charPos] = Integer.digits[r];
+            i2 = q2;
+            if (i2 == 0) break;
+        }
+        if (sign != 0) {
+            buf[--charPos] = sign;
+        }
+    }
+
+    // Requires positive x
+    static int stringSize(long x) {
+        long p = 10;
+        for (int i=1; i<19; i++) {
+            if (x < p)
+                return i;
+            p = 10*p;
+        }
+        return 19;
+    }
+
+    /**
+     * Parses the string argument as a signed {@code long} in the
+     * radix specified by the second argument. The characters in the
+     * string must all be digits of the specified radix (as determined
+     * by whether {@link java.lang.Character#digit(char, int)} returns
+     * a nonnegative value), except that the first character may be an
+     * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
+     * indicate a negative value or an ASCII plus sign {@code '+'}
+     * ({@code '\u005Cu002B'}) to indicate a positive value. The
+     * resulting {@code long} value is returned.
+     *
+     * <p>Note that neither the character {@code L}
+     * ({@code '\u005Cu004C'}) nor {@code l}
+     * ({@code '\u005Cu006C'}) is permitted to appear at the end
+     * of the string as a type indicator, as would be permitted in
+     * Java programming language source code - except that either
+     * {@code L} or {@code l} may appear as a digit for a
+     * radix greater than or equal to 22.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     *
+     * <li>The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li>The {@code radix} is either smaller than {@link
+     * java.lang.Character#MIN_RADIX} or larger than {@link
+     * java.lang.Character#MAX_RADIX}.
+     *
+     * <li>Any character of the string is not a digit of the specified
+     * radix, except that the first character may be a minus sign
+     * {@code '-'} ({@code '\u005Cu002d'}) or plus sign {@code
+     * '+'} ({@code '\u005Cu002B'}) provided that the string is
+     * longer than length 1.
+     *
+     * <li>The value represented by the string is not a value of type
+     *      {@code long}.
+     * </ul>
+     *
+     * <p>Examples:
+     * <blockquote><pre>
+     * parseLong("0", 10) returns 0L
+     * parseLong("473", 10) returns 473L
+     * parseLong("+42", 10) returns 42L
+     * parseLong("-0", 10) returns 0L
+     * parseLong("-FF", 16) returns -255L
+     * parseLong("1100110", 2) returns 102L
+     * parseLong("99", 8) throws a NumberFormatException
+     * parseLong("Hazelnut", 10) throws a NumberFormatException
+     * parseLong("Hazelnut", 36) returns 1356099454469L
+     * </pre></blockquote>
+     *
+     * @param      s       the {@code String} containing the
+     *                     {@code long} representation to be parsed.
+     * @param      radix   the radix to be used while parsing {@code s}.
+     * @return     the {@code long} represented by the string argument in
+     *             the specified radix.
+     * @throws     NumberFormatException  if the string does not contain a
+     *             parsable {@code long}.
+     */
+    public static long parseLong(String s, int radix)
+              throws NumberFormatException
+    {
+        if (s == null) {
+            throw new NumberFormatException("null");
+        }
+
+        if (radix < Character.MIN_RADIX) {
+            throw new NumberFormatException("radix " + radix +
+                                            " less than Character.MIN_RADIX");
+        }
+        if (radix > Character.MAX_RADIX) {
+            throw new NumberFormatException("radix " + radix +
+                                            " greater than Character.MAX_RADIX");
+        }
+
+        long result = 0;
+        boolean negative = false;
+        int i = 0, len = s.length();
+        long limit = -Long.MAX_VALUE;
+        long multmin;
+        int digit;
+
+        if (len > 0) {
+            char firstChar = s.charAt(0);
+            if (firstChar < '0') { // Possible leading "+" or "-"
+                if (firstChar == '-') {
+                    negative = true;
+                    limit = Long.MIN_VALUE;
+                } else if (firstChar != '+')
+                    throw NumberFormatException.forInputString(s);
+
+                if (len == 1) // Cannot have lone "+" or "-"
+                    throw NumberFormatException.forInputString(s);
+                i++;
+            }
+            multmin = limit / radix;
+            while (i < len) {
+                // Accumulating negatively avoids surprises near MAX_VALUE
+                digit = Character.digit(s.charAt(i++),radix);
+                if (digit < 0) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                if (result < multmin) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                result *= radix;
+                if (result < limit + digit) {
+                    throw NumberFormatException.forInputString(s);
+                }
+                result -= digit;
+            }
+        } else {
+            throw NumberFormatException.forInputString(s);
+        }
+        return negative ? result : -result;
+    }
+
+    /**
+     * Parses the string argument as a signed decimal {@code long}.
+     * The characters in the string must all be decimal digits, except
+     * that the first character may be an ASCII minus sign {@code '-'}
+     * ({@code \u005Cu002D'}) to indicate a negative value or an
+     * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+     * indicate a positive value. The resulting {@code long} value is
+     * returned, exactly as if the argument and the radix {@code 10}
+     * were given as arguments to the {@link
+     * #parseLong(java.lang.String, int)} method.
+     *
+     * <p>Note that neither the character {@code L}
+     * ({@code '\u005Cu004C'}) nor {@code l}
+     * ({@code '\u005Cu006C'}) is permitted to appear at the end
+     * of the string as a type indicator, as would be permitted in
+     * Java programming language source code.
+     *
+     * @param      s   a {@code String} containing the {@code long}
+     *             representation to be parsed
+     * @return     the {@code long} represented by the argument in
+     *             decimal.
+     * @throws     NumberFormatException  if the string does not contain a
+     *             parsable {@code long}.
+     */
+    public static long parseLong(String s) throws NumberFormatException {
+        return parseLong(s, 10);
+    }
+
+    /**
+     * Parses the string argument as an unsigned {@code long} in the
+     * radix specified by the second argument.  An unsigned integer
+     * maps the values usually associated with negative numbers to
+     * positive numbers larger than {@code MAX_VALUE}.
+     *
+     * The characters in the string must all be digits of the
+     * specified radix (as determined by whether {@link
+     * java.lang.Character#digit(char, int)} returns a nonnegative
+     * value), except that the first character may be an ASCII plus
+     * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
+     * integer value is returned.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     * <li>The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li>The radix is either smaller than
+     * {@link java.lang.Character#MIN_RADIX} or
+     * larger than {@link java.lang.Character#MAX_RADIX}.
+     *
+     * <li>Any character of the string is not a digit of the specified
+     * radix, except that the first character may be a plus sign
+     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+     * string is longer than length 1.
+     *
+     * <li>The value represented by the string is larger than the
+     * largest unsigned {@code long}, 2<sup>64</sup>-1.
+     *
+     * </ul>
+     *
+     *
+     * @param      s   the {@code String} containing the unsigned integer
+     *                  representation to be parsed
+     * @param      radix   the radix to be used while parsing {@code s}.
+     * @return     the unsigned {@code long} represented by the string
+     *             argument in the specified radix.
+     * @throws     NumberFormatException if the {@code String}
+     *             does not contain a parsable {@code long}.
+     * @since 1.8
+     */
+    public static long parseUnsignedLong(String s, int radix)
+                throws NumberFormatException {
+        if (s == null)  {
+            throw new NumberFormatException("null");
+        }
+
+        int len = s.length();
+        if (len > 0) {
+            char firstChar = s.charAt(0);
+            if (firstChar == '-') {
+                throw new
+                    NumberFormatException(String.format("Illegal leading minus sign " +
+                                                       "on unsigned string %s.", s));
+            } else {
+                if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
+                    (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
+                    return parseLong(s, radix);
+                }
+
+                // No need for range checks on len due to testing above.
+                long first = parseLong(s.substring(0, len - 1), radix);
+                int second = Character.digit(s.charAt(len - 1), radix);
+                if (second < 0) {
+                    throw new NumberFormatException("Bad digit at end of " + s);
+                }
+                long result = first * radix + second;
+                if (compareUnsigned(result, first) < 0) {
+                    /*
+                     * The maximum unsigned value, (2^64)-1, takes at
+                     * most one more digit to represent than the
+                     * maximum signed value, (2^63)-1.  Therefore,
+                     * parsing (len - 1) digits will be appropriately
+                     * in-range of the signed parsing.  In other
+                     * words, if parsing (len -1) digits overflows
+                     * signed parsing, parsing len digits will
+                     * certainly overflow unsigned parsing.
+                     *
+                     * The compareUnsigned check above catches
+                     * situations where an unsigned overflow occurs
+                     * incorporating the contribution of the final
+                     * digit.
+                     */
+                    throw new NumberFormatException(String.format("String value %s exceeds " +
+                                                                  "range of unsigned long.", s));
+                }
+                return result;
+            }
+        } else {
+            throw NumberFormatException.forInputString(s);
+        }
+    }
+
+    /**
+     * Parses the string argument as an unsigned decimal {@code long}. The
+     * characters in the string must all be decimal digits, except
+     * that the first character may be an an ASCII plus sign {@code
+     * '+'} ({@code '\u005Cu002B'}). The resulting integer value
+     * is returned, exactly as if the argument and the radix 10 were
+     * given as arguments to the {@link
+     * #parseUnsignedLong(java.lang.String, int)} method.
+     *
+     * @param s   a {@code String} containing the unsigned {@code long}
+     *            representation to be parsed
+     * @return    the unsigned {@code long} value represented by the decimal string argument
+     * @throws    NumberFormatException  if the string does not contain a
+     *            parsable unsigned integer.
+     * @since 1.8
+     */
+    public static long parseUnsignedLong(String s) throws NumberFormatException {
+        return parseUnsignedLong(s, 10);
+    }
+
+    /**
+     * Returns a {@code Long} object holding the value
+     * extracted from the specified {@code String} when parsed
+     * with the radix given by the second argument.  The first
+     * argument is interpreted as representing a signed
+     * {@code long} in the radix specified by the second
+     * argument, exactly as if the arguments were given to the {@link
+     * #parseLong(java.lang.String, int)} method. The result is a
+     * {@code Long} object that represents the {@code long}
+     * value specified by the string.
+     *
+     * <p>In other words, this method returns a {@code Long} object equal
+     * to the value of:
+     *
+     * <blockquote>
+     *  {@code new Long(Long.parseLong(s, radix))}
+     * </blockquote>
+     *
+     * @param      s       the string to be parsed
+     * @param      radix   the radix to be used in interpreting {@code s}
+     * @return     a {@code Long} object holding the value
+     *             represented by the string argument in the specified
+     *             radix.
+     * @throws     NumberFormatException  If the {@code String} does not
+     *             contain a parsable {@code long}.
+     */
+    public static Long valueOf(String s, int radix) throws NumberFormatException {
+        return Long.valueOf(parseLong(s, radix));
+    }
+
+    /**
+     * Returns a {@code Long} object holding the value
+     * of the specified {@code String}. The argument is
+     * interpreted as representing a signed decimal {@code long},
+     * exactly as if the argument were given to the {@link
+     * #parseLong(java.lang.String)} method. The result is a
+     * {@code Long} object that represents the integer value
+     * specified by the string.
+     *
+     * <p>In other words, this method returns a {@code Long} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     *  {@code new Long(Long.parseLong(s))}
+     * </blockquote>
+     *
+     * @param      s   the string to be parsed.
+     * @return     a {@code Long} object holding the value
+     *             represented by the string argument.
+     * @throws     NumberFormatException  If the string cannot be parsed
+     *             as a {@code long}.
+     */
+    public static Long valueOf(String s) throws NumberFormatException
+    {
+        return Long.valueOf(parseLong(s, 10));
+    }
+
+    private static class LongCache {
+        private LongCache(){}
+
+        static final Long cache[] = new Long[-(-128) + 127 + 1];
+
+        static {
+            for(int i = 0; i < cache.length; i++)
+                cache[i] = new Long(i - 128);
+        }
+    }
+
+    /**
+     * Returns a {@code Long} instance representing the specified
+     * {@code long} value.
+     * If a new {@code Long} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Long(long)}, as this method is likely to yield
+     * significantly better space and time performance by caching
+     * frequently requested values.
+     *
+     * Note that unlike the {@linkplain Integer#valueOf(int)
+     * corresponding method} in the {@code Integer} class, this method
+     * is <em>not</em> required to cache values within a particular
+     * range.
+     *
+     * @param  l a long value.
+     * @return a {@code Long} instance representing {@code l}.
+     * @since  1.5
+     */
+    public static Long valueOf(long l) {
+        final int offset = 128;
+        if (l >= -128 && l <= 127) { // will cache
+            return LongCache.cache[(int)l + offset];
+        }
+        return new Long(l);
+    }
+
+    /**
+     * Decodes a {@code String} into a {@code Long}.
+     * Accepts decimal, hexadecimal, and octal numbers given by the
+     * following grammar:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>DecodableString:</i>
+     * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+     *
+     * <dt><i>Sign:</i>
+     * <dd>{@code -}
+     * <dd>{@code +}
+     * </dl>
+     * </blockquote>
+     *
+     * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+     * are as defined in section 3.10.1 of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     *
+     * <p>The sequence of characters following an optional
+     * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+     * "{@code #}", or leading zero) is parsed as by the {@code
+     * Long.parseLong} method with the indicated radix (10, 16, or 8).
+     * This sequence of characters must represent a positive value or
+     * a {@link NumberFormatException} will be thrown.  The result is
+     * negated if first character of the specified {@code String} is
+     * the minus sign.  No whitespace characters are permitted in the
+     * {@code String}.
+     *
+     * @param     nm the {@code String} to decode.
+     * @return    a {@code Long} object holding the {@code long}
+     *            value represented by {@code nm}
+     * @throws    NumberFormatException  if the {@code String} does not
+     *            contain a parsable {@code long}.
+     * @see java.lang.Long#parseLong(String, int)
+     * @since 1.2
+     */
+    public static Long decode(String nm) throws NumberFormatException {
+        int radix = 10;
+        int index = 0;
+        boolean negative = false;
+        Long result;
+
+        if (nm.length() == 0)
+            throw new NumberFormatException("Zero length string");
+        char firstChar = nm.charAt(0);
+        // Handle sign, if present
+        if (firstChar == '-') {
+            negative = true;
+            index++;
+        } else if (firstChar == '+')
+            index++;
+
+        // Handle radix specifier, if present
+        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
+            index += 2;
+            radix = 16;
+        }
+        else if (nm.startsWith("#", index)) {
+            index ++;
+            radix = 16;
+        }
+        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
+            index ++;
+            radix = 8;
+        }
+
+        if (nm.startsWith("-", index) || nm.startsWith("+", index))
+            throw new NumberFormatException("Sign character in wrong position");
+
+        try {
+            result = Long.valueOf(nm.substring(index), radix);
+            result = negative ? Long.valueOf(-result.longValue()) : result;
+        } catch (NumberFormatException e) {
+            // If number is Long.MIN_VALUE, we'll end up here. The next line
+            // handles this case, and causes any genuine format error to be
+            // rethrown.
+            String constant = negative ? ("-" + nm.substring(index))
+                                       : nm.substring(index);
+            result = Long.valueOf(constant, radix);
+        }
+        return result;
+    }
+
+    /**
+     * The value of the {@code Long}.
+     *
+     * @serial
+     */
+    private final long value;
+
+    /**
+     * Constructs a newly allocated {@code Long} object that
+     * represents the specified {@code long} argument.
+     *
+     * @param   value   the value to be represented by the
+     *          {@code Long} object.
+     */
+    public Long(long value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Long} object that
+     * represents the {@code long} value indicated by the
+     * {@code String} parameter. The string is converted to a
+     * {@code long} value in exactly the manner used by the
+     * {@code parseLong} method for radix 10.
+     *
+     * @param      s   the {@code String} to be converted to a
+     *             {@code Long}.
+     * @throws     NumberFormatException  if the {@code String} does not
+     *             contain a parsable {@code long}.
+     * @see        java.lang.Long#parseLong(java.lang.String, int)
+     */
+    public Long(String s) throws NumberFormatException {
+        this.value = parseLong(s, 10);
+    }
+
+    /**
+     * Returns the value of this {@code Long} as a {@code byte} after
+     * a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public byte byteValue() {
+        return (byte)value;
+    }
+
+    /**
+     * Returns the value of this {@code Long} as a {@code short} after
+     * a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public short shortValue() {
+        return (short)value;
+    }
+
+    /**
+     * Returns the value of this {@code Long} as an {@code int} after
+     * a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public int intValue() {
+        return (int)value;
+    }
+
+    /**
+     * Returns the value of this {@code Long} as a
+     * {@code long} value.
+     */
+    public long longValue() {
+        return value;
+    }
+
+    /**
+     * Returns the value of this {@code Long} as a {@code float} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public float floatValue() {
+        return (float)value;
+    }
+
+    /**
+     * Returns the value of this {@code Long} as a {@code double}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public double doubleValue() {
+        return (double)value;
+    }
+
+    /**
+     * Returns a {@code String} object representing this
+     * {@code Long}'s value.  The value is converted to signed
+     * decimal representation and returned as a string, exactly as if
+     * the {@code long} value were given as an argument to the
+     * {@link java.lang.Long#toString(long)} method.
+     *
+     * @return  a string representation of the value of this object in
+     *          base&nbsp;10.
+     */
+    public String toString() {
+        return toString(value);
+    }
+
+    /**
+     * Returns a hash code for this {@code Long}. The result is
+     * the exclusive OR of the two halves of the primitive
+     * {@code long} value held by this {@code Long}
+     * object. That is, the hashcode is the value of the expression:
+     *
+     * <blockquote>
+     *  {@code (int)(this.longValue()^(this.longValue()>>>32))}
+     * </blockquote>
+     *
+     * @return  a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return Long.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code long} value; compatible with
+     * {@code Long.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code long} value.
+     * @since 1.8
+     */
+    public static int hashCode(long value) {
+        return (int)(value ^ (value >>> 32));
+    }
+
+    /**
+     * Compares this object to the specified object.  The result is
+     * {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Long} object that
+     * contains the same {@code long} value as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Long) {
+            return value == ((Long)obj).longValue();
+        }
+        return false;
+    }
+
+    /**
+     * Determines the {@code long} value of the system property
+     * with the specified name.
+     *
+     * <p>The first argument is treated as the name of a system
+     * property.  System properties are accessible through the {@link
+     * java.lang.System#getProperty(java.lang.String)} method. The
+     * string value of this property is then interpreted as a {@code
+     * long} value using the grammar supported by {@link Long#decode decode}
+     * and a {@code Long} object representing this value is returned.
+     *
+     * <p>If there is no property with the specified name, if the
+     * specified name is empty or {@code null}, or if the property
+     * does not have the correct numeric format, then {@code null} is
+     * returned.
+     *
+     * <p>In other words, this method returns a {@code Long} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     *  {@code getLong(nm, null)}
+     * </blockquote>
+     *
+     * @param   nm   property name.
+     * @return  the {@code Long} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     java.lang.System#getProperty(java.lang.String)
+     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Long getLong(String nm) {
+        return getLong(nm, null);
+    }
+
+    /**
+     * Determines the {@code long} value of the system property
+     * with the specified name.
+     *
+     * <p>The first argument is treated as the name of a system
+     * property.  System properties are accessible through the {@link
+     * java.lang.System#getProperty(java.lang.String)} method. The
+     * string value of this property is then interpreted as a {@code
+     * long} value using the grammar supported by {@link Long#decode decode}
+     * and a {@code Long} object representing this value is returned.
+     *
+     * <p>The second argument is the default value. A {@code Long} object
+     * that represents the value of the second argument is returned if there
+     * is no property of the specified name, if the property does not have
+     * the correct numeric format, or if the specified name is empty or null.
+     *
+     * <p>In other words, this method returns a {@code Long} object equal
+     * to the value of:
+     *
+     * <blockquote>
+     *  {@code getLong(nm, new Long(val))}
+     * </blockquote>
+     *
+     * but in practice it may be implemented in a manner such as:
+     *
+     * <blockquote><pre>
+     * Long result = getLong(nm, null);
+     * return (result == null) ? new Long(val) : result;
+     * </pre></blockquote>
+     *
+     * to avoid the unnecessary allocation of a {@code Long} object when
+     * the default value is not needed.
+     *
+     * @param   nm    property name.
+     * @param   val   default value.
+     * @return  the {@code Long} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     java.lang.System#getProperty(java.lang.String)
+     * @see     java.lang.System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Long getLong(String nm, long val) {
+        Long result = Long.getLong(nm, null);
+        return (result == null) ? Long.valueOf(val) : result;
+    }
+
+    /**
+     * Returns the {@code long} value of the system property with
+     * the specified name.  The first argument is treated as the name
+     * of a system property.  System properties are accessible through
+     * the {@link java.lang.System#getProperty(java.lang.String)}
+     * method. The string value of this property is then interpreted
+     * as a {@code long} value, as per the
+     * {@link Long#decode decode} method, and a {@code Long} object
+     * representing this value is returned; in summary:
+     *
+     * <ul>
+     * <li>If the property value begins with the two ASCII characters
+     * {@code 0x} or the ASCII character {@code #}, not followed by
+     * a minus sign, then the rest of it is parsed as a hexadecimal integer
+     * exactly as for the method {@link #valueOf(java.lang.String, int)}
+     * with radix 16.
+     * <li>If the property value begins with the ASCII character
+     * {@code 0} followed by another character, it is parsed as
+     * an octal integer exactly as by the method {@link
+     * #valueOf(java.lang.String, int)} with radix 8.
+     * <li>Otherwise the property value is parsed as a decimal
+     * integer exactly as by the method
+     * {@link #valueOf(java.lang.String, int)} with radix 10.
+     * </ul>
+     *
+     * <p>Note that, in every case, neither {@code L}
+     * ({@code '\u005Cu004C'}) nor {@code l}
+     * ({@code '\u005Cu006C'}) is permitted to appear at the end
+     * of the property value as a type indicator, as would be
+     * permitted in Java programming language source code.
+     *
+     * <p>The second argument is the default value. The default value is
+     * returned if there is no property of the specified name, if the
+     * property does not have the correct numeric format, or if the
+     * specified name is empty or {@code null}.
+     *
+     * @param   nm   property name.
+     * @param   val   default value.
+     * @return  the {@code Long} value of the property.
+     * @throws  SecurityException for the same reasons as
+     *          {@link System#getProperty(String) System.getProperty}
+     * @see     System#getProperty(java.lang.String)
+     * @see     System#getProperty(java.lang.String, java.lang.String)
+     */
+    public static Long getLong(String nm, Long val) {
+        String v = null;
+        try {
+            v = System.getProperty(nm);
+        } catch (IllegalArgumentException | NullPointerException e) {
+        }
+        if (v != null) {
+            try {
+                return Long.decode(v);
+            } catch (NumberFormatException e) {
+            }
+        }
+        return val;
+    }
+
+    /**
+     * Compares two {@code Long} objects numerically.
+     *
+     * @param   anotherLong   the {@code Long} to be compared.
+     * @return  the value {@code 0} if this {@code Long} is
+     *          equal to the argument {@code Long}; a value less than
+     *          {@code 0} if this {@code Long} is numerically less
+     *          than the argument {@code Long}; and a value greater
+     *          than {@code 0} if this {@code Long} is numerically
+     *           greater than the argument {@code Long} (signed
+     *           comparison).
+     * @since   1.2
+     */
+    public int compareTo(Long anotherLong) {
+        return compare(this.value, anotherLong.value);
+    }
+
+    /**
+     * Compares two {@code long} values numerically.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Long.valueOf(x).compareTo(Long.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code long} to compare
+     * @param  y the second {@code long} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code x < y}; and
+     *         a value greater than {@code 0} if {@code x > y}
+     * @since 1.7
+     */
+    public static int compare(long x, long y) {
+        return (x < y) ? -1 : ((x == y) ? 0 : 1);
+    }
+
+    /**
+     * Compares two {@code long} values numerically treating the values
+     * as unsigned.
+     *
+     * @param  x the first {@code long} to compare
+     * @param  y the second {@code long} to compare
+     * @return the value {@code 0} if {@code x == y}; a value less
+     *         than {@code 0} if {@code x < y} as unsigned values; and
+     *         a value greater than {@code 0} if {@code x > y} as
+     *         unsigned values
+     * @since 1.8
+     */
+    public static int compareUnsigned(long x, long y) {
+        return compare(x + MIN_VALUE, y + MIN_VALUE);
+    }
+
+
+    /**
+     * Returns the unsigned quotient of dividing the first argument by
+     * the second where each argument and the result is interpreted as
+     * an unsigned value.
+     *
+     * <p>Note that in two's complement arithmetic, the three other
+     * basic arithmetic operations of add, subtract, and multiply are
+     * bit-wise identical if the two operands are regarded as both
+     * being signed or both being unsigned.  Therefore separate {@code
+     * addUnsigned}, etc. methods are not provided.
+     *
+     * @param dividend the value to be divided
+     * @param divisor the value doing the dividing
+     * @return the unsigned quotient of the first argument divided by
+     * the second argument
+     * @see #remainderUnsigned
+     * @since 1.8
+     */
+    public static long divideUnsigned(long dividend, long divisor) {
+        if (divisor < 0L) { // signed comparison
+            // Answer must be 0 or 1 depending on relative magnitude
+            // of dividend and divisor.
+            return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;
+        }
+
+        if (dividend > 0) //  Both inputs non-negative
+            return dividend/divisor;
+        else {
+            /*
+             * For simple code, leveraging BigInteger.  Longer and faster
+             * code written directly in terms of operations on longs is
+             * possible; see "Hacker's Delight" for divide and remainder
+             * algorithms.
+             */
+            return toUnsignedBigInteger(dividend).
+                divide(toUnsignedBigInteger(divisor)).longValue();
+        }
+    }
+
+    /**
+     * Returns the unsigned remainder from dividing the first argument
+     * by the second where each argument and the result is interpreted
+     * as an unsigned value.
+     *
+     * @param dividend the value to be divided
+     * @param divisor the value doing the dividing
+     * @return the unsigned remainder of the first argument divided by
+     * the second argument
+     * @see #divideUnsigned
+     * @since 1.8
+     */
+    public static long remainderUnsigned(long dividend, long divisor) {
+        if (dividend > 0 && divisor > 0) { // signed comparisons
+            return dividend % divisor;
+        } else {
+            if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor
+                return dividend;
+            else
+                return toUnsignedBigInteger(dividend).
+                    remainder(toUnsignedBigInteger(divisor)).longValue();
+        }
+    }
+
+    // Bit Twiddling
+
+    /**
+     * The number of bits used to represent a {@code long} value in two's
+     * complement binary form.
+     *
+     * @since 1.5
+     */
+    @Native public static final int SIZE = 64;
+
+    /**
+     * The number of bytes used to represent a {@code long} value in two's
+     * complement binary form.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * Returns a {@code long} value with at most a single one-bit, in the
+     * position of the highest-order ("leftmost") one-bit in the specified
+     * {@code long} value.  Returns zero if the specified value has no
+     * one-bits in its two's complement binary representation, that is, if it
+     * is equal to zero.
+     *
+     * @param i the value whose highest one bit is to be computed
+     * @return a {@code long} value with a single one-bit, in the position
+     *     of the highest-order one-bit in the specified value, or zero if
+     *     the specified value is itself equal to zero.
+     * @since 1.5
+     */
+    public static long highestOneBit(long i) {
+        // HD, Figure 3-1
+        i |= (i >>  1);
+        i |= (i >>  2);
+        i |= (i >>  4);
+        i |= (i >>  8);
+        i |= (i >> 16);
+        i |= (i >> 32);
+        return i - (i >>> 1);
+    }
+
+    /**
+     * Returns a {@code long} value with at most a single one-bit, in the
+     * position of the lowest-order ("rightmost") one-bit in the specified
+     * {@code long} value.  Returns zero if the specified value has no
+     * one-bits in its two's complement binary representation, that is, if it
+     * is equal to zero.
+     *
+     * @param i the value whose lowest one bit is to be computed
+     * @return a {@code long} value with a single one-bit, in the position
+     *     of the lowest-order one-bit in the specified value, or zero if
+     *     the specified value is itself equal to zero.
+     * @since 1.5
+     */
+    public static long lowestOneBit(long i) {
+        // HD, Section 2-1
+        return i & -i;
+    }
+
+    /**
+     * Returns the number of zero bits preceding the highest-order
+     * ("leftmost") one-bit in the two's complement binary representation
+     * of the specified {@code long} value.  Returns 64 if the
+     * specified value has no one-bits in its two's complement representation,
+     * in other words if it is equal to zero.
+     *
+     * <p>Note that this method is closely related to the logarithm base 2.
+     * For all positive {@code long} values x:
+     * <ul>
+     * <li>floor(log<sub>2</sub>(x)) = {@code 63 - numberOfLeadingZeros(x)}
+     * <li>ceil(log<sub>2</sub>(x)) = {@code 64 - numberOfLeadingZeros(x - 1)}
+     * </ul>
+     *
+     * @param i the value whose number of leading zeros is to be computed
+     * @return the number of zero bits preceding the highest-order
+     *     ("leftmost") one-bit in the two's complement binary representation
+     *     of the specified {@code long} value, or 64 if the value
+     *     is equal to zero.
+     * @since 1.5
+     */
+    public static int numberOfLeadingZeros(long i) {
+        // HD, Figure 5-6
+         if (i == 0)
+            return 64;
+        int n = 1;
+        int x = (int)(i >>> 32);
+        if (x == 0) { n += 32; x = (int)i; }
+        if (x >>> 16 == 0) { n += 16; x <<= 16; }
+        if (x >>> 24 == 0) { n +=  8; x <<=  8; }
+        if (x >>> 28 == 0) { n +=  4; x <<=  4; }
+        if (x >>> 30 == 0) { n +=  2; x <<=  2; }
+        n -= x >>> 31;
+        return n;
+    }
+
+    /**
+     * Returns the number of zero bits following the lowest-order ("rightmost")
+     * one-bit in the two's complement binary representation of the specified
+     * {@code long} value.  Returns 64 if the specified value has no
+     * one-bits in its two's complement representation, in other words if it is
+     * equal to zero.
+     *
+     * @param i the value whose number of trailing zeros is to be computed
+     * @return the number of zero bits following the lowest-order ("rightmost")
+     *     one-bit in the two's complement binary representation of the
+     *     specified {@code long} value, or 64 if the value is equal
+     *     to zero.
+     * @since 1.5
+     */
+    public static int numberOfTrailingZeros(long i) {
+        // HD, Figure 5-14
+        int x, y;
+        if (i == 0) return 64;
+        int n = 63;
+        y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
+        y = x <<16; if (y != 0) { n = n -16; x = y; }
+        y = x << 8; if (y != 0) { n = n - 8; x = y; }
+        y = x << 4; if (y != 0) { n = n - 4; x = y; }
+        y = x << 2; if (y != 0) { n = n - 2; x = y; }
+        return n - ((x << 1) >>> 31);
+    }
+
+    /**
+     * Returns the number of one-bits in the two's complement binary
+     * representation of the specified {@code long} value.  This function is
+     * sometimes referred to as the <i>population count</i>.
+     *
+     * @param i the value whose bits are to be counted
+     * @return the number of one-bits in the two's complement binary
+     *     representation of the specified {@code long} value.
+     * @since 1.5
+     */
+     public static int bitCount(long i) {
+        // HD, Figure 5-14
+        i = i - ((i >>> 1) & 0x5555555555555555L);
+        i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
+        i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
+        i = i + (i >>> 8);
+        i = i + (i >>> 16);
+        i = i + (i >>> 32);
+        return (int)i & 0x7f;
+     }
+
+    /**
+     * Returns the value obtained by rotating the two's complement binary
+     * representation of the specified {@code long} value left by the
+     * specified number of bits.  (Bits shifted out of the left hand, or
+     * high-order, side reenter on the right, or low-order.)
+     *
+     * <p>Note that left rotation with a negative distance is equivalent to
+     * right rotation: {@code rotateLeft(val, -distance) == rotateRight(val,
+     * distance)}.  Note also that rotation by any multiple of 64 is a
+     * no-op, so all but the last six bits of the rotation distance can be
+     * ignored, even if the distance is negative: {@code rotateLeft(val,
+     * distance) == rotateLeft(val, distance & 0x3F)}.
+     *
+     * @param i the value whose bits are to be rotated left
+     * @param distance the number of bit positions to rotate left
+     * @return the value obtained by rotating the two's complement binary
+     *     representation of the specified {@code long} value left by the
+     *     specified number of bits.
+     * @since 1.5
+     */
+    public static long rotateLeft(long i, int distance) {
+        return (i << distance) | (i >>> -distance);
+    }
+
+    /**
+     * Returns the value obtained by rotating the two's complement binary
+     * representation of the specified {@code long} value right by the
+     * specified number of bits.  (Bits shifted out of the right hand, or
+     * low-order, side reenter on the left, or high-order.)
+     *
+     * <p>Note that right rotation with a negative distance is equivalent to
+     * left rotation: {@code rotateRight(val, -distance) == rotateLeft(val,
+     * distance)}.  Note also that rotation by any multiple of 64 is a
+     * no-op, so all but the last six bits of the rotation distance can be
+     * ignored, even if the distance is negative: {@code rotateRight(val,
+     * distance) == rotateRight(val, distance & 0x3F)}.
+     *
+     * @param i the value whose bits are to be rotated right
+     * @param distance the number of bit positions to rotate right
+     * @return the value obtained by rotating the two's complement binary
+     *     representation of the specified {@code long} value right by the
+     *     specified number of bits.
+     * @since 1.5
+     */
+    public static long rotateRight(long i, int distance) {
+        return (i >>> distance) | (i << -distance);
+    }
+
+    /**
+     * Returns the value obtained by reversing the order of the bits in the
+     * two's complement binary representation of the specified {@code long}
+     * value.
+     *
+     * @param i the value to be reversed
+     * @return the value obtained by reversing order of the bits in the
+     *     specified {@code long} value.
+     * @since 1.5
+     */
+    public static long reverse(long i) {
+        // HD, Figure 7-1
+        i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
+        i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
+        i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
+        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
+        i = (i << 48) | ((i & 0xffff0000L) << 16) |
+            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
+        return i;
+    }
+
+    /**
+     * Returns the signum function of the specified {@code long} value.  (The
+     * return value is -1 if the specified value is negative; 0 if the
+     * specified value is zero; and 1 if the specified value is positive.)
+     *
+     * @param i the value whose signum is to be computed
+     * @return the signum function of the specified {@code long} value.
+     * @since 1.5
+     */
+    public static int signum(long i) {
+        // HD, Section 2-7
+        return (int) ((i >> 63) | (-i >>> 63));
+    }
+
+    /**
+     * Returns the value obtained by reversing the order of the bytes in the
+     * two's complement representation of the specified {@code long} value.
+     *
+     * @param i the value whose bytes are to be reversed
+     * @return the value obtained by reversing the bytes in the specified
+     *     {@code long} value.
+     * @since 1.5
+     */
+    public static long reverseBytes(long i) {
+        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
+        return (i << 48) | ((i & 0xffff0000L) << 16) |
+            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
+    }
+
+    /**
+     * Adds two {@code long} values together as per the + operator.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the sum of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static long sum(long a, long b) {
+        return a + b;
+    }
+
+    /**
+     * Returns the greater of two {@code long} values
+     * as if by calling {@link Math#max(long, long) Math.max}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the greater of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static long max(long a, long b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code long} values
+     * as if by calling {@link Math#min(long, long) Math.min}.
+     *
+     * @param a the first operand
+     * @param b the second operand
+     * @return the smaller of {@code a} and {@code b}
+     * @see java.util.function.BinaryOperator
+     * @since 1.8
+     */
+    public static long min(long a, long b) {
+        return Math.min(a, b);
+    }
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    @Native private static final long serialVersionUID = 4290774380558885855L;
+}
diff --git a/java/lang/Math.annotated.java b/java/lang/Math.annotated.java
new file mode 100644
index 0000000..46fae4e
--- /dev/null
+++ b/java/lang/Math.annotated.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.util.Random;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Math {
+
+Math() { throw new RuntimeException("Stub!"); }
+
+public static native double sin(double a);
+
+public static native double cos(double a);
+
+public static native double tan(double a);
+
+public static native double asin(double a);
+
+public static native double acos(double a);
+
+public static native double atan(double a);
+
+public static double toRadians(double angdeg) { throw new RuntimeException("Stub!"); }
+
+public static double toDegrees(double angrad) { throw new RuntimeException("Stub!"); }
+
+public static native double exp(double a);
+
+public static native double log(double a);
+
+public static native double log10(double a);
+
+public static native double sqrt(double a);
+
+public static native double cbrt(double a);
+
+public static native double IEEEremainder(double f1, double f2);
+
+public static native double ceil(double a);
+
+public static native double floor(double a);
+
+public static native double rint(double a);
+
+public static native double atan2(double y, double x);
+
+public static native double pow(double a, double b);
+
+public static int round(float a) { throw new RuntimeException("Stub!"); }
+
+public static long round(double a) { throw new RuntimeException("Stub!"); }
+
+public static double random() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static long randomLongInternal() { throw new RuntimeException("Stub!"); }
+
+public static int addExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long addExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int subtractExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long subtractExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int multiplyExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long multiplyExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int incrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long incrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int decrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long decrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int negateExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long negateExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int toIntExact(long value) { throw new RuntimeException("Stub!"); }
+
+public static int floorDiv(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorDiv(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int floorMod(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorMod(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int abs(int a) { throw new RuntimeException("Stub!"); }
+
+public static long abs(long a) { throw new RuntimeException("Stub!"); }
+
+public static float abs(float a) { throw new RuntimeException("Stub!"); }
+
+public static double abs(double a) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double ulp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float ulp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double signum(double d) { throw new RuntimeException("Stub!"); }
+
+public static float signum(float f) { throw new RuntimeException("Stub!"); }
+
+public static native double sinh(double x);
+
+public static native double cosh(double x);
+
+public static native double tanh(double x);
+
+public static native double hypot(double x, double y);
+
+public static native double expm1(double x);
+
+public static native double log1p(double x);
+
+public static double copySign(double magnitude, double sign) { throw new RuntimeException("Stub!"); }
+
+public static float copySign(float magnitude, float sign) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(float f) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(double d) { throw new RuntimeException("Stub!"); }
+
+public static double nextAfter(double start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static float nextAfter(float start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static double nextUp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextUp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double nextDown(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextDown(float f) { throw new RuntimeException("Stub!"); }
+
+public static double scalb(double d, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static float scalb(float f, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static final double E = 2.718281828459045;
+
+public static final double PI = 3.141592653589793;
+}
+
diff --git a/java/lang/Math.java b/java/lang/Math.java
new file mode 100644
index 0000000..17cbf6d
--- /dev/null
+++ b/java/lang/Math.java
@@ -0,0 +1,2397 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+import dalvik.annotation.optimization.CriticalNative;
+import java.util.Random;
+
+import sun.misc.FloatConsts;
+import sun.misc.DoubleConsts;
+
+// Android-note: Document that the results from Math are based on libm's behavior.
+// For performance, Android implements many of the methods in this class in terms of the underlying
+// OS's libm functions. libm has well-defined behavior for special cases. Where known these are
+// marked with the tag above and the documentation has been modified as needed.
+/**
+ * The class {@code Math} contains methods for performing basic
+ * numeric operations such as the elementary exponential, logarithm,
+ * square root, and trigonometric functions.
+ *
+ * <p>Unlike some of the numeric methods of class
+ * {@code StrictMath}, all implementations of the equivalent
+ * functions of class {@code Math} are not defined to return the
+ * bit-for-bit same results.  This relaxation permits
+ * better-performing implementations where strict reproducibility is
+ * not required.
+ *
+ * <p>By default many of the {@code Math} methods simply call
+ * the equivalent method in {@code StrictMath} for their
+ * implementation.  Code generators are encouraged to use
+ * platform-specific native libraries or microprocessor instructions,
+ * where available, to provide higher-performance implementations of
+ * {@code Math} methods.  Such higher-performance
+ * implementations still must conform to the specification for
+ * {@code Math}.
+ *
+ * <p>The quality of implementation specifications concern two
+ * properties, accuracy of the returned result and monotonicity of the
+ * method.  Accuracy of the floating-point {@code Math} methods is
+ * measured in terms of <i>ulps</i>, units in the last place.  For a
+ * given floating-point format, an {@linkplain #ulp(double) ulp} of a
+ * specific real number value is the distance between the two
+ * floating-point values bracketing that numerical value.  When
+ * discussing the accuracy of a method as a whole rather than at a
+ * specific argument, the number of ulps cited is for the worst-case
+ * error at any argument.  If a method always has an error less than
+ * 0.5 ulps, the method always returns the floating-point number
+ * nearest the exact result; such a method is <i>correctly
+ * rounded</i>.  A correctly rounded method is generally the best a
+ * floating-point approximation can be; however, it is impractical for
+ * many floating-point methods to be correctly rounded.  Instead, for
+ * the {@code Math} class, a larger error bound of 1 or 2 ulps is
+ * allowed for certain methods.  Informally, with a 1 ulp error bound,
+ * when the exact result is a representable number, the exact result
+ * should be returned as the computed result; otherwise, either of the
+ * two floating-point values which bracket the exact result may be
+ * returned.  For exact results large in magnitude, one of the
+ * endpoints of the bracket may be infinite.  Besides accuracy at
+ * individual arguments, maintaining proper relations between the
+ * method at different arguments is also important.  Therefore, most
+ * methods with more than 0.5 ulp errors are required to be
+ * <i>semi-monotonic</i>: whenever the mathematical function is
+ * non-decreasing, so is the floating-point approximation, likewise,
+ * whenever the mathematical function is non-increasing, so is the
+ * floating-point approximation.  Not all approximations that have 1
+ * ulp accuracy will automatically meet the monotonicity requirements.
+ *
+ * <p>
+ * The platform uses signed two's complement integer arithmetic with
+ * int and long primitive types.  The developer should choose
+ * the primitive type to ensure that arithmetic operations consistently
+ * produce correct results, which in some cases means the operations
+ * will not overflow the range of values of the computation.
+ * The best practice is to choose the primitive type and algorithm to avoid
+ * overflow. In cases where the size is {@code int} or {@code long} and
+ * overflow errors need to be detected, the methods {@code addExact},
+ * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * throw an {@code ArithmeticException} when the results overflow.
+ * For other arithmetic operations such as divide, absolute value,
+ * increment, decrement, and negation overflow occurs only with
+ * a specific minimum or maximum value and should be checked against
+ * the minimum or maximum as appropriate.
+ *
+ * @author  unascribed
+ * @author  Joseph D. Darcy
+ * @since   JDK1.0
+ */
+
+public final class Math {
+
+    // Android-changed: Numerous methods in this class are re-implemented in native for performance.
+    // Those methods are also annotated @CriticalNative.
+
+    /**
+     * Don't let anyone instantiate this class.
+     */
+    private Math() {}
+
+    /**
+     * The {@code double} value that is closer than any other to
+     * <i>e</i>, the base of the natural logarithms.
+     */
+    public static final double E = 2.7182818284590452354;
+
+    /**
+     * The {@code double} value that is closer than any other to
+     * <i>pi</i>, the ratio of the circumference of a circle to its
+     * diameter.
+     */
+    public static final double PI = 3.14159265358979323846;
+
+    /**
+     * Returns the trigonometric sine of an angle.  Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the
+     * result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   an angle, in radians.
+     * @return  the sine of the argument.
+     */
+    @CriticalNative
+    public static native double sin(double a);
+
+    /**
+     * Returns the trigonometric cosine of an angle. Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the
+     * result is NaN.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   an angle, in radians.
+     * @return  the cosine of the argument.
+     */
+    @CriticalNative
+    public static native double cos(double a);
+
+    /**
+     * Returns the trigonometric tangent of an angle.  Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the result
+     * is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   an angle, in radians.
+     * @return  the tangent of the argument.
+     */
+    @CriticalNative
+    public static native double tan(double a);
+
+    /**
+     * Returns the arc sine of a value; the returned angle is in the
+     * range -<i>pi</i>/2 through <i>pi</i>/2.  Special cases:
+     * <ul><li>If the argument is NaN or its absolute value is greater
+     * than 1, then the result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   the value whose arc sine is to be returned.
+     * @return  the arc sine of the argument.
+     */
+    @CriticalNative
+    public static native double asin(double a);
+
+    /**
+     * Returns the arc cosine of a value; the returned angle is in the
+     * range 0.0 through <i>pi</i>.  Special case:
+     * <ul><li>If the argument is NaN or its absolute value is greater
+     * than 1, then the result is NaN.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   the value whose arc cosine is to be returned.
+     * @return  the arc cosine of the argument.
+     */
+    @CriticalNative
+    public static native double acos(double a);
+
+    /**
+     * Returns the arc tangent of a value; the returned angle is in the
+     * range -<i>pi</i>/2 through <i>pi</i>/2.  Special cases:
+     * <ul><li>If the argument is NaN, then the result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   the value whose arc tangent is to be returned.
+     * @return  the arc tangent of the argument.
+     */
+    @CriticalNative
+    public static native double atan(double a);
+
+    /**
+     * Converts an angle measured in degrees to an approximately
+     * equivalent angle measured in radians.  The conversion from
+     * degrees to radians is generally inexact.
+     *
+     * @param   angdeg   an angle, in degrees
+     * @return  the measurement of the angle {@code angdeg}
+     *          in radians.
+     * @since   1.2
+     */
+    public static double toRadians(double angdeg) {
+        return angdeg / 180.0 * PI;
+    }
+
+    /**
+     * Converts an angle measured in radians to an approximately
+     * equivalent angle measured in degrees.  The conversion from
+     * radians to degrees is generally inexact; users should
+     * <i>not</i> expect {@code cos(toRadians(90.0))} to exactly
+     * equal {@code 0.0}.
+     *
+     * @param   angrad   an angle, in radians
+     * @return  the measurement of the angle {@code angrad}
+     *          in degrees.
+     * @since   1.2
+     */
+    public static double toDegrees(double angrad) {
+        return angrad * 180.0 / PI;
+    }
+
+    /**
+     * Returns Euler's number <i>e</i> raised to the power of a
+     * {@code double} value.  Special cases:
+     * <ul><li>If the argument is NaN, the result is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is negative infinity, then the result is
+     * positive zero.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   the exponent to raise <i>e</i> to.
+     * @return  the value <i>e</i><sup>{@code a}</sup>,
+     *          where <i>e</i> is the base of the natural logarithms.
+     */
+    @CriticalNative
+    public static native double exp(double a);
+
+    /**
+     * Returns the natural logarithm (base <i>e</i>) of a {@code double}
+     * value.  Special cases:
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is negative infinity.</ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   a value
+     * @return  the value ln&nbsp;{@code a}, the natural logarithm of
+     *          {@code a}.
+     */
+    @CriticalNative
+    public static native double log(double a);
+
+    /**
+     * Returns the base 10 logarithm of a {@code double} value.
+     * Special cases:
+     *
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is negative infinity.
+     * <li> If the argument is equal to 10<sup><i>n</i></sup> for
+     * integer <i>n</i>, then the result is <i>n</i>.
+     * </ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   a value
+     * @return  the base 10 logarithm of  {@code a}.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double log10(double a);
+
+    /**
+     * Returns the correctly rounded positive square root of a
+     * {@code double} value.
+     * Special cases:
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is positive
+     * infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is the same as the argument.</ul>
+     * Otherwise, the result is the {@code double} value closest to
+     * the true mathematical square root of the argument value.
+     *
+     * @param   a   a value.
+     * @return  the positive square root of {@code a}.
+     *          If the argument is NaN or less than zero, the result is NaN.
+     */
+    @CriticalNative
+    public static native double sqrt(double a);
+
+
+    /**
+     * Returns the cube root of a {@code double} value.  For
+     * positive finite {@code x}, {@code cbrt(-x) ==
+     * -cbrt(x)}; that is, the cube root of a negative value is
+     * the negative of the cube root of that value's magnitude.
+     *
+     * Special cases:
+     *
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is an infinity
+     * with the same sign as the argument.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     *
+     * @param   a   a value.
+     * @return  the cube root of {@code a}.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double cbrt(double a);
+
+    /**
+     * Computes the remainder operation on two arguments as prescribed
+     * by the IEEE 754 standard.
+     * The remainder value is mathematically equal to
+     * <code>f1&nbsp;-&nbsp;f2</code>&nbsp;&times;&nbsp;<i>n</i>,
+     * where <i>n</i> is the mathematical integer closest to the exact
+     * mathematical value of the quotient {@code f1/f2}, and if two
+     * mathematical integers are equally close to {@code f1/f2},
+     * then <i>n</i> is the integer that is even. If the remainder is
+     * zero, its sign is the same as the sign of the first argument.
+     * Special cases:
+     * <ul><li>If either argument is NaN, or the first argument is infinite,
+     * or the second argument is positive zero or negative zero, then the
+     * result is NaN.
+     * <li>If the first argument is finite and the second argument is
+     * infinite, then the result is the same as the first argument.</ul>
+     *
+     * @param   f1   the dividend.
+     * @param   f2   the divisor.
+     * @return  the remainder when {@code f1} is divided by
+     *          {@code f2}.
+     */
+    @CriticalNative
+    public static native double IEEEremainder(double f1, double f2);
+
+    /**
+     * Returns the smallest (closest to negative infinity)
+     * {@code double} value that is greater than or equal to the
+     * argument and is equal to a mathematical integer. Special cases:
+     * <ul><li>If the argument value is already equal to a
+     * mathematical integer, then the result is the same as the
+     * argument.  <li>If the argument is NaN or an infinity or
+     * positive zero or negative zero, then the result is the same as
+     * the argument.  <li>If the argument value is less than zero but
+     * greater than -1.0, then the result is negative zero.</ul> Note
+     * that the value of {@code Math.ceil(x)} is exactly the
+     * value of {@code -Math.floor(-x)}.
+     *
+     *
+     * @param   a   a value.
+     * @return  the smallest (closest to negative infinity)
+     *          floating-point value that is greater than or equal to
+     *          the argument and is equal to a mathematical integer.
+     */
+    @CriticalNative
+    public static native double ceil(double a);
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code double} value that is less than or equal to the
+     * argument and is equal to a mathematical integer. Special cases:
+     * <ul><li>If the argument value is already equal to a
+     * mathematical integer, then the result is the same as the
+     * argument.  <li>If the argument is NaN or an infinity or
+     * positive zero or negative zero, then the result is the same as
+     * the argument.</ul>
+     *
+     * @param   a   a value.
+     * @return  the largest (closest to positive infinity)
+     *          floating-point value that less than or equal to the argument
+     *          and is equal to a mathematical integer.
+     */
+    @CriticalNative
+    public static native double floor(double a);
+
+    /**
+     * Returns the {@code double} value that is closest in value
+     * to the argument and is equal to a mathematical integer. If two
+     * {@code double} values that are mathematical integers are
+     * equally close, the result is the integer value that is
+     * even. Special cases:
+     * <ul><li>If the argument value is already equal to a mathematical
+     * integer, then the result is the same as the argument.
+     * <li>If the argument is NaN or an infinity or positive zero or negative
+     * zero, then the result is the same as the argument.</ul>
+     *
+     * @param   a   a {@code double} value.
+     * @return  the closest floating-point value to {@code a} that is
+     *          equal to a mathematical integer.
+     */
+    @CriticalNative
+    public static native double rint(double a);
+
+    /**
+     * Returns the angle <i>theta</i> from the conversion of rectangular
+     * coordinates ({@code x},&nbsp;{@code y}) to polar
+     * coordinates (r,&nbsp;<i>theta</i>).
+     * This method computes the phase <i>theta</i> by computing an arc tangent
+     * of {@code y/x} in the range of -<i>pi</i> to <i>pi</i>. Special
+     * cases:
+     * <ul><li>If either argument is NaN, then the result is NaN.
+     * <li>If the first argument is positive zero and the second argument
+     * is positive, or the first argument is positive and finite and the
+     * second argument is positive infinity, then the result is positive
+     * zero.
+     * <li>If the first argument is negative zero and the second argument
+     * is positive, or the first argument is negative and finite and the
+     * second argument is positive infinity, then the result is negative zero.
+     * <li>If the first argument is positive zero and the second argument
+     * is negative, or the first argument is positive and finite and the
+     * second argument is negative infinity, then the result is the
+     * {@code double} value closest to <i>pi</i>.
+     * <li>If the first argument is negative zero and the second argument
+     * is negative, or the first argument is negative and finite and the
+     * second argument is negative infinity, then the result is the
+     * {@code double} value closest to -<i>pi</i>.
+     * <li>If the first argument is positive and the second argument is
+     * positive zero or negative zero, or the first argument is positive
+     * infinity and the second argument is finite, then the result is the
+     * {@code double} value closest to <i>pi</i>/2.
+     * <li>If the first argument is negative and the second argument is
+     * positive zero or negative zero, or the first argument is negative
+     * infinity and the second argument is finite, then the result is the
+     * {@code double} value closest to -<i>pi</i>/2.
+     * <li>If both arguments are positive infinity, then the result is the
+     * {@code double} value closest to <i>pi</i>/4.
+     * <li>If the first argument is positive infinity and the second argument
+     * is negative infinity, then the result is the {@code double}
+     * value closest to 3*<i>pi</i>/4.
+     * <li>If the first argument is negative infinity and the second argument
+     * is positive infinity, then the result is the {@code double} value
+     * closest to -<i>pi</i>/4.
+     * <li>If both arguments are negative infinity, then the result is the
+     * {@code double} value closest to -3*<i>pi</i>/4.</ul>
+     *
+     * <p>The computed result must be within 2 ulps of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   y   the ordinate coordinate
+     * @param   x   the abscissa coordinate
+     * @return  the <i>theta</i> component of the point
+     *          (<i>r</i>,&nbsp;<i>theta</i>)
+     *          in polar coordinates that corresponds to the point
+     *          (<i>x</i>,&nbsp;<i>y</i>) in Cartesian coordinates.
+     */
+    @CriticalNative
+    public static native double atan2(double y, double x);
+
+    // Android-changed: Document that the results from Math are based on libm's behavior.
+    // The cases known to differ with libm's pow():
+    //   If the first argument is 1.0 then result is always 1.0 (not NaN).
+    //   If the first argument is -1.0 and the second argument is infinite, the result is 1.0 (not
+    //   NaN).
+    /**
+     * Returns the value of the first argument raised to the power of the
+     * second argument. Special cases:
+     *
+     * <ul><li>If the second argument is positive or negative zero, then the
+     * result is 1.0.
+     * <li>If the second argument is 1.0, then the result is the same as the
+     * first argument.
+     * <li>If the first argument is 1.0, then the result is 1.0.
+     * <li>If the second argument is NaN, then the result is NaN except where the first argument is
+     * 1.0.
+     * <li>If the first argument is NaN and the second argument is nonzero,
+     * then the result is NaN.
+     *
+     * <li>If
+     * <ul>
+     * <li>the absolute value of the first argument is greater than 1
+     * and the second argument is positive infinity, or
+     * <li>the absolute value of the first argument is less than 1 and
+     * the second argument is negative infinity,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the absolute value of the first argument is greater than 1 and
+     * the second argument is negative infinity, or
+     * <li>the absolute value of the
+     * first argument is less than 1 and the second argument is positive
+     * infinity,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If the absolute value of the first argument equals 1 and the
+     * second argument is infinite, then the result is 1.0.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is positive zero and the second argument
+     * is greater than zero, or
+     * <li>the first argument is positive infinity and the second
+     * argument is less than zero,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is positive zero and the second argument
+     * is less than zero, or
+     * <li>the first argument is positive infinity and the second
+     * argument is greater than zero,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is greater than zero but not a finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is less than zero but not a finite odd integer,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is a positive finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is a negative finite odd integer,
+     * </ul>
+     * then the result is negative zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is less than zero but not a finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is greater than zero but not a finite odd integer,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is a negative finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is a positive finite odd integer,
+     * </ul>
+     * then the result is negative infinity.
+     *
+     * <li>If the first argument is finite and less than zero
+     * <ul>
+     * <li> if the second argument is a finite even integer, the
+     * result is equal to the result of raising the absolute value of
+     * the first argument to the power of the second argument
+     *
+     * <li>if the second argument is a finite odd integer, the result
+     * is equal to the negative of the result of raising the absolute
+     * value of the first argument to the power of the second
+     * argument
+     *
+     * <li>if the second argument is finite and not an integer, then
+     * the result is NaN.
+     * </ul>
+     *
+     * <li>If both arguments are integers, then the result is exactly equal
+     * to the mathematical result of raising the first argument to the power
+     * of the second argument if that result can in fact be represented
+     * exactly as a {@code double} value.</ul>
+     *
+     * <p>(In the foregoing descriptions, a floating-point value is
+     * considered to be an integer if and only if it is finite and a
+     * fixed point of the method {@link #ceil ceil} or,
+     * equivalently, a fixed point of the method {@link #floor
+     * floor}. A value is a fixed point of a one-argument
+     * method if and only if the result of applying the method to the
+     * value is equal to the value.)
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   a   the base.
+     * @param   b   the exponent.
+     * @return  the value {@code a}<sup>{@code b}</sup>.
+     */
+    @CriticalNative
+    public static native double pow(double a, double b);
+
+    /**
+     * Returns the closest {@code int} to the argument, with ties
+     * rounding to positive infinity.
+     *
+     * <p>
+     * Special cases:
+     * <ul><li>If the argument is NaN, the result is 0.
+     * <li>If the argument is negative infinity or any value less than or
+     * equal to the value of {@code Integer.MIN_VALUE}, the result is
+     * equal to the value of {@code Integer.MIN_VALUE}.
+     * <li>If the argument is positive infinity or any value greater than or
+     * equal to the value of {@code Integer.MAX_VALUE}, the result is
+     * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+     *
+     * @param   a   a floating-point value to be rounded to an integer.
+     * @return  the value of the argument rounded to the nearest
+     *          {@code int} value.
+     * @see     java.lang.Integer#MAX_VALUE
+     * @see     java.lang.Integer#MIN_VALUE
+     */
+    public static int round(float a) {
+        int intBits = Float.floatToRawIntBits(a);
+        int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
+                >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
+        int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
+                + FloatConsts.EXP_BIAS) - biasedExp;
+        if ((shift & -32) == 0) { // shift >= 0 && shift < 32
+            // a is a finite number such that pow(2,-32) <= ulp(a) < 1
+            int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
+                    | (FloatConsts.SIGNIF_BIT_MASK + 1));
+            if (intBits < 0) {
+                r = -r;
+            }
+            // In the comments below each Java expression evaluates to the value
+            // the corresponding mathematical expression:
+            // (r) evaluates to a / ulp(a)
+            // (r >> shift) evaluates to floor(a * 2)
+            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+            return ((r >> shift) + 1) >> 1;
+        } else {
+            // a is either
+            // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
+            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+            // - an infinity or NaN
+            return (int) a;
+        }
+    }
+
+    /**
+     * Returns the closest {@code long} to the argument, with ties
+     * rounding to positive infinity.
+     *
+     * <p>Special cases:
+     * <ul><li>If the argument is NaN, the result is 0.
+     * <li>If the argument is negative infinity or any value less than or
+     * equal to the value of {@code Long.MIN_VALUE}, the result is
+     * equal to the value of {@code Long.MIN_VALUE}.
+     * <li>If the argument is positive infinity or any value greater than or
+     * equal to the value of {@code Long.MAX_VALUE}, the result is
+     * equal to the value of {@code Long.MAX_VALUE}.</ul>
+     *
+     * @param   a   a floating-point value to be rounded to a
+     *          {@code long}.
+     * @return  the value of the argument rounded to the nearest
+     *          {@code long} value.
+     * @see     java.lang.Long#MAX_VALUE
+     * @see     java.lang.Long#MIN_VALUE
+     */
+    public static long round(double a) {
+        long longBits = Double.doubleToRawLongBits(a);
+        long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
+                >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
+        long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
+                + DoubleConsts.EXP_BIAS) - biasedExp;
+        if ((shift & -64) == 0) { // shift >= 0 && shift < 64
+            // a is a finite number such that pow(2,-64) <= ulp(a) < 1
+            long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
+                    | (DoubleConsts.SIGNIF_BIT_MASK + 1));
+            if (longBits < 0) {
+                r = -r;
+            }
+            // In the comments below each Java expression evaluates to the value
+            // the corresponding mathematical expression:
+            // (r) evaluates to a / ulp(a)
+            // (r >> shift) evaluates to floor(a * 2)
+            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+            return ((r >> shift) + 1) >> 1;
+        } else {
+            // a is either
+            // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
+            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+            // - an infinity or NaN
+            return (long) a;
+        }
+    }
+
+    private static final class RandomNumberGeneratorHolder {
+        static final Random randomNumberGenerator = new Random();
+    }
+
+    /**
+     * Returns a {@code double} value with a positive sign, greater
+     * than or equal to {@code 0.0} and less than {@code 1.0}.
+     * Returned values are chosen pseudorandomly with (approximately)
+     * uniform distribution from that range.
+     *
+     * <p>When this method is first called, it creates a single new
+     * pseudorandom-number generator, exactly as if by the expression
+     *
+     * <blockquote>{@code new java.util.Random()}</blockquote>
+     *
+     * This new pseudorandom-number generator is used thereafter for
+     * all calls to this method and is used nowhere else.
+     *
+     * <p>This method is properly synchronized to allow correct use by
+     * more than one thread. However, if many threads need to generate
+     * pseudorandom numbers at a great rate, it may reduce contention
+     * for each thread to have its own pseudorandom-number generator.
+     *
+     * @return  a pseudorandom {@code double} greater than or equal
+     * to {@code 0.0} and less than {@code 1.0}.
+     * @see Random#nextDouble()
+     */
+    public static double random() {
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
+    }
+
+    // Android-added: setRandomSeedInternal(long), called after zygote forks.
+    // This allows different processes to have different random seeds.
+    /**
+     * Set the seed for the pseudo random generator used by {@link #random()}
+     * and {@link #randomIntInternal()}.
+     *
+     * @hide for internal use only.
+     */
+    public static void setRandomSeedInternal(long seed) {
+        RandomNumberGeneratorHolder.randomNumberGenerator.setSeed(seed);
+    }
+
+    // Android-added: randomIntInternal() method: like random() but for int.
+    /**
+     * @hide for internal use only.
+     */
+    public static int randomIntInternal() {
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextInt();
+    }
+
+    // Android-added: randomLongInternal() method: like random() but for long.
+    /**
+     * @hide for internal use only.
+     */
+    public static long randomLongInternal() {
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextLong();
+    }
+
+    /**
+     * Returns the sum of its arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int addExact(int x, int y) {
+        int r = x + y;
+        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+        if (((x ^ r) & (y ^ r)) < 0) {
+            throw new ArithmeticException("integer overflow");
+        }
+        return r;
+    }
+
+    /**
+     * Returns the sum of its arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long addExact(long x, long y) {
+        long r = x + y;
+        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+        if (((x ^ r) & (y ^ r)) < 0) {
+            throw new ArithmeticException("long overflow");
+        }
+        return r;
+    }
+
+    /**
+     * Returns the difference of the arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int subtractExact(int x, int y) {
+        int r = x - y;
+        // HD 2-12 Overflow iff the arguments have different signs and
+        // the sign of the result is different than the sign of x
+        if (((x ^ y) & (x ^ r)) < 0) {
+            throw new ArithmeticException("integer overflow");
+        }
+        return r;
+    }
+
+    /**
+     * Returns the difference of the arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long subtractExact(long x, long y) {
+        long r = x - y;
+        // HD 2-12 Overflow iff the arguments have different signs and
+        // the sign of the result is different than the sign of x
+        if (((x ^ y) & (x ^ r)) < 0) {
+            throw new ArithmeticException("long overflow");
+        }
+        return r;
+    }
+
+    /**
+     * Returns the product of the arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int multiplyExact(int x, int y) {
+        long r = (long)x * (long)y;
+        if ((int)r != r) {
+            throw new ArithmeticException("integer overflow");
+        }
+        return (int)r;
+    }
+
+    /**
+     * Returns the product of the arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long multiplyExact(long x, long y) {
+        long r = x * y;
+        long ax = Math.abs(x);
+        long ay = Math.abs(y);
+        if (((ax | ay) >>> 31 != 0)) {
+            // Some bits greater than 2^31 that might cause overflow
+            // Check the result using the divide operator
+            // and check for the special case of Long.MIN_VALUE * -1
+           if (((y != 0) && (r / y != x)) ||
+               (x == Long.MIN_VALUE && y == -1)) {
+                throw new ArithmeticException("long overflow");
+            }
+        }
+        return r;
+    }
+
+    /**
+     * Returns the argument incremented by one, throwing an exception if the
+     * result overflows an {@code int}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int incrementExact(int a) {
+        if (a == Integer.MAX_VALUE) {
+            throw new ArithmeticException("integer overflow");
+        }
+
+        return a + 1;
+    }
+
+    /**
+     * Returns the argument incremented by one, throwing an exception if the
+     * result overflows a {@code long}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long incrementExact(long a) {
+        if (a == Long.MAX_VALUE) {
+            throw new ArithmeticException("long overflow");
+        }
+
+        return a + 1L;
+    }
+
+    /**
+     * Returns the argument decremented by one, throwing an exception if the
+     * result overflows an {@code int}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int decrementExact(int a) {
+        if (a == Integer.MIN_VALUE) {
+            throw new ArithmeticException("integer overflow");
+        }
+
+        return a - 1;
+    }
+
+    /**
+     * Returns the argument decremented by one, throwing an exception if the
+     * result overflows a {@code long}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long decrementExact(long a) {
+        if (a == Long.MIN_VALUE) {
+            throw new ArithmeticException("long overflow");
+        }
+
+        return a - 1L;
+    }
+
+    /**
+     * Returns the negation of the argument, throwing an exception if the
+     * result overflows an {@code int}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @since 1.8
+     */
+    public static int negateExact(int a) {
+        if (a == Integer.MIN_VALUE) {
+            throw new ArithmeticException("integer overflow");
+        }
+
+        return -a;
+    }
+
+    /**
+     * Returns the negation of the argument, throwing an exception if the
+     * result overflows a {@code long}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 1.8
+     */
+    public static long negateExact(long a) {
+        if (a == Long.MIN_VALUE) {
+            throw new ArithmeticException("long overflow");
+        }
+
+        return -a;
+    }
+
+    /**
+     * Returns the value of the {@code long} argument;
+     * throwing an exception if the value overflows an {@code int}.
+     *
+     * @param value the long value
+     * @return the argument as an int
+     * @throws ArithmeticException if the {@code argument} overflows an int
+     * @since 1.8
+     */
+    public static int toIntExact(long value) {
+        if ((int)value != value) {
+            throw new ArithmeticException("integer overflow");
+        }
+        return (int)value;
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
+     * the result is equal to the {@code Integer.MIN_VALUE}.
+     * <p>
+     * Normal integer division operates under the round to zero rounding mode
+     * (truncation).  This operation instead acts under the round toward
+     * negative infinity (floor) rounding mode.
+     * The floor rounding mode gives different results than truncation
+     * when the exact result is negative.
+     * <ul>
+     *   <li>If the signs of the arguments are the same, the results of
+     *       {@code floorDiv} and the {@code /} operator are the same.  <br>
+     *       For example, {@code floorDiv(4, 3) == 1} and {@code (4 / 3) == 1}.</li>
+     *   <li>If the signs of the arguments are different,  the quotient is negative and
+     *       {@code floorDiv} returns the integer less than or equal to the quotient
+     *       and the {@code /} operator returns the integer closest to zero.<br>
+     *       For example, {@code floorDiv(-4, 3) == -2},
+     *       whereas {@code (-4 / 3) == -1}.
+     *   </li>
+     * </ul>
+     * <p>
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorMod(int, int)
+     * @see #floor(double)
+     * @since 1.8
+     */
+    public static int floorDiv(int x, int y) {
+        int r = x / y;
+        // if the signs are different and modulo not zero, round down
+        if ((x ^ y) < 0 && (r * y != x)) {
+            r--;
+        }
+        return r;
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
+     * the result is equal to the {@code Long.MIN_VALUE}.
+     * <p>
+     * Normal integer division operates under the round to zero rounding mode
+     * (truncation).  This operation instead acts under the round toward
+     * negative infinity (floor) rounding mode.
+     * The floor rounding mode gives different results than truncation
+     * when the exact result is negative.
+     * <p>
+     * For examples, see {@link #floorDiv(int, int)}.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorMod(long, long)
+     * @see #floor(double)
+     * @since 1.8
+     */
+    public static long floorDiv(long x, long y) {
+        long r = x / y;
+        // if the signs are different and modulo not zero, round down
+        if ((x ^ y) < 0 && (r * y != x)) {
+            r--;
+        }
+        return r;
+    }
+
+    /**
+     * Returns the floor modulus of the {@code int} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     *
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * The difference in values between {@code floorMod} and
+     * the {@code %} operator is due to the difference between
+     * {@code floorDiv} that returns the integer less than or equal to the quotient
+     * and the {@code /} operator that returns the integer closest to zero.
+     * <p>
+     * Examples:
+     * <ul>
+     *   <li>If the signs of the arguments are the same, the results
+     *       of {@code floorMod} and the {@code %} operator are the same.  <br>
+     *       <ul>
+     *       <li>{@code floorMod(4, 3) == 1}; &nbsp; and {@code (4 % 3) == 1}</li>
+     *       </ul>
+     *   <li>If the signs of the arguments are different, the results differ from the {@code %} operator.<br>
+     *      <ul>
+     *      <li>{@code floorMod(+4, -3) == -2}; &nbsp; and {@code (+4 % -3) == +1} </li>
+     *      <li>{@code floorMod(-4, +3) == +2}; &nbsp; and {@code (-4 % +3) == -1} </li>
+     *      <li>{@code floorMod(-4, -3) == -1}; &nbsp; and {@code (-4 % -3) == -1 } </li>
+     *      </ul>
+     *   </li>
+     * </ul>
+     * <p>
+     * If the signs of arguments are unknown and a positive modulus
+     * is needed it can be computed as {@code (floorMod(x, y) + abs(y)) % abs(y)}.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorDiv(int, int)
+     * @since 1.8
+     */
+    public static int floorMod(int x, int y) {
+        int r = x - floorDiv(x, y) * y;
+        return r;
+    }
+
+    /**
+     * Returns the floor modulus of the {@code long} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     *
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * For examples, see {@link #floorMod(int, int)}.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorDiv(long, long)
+     * @since 1.8
+     */
+    public static long floorMod(long x, long y) {
+        return x - floorDiv(x, y) * y;
+    }
+
+    /**
+     * Returns the absolute value of an {@code int} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     *
+     * <p>Note that if the argument is equal to the value of
+     * {@link Integer#MIN_VALUE}, the most negative representable
+     * {@code int} value, the result is that same value, which is
+     * negative.
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static int abs(int a) {
+        return (a < 0) ? -a : a;
+    }
+
+    /**
+     * Returns the absolute value of a {@code long} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     *
+     * <p>Note that if the argument is equal to the value of
+     * {@link Long#MIN_VALUE}, the most negative representable
+     * {@code long} value, the result is that same value, which
+     * is negative.
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static long abs(long a) {
+        return (a < 0) ? -a : a;
+    }
+
+    /**
+     * Returns the absolute value of a {@code float} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     * Special cases:
+     * <ul><li>If the argument is positive zero or negative zero, the
+     * result is positive zero.
+     * <li>If the argument is infinite, the result is positive infinity.
+     * <li>If the argument is NaN, the result is NaN.</ul>
+     * In other words, the result is the same as the value of the expression:
+     * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static float abs(float a) {
+        // Android-changed: Implementation modified to exactly match ART intrinsics behavior.
+        // Note, as a "quality of implementation", rather than pure "spec compliance",
+        // we require that Math.abs() clears the sign bit (but changes nothing else)
+        // for all numbers, including NaN (signaling NaN may become quiet though).
+        // http://b/30758343
+        return Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a));
+    }
+
+    /**
+     * Returns the absolute value of a {@code double} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     * Special cases:
+     * <ul><li>If the argument is positive zero or negative zero, the result
+     * is positive zero.
+     * <li>If the argument is infinite, the result is positive infinity.
+     * <li>If the argument is NaN, the result is NaN.</ul>
+     * In other words, the result is the same as the value of the expression:
+     * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static double abs(double a) {
+        // Android-changed: Implementation modified to exactly match ART intrinsics behavior.
+        // Note, as a "quality of implementation", rather than pure "spec compliance",
+        // we require that Math.abs() clears the sign bit (but changes nothing else)
+        // for all numbers, including NaN (signaling NaN may become quiet though).
+        // http://b/30758343
+        return Double.longBitsToDouble(0x7fffffffffffffffL & Double.doubleToRawLongBits(a));
+    }
+
+    /**
+     * Returns the greater of two {@code int} values. That is, the
+     * result is the argument closer to the value of
+     * {@link Integer#MAX_VALUE}. If the arguments have the same value,
+     * the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static int max(int a, int b) {
+        return (a >= b) ? a : b;
+    }
+
+    /**
+     * Returns the greater of two {@code long} values. That is, the
+     * result is the argument closer to the value of
+     * {@link Long#MAX_VALUE}. If the arguments have the same value,
+     * the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static long max(long a, long b) {
+        return (a >= b) ? a : b;
+    }
+
+    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
+    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
+    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
+
+    /**
+     * Returns the greater of two {@code float} values.  That is,
+     * the result is the argument closer to positive infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other negative zero, the
+     * result is positive zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static float max(float a, float b) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0f) &&
+            (b == 0.0f) &&
+            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
+            return b;
+        }
+        return (a >= b) ? a : b;
+    }
+
+    /**
+     * Returns the greater of two {@code double} values.  That
+     * is, the result is the argument closer to positive infinity. If
+     * the arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other negative zero, the
+     * result is positive zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static double max(double a, double b) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0d) &&
+            (b == 0.0d) &&
+            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
+            return b;
+        }
+        return (a >= b) ? a : b;
+    }
+
+    /**
+     * Returns the smaller of two {@code int} values. That is,
+     * the result the argument closer to the value of
+     * {@link Integer#MIN_VALUE}.  If the arguments have the same
+     * value, the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static int min(int a, int b) {
+        return (a <= b) ? a : b;
+    }
+
+    /**
+     * Returns the smaller of two {@code long} values. That is,
+     * the result is the argument closer to the value of
+     * {@link Long#MIN_VALUE}. If the arguments have the same
+     * value, the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static long min(long a, long b) {
+        return (a <= b) ? a : b;
+    }
+
+    /**
+     * Returns the smaller of two {@code float} values.  That is,
+     * the result is the value closer to negative infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero.  If
+     * one argument is positive zero and the other is negative zero,
+     * the result is negative zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static float min(float a, float b) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0f) &&
+            (b == 0.0f) &&
+            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
+            return b;
+        }
+        return (a <= b) ? a : b;
+    }
+
+    /**
+     * Returns the smaller of two {@code double} values.  That
+     * is, the result is the value closer to negative infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other is negative zero, the
+     * result is negative zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static double min(double a, double b) {
+        if (a != a)
+            return a;   // a is NaN
+        if ((a == 0.0d) &&
+            (b == 0.0d) &&
+            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
+            // Raw conversion ok since NaN can't map to -0.0.
+            return b;
+        }
+        return (a <= b) ? a : b;
+    }
+
+    /**
+     * Returns the size of an ulp of the argument.  An ulp, unit in
+     * the last place, of a {@code double} value is the positive
+     * distance between this floating-point value and the {@code
+     * double} value next larger in magnitude.  Note that for non-NaN
+     * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive or negative infinity, then the
+     * result is positive infinity.
+     * <li> If the argument is positive or negative zero, then the result is
+     * {@code Double.MIN_VALUE}.
+     * <li> If the argument is &plusmn;{@code Double.MAX_VALUE}, then
+     * the result is equal to 2<sup>971</sup>.
+     * </ul>
+     *
+     * @param d the floating-point value whose ulp is to be returned
+     * @return the size of an ulp of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static double ulp(double d) {
+        int exp = getExponent(d);
+
+        switch(exp) {
+        case DoubleConsts.MAX_EXPONENT+1:       // NaN or infinity
+            return Math.abs(d);
+
+        case DoubleConsts.MIN_EXPONENT-1:       // zero or subnormal
+            return Double.MIN_VALUE;
+
+        default:
+            assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;
+
+            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
+            exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
+            if (exp >= DoubleConsts.MIN_EXPONENT) {
+                return powerOfTwoD(exp);
+            }
+            else {
+                // return a subnormal result; left shift integer
+                // representation of Double.MIN_VALUE appropriate
+                // number of positions
+                return Double.longBitsToDouble(1L <<
+                (exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
+            }
+        }
+    }
+
+    /**
+     * Returns the size of an ulp of the argument.  An ulp, unit in
+     * the last place, of a {@code float} value is the positive
+     * distance between this floating-point value and the {@code
+     * float} value next larger in magnitude.  Note that for non-NaN
+     * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive or negative infinity, then the
+     * result is positive infinity.
+     * <li> If the argument is positive or negative zero, then the result is
+     * {@code Float.MIN_VALUE}.
+     * <li> If the argument is &plusmn;{@code Float.MAX_VALUE}, then
+     * the result is equal to 2<sup>104</sup>.
+     * </ul>
+     *
+     * @param f the floating-point value whose ulp is to be returned
+     * @return the size of an ulp of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static float ulp(float f) {
+        int exp = getExponent(f);
+
+        switch(exp) {
+        case FloatConsts.MAX_EXPONENT+1:        // NaN or infinity
+            return Math.abs(f);
+
+        case FloatConsts.MIN_EXPONENT-1:        // zero or subnormal
+            return FloatConsts.MIN_VALUE;
+
+        default:
+            assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;
+
+            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
+            exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
+            if (exp >= FloatConsts.MIN_EXPONENT) {
+                return powerOfTwoF(exp);
+            }
+            else {
+                // return a subnormal result; left shift integer
+                // representation of FloatConsts.MIN_VALUE appropriate
+                // number of positions
+                return Float.intBitsToFloat(1 <<
+                (exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
+            }
+        }
+    }
+
+    /**
+     * Returns the signum function of the argument; zero if the argument
+     * is zero, 1.0 if the argument is greater than zero, -1.0 if the
+     * argument is less than zero.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive zero or negative zero, then the
+     *      result is the same as the argument.
+     * </ul>
+     *
+     * @param d the floating-point value whose signum is to be returned
+     * @return the signum function of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static double signum(double d) {
+        return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
+    }
+
+    /**
+     * Returns the signum function of the argument; zero if the argument
+     * is zero, 1.0f if the argument is greater than zero, -1.0f if the
+     * argument is less than zero.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive zero or negative zero, then the
+     *      result is the same as the argument.
+     * </ul>
+     *
+     * @param f the floating-point value whose signum is to be returned
+     * @return the signum function of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static float signum(float f) {
+        return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
+    }
+
+    /**
+     * Returns the hyperbolic sine of a {@code double} value.
+     * The hyperbolic sine of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/2
+     * where <i>e</i> is {@linkplain Math#E Euler's number}.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is an infinity
+     * with the same sign as the argument.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 2.5 ulps of the exact result.
+     *
+     * @param   x The number whose hyperbolic sine is to be returned.
+     * @return  The hyperbolic sine of {@code x}.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double sinh(double x);
+
+    /**
+     * Returns the hyperbolic cosine of a {@code double} value.
+     * The hyperbolic cosine of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>)/2
+     * where <i>e</i> is {@linkplain Math#E Euler's number}.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is positive
+     * infinity.
+     *
+     * <li>If the argument is zero, then the result is {@code 1.0}.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 2.5 ulps of the exact result.
+     *
+     * @param   x The number whose hyperbolic cosine is to be returned.
+     * @return  The hyperbolic cosine of {@code x}.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double cosh(double x);
+
+    /**
+     * Returns the hyperbolic tangent of a {@code double} value.
+     * The hyperbolic tangent of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/(<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>),
+     * in other words, {@linkplain Math#sinh
+     * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}.  Note
+     * that the absolute value of the exact tanh is always less than
+     * 1.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * {@code +1.0}.
+     *
+     * <li>If the argument is negative infinity, then the result is
+     * {@code -1.0}.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 2.5 ulps of the exact result.
+     * The result of {@code tanh} for any finite input must have
+     * an absolute value less than or equal to 1.  Note that once the
+     * exact result of tanh is within 1/2 of an ulp of the limit value
+     * of &plusmn;1, correctly signed &plusmn;{@code 1.0} should
+     * be returned.
+     *
+     * @param   x The number whose hyperbolic tangent is to be returned.
+     * @return  The hyperbolic tangent of {@code x}.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double tanh(double x);
+
+    /**
+     * Returns sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * without intermediate overflow or underflow.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li> If either argument is infinite, then the result
+     * is positive infinity.
+     *
+     * <li> If either argument is NaN and neither argument is infinite,
+     * then the result is NaN.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact
+     * result.  If one parameter is held constant, the results must be
+     * semi-monotonic in the other parameter.
+     *
+     * @param x a value
+     * @param y a value
+     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * without intermediate overflow or underflow
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double hypot(double x, double y);
+
+    /**
+     * Returns <i>e</i><sup>x</sup>&nbsp;-1.  Note that for values of
+     * <i>x</i> near 0, the exact sum of
+     * {@code expm1(x)}&nbsp;+&nbsp;1 is much closer to the true
+     * result of <i>e</i><sup>x</sup> than {@code exp(x)}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li>If the argument is NaN, the result is NaN.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     *
+     * <li>If the argument is negative infinity, then the result is
+     * -1.0.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.  The result of
+     * {@code expm1} for any finite input must be greater than or
+     * equal to {@code -1.0}.  Note that once the exact result of
+     * <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1 is within 1/2
+     * ulp of the limit value -1, {@code -1.0} should be
+     * returned.
+     *
+     * @param   x   the exponent to raise <i>e</i> to in the computation of
+     *              <i>e</i><sup>{@code x}</sup>&nbsp;-1.
+     * @return  the value <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1.
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double expm1(double x);
+
+    /**
+     * Returns the natural logarithm of the sum of the argument and 1.
+     * Note that for small values {@code x}, the result of
+     * {@code log1p(x)} is much closer to the true result of ln(1
+     * + {@code x}) than the floating-point evaluation of
+     * {@code log(1.0+x)}.
+     *
+     * <p>Special cases:
+     *
+     * <ul>
+     *
+     * <li>If the argument is NaN or less than -1, then the result is
+     * NaN.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     *
+     * <li>If the argument is negative one, then the result is
+     * negative infinity.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * <p>The computed result must be within 1 ulp of the exact result.
+     * Results must be semi-monotonic.
+     *
+     * @param   x   a value
+     * @return the value ln({@code x}&nbsp;+&nbsp;1), the natural
+     * log of {@code x}&nbsp;+&nbsp;1
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native double log1p(double x);
+
+    /**
+     * Returns the first floating-point argument with the sign of the
+     * second floating-point argument.  Note that unlike the {@link
+     * StrictMath#copySign(double, double) StrictMath.copySign}
+     * method, this method does not require NaN {@code sign}
+     * arguments to be treated as positive values; implementations are
+     * permitted to treat some NaN arguments as positive and other NaN
+     * arguments as negative to allow greater performance.
+     *
+     * @param magnitude  the parameter providing the magnitude of the result
+     * @param sign   the parameter providing the sign of the result
+     * @return a value with the magnitude of {@code magnitude}
+     * and the sign of {@code sign}.
+     * @since 1.6
+     */
+    public static double copySign(double magnitude, double sign) {
+        return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
+                                        (DoubleConsts.SIGN_BIT_MASK)) |
+                                       (Double.doubleToRawLongBits(magnitude) &
+                                        (DoubleConsts.EXP_BIT_MASK |
+                                         DoubleConsts.SIGNIF_BIT_MASK)));
+    }
+
+    /**
+     * Returns the first floating-point argument with the sign of the
+     * second floating-point argument.  Note that unlike the {@link
+     * StrictMath#copySign(float, float) StrictMath.copySign}
+     * method, this method does not require NaN {@code sign}
+     * arguments to be treated as positive values; implementations are
+     * permitted to treat some NaN arguments as positive and other NaN
+     * arguments as negative to allow greater performance.
+     *
+     * @param magnitude  the parameter providing the magnitude of the result
+     * @param sign   the parameter providing the sign of the result
+     * @return a value with the magnitude of {@code magnitude}
+     * and the sign of {@code sign}.
+     * @since 1.6
+     */
+    public static float copySign(float magnitude, float sign) {
+        return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
+                                     (FloatConsts.SIGN_BIT_MASK)) |
+                                    (Float.floatToRawIntBits(magnitude) &
+                                     (FloatConsts.EXP_BIT_MASK |
+                                      FloatConsts.SIGNIF_BIT_MASK)));
+    }
+
+    /**
+     * Returns the unbiased exponent used in the representation of a
+     * {@code float}.  Special cases:
+     *
+     * <ul>
+     * <li>If the argument is NaN or infinite, then the result is
+     * {@link Float#MAX_EXPONENT} + 1.
+     * <li>If the argument is zero or subnormal, then the result is
+     * {@link Float#MIN_EXPONENT} -1.
+     * </ul>
+     * @param f a {@code float} value
+     * @return the unbiased exponent of the argument
+     * @since 1.6
+     */
+    public static int getExponent(float f) {
+        /*
+         * Bitwise convert f to integer, mask out exponent bits, shift
+         * to the right and then subtract out float's bias adjust to
+         * get true exponent value
+         */
+        return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
+                (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
+    }
+
+    /**
+     * Returns the unbiased exponent used in the representation of a
+     * {@code double}.  Special cases:
+     *
+     * <ul>
+     * <li>If the argument is NaN or infinite, then the result is
+     * {@link Double#MAX_EXPONENT} + 1.
+     * <li>If the argument is zero or subnormal, then the result is
+     * {@link Double#MIN_EXPONENT} -1.
+     * </ul>
+     * @param d a {@code double} value
+     * @return the unbiased exponent of the argument
+     * @since 1.6
+     */
+    public static int getExponent(double d) {
+        /*
+         * Bitwise convert d to long, mask out exponent bits, shift
+         * to the right and then subtract out double's bias adjust to
+         * get true exponent value.
+         */
+        return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >>
+                      (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
+    }
+
+    /**
+     * Returns the floating-point number adjacent to the first
+     * argument in the direction of the second argument.  If both
+     * arguments compare as equal the second argument is returned.
+     *
+     * <p>
+     * Special cases:
+     * <ul>
+     * <li> If either argument is a NaN, then NaN is returned.
+     *
+     * <li> If both arguments are signed zeros, {@code direction}
+     * is returned unchanged (as implied by the requirement of
+     * returning the second argument if the arguments compare as
+     * equal).
+     *
+     * <li> If {@code start} is
+     * &plusmn;{@link Double#MIN_VALUE} and {@code direction}
+     * has a value such that the result should have a smaller
+     * magnitude, then a zero with the same sign as {@code start}
+     * is returned.
+     *
+     * <li> If {@code start} is infinite and
+     * {@code direction} has a value such that the result should
+     * have a smaller magnitude, {@link Double#MAX_VALUE} with the
+     * same sign as {@code start} is returned.
+     *
+     * <li> If {@code start} is equal to &plusmn;
+     * {@link Double#MAX_VALUE} and {@code direction} has a
+     * value such that the result should have a larger magnitude, an
+     * infinity with same sign as {@code start} is returned.
+     * </ul>
+     *
+     * @param start  starting floating-point value
+     * @param direction value indicating which of
+     * {@code start}'s neighbors or {@code start} should
+     * be returned
+     * @return The floating-point number adjacent to {@code start} in the
+     * direction of {@code direction}.
+     * @since 1.6
+     */
+    public static double nextAfter(double start, double direction) {
+        /*
+         * The cases:
+         *
+         * nextAfter(+infinity, 0)  == MAX_VALUE
+         * nextAfter(+infinity, +infinity)  == +infinity
+         * nextAfter(-infinity, 0)  == -MAX_VALUE
+         * nextAfter(-infinity, -infinity)  == -infinity
+         *
+         * are naturally handled without any additional testing
+         */
+
+        // First check for NaN values
+        if (Double.isNaN(start) || Double.isNaN(direction)) {
+            // return a NaN derived from the input NaN(s)
+            return start + direction;
+        } else if (start == direction) {
+            return direction;
+        } else {        // start > direction or start < direction
+            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
+            // then bitwise convert start to integer.
+            long transducer = Double.doubleToRawLongBits(start + 0.0d);
+
+            /*
+             * IEEE 754 floating-point numbers are lexicographically
+             * ordered if treated as signed- magnitude integers .
+             * Since Java's integers are two's complement,
+             * incrementing" the two's complement representation of a
+             * logically negative floating-point value *decrements*
+             * the signed-magnitude representation. Therefore, when
+             * the integer representation of a floating-point values
+             * is less than zero, the adjustment to the representation
+             * is in the opposite direction than would be expected at
+             * first .
+             */
+            if (direction > start) { // Calculate next greater value
+                transducer = transducer + (transducer >= 0L ? 1L:-1L);
+            } else  { // Calculate next lesser value
+                assert direction < start;
+                if (transducer > 0L)
+                    --transducer;
+                else
+                    if (transducer < 0L )
+                        ++transducer;
+                    /*
+                     * transducer==0, the result is -MIN_VALUE
+                     *
+                     * The transition from zero (implicitly
+                     * positive) to the smallest negative
+                     * signed magnitude value must be done
+                     * explicitly.
+                     */
+                    else
+                        transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
+            }
+
+            return Double.longBitsToDouble(transducer);
+        }
+    }
+
+    /**
+     * Returns the floating-point number adjacent to the first
+     * argument in the direction of the second argument.  If both
+     * arguments compare as equal a value equivalent to the second argument
+     * is returned.
+     *
+     * <p>
+     * Special cases:
+     * <ul>
+     * <li> If either argument is a NaN, then NaN is returned.
+     *
+     * <li> If both arguments are signed zeros, a value equivalent
+     * to {@code direction} is returned.
+     *
+     * <li> If {@code start} is
+     * &plusmn;{@link Float#MIN_VALUE} and {@code direction}
+     * has a value such that the result should have a smaller
+     * magnitude, then a zero with the same sign as {@code start}
+     * is returned.
+     *
+     * <li> If {@code start} is infinite and
+     * {@code direction} has a value such that the result should
+     * have a smaller magnitude, {@link Float#MAX_VALUE} with the
+     * same sign as {@code start} is returned.
+     *
+     * <li> If {@code start} is equal to &plusmn;
+     * {@link Float#MAX_VALUE} and {@code direction} has a
+     * value such that the result should have a larger magnitude, an
+     * infinity with same sign as {@code start} is returned.
+     * </ul>
+     *
+     * @param start  starting floating-point value
+     * @param direction value indicating which of
+     * {@code start}'s neighbors or {@code start} should
+     * be returned
+     * @return The floating-point number adjacent to {@code start} in the
+     * direction of {@code direction}.
+     * @since 1.6
+     */
+    public static float nextAfter(float start, double direction) {
+        /*
+         * The cases:
+         *
+         * nextAfter(+infinity, 0)  == MAX_VALUE
+         * nextAfter(+infinity, +infinity)  == +infinity
+         * nextAfter(-infinity, 0)  == -MAX_VALUE
+         * nextAfter(-infinity, -infinity)  == -infinity
+         *
+         * are naturally handled without any additional testing
+         */
+
+        // First check for NaN values
+        if (Float.isNaN(start) || Double.isNaN(direction)) {
+            // return a NaN derived from the input NaN(s)
+            return start + (float)direction;
+        } else if (start == direction) {
+            return (float)direction;
+        } else {        // start > direction or start < direction
+            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
+            // then bitwise convert start to integer.
+            int transducer = Float.floatToRawIntBits(start + 0.0f);
+
+            /*
+             * IEEE 754 floating-point numbers are lexicographically
+             * ordered if treated as signed- magnitude integers .
+             * Since Java's integers are two's complement,
+             * incrementing" the two's complement representation of a
+             * logically negative floating-point value *decrements*
+             * the signed-magnitude representation. Therefore, when
+             * the integer representation of a floating-point values
+             * is less than zero, the adjustment to the representation
+             * is in the opposite direction than would be expected at
+             * first.
+             */
+            if (direction > start) {// Calculate next greater value
+                transducer = transducer + (transducer >= 0 ? 1:-1);
+            } else  { // Calculate next lesser value
+                assert direction < start;
+                if (transducer > 0)
+                    --transducer;
+                else
+                    if (transducer < 0 )
+                        ++transducer;
+                    /*
+                     * transducer==0, the result is -MIN_VALUE
+                     *
+                     * The transition from zero (implicitly
+                     * positive) to the smallest negative
+                     * signed magnitude value must be done
+                     * explicitly.
+                     */
+                    else
+                        transducer = FloatConsts.SIGN_BIT_MASK | 1;
+            }
+
+            return Float.intBitsToFloat(transducer);
+        }
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code d} in
+     * the direction of positive infinity.  This method is
+     * semantically equivalent to {@code nextAfter(d,
+     * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
+     * implementation may run faster than its equivalent
+     * {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is positive infinity, the result is
+     * positive infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@link Double#MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param d starting floating-point value
+     * @return The adjacent floating-point value closer to positive
+     * infinity.
+     * @since 1.6
+     */
+    public static double nextUp(double d) {
+        if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
+            return d;
+        else {
+            d += 0.0d;
+            return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
+                                           ((d >= 0.0d)?+1L:-1L));
+        }
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code f} in
+     * the direction of positive infinity.  This method is
+     * semantically equivalent to {@code nextAfter(f,
+     * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
+     * implementation may run faster than its equivalent
+     * {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is positive infinity, the result is
+     * positive infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@link Float#MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param f starting floating-point value
+     * @return The adjacent floating-point value closer to positive
+     * infinity.
+     * @since 1.6
+     */
+    public static float nextUp(float f) {
+        if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
+            return f;
+        else {
+            f += 0.0f;
+            return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
+                                        ((f >= 0.0f)?+1:-1));
+        }
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code d} in
+     * the direction of negative infinity.  This method is
+     * semantically equivalent to {@code nextAfter(d,
+     * Double.NEGATIVE_INFINITY)}; however, a
+     * {@code nextDown} implementation may run faster than its
+     * equivalent {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is negative infinity, the result is
+     * negative infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@code -Double.MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param d  starting floating-point value
+     * @return The adjacent floating-point value closer to negative
+     * infinity.
+     * @since 1.8
+     */
+    public static double nextDown(double d) {
+        if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
+            return d;
+        else {
+            if (d == 0.0)
+                return -Double.MIN_VALUE;
+            else
+                return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
+                                               ((d > 0.0d)?-1L:+1L));
+        }
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code f} in
+     * the direction of negative infinity.  This method is
+     * semantically equivalent to {@code nextAfter(f,
+     * Float.NEGATIVE_INFINITY)}; however, a
+     * {@code nextDown} implementation may run faster than its
+     * equivalent {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is negative infinity, the result is
+     * negative infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@code -Float.MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param f  starting floating-point value
+     * @return The adjacent floating-point value closer to negative
+     * infinity.
+     * @since 1.8
+     */
+    public static float nextDown(float f) {
+        if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
+            return f;
+        else {
+            if (f == 0.0f)
+                return -Float.MIN_VALUE;
+            else
+                return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
+                                            ((f > 0.0f)?-1:+1));
+        }
+    }
+
+    /**
+     * Returns {@code d} &times;
+     * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+     * by a single correctly rounded floating-point multiply to a
+     * member of the double value set.  See the Java
+     * Language Specification for a discussion of floating-point
+     * value sets.  If the exponent of the result is between {@link
+     * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
+     * answer is calculated exactly.  If the exponent of the result
+     * would be larger than {@code Double.MAX_EXPONENT}, an
+     * infinity is returned.  Note that if the result is subnormal,
+     * precision may be lost; that is, when {@code scalb(x, n)}
+     * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+     * <i>x</i>.  When the result is non-NaN, the result has the same
+     * sign as {@code d}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If the first argument is NaN, NaN is returned.
+     * <li> If the first argument is infinite, then an infinity of the
+     * same sign is returned.
+     * <li> If the first argument is zero, then a zero of the same
+     * sign is returned.
+     * </ul>
+     *
+     * @param d number to be scaled by a power of two.
+     * @param scaleFactor power of 2 used to scale {@code d}
+     * @return {@code d} &times; 2<sup>{@code scaleFactor}</sup>
+     * @since 1.6
+     */
+    public static double scalb(double d, int scaleFactor) {
+        /*
+         * This method does not need to be declared strictfp to
+         * compute the same correct result on all platforms.  When
+         * scaling up, it does not matter what order the
+         * multiply-store operations are done; the result will be
+         * finite or overflow regardless of the operation ordering.
+         * However, to get the correct result when scaling down, a
+         * particular ordering must be used.
+         *
+         * When scaling down, the multiply-store operations are
+         * sequenced so that it is not possible for two consecutive
+         * multiply-stores to return subnormal results.  If one
+         * multiply-store result is subnormal, the next multiply will
+         * round it away to zero.  This is done by first multiplying
+         * by 2 ^ (scaleFactor % n) and then multiplying several
+         * times by by 2^n as needed where n is the exponent of number
+         * that is a covenient power of two.  In this way, at most one
+         * real rounding error occurs.  If the double value set is
+         * being used exclusively, the rounding will occur on a
+         * multiply.  If the double-extended-exponent value set is
+         * being used, the products will (perhaps) be exact but the
+         * stores to d are guaranteed to round to the double value
+         * set.
+         *
+         * It is _not_ a valid implementation to first multiply d by
+         * 2^MIN_EXPONENT and then by 2 ^ (scaleFactor %
+         * MIN_EXPONENT) since even in a strictfp program double
+         * rounding on underflow could occur; e.g. if the scaleFactor
+         * argument was (MIN_EXPONENT - n) and the exponent of d was a
+         * little less than -(MIN_EXPONENT - n), meaning the final
+         * result would be subnormal.
+         *
+         * Since exact reproducibility of this method can be achieved
+         * without any undue performance burden, there is no
+         * compelling reason to allow double rounding on underflow in
+         * scalb.
+         */
+
+        // magnitude of a power of two so large that scaling a finite
+        // nonzero value by it would be guaranteed to over or
+        // underflow; due to rounding, scaling down takes takes an
+        // additional power of two which is reflected here
+        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
+                              DoubleConsts.SIGNIFICAND_WIDTH + 1;
+        int exp_adjust = 0;
+        int scale_increment = 0;
+        double exp_delta = Double.NaN;
+
+        // Make sure scaling factor is in a reasonable range
+
+        if(scaleFactor < 0) {
+            scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
+            scale_increment = -512;
+            exp_delta = twoToTheDoubleScaleDown;
+        }
+        else {
+            scaleFactor = Math.min(scaleFactor, MAX_SCALE);
+            scale_increment = 512;
+            exp_delta = twoToTheDoubleScaleUp;
+        }
+
+        // Calculate (scaleFactor % +/-512), 512 = 2^9, using
+        // technique from "Hacker's Delight" section 10-2.
+        int t = (scaleFactor >> 9-1) >>> 32 - 9;
+        exp_adjust = ((scaleFactor + t) & (512 -1)) - t;
+
+        d *= powerOfTwoD(exp_adjust);
+        scaleFactor -= exp_adjust;
+
+        while(scaleFactor != 0) {
+            d *= exp_delta;
+            scaleFactor -= scale_increment;
+        }
+        return d;
+    }
+
+    /**
+     * Returns {@code f} &times;
+     * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+     * by a single correctly rounded floating-point multiply to a
+     * member of the float value set.  See the Java
+     * Language Specification for a discussion of floating-point
+     * value sets.  If the exponent of the result is between {@link
+     * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
+     * answer is calculated exactly.  If the exponent of the result
+     * would be larger than {@code Float.MAX_EXPONENT}, an
+     * infinity is returned.  Note that if the result is subnormal,
+     * precision may be lost; that is, when {@code scalb(x, n)}
+     * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+     * <i>x</i>.  When the result is non-NaN, the result has the same
+     * sign as {@code f}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If the first argument is NaN, NaN is returned.
+     * <li> If the first argument is infinite, then an infinity of the
+     * same sign is returned.
+     * <li> If the first argument is zero, then a zero of the same
+     * sign is returned.
+     * </ul>
+     *
+     * @param f number to be scaled by a power of two.
+     * @param scaleFactor power of 2 used to scale {@code f}
+     * @return {@code f} &times; 2<sup>{@code scaleFactor}</sup>
+     * @since 1.6
+     */
+    public static float scalb(float f, int scaleFactor) {
+        // magnitude of a power of two so large that scaling a finite
+        // nonzero value by it would be guaranteed to over or
+        // underflow; due to rounding, scaling down takes takes an
+        // additional power of two which is reflected here
+        final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
+                              FloatConsts.SIGNIFICAND_WIDTH + 1;
+
+        // Make sure scaling factor is in a reasonable range
+        scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);
+
+        /*
+         * Since + MAX_SCALE for float fits well within the double
+         * exponent range and + float -> double conversion is exact
+         * the multiplication below will be exact. Therefore, the
+         * rounding that occurs when the double product is cast to
+         * float will be the correctly rounded float result.  Since
+         * all operations other than the final multiply will be exact,
+         * it is not necessary to declare this method strictfp.
+         */
+        return (float)((double)f*powerOfTwoD(scaleFactor));
+    }
+
+    // Constants used in scalb
+    static double twoToTheDoubleScaleUp = powerOfTwoD(512);
+    static double twoToTheDoubleScaleDown = powerOfTwoD(-512);
+
+    /**
+     * Returns a floating-point power of two in the normal range.
+     */
+    static double powerOfTwoD(int n) {
+        assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
+        return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) <<
+                                        (DoubleConsts.SIGNIFICAND_WIDTH-1))
+                                       & DoubleConsts.EXP_BIT_MASK);
+    }
+
+    /**
+     * Returns a floating-point power of two in the normal range.
+     */
+    static float powerOfTwoF(int n) {
+        assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
+        return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
+                                     (FloatConsts.SIGNIFICAND_WIDTH-1))
+                                    & FloatConsts.EXP_BIT_MASK);
+    }
+}
diff --git a/java/lang/NegativeArraySizeException.java b/java/lang/NegativeArraySizeException.java
new file mode 100644
index 0000000..a90c815
--- /dev/null
+++ b/java/lang/NegativeArraySizeException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if an application tries to create an array with negative size.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class NegativeArraySizeException extends RuntimeException {
+    private static final long serialVersionUID = -8960118058596991861L;
+
+    /**
+     * Constructs a <code>NegativeArraySizeException</code> with no
+     * detail message.
+     */
+    public NegativeArraySizeException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NegativeArraySizeException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NegativeArraySizeException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/NoClassDefFoundError.java b/java/lang/NoClassDefFoundError.java
new file mode 100644
index 0000000..e4f764f
--- /dev/null
+++ b/java/lang/NoClassDefFoundError.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if the Java Virtual Machine or a <code>ClassLoader</code> instance
+ * tries to load in the definition of a class (as part of a normal method call
+ * or as part of creating a new instance using the <code>new</code> expression)
+ * and no definition of the class could be found.
+ * <p>
+ * The searched-for class definition existed when the currently
+ * executing class was compiled, but the definition can no longer be
+ * found.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class NoClassDefFoundError extends LinkageError {
+    private static final long serialVersionUID = 9095859863287012458L;
+
+    /**
+     * Constructs a <code>NoClassDefFoundError</code> with no detail message.
+     */
+    public NoClassDefFoundError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NoClassDefFoundError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NoClassDefFoundError(String s) {
+        super(s);
+    }
+
+    // Android-added: A new constructor for use by the Android runtime.
+    /**
+     * Constructs a new {@code NoClassDefFoundError} with the current stack
+     * trace, the specified detail message and the specified cause. Used
+     * internally by the Android runtime.
+     *
+     * @param detailMessage
+     *            the detail message for this error.
+     * @param throwable
+     *            the cause of this error.
+     */
+    private NoClassDefFoundError(String detailMessage, Throwable throwable) {
+        super(detailMessage, throwable);
+    }
+}
diff --git a/java/lang/NoSuchFieldError.java b/java/lang/NoSuchFieldError.java
new file mode 100644
index 0000000..735adbb
--- /dev/null
+++ b/java/lang/NoSuchFieldError.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown if an application tries to access or modify a specified
+ * field of an object, and that object no longer has that field.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class NoSuchFieldError extends IncompatibleClassChangeError {
+    private static final long serialVersionUID = -3456430195886129035L;
+
+    /**
+     * Constructs a <code>NoSuchFieldError</code> with no detail message.
+     */
+    public NoSuchFieldError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NoSuchFieldError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NoSuchFieldError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/NoSuchFieldException.java b/java/lang/NoSuchFieldException.java
new file mode 100644
index 0000000..0058264
--- /dev/null
+++ b/java/lang/NoSuchFieldException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1996, 2008, 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;
+
+/**
+ * Signals that the class doesn't have a field of a specified name.
+ *
+ * @author  unascribed
+ * @since   JDK1.1
+ */
+public class NoSuchFieldException extends ReflectiveOperationException {
+    private static final long serialVersionUID = -6143714805279938260L;
+
+    /**
+     * Constructor.
+     */
+    public NoSuchFieldException() {
+        super();
+    }
+
+    /**
+     * Constructor with a detail message.
+     *
+     * @param s the detail message
+     */
+    public NoSuchFieldException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/NoSuchMethodError.java b/java/lang/NoSuchMethodError.java
new file mode 100644
index 0000000..248de62
--- /dev/null
+++ b/java/lang/NoSuchMethodError.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if an application tries to call a specified method of a
+ * class (either static or instance), and that class no longer has a
+ * definition of that method.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class NoSuchMethodError extends IncompatibleClassChangeError {
+    private static final long serialVersionUID = -3765521442372831335L;
+
+    /**
+     * Constructs a <code>NoSuchMethodError</code> with no detail message.
+     */
+    public NoSuchMethodError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NoSuchMethodError</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NoSuchMethodError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/NoSuchMethodException.java b/java/lang/NoSuchMethodException.java
new file mode 100644
index 0000000..701437c
--- /dev/null
+++ b/java/lang/NoSuchMethodException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when a particular method cannot be found.
+ *
+ * @author     unascribed
+ * @since      JDK1.0
+ */
+public
+class NoSuchMethodException extends ReflectiveOperationException {
+    private static final long serialVersionUID = 5034388446362600923L;
+
+    /**
+     * Constructs a <code>NoSuchMethodException</code> without a detail message.
+     */
+    public NoSuchMethodException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NoSuchMethodException</code> with a detail message.
+     *
+     * @param      s   the detail message.
+     */
+    public NoSuchMethodException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/NullPointerException.java b/java/lang/NullPointerException.java
new file mode 100644
index 0000000..5b87ec4
--- /dev/null
+++ b/java/lang/NullPointerException.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * Thrown when an application attempts to use {@code null} in a
+ * case where an object is required. These include:
+ * <ul>
+ * <li>Calling the instance method of a {@code null} object.
+ * <li>Accessing or modifying the field of a {@code null} object.
+ * <li>Taking the length of {@code null} as if it were an array.
+ * <li>Accessing or modifying the slots of {@code null} as if it
+ *     were an array.
+ * <li>Throwing {@code null} as if it were a {@code Throwable}
+ *     value.
+ * </ul>
+ * <p>
+ * Applications should throw instances of this class to indicate
+ * other illegal uses of the {@code null} object.
+ *
+ * {@code NullPointerException} objects may be constructed by the
+ * virtual machine as if {@linkplain Throwable#Throwable(String,
+ * Throwable, boolean, boolean) suppression were disabled and/or the
+ * stack trace was not writable}.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class NullPointerException extends RuntimeException {
+    private static final long serialVersionUID = 5162710183389028792L;
+
+    /**
+     * Constructs a {@code NullPointerException} with no detail message.
+     */
+    public NullPointerException() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code NullPointerException} with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NullPointerException(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/Number.java b/java/lang/Number.java
new file mode 100644
index 0000000..d901609
--- /dev/null
+++ b/java/lang/Number.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * The abstract class {@code Number} is the superclass of platform
+ * classes representing numeric values that are convertible to the
+ * primitive types {@code byte}, {@code double}, {@code float}, {@code
+ * int}, {@code long}, and {@code short}.
+ *
+ * The specific semantics of the conversion from the numeric value of
+ * a particular {@code Number} implementation to a given primitive
+ * type is defined by the {@code Number} implementation in question.
+ *
+ * For platform classes, the conversion is often analogous to a
+ * narrowing primitive conversion or a widening primitive conversion
+ * as defining in <cite>The Java&trade; Language Specification</cite>
+ * for converting between primitive types.  Therefore, conversions may
+ * lose information about the overall magnitude of a numeric value, may
+ * lose precision, and may even return a result of a different sign
+ * than the input.
+ *
+ * See the documentation of a given {@code Number} implementation for
+ * conversion details.
+ *
+ * @author      Lee Boynton
+ * @author      Arthur van Hoff
+ * @jls 5.1.2 Widening Primitive Conversions
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since   JDK1.0
+ */
+public abstract class Number implements java.io.Serializable {
+    /**
+     * Returns the value of the specified number as an {@code int},
+     * which may involve rounding or truncation.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code int}.
+     */
+    public abstract int intValue();
+
+    /**
+     * Returns the value of the specified number as a {@code long},
+     * which may involve rounding or truncation.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code long}.
+     */
+    public abstract long longValue();
+
+    /**
+     * Returns the value of the specified number as a {@code float},
+     * which may involve rounding.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code float}.
+     */
+    public abstract float floatValue();
+
+    /**
+     * Returns the value of the specified number as a {@code double},
+     * which may involve rounding.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code double}.
+     */
+    public abstract double doubleValue();
+
+    /**
+     * Returns the value of the specified number as a {@code byte},
+     * which may involve rounding or truncation.
+     *
+     * <p>This implementation returns the result of {@link #intValue} cast
+     * to a {@code byte}.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code byte}.
+     * @since   JDK1.1
+     */
+    public byte byteValue() {
+        return (byte)intValue();
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code short},
+     * which may involve rounding or truncation.
+     *
+     * <p>This implementation returns the result of {@link #intValue} cast
+     * to a {@code short}.
+     *
+     * @return  the numeric value represented by this object after conversion
+     *          to type {@code short}.
+     * @since   JDK1.1
+     */
+    public short shortValue() {
+        return (short)intValue();
+    }
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -8742448824652078965L;
+}
diff --git a/java/lang/NumberFormatException.java b/java/lang/NumberFormatException.java
new file mode 100644
index 0000000..ea1ec9f
--- /dev/null
+++ b/java/lang/NumberFormatException.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1994, 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;
+
+/**
+ * Thrown to indicate that the application has attempted to convert
+ * a string to one of the numeric types, but that the string does not
+ * have the appropriate format.
+ *
+ * @author  unascribed
+ * @see     java.lang.Integer#parseInt(String)
+ * @since   JDK1.0
+ */
+public
+class NumberFormatException extends IllegalArgumentException {
+    static final long serialVersionUID = -2848938806368998894L;
+
+    /**
+     * Constructs a <code>NumberFormatException</code> with no detail message.
+     */
+    public NumberFormatException () {
+        super();
+    }
+
+    /**
+     * Constructs a <code>NumberFormatException</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public NumberFormatException (String s) {
+        super (s);
+    }
+
+    /**
+     * Factory method for making a <code>NumberFormatException</code>
+     * given the specified input which caused the error.
+     *
+     * @param   s   the input causing the error
+     */
+    static NumberFormatException forInputString(String s) {
+        return new NumberFormatException("For input string: \"" + s + "\"");
+    }
+}
diff --git a/java/lang/Object.annotated.java b/java/lang/Object.annotated.java
new file mode 100644
index 0000000..45939e8
--- /dev/null
+++ b/java/lang/Object.annotated.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Object {
+
+public Object() { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.Class<?> getClass() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final native void notify();
+
+public final native void notifyAll();
+
+public final void wait(long timeout) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final native void wait(long timeout, int nanos) throws java.lang.InterruptedException;
+
+public final void wait() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected void finalize() throws java.lang.Throwable { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Object.java b/java/lang/Object.java
new file mode 100644
index 0000000..d307144
--- /dev/null
+++ b/java/lang/Object.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * Class {@code Object} is the root of the class hierarchy.
+ * Every class has {@code Object} as a superclass. All objects,
+ * including arrays, implement the methods of this class.
+ *
+ * @author  unascribed
+ * @see     java.lang.Class
+ * @since   JDK1.0
+ */
+public class Object {
+
+    // Android-removed: registerNatives() not used on Android
+    // private static native void registerNatives();
+    // static {
+    //     registerNatives();
+    // }
+
+    // Android-added: Use Android specific fields for Class and monitor.
+    private transient Class<?> shadow$_klass_;
+    private transient int shadow$_monitor_;
+
+    /**
+     * Returns the runtime class of this {@code Object}. The returned
+     * {@code Class} object is the object that is locked by {@code
+     * static synchronized} methods of the represented class.
+     *
+     * <p><b>The actual result type is {@code Class<? extends |X|>}
+     * where {@code |X|} is the erasure of the static type of the
+     * expression on which {@code getClass} is called.</b> For
+     * example, no cast is required in this code fragment:</p>
+     *
+     * <p>
+     * {@code Number n = 0;                             }<br>
+     * {@code Class<? extends Number> c = n.getClass(); }
+     * </p>
+     *
+     * @return The {@code Class} object that represents the runtime
+     *         class of this object.
+     * @jls 15.8.2 Class Literals
+     */
+    // Android-changed: Use Android specific fields for Class and monitor.
+    // public final native Class<?> getClass();
+    public final Class<?> getClass() {
+      return shadow$_klass_;
+    }
+
+    /**
+     * Returns a hash code value for the object. This method is
+     * supported for the benefit of hash tables such as those provided by
+     * {@link java.util.HashMap}.
+     * <p>
+     * The general contract of {@code hashCode} is:
+     * <ul>
+     * <li>Whenever it is invoked on the same object more than once during
+     *     an execution of a Java application, the {@code hashCode} method
+     *     must consistently return the same integer, provided no information
+     *     used in {@code equals} comparisons on the object is modified.
+     *     This integer need not remain consistent from one execution of an
+     *     application to another execution of the same application.
+     * <li>If two objects are equal according to the {@code equals(Object)}
+     *     method, then calling the {@code hashCode} method on each of
+     *     the two objects must produce the same integer result.
+     * <li>It is <em>not</em> required that if two objects are unequal
+     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
+     *     method, then calling the {@code hashCode} method on each of the
+     *     two objects must produce distinct integer results.  However, the
+     *     programmer should be aware that producing distinct integer results
+     *     for unequal objects may improve the performance of hash tables.
+     * </ul>
+     * <p>
+     * As much as is reasonably practical, the hashCode method defined by
+     * class {@code Object} does return distinct integers for distinct
+     * objects. (This is typically implemented by converting the internal
+     * address of the object into an integer, but this implementation
+     * technique is not required by the
+     * Java&trade; programming language.)
+     *
+     * @return  a hash code value for this object.
+     * @see     java.lang.Object#equals(java.lang.Object)
+     * @see     java.lang.System#identityHashCode
+     */
+    // BEGIN Android-changed: Added a local helper for identityHashCode.
+    // public native int hashCode();
+    public int hashCode() {
+        return identityHashCode(this);
+    }
+
+    // Package-private to be used by j.l.System. We do the implementation here
+    // to avoid Object.hashCode doing a clinit check on j.l.System, and also
+    // to avoid leaking shadow$_monitor_ outside of this class.
+    /* package-private */ static int identityHashCode(Object obj) {
+        int lockWord = obj.shadow$_monitor_;
+        final int lockWordStateMask = 0xC0000000;  // Top 2 bits.
+        final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
+        final int lockWordHashMask = 0x0FFFFFFF;  // Low 28 bits.
+        if ((lockWord & lockWordStateMask) == lockWordStateHash) {
+            return lockWord & lockWordHashMask;
+        }
+        return identityHashCodeNative(obj);
+    }
+
+    /**
+     * Return the identity hash code when the information in the monitor field
+     * is not sufficient.
+     */
+    @FastNative
+    private static native int identityHashCodeNative(Object obj);
+    // END Android-changed: Added a local helper for identityHashCode.
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     * <p>
+     * The {@code equals} method implements an equivalence relation
+     * on non-null object references:
+     * <ul>
+     * <li>It is <i>reflexive</i>: for any non-null reference value
+     *     {@code x}, {@code x.equals(x)} should return
+     *     {@code true}.
+     * <li>It is <i>symmetric</i>: for any non-null reference values
+     *     {@code x} and {@code y}, {@code x.equals(y)}
+     *     should return {@code true} if and only if
+     *     {@code y.equals(x)} returns {@code true}.
+     * <li>It is <i>transitive</i>: for any non-null reference values
+     *     {@code x}, {@code y}, and {@code z}, if
+     *     {@code x.equals(y)} returns {@code true} and
+     *     {@code y.equals(z)} returns {@code true}, then
+     *     {@code x.equals(z)} should return {@code true}.
+     * <li>It is <i>consistent</i>: for any non-null reference values
+     *     {@code x} and {@code y}, multiple invocations of
+     *     {@code x.equals(y)} consistently return {@code true}
+     *     or consistently return {@code false}, provided no
+     *     information used in {@code equals} comparisons on the
+     *     objects is modified.
+     * <li>For any non-null reference value {@code x},
+     *     {@code x.equals(null)} should return {@code false}.
+     * </ul>
+     * <p>
+     * The {@code equals} method for class {@code Object} implements
+     * the most discriminating possible equivalence relation on objects;
+     * that is, for any non-null reference values {@code x} and
+     * {@code y}, this method returns {@code true} if and only
+     * if {@code x} and {@code y} refer to the same object
+     * ({@code x == y} has the value {@code true}).
+     * <p>
+     * Note that it is generally necessary to override the {@code hashCode}
+     * method whenever this method is overridden, so as to maintain the
+     * general contract for the {@code hashCode} method, which states
+     * that equal objects must have equal hash codes.
+     *
+     * @param   obj   the reference object with which to compare.
+     * @return  {@code true} if this object is the same as the obj
+     *          argument; {@code false} otherwise.
+     * @see     #hashCode()
+     * @see     java.util.HashMap
+     */
+    public boolean equals(Object obj) {
+        return (this == obj);
+    }
+
+    /**
+     * Creates and returns a copy of this object.  The precise meaning
+     * of "copy" may depend on the class of the object. The general
+     * intent is that, for any object {@code x}, the expression:
+     * <blockquote>
+     * <pre>
+     * x.clone() != x</pre></blockquote>
+     * will be true, and that the expression:
+     * <blockquote>
+     * <pre>
+     * x.clone().getClass() == x.getClass()</pre></blockquote>
+     * will be {@code true}, but these are not absolute requirements.
+     * While it is typically the case that:
+     * <blockquote>
+     * <pre>
+     * x.clone().equals(x)</pre></blockquote>
+     * will be {@code true}, this is not an absolute requirement.
+     * <p>
+     * By convention, the returned object should be obtained by calling
+     * {@code super.clone}.  If a class and all of its superclasses (except
+     * {@code Object}) obey this convention, it will be the case that
+     * {@code x.clone().getClass() == x.getClass()}.
+     * <p>
+     * By convention, the object returned by this method should be independent
+     * of this object (which is being cloned).  To achieve this independence,
+     * it may be necessary to modify one or more fields of the object returned
+     * by {@code super.clone} before returning it.  Typically, this means
+     * copying any mutable objects that comprise the internal "deep structure"
+     * of the object being cloned and replacing the references to these
+     * objects with references to the copies.  If a class contains only
+     * primitive fields or references to immutable objects, then it is usually
+     * the case that no fields in the object returned by {@code super.clone}
+     * need to be modified.
+     * <p>
+     * The method {@code clone} for class {@code Object} performs a
+     * specific cloning operation. First, if the class of this object does
+     * not implement the interface {@code Cloneable}, then a
+     * {@code CloneNotSupportedException} is thrown. Note that all arrays
+     * are considered to implement the interface {@code Cloneable} and that
+     * the return type of the {@code clone} method of an array type {@code T[]}
+     * is {@code T[]} where T is any reference or primitive type.
+     * Otherwise, this method creates a new instance of the class of this
+     * object and initializes all its fields with exactly the contents of
+     * the corresponding fields of this object, as if by assignment; the
+     * contents of the fields are not themselves cloned. Thus, this method
+     * performs a "shallow copy" of this object, not a "deep copy" operation.
+     * <p>
+     * The class {@code Object} does not itself implement the interface
+     * {@code Cloneable}, so calling the {@code clone} method on an object
+     * whose class is {@code Object} will result in throwing an
+     * exception at run time.
+     *
+     * @return     a clone of this instance.
+     * @throws  CloneNotSupportedException  if the object's class does not
+     *               support the {@code Cloneable} interface. Subclasses
+     *               that override the {@code clone} method can also
+     *               throw this exception to indicate that an instance cannot
+     *               be cloned.
+     * @see java.lang.Cloneable
+     */
+    // BEGIN Android-changed: Use native local helper for clone()
+    // Checks whether cloning is allowed before calling native local helper.
+    // protected native Object clone() throws CloneNotSupportedException;
+    protected Object clone() throws CloneNotSupportedException {
+        if (!(this instanceof Cloneable)) {
+            throw new CloneNotSupportedException("Class " + getClass().getName() +
+                                                 " doesn't implement Cloneable");
+        }
+
+        return internalClone();
+    }
+
+    /*
+     * Native helper method for cloning.
+     */
+    @FastNative
+    private native Object internalClone();
+    // END Android-changed: Use native local helper for clone()
+
+    /**
+     * Returns a string representation of the object. In general, the
+     * {@code toString} method returns a string that
+     * "textually represents" this object. The result should
+     * be a concise but informative representation that is easy for a
+     * person to read.
+     * It is recommended that all subclasses override this method.
+     * <p>
+     * The {@code toString} method for class {@code Object}
+     * returns a string consisting of the name of the class of which the
+     * object is an instance, the at-sign character `{@code @}', and
+     * the unsigned hexadecimal representation of the hash code of the
+     * object. In other words, this method returns a string equal to the
+     * value of:
+     * <blockquote>
+     * <pre>
+     * getClass().getName() + '@' + Integer.toHexString(hashCode())
+     * </pre></blockquote>
+     *
+     * @return  a string representation of the object.
+     */
+    public String toString() {
+        return getClass().getName() + "@" + Integer.toHexString(hashCode());
+    }
+
+    /**
+     * Wakes up a single thread that is waiting on this object's
+     * monitor. If any threads are waiting on this object, one of them
+     * is chosen to be awakened. The choice is arbitrary and occurs at
+     * the discretion of the implementation. A thread waits on an object's
+     * monitor by calling one of the {@code wait} methods.
+     * <p>
+     * The awakened thread will not be able to proceed until the current
+     * thread relinquishes the lock on this object. The awakened thread will
+     * compete in the usual manner with any other threads that might be
+     * actively competing to synchronize on this object; for example, the
+     * awakened thread enjoys no reliable privilege or disadvantage in being
+     * the next thread to lock this object.
+     * <p>
+     * This method should only be called by a thread that is the owner
+     * of this object's monitor. A thread becomes the owner of the
+     * object's monitor in one of three ways:
+     * <ul>
+     * <li>By executing a synchronized instance method of that object.
+     * <li>By executing the body of a {@code synchronized} statement
+     *     that synchronizes on the object.
+     * <li>For objects of type {@code Class,} by executing a
+     *     synchronized static method of that class.
+     * </ul>
+     * <p>
+     * Only one thread at a time can own an object's monitor.
+     *
+     * @throws  IllegalMonitorStateException  if the current thread is not
+     *               the owner of this object's monitor.
+     * @see        java.lang.Object#notifyAll()
+     * @see        java.lang.Object#wait()
+     */
+    @FastNative
+    public final native void notify();
+
+    /**
+     * Wakes up all threads that are waiting on this object's monitor. A
+     * thread waits on an object's monitor by calling one of the
+     * {@code wait} methods.
+     * <p>
+     * The awakened threads will not be able to proceed until the current
+     * thread relinquishes the lock on this object. The awakened threads
+     * will compete in the usual manner with any other threads that might
+     * be actively competing to synchronize on this object; for example,
+     * the awakened threads enjoy no reliable privilege or disadvantage in
+     * being the next thread to lock this object.
+     * <p>
+     * This method should only be called by a thread that is the owner
+     * of this object's monitor. See the {@code notify} method for a
+     * description of the ways in which a thread can become the owner of
+     * a monitor.
+     *
+     * @throws  IllegalMonitorStateException  if the current thread is not
+     *               the owner of this object's monitor.
+     * @see        java.lang.Object#notify()
+     * @see        java.lang.Object#wait()
+     */
+    @FastNative
+    public final native void notifyAll();
+
+    /**
+     * Causes the current thread to wait until either another thread invokes the
+     * {@link java.lang.Object#notify()} method or the
+     * {@link java.lang.Object#notifyAll()} method for this object, or a
+     * specified amount of time has elapsed.
+     * <p>
+     * The current thread must own this object's monitor.
+     * <p>
+     * This method causes the current thread (call it <var>T</var>) to
+     * place itself in the wait set for this object and then to relinquish
+     * any and all synchronization claims on this object. Thread <var>T</var>
+     * becomes disabled for thread scheduling purposes and lies dormant
+     * until one of four things happens:
+     * <ul>
+     * <li>Some other thread invokes the {@code notify} method for this
+     * object and thread <var>T</var> happens to be arbitrarily chosen as
+     * the thread to be awakened.
+     * <li>Some other thread invokes the {@code notifyAll} method for this
+     * object.
+     * <li>Some other thread {@linkplain Thread#interrupt() interrupts}
+     * thread <var>T</var>.
+     * <li>The specified amount of real time has elapsed, more or less.  If
+     * {@code timeout} is zero, however, then real time is not taken into
+     * consideration and the thread simply waits until notified.
+     * </ul>
+     * The thread <var>T</var> is then removed from the wait set for this
+     * object and re-enabled for thread scheduling. It then competes in the
+     * usual manner with other threads for the right to synchronize on the
+     * object; once it has gained control of the object, all its
+     * synchronization claims on the object are restored to the status quo
+     * ante - that is, to the situation as of the time that the {@code wait}
+     * method was invoked. Thread <var>T</var> then returns from the
+     * invocation of the {@code wait} method. Thus, on return from the
+     * {@code wait} method, the synchronization state of the object and of
+     * thread {@code T} is exactly as it was when the {@code wait} method
+     * was invoked.
+     * <p>
+     * A thread can also wake up without being notified, interrupted, or
+     * timing out, a so-called <i>spurious wakeup</i>.  While this will rarely
+     * occur in practice, applications must guard against it by testing for
+     * the condition that should have caused the thread to be awakened, and
+     * continuing to wait if the condition is not satisfied.  In other words,
+     * waits should always occur in loops, like this one:
+     * <pre>
+     *     synchronized (obj) {
+     *         while (&lt;condition does not hold&gt;)
+     *             obj.wait(timeout);
+     *         ... // Perform action appropriate to condition
+     *     }
+     * </pre>
+     * (For more information on this topic, see Section 3.2.3 in Doug Lea's
+     * "Concurrent Programming in Java (Second Edition)" (Addison-Wesley,
+     * 2000), or Item 50 in Joshua Bloch's "Effective Java Programming
+     * Language Guide" (Addison-Wesley, 2001).
+     *
+     * <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
+     * interrupted} by any thread before or while it is waiting, then an
+     * {@code InterruptedException} is thrown.  This exception is not
+     * thrown until the lock status of this object has been restored as
+     * described above.
+     *
+     * <p>
+     * Note that the {@code wait} method, as it places the current thread
+     * into the wait set for this object, unlocks only this object; any
+     * other objects on which the current thread may be synchronized remain
+     * locked while the thread waits.
+     * <p>
+     * This method should only be called by a thread that is the owner
+     * of this object's monitor. See the {@code notify} method for a
+     * description of the ways in which a thread can become the owner of
+     * a monitor.
+     *
+     * @param      timeout   the maximum time to wait in milliseconds.
+     * @throws  IllegalArgumentException      if the value of timeout is
+     *               negative.
+     * @throws  IllegalMonitorStateException  if the current thread is not
+     *               the owner of the object's monitor.
+     * @throws  InterruptedException if any thread interrupted the
+     *             current thread before or while the current thread
+     *             was waiting for a notification.  The <i>interrupted
+     *             status</i> of the current thread is cleared when
+     *             this exception is thrown.
+     * @see        java.lang.Object#notify()
+     * @see        java.lang.Object#notifyAll()
+     */
+    // Android-changed: Implement wait(long) non-natively.
+    // public final native void wait(long timeout) throws InterruptedException;
+    public final void wait(long timeout) throws InterruptedException {
+        wait(timeout, 0);
+    }
+
+    /**
+     * Causes the current thread to wait until another thread invokes the
+     * {@link java.lang.Object#notify()} method or the
+     * {@link java.lang.Object#notifyAll()} method for this object, or
+     * some other thread interrupts the current thread, or a certain
+     * amount of real time has elapsed.
+     * <p>
+     * This method is similar to the {@code wait} method of one
+     * argument, but it allows finer control over the amount of time to
+     * wait for a notification before giving up. The amount of real time,
+     * measured in nanoseconds, is given by:
+     * <blockquote>
+     * <pre>
+     * 1000000*timeout+nanos</pre></blockquote>
+     * <p>
+     * In all other respects, this method does the same thing as the
+     * method {@link #wait(long)} of one argument. In particular,
+     * {@code wait(0, 0)} means the same thing as {@code wait(0)}.
+     * <p>
+     * The current thread must own this object's monitor. The thread
+     * releases ownership of this monitor and waits until either of the
+     * following two conditions has occurred:
+     * <ul>
+     * <li>Another thread notifies threads waiting on this object's monitor
+     *     to wake up either through a call to the {@code notify} method
+     *     or the {@code notifyAll} method.
+     * <li>The timeout period, specified by {@code timeout}
+     *     milliseconds plus {@code nanos} nanoseconds arguments, has
+     *     elapsed.
+     * </ul>
+     * <p>
+     * The thread then waits until it can re-obtain ownership of the
+     * monitor and resumes execution.
+     * <p>
+     * As in the one argument version, interrupts and spurious wakeups are
+     * possible, and this method should always be used in a loop:
+     * <pre>
+     *     synchronized (obj) {
+     *         while (&lt;condition does not hold&gt;)
+     *             obj.wait(timeout, nanos);
+     *         ... // Perform action appropriate to condition
+     *     }
+     * </pre>
+     * This method should only be called by a thread that is the owner
+     * of this object's monitor. See the {@code notify} method for a
+     * description of the ways in which a thread can become the owner of
+     * a monitor.
+     *
+     * @param      timeout   the maximum time to wait in milliseconds.
+     * @param      nanos      additional time, in nanoseconds range
+     *                       0-999999.
+     * @throws  IllegalArgumentException      if the value of timeout is
+     *                      negative or the value of nanos is
+     *                      not in the range 0-999999.
+     * @throws  IllegalMonitorStateException  if the current thread is not
+     *               the owner of this object's monitor.
+     * @throws  InterruptedException if any thread interrupted the
+     *             current thread before or while the current thread
+     *             was waiting for a notification.  The <i>interrupted
+     *             status</i> of the current thread is cleared when
+     *             this exception is thrown.
+     */
+    // Android-changed: Implement wait(long, int) natively.
+    /*
+    public final void wait(long timeout, int nanos) throws InterruptedException {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+
+        if (nanos > 0) {
+            timeout++;
+        }
+
+        wait(timeout);
+    }
+    */
+    @FastNative
+    public final native void wait(long timeout, int nanos) throws InterruptedException;
+
+    /**
+     * Causes the current thread to wait until another thread invokes the
+     * {@link java.lang.Object#notify()} method or the
+     * {@link java.lang.Object#notifyAll()} method for this object.
+     * In other words, this method behaves exactly as if it simply
+     * performs the call {@code wait(0)}.
+     * <p>
+     * The current thread must own this object's monitor. The thread
+     * releases ownership of this monitor and waits until another thread
+     * notifies threads waiting on this object's monitor to wake up
+     * either through a call to the {@code notify} method or the
+     * {@code notifyAll} method. The thread then waits until it can
+     * re-obtain ownership of the monitor and resumes execution.
+     * <p>
+     * As in the one argument version, interrupts and spurious wakeups are
+     * possible, and this method should always be used in a loop:
+     * <pre>
+     *     synchronized (obj) {
+     *         while (&lt;condition does not hold&gt;)
+     *             obj.wait();
+     *         ... // Perform action appropriate to condition
+     *     }
+     * </pre>
+     * This method should only be called by a thread that is the owner
+     * of this object's monitor. See the {@code notify} method for a
+     * description of the ways in which a thread can become the owner of
+     * a monitor.
+     *
+     * @throws  IllegalMonitorStateException  if the current thread is not
+     *               the owner of the object's monitor.
+     * @throws  InterruptedException if any thread interrupted the
+     *             current thread before or while the current thread
+     *             was waiting for a notification.  The <i>interrupted
+     *             status</i> of the current thread is cleared when
+     *             this exception is thrown.
+     * @see        java.lang.Object#notify()
+     * @see        java.lang.Object#notifyAll()
+     */
+    public final void wait() throws InterruptedException {
+        wait(0);
+    }
+
+    /**
+     * Called by the garbage collector on an object when garbage collection
+     * determines that there are no more references to the object.
+     * A subclass overrides the {@code finalize} method to dispose of
+     * system resources or to perform other cleanup.
+     * <p>
+     * The general contract of {@code finalize} is that it is invoked
+     * if and when the Java&trade; virtual
+     * machine has determined that there is no longer any
+     * means by which this object can be accessed by any thread that has
+     * not yet died, except as a result of an action taken by the
+     * finalization of some other object or class which is ready to be
+     * finalized. The {@code finalize} method may take any action, including
+     * making this object available again to other threads; the usual purpose
+     * of {@code finalize}, however, is to perform cleanup actions before
+     * the object is irrevocably discarded. For example, the finalize method
+     * for an object that represents an input/output connection might perform
+     * explicit I/O transactions to break the connection before the object is
+     * permanently discarded.
+     * <p>
+     * The {@code finalize} method of class {@code Object} performs no
+     * special action; it simply returns normally. Subclasses of
+     * {@code Object} may override this definition.
+     * <p>
+     * The Java programming language does not guarantee which thread will
+     * invoke the {@code finalize} method for any given object. It is
+     * guaranteed, however, that the thread that invokes finalize will not
+     * be holding any user-visible synchronization locks when finalize is
+     * invoked. If an uncaught exception is thrown by the finalize method,
+     * the exception is ignored and finalization of that object terminates.
+     * <p>
+     * After the {@code finalize} method has been invoked for an object, no
+     * further action is taken until the Java virtual machine has again
+     * determined that there is no longer any means by which this object can
+     * be accessed by any thread that has not yet died, including possible
+     * actions by other objects or classes which are ready to be finalized,
+     * at which point the object may be discarded.
+     * <p>
+     * The {@code finalize} method is never invoked more than once by a Java
+     * virtual machine for any given object.
+     * <p>
+     * Any exception thrown by the {@code finalize} method causes
+     * the finalization of this object to be halted, but is otherwise
+     * ignored.
+     *
+     * @throws Throwable the {@code Exception} raised by this method
+     * @see java.lang.ref.WeakReference
+     * @see java.lang.ref.PhantomReference
+     * @jls 12.6 Finalization of Class Instances
+     */
+    protected void finalize() throws Throwable { }
+}
diff --git a/java/lang/OutOfMemoryError.java b/java/lang/OutOfMemoryError.java
new file mode 100644
index 0000000..0f9df4e
--- /dev/null
+++ b/java/lang/OutOfMemoryError.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 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 java.lang;
+
+/**
+ * Thrown when the Java Virtual Machine cannot allocate an object
+ * because it is out of memory, and no more memory could be made
+ * available by the garbage collector.
+ *
+ * {@code OutOfMemoryError} objects may be constructed by the virtual
+ * machine as if {@linkplain Throwable#Throwable(String, Throwable,
+ * boolean, boolean) suppression were disabled and/or the stack trace was not
+ * writable}.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public class OutOfMemoryError extends VirtualMachineError {
+    private static final long serialVersionUID = 8228564086184010517L;
+
+    /**
+     * Constructs an {@code OutOfMemoryError} with no detail message.
+     */
+    public OutOfMemoryError() {
+        super();
+    }
+
+    /**
+     * Constructs an {@code OutOfMemoryError} with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public OutOfMemoryError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/Override.java b/java/lang/Override.java
new file mode 100644
index 0000000..bf77344
--- /dev/null
+++ b/java/lang/Override.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that a method declaration is intended to override a
+ * method declaration in a supertype. If a method is annotated with
+ * this annotation type compilers are required to generate an error
+ * message unless at least one of the following conditions hold:
+ *
+ * <ul><li>
+ * The method does override or implement a method declared in a
+ * supertype.
+ * </li><li>
+ * The method has a signature that is override-equivalent to that of
+ * any public method declared in {@linkplain Object}.
+ * </li></ul>
+ *
+ * @author  Peter von der Ah&eacute;
+ * @author  Joshua Bloch
+ * @jls 9.6.1.4 @Override
+ * @since 1.5
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Override {
+}
diff --git a/java/lang/Package.java b/java/lang/Package.java
new file mode 100644
index 0000000..b6a37fd
--- /dev/null
+++ b/java/lang/Package.java
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 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;
+
+import java.lang.reflect.AnnotatedElement;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import java.util.StringTokenizer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarException;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import sun.net.www.ParseUtil;
+import sun.reflect.CallerSensitive;
+import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * {@code Package} objects contain version information
+ * about the implementation and specification of a Java package.
+ * This versioning information is retrieved and made available
+ * by the {@link ClassLoader} instance that
+ * loaded the class(es).  Typically, it is stored in the manifest that is
+ * distributed with the classes.
+ *
+ * <p>The set of classes that make up the package may implement a
+ * particular specification and if so the specification title, version number,
+ * and vendor strings identify that specification.
+ * An application can ask if the package is
+ * compatible with a particular version, see the {@link
+ * #isCompatibleWith isCompatibleWith}
+ * method for details.
+ *
+ * <p>Specification version numbers use a syntax that consists of nonnegative
+ * decimal integers separated by periods ".", for example "2.0" or
+ * "1.2.3.4.5.6.7".  This allows an extensible number to be used to represent
+ * major, minor, micro, etc. versions.  The version specification is described
+ * by the following formal grammar:
+ * <blockquote>
+ * <dl>
+ * <dt><i>SpecificationVersion:</i>
+ * <dd><i>Digits RefinedVersion<sub>opt</sub></i>
+
+ * <dt><i>RefinedVersion:</i>
+ * <dd>{@code .} <i>Digits</i>
+ * <dd>{@code .} <i>Digits RefinedVersion</i>
+ *
+ * <dt><i>Digits:</i>
+ * <dd><i>Digit</i>
+ * <dd><i>Digits</i>
+ *
+ * <dt><i>Digit:</i>
+ * <dd>any character for which {@link Character#isDigit} returns {@code true},
+ * e.g. 0, 1, 2, ...
+ * </dl>
+ * </blockquote>
+ *
+ * <p>The implementation title, version, and vendor strings identify an
+ * implementation and are made available conveniently to enable accurate
+ * reporting of the packages involved when a problem occurs. The contents
+ * all three implementation strings are vendor specific. The
+ * implementation version strings have no specified syntax and should
+ * only be compared for equality with desired version identifiers.
+ *
+ * <p>Within each {@code ClassLoader} instance all classes from the same
+ * java package have the same Package object.  The static methods allow a package
+ * to be found by name or the set of all packages known to the current class
+ * loader to be found.
+ *
+ * @see ClassLoader#definePackage
+ */
+public class Package implements java.lang.reflect.AnnotatedElement {
+    /**
+     * Return the name of this package.
+     *
+     * @return  The fully-qualified name of this package as defined in section 6.5.3 of
+     *          <cite>The Java&trade; Language Specification</cite>,
+     *          for example, {@code java.lang}
+     */
+    public String getName() {
+        return pkgName;
+    }
+
+
+    /**
+     * Return the title of the specification that this package implements.
+     * @return the specification title, null is returned if it is not known.
+     */
+    public String getSpecificationTitle() {
+        return specTitle;
+    }
+
+    /**
+     * Returns the version number of the specification
+     * that this package implements.
+     * This version string must be a sequence of nonnegative decimal
+     * integers separated by "."'s and may have leading zeros.
+     * When version strings are compared the most significant
+     * numbers are compared.
+     * @return the specification version, null is returned if it is not known.
+     */
+    public String getSpecificationVersion() {
+        return specVersion;
+    }
+
+    /**
+     * Return the name of the organization, vendor,
+     * or company that owns and maintains the specification
+     * of the classes that implement this package.
+     * @return the specification vendor, null is returned if it is not known.
+     */
+    public String getSpecificationVendor() {
+        return specVendor;
+    }
+
+    /**
+     * Return the title of this package.
+     * @return the title of the implementation, null is returned if it is not known.
+     */
+    public String getImplementationTitle() {
+        return implTitle;
+    }
+
+    /**
+     * Return the version of this implementation. It consists of any string
+     * assigned by the vendor of this implementation and does
+     * not have any particular syntax specified or expected by the Java
+     * runtime. It may be compared for equality with other
+     * package version strings used for this implementation
+     * by this vendor for this package.
+     * @return the version of the implementation, null is returned if it is not known.
+     */
+    public String getImplementationVersion() {
+        return implVersion;
+    }
+
+    /**
+     * Returns the name of the organization,
+     * vendor or company that provided this implementation.
+     * @return the vendor that implemented this package..
+     */
+    public String getImplementationVendor() {
+        return implVendor;
+    }
+
+    /**
+     * Returns true if this package is sealed.
+     *
+     * @return true if the package is sealed, false otherwise
+     */
+    public boolean isSealed() {
+        return sealBase != null;
+    }
+
+    /**
+     * Returns true if this package is sealed with respect to the specified
+     * code source url.
+     *
+     * @param url the code source url
+     * @return true if this package is sealed with respect to url
+     */
+    public boolean isSealed(URL url) {
+        return url.equals(sealBase);
+    }
+
+    /**
+     * Compare this package's specification version with a
+     * desired version. It returns true if
+     * this packages specification version number is greater than or equal
+     * to the desired version number. <p>
+     *
+     * Version numbers are compared by sequentially comparing corresponding
+     * components of the desired and specification strings.
+     * Each component is converted as a decimal integer and the values
+     * compared.
+     * If the specification value is greater than the desired
+     * value true is returned. If the value is less false is returned.
+     * If the values are equal the period is skipped and the next pair of
+     * components is compared.
+     *
+     * @param desired the version string of the desired version.
+     * @return true if this package's version number is greater
+     *          than or equal to the desired version number
+     *
+     * @exception NumberFormatException if the desired or current version
+     *          is not of the correct dotted form.
+     */
+    public boolean isCompatibleWith(String desired)
+        throws NumberFormatException
+    {
+        if (specVersion == null || specVersion.length() < 1) {
+            throw new NumberFormatException("Empty version string");
+        }
+
+        String [] sa = specVersion.split("\\.", -1);
+        int [] si = new int[sa.length];
+        for (int i = 0; i < sa.length; i++) {
+            si[i] = Integer.parseInt(sa[i]);
+            if (si[i] < 0)
+                throw NumberFormatException.forInputString("" + si[i]);
+        }
+
+        String [] da = desired.split("\\.", -1);
+        int [] di = new int[da.length];
+        for (int i = 0; i < da.length; i++) {
+            di[i] = Integer.parseInt(da[i]);
+            if (di[i] < 0)
+                throw NumberFormatException.forInputString("" + di[i]);
+        }
+
+        int len = Math.max(di.length, si.length);
+        for (int i = 0; i < len; i++) {
+            int d = (i < di.length ? di[i] : 0);
+            int s = (i < si.length ? si[i] : 0);
+            if (s < d)
+                return false;
+            if (s > d)
+                return true;
+        }
+        return true;
+    }
+
+    /**
+     * Find a package by name in the callers {@code ClassLoader} instance.
+     * The callers {@code ClassLoader} instance is used to find the package
+     * instance corresponding to the named class. If the callers
+     * {@code ClassLoader} instance is null then the set of packages loaded
+     * by the system {@code ClassLoader} instance is searched to find the
+     * named package. <p>
+     *
+     * Packages have attributes for versions and specifications only if the class
+     * loader created the package instance with the appropriate attributes. Typically,
+     * those attributes are defined in the manifests that accompany the classes.
+     *
+     * @param name a package name, for example, java.lang.
+     * @return the package of the requested name. It may be null if no package
+     *          information is available from the archive or codebase.
+     */
+    @CallerSensitive
+    public static Package getPackage(String name) {
+        ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+        if (l != null) {
+            return l.getPackage(name);
+        } else {
+            return getSystemPackage(name);
+        }
+    }
+
+    /**
+     * Get all the packages currently known for the caller's {@code ClassLoader}
+     * instance.  Those packages correspond to classes loaded via or accessible by
+     * name to that {@code ClassLoader} instance.  If the caller's
+     * {@code ClassLoader} instance is the bootstrap {@code ClassLoader}
+     * instance, which may be represented by {@code null} in some implementations,
+     * only packages corresponding to classes loaded by the bootstrap
+     * {@code ClassLoader} instance will be returned.
+     *
+     * @return a new array of packages known to the callers {@code ClassLoader}
+     * instance.  An zero length array is returned if none are known.
+     */
+    @CallerSensitive
+    public static Package[] getPackages() {
+        ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+        if (l != null) {
+            return l.getPackages();
+        } else {
+            return getSystemPackages();
+        }
+    }
+
+    /**
+     * Get the package for the specified class.
+     * The class's class loader is used to find the package instance
+     * corresponding to the specified class. If the class loader
+     * is the bootstrap class loader, which may be represented by
+     * {@code null} in some implementations, then the set of packages
+     * loaded by the bootstrap class loader is searched to find the package.
+     * <p>
+     * Packages have attributes for versions and specifications only
+     * if the class loader created the package
+     * instance with the appropriate attributes. Typically those
+     * attributes are defined in the manifests that accompany
+     * the classes.
+     *
+     * @param c the class to get the package of.
+     * @return the package of the class. It may be null if no package
+     *          information is available from the archive or codebase.  */
+    static Package getPackage(Class<?> c) {
+        String name = c.getName();
+        int i = name.lastIndexOf('.');
+        if (i != -1) {
+            name = name.substring(0, i);
+            ClassLoader cl = c.getClassLoader();
+            if (cl != null) {
+                return cl.getPackage(name);
+            } else {
+                return getSystemPackage(name);
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Return the hash code computed from the package name.
+     * @return the hash code computed from the package name.
+     */
+    public int hashCode(){
+        return pkgName.hashCode();
+    }
+
+    /**
+     * Returns the string representation of this Package.
+     * Its value is the string "package " and the package name.
+     * If the package title is defined it is appended.
+     * If the package version is defined it is appended.
+     * @return the string representation of the package.
+     */
+    public String toString() {
+        // BEGIN Android-added: Backwards compatibility fix for target API <= 24.
+        // Several apps try to parse the output of toString(). This is a really
+        // bad idea - especially when there's a Package.getName() function as well as a
+        // Class.getName() function that can be used instead.
+        // Starting from the API level 25 the proper output is generated.
+        final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+        if (targetSdkVersion > 0 && targetSdkVersion <= 24) {
+            return "package " + pkgName;
+        }
+        // END Android-added: Backwards compatibility fix for target API <= 24.
+
+        String spec = specTitle;
+        String ver =  specVersion;
+        if (spec != null && spec.length() > 0)
+            spec = ", " + spec;
+        else
+            spec = "";
+        if (ver != null && ver.length() > 0)
+            ver = ", version " + ver;
+        else
+            ver = "";
+        return "package " + pkgName + spec + ver;
+    }
+
+    private Class<?> getPackageInfo() {
+        if (packageInfo == null) {
+            try {
+                packageInfo = Class.forName(pkgName + ".package-info", false, loader);
+            } catch (ClassNotFoundException ex) {
+                // store a proxy for the package info that has no annotations
+                class PackageInfoProxy {}
+                packageInfo = PackageInfoProxy.class;
+            }
+        }
+        return packageInfo;
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+        return getPackageInfo().getAnnotation(annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public  <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
+        return getPackageInfo().getAnnotationsByType(annotationClass);
+    }
+
+    /**
+     * @since 1.5
+     */
+    public Annotation[] getAnnotations() {
+        return getPackageInfo().getAnnotations();
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
+        return getPackageInfo().getDeclaredAnnotation(annotationClass);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
+        return getPackageInfo().getDeclaredAnnotationsByType(annotationClass);
+    }
+
+    /**
+     * @since 1.5
+     */
+    public Annotation[] getDeclaredAnnotations()  {
+        return getPackageInfo().getDeclaredAnnotations();
+    }
+
+    /**
+     * Construct a package instance with the specified version
+     * information.
+     * @param name the name of the package
+     * @param spectitle the title of the specification
+     * @param specversion the version of the specification
+     * @param specvendor the organization that maintains the specification
+     * @param impltitle the title of the implementation
+     * @param implversion the version of the implementation
+     * @param implvendor the organization that maintains the implementation
+     */
+    Package(String name,
+            String spectitle, String specversion, String specvendor,
+            String impltitle, String implversion, String implvendor,
+            URL sealbase, ClassLoader loader)
+    {
+        pkgName = name;
+        implTitle = impltitle;
+        implVersion = implversion;
+        implVendor = implvendor;
+        specTitle = spectitle;
+        specVersion = specversion;
+        specVendor = specvendor;
+        sealBase = sealbase;
+        this.loader = loader;
+    }
+
+    /*
+     * Construct a package using the attributes from the specified manifest.
+     *
+     * @param name the package name
+     * @param man the optional manifest for the package
+     * @param url the optional code source url for the package
+     */
+    private Package(String name, Manifest man, URL url, ClassLoader loader) {
+        String path = name.replace('.', '/').concat("/");
+        String sealed = null;
+        String specTitle= null;
+        String specVersion= null;
+        String specVendor= null;
+        String implTitle= null;
+        String implVersion= null;
+        String implVendor= null;
+        URL sealBase= null;
+        Attributes attr = man.getAttributes(path);
+        if (attr != null) {
+            specTitle   = attr.getValue(Name.SPECIFICATION_TITLE);
+            specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+            specVendor  = attr.getValue(Name.SPECIFICATION_VENDOR);
+            implTitle   = attr.getValue(Name.IMPLEMENTATION_TITLE);
+            implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+            implVendor  = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+            sealed      = attr.getValue(Name.SEALED);
+        }
+        attr = man.getMainAttributes();
+        if (attr != null) {
+            if (specTitle == null) {
+                specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+            }
+            if (specVersion == null) {
+                specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+            }
+            if (specVendor == null) {
+                specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+            }
+            if (implTitle == null) {
+                implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+            }
+            if (implVersion == null) {
+                implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+            }
+            if (implVendor == null) {
+                implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+            }
+            if (sealed == null) {
+                sealed = attr.getValue(Name.SEALED);
+            }
+        }
+        if ("true".equalsIgnoreCase(sealed)) {
+            sealBase = url;
+        }
+        pkgName = name;
+        this.specTitle = specTitle;
+        this.specVersion = specVersion;
+        this.specVendor = specVendor;
+        this.implTitle = implTitle;
+        this.implVersion = implVersion;
+        this.implVendor = implVendor;
+        this.sealBase = sealBase;
+        this.loader = loader;
+    }
+
+    /*
+     * Returns the loaded system package for the specified name.
+     */
+    static Package getSystemPackage(String name) {
+        synchronized (pkgs) {
+            Package pkg = pkgs.get(name);
+            if (pkg == null) {
+                name = name.replace('.', '/').concat("/");
+                String fn = getSystemPackage0(name);
+                if (fn != null) {
+                    pkg = defineSystemPackage(name, fn);
+                }
+            }
+            return pkg;
+        }
+    }
+
+    /*
+     * Return an array of loaded system packages.
+     */
+    static Package[] getSystemPackages() {
+        // First, update the system package map with new package names
+        String[] names = getSystemPackages0();
+        synchronized (pkgs) {
+            for (int i = 0; i < names.length; i++) {
+                defineSystemPackage(names[i], getSystemPackage0(names[i]));
+            }
+            return pkgs.values().toArray(new Package[pkgs.size()]);
+        }
+    }
+
+    private static Package defineSystemPackage(final String iname,
+                                               final String fn)
+    {
+        return AccessController.doPrivileged(new PrivilegedAction<Package>() {
+            public Package run() {
+                String name = iname;
+                // Get the cached code source url for the file name
+                URL url = urls.get(fn);
+                if (url == null) {
+                    // URL not found, so create one
+                    File file = new File(fn);
+                    try {
+                        url = ParseUtil.fileToEncodedURL(file);
+                    } catch (MalformedURLException e) {
+                    }
+                    if (url != null) {
+                        urls.put(fn, url);
+                        // If loading a JAR file, then also cache the manifest
+                        if (file.isFile()) {
+                            mans.put(fn, loadManifest(fn));
+                        }
+                    }
+                }
+                // Convert to "."-separated package name
+                name = name.substring(0, name.length() - 1).replace('/', '.');
+                Package pkg;
+                Manifest man = mans.get(fn);
+                if (man != null) {
+                    pkg = new Package(name, man, url, null);
+                } else {
+                    pkg = new Package(name, null, null, null,
+                                      null, null, null, null, null);
+                }
+                pkgs.put(name, pkg);
+                return pkg;
+            }
+        });
+    }
+
+    /*
+     * Returns the Manifest for the specified JAR file name.
+     */
+    private static Manifest loadManifest(String fn) {
+        try (FileInputStream fis = new FileInputStream(fn);
+             JarInputStream jis = new JarInputStream(fis, false))
+        {
+            return jis.getManifest();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    // The map of loaded system packages
+    private static Map<String, Package> pkgs = new HashMap<>(31);
+
+    // Maps each directory or zip file name to its corresponding url
+    private static Map<String, URL> urls = new HashMap<>(10);
+
+    // Maps each code source url for a jar file to its manifest
+    private static Map<String, Manifest> mans = new HashMap<>(10);
+
+    private static native String getSystemPackage0(String name);
+    private static native String[] getSystemPackages0();
+
+    /*
+     * Private storage for the package name and attributes.
+     */
+    private final String pkgName;
+    private final String specTitle;
+    private final String specVersion;
+    private final String specVendor;
+    private final String implTitle;
+    private final String implVersion;
+    private final String implVendor;
+    private final URL sealBase;
+    private transient final ClassLoader loader;
+    private transient Class<?> packageInfo;
+}
diff --git a/java/lang/Process.java b/java/lang/Process.java
new file mode 100644
index 0000000..4e94538
--- /dev/null
+++ b/java/lang/Process.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 1995, 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;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The {@link ProcessBuilder#start()} and
+ * {@link Runtime#exec(String[],String[],File) Runtime.exec}
+ * methods create a native process and return an instance of a
+ * subclass of {@code Process} that can be used to control the process
+ * and obtain information about it.  The class {@code Process}
+ * provides methods for performing input from the process, performing
+ * output to the process, waiting for the process to complete,
+ * checking the exit status of the process, and destroying (killing)
+ * the process.
+ *
+ * <p>The methods that create processes may not work well for special
+ * processes on certain native platforms, such as native windowing
+ * processes, daemon processes, Win16/DOS processes on Microsoft
+ * Windows, or shell scripts.
+ *
+ * <p>By default, the created subprocess does not have its own terminal
+ * or console.  All its standard I/O (i.e. stdin, stdout, stderr)
+ * operations will be redirected to the parent process, where they can
+ * be accessed via the streams obtained using the methods
+ * {@link #getOutputStream()},
+ * {@link #getInputStream()}, and
+ * {@link #getErrorStream()}.
+ * The parent process uses these streams to feed input to and get output
+ * from the subprocess.  Because some native platforms only provide
+ * limited buffer size for standard input and output streams, failure
+ * to promptly write the input stream or read the output stream of
+ * the subprocess may cause the subprocess to block, or even deadlock.
+ *
+ * <p>Where desired, <a href="ProcessBuilder.html#redirect-input">
+ * subprocess I/O can also be redirected</a>
+ * using methods of the {@link ProcessBuilder} class.
+ *
+ * <p>The subprocess is not killed when there are no more references to
+ * the {@code Process} object, but rather the subprocess
+ * continues executing asynchronously.
+ *
+ * <p>There is no requirement that a process represented by a {@code
+ * Process} object execute asynchronously or concurrently with respect
+ * to the Java process that owns the {@code Process} object.
+ *
+ * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way
+ * to create a {@code Process}.
+ *
+ * @since   JDK1.0
+ */
+public abstract class Process {
+    /**
+     * Returns the output stream connected to the normal input of the
+     * subprocess.  Output to the stream is piped into the standard
+     * input of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard input of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectInput(Redirect)
+     * ProcessBuilder.redirectInput}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
+     *
+     * <p>Implementation note: It is a good idea for the returned
+     * output stream to be buffered.
+     *
+     * @return the output stream connected to the normal input of the
+     *         subprocess
+     */
+    public abstract OutputStream getOutputStream();
+
+    /**
+     * Returns the input stream connected to the normal output of the
+     * subprocess.  The stream obtains data piped from the standard
+     * output of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard output of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectOutput(Redirect)
+     * ProcessBuilder.redirectOutput}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
+     *
+     * <p>Otherwise, if the standard error of the subprocess has been
+     * redirected using
+     * {@link ProcessBuilder#redirectErrorStream(boolean)
+     * ProcessBuilder.redirectErrorStream}
+     * then the input stream returned by this method will receive the
+     * merged standard output and the standard error of the subprocess.
+     *
+     * <p>Implementation note: It is a good idea for the returned
+     * input stream to be buffered.
+     *
+     * @return the input stream connected to the normal output of the
+     *         subprocess
+     */
+    public abstract InputStream getInputStream();
+
+    /**
+     * Returns the input stream connected to the error output of the
+     * subprocess.  The stream obtains data piped from the error output
+     * of the process represented by this {@code Process} object.
+     *
+     * <p>If the standard error of the subprocess has been redirected using
+     * {@link ProcessBuilder#redirectError(Redirect)
+     * ProcessBuilder.redirectError} or
+     * {@link ProcessBuilder#redirectErrorStream(boolean)
+     * ProcessBuilder.redirectErrorStream}
+     * then this method will return a
+     * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
+     *
+     * <p>Implementation note: It is a good idea for the returned
+     * input stream to be buffered.
+     *
+     * @return the input stream connected to the error output of
+     *         the subprocess
+     */
+    public abstract InputStream getErrorStream();
+
+    /**
+     * Causes the current thread to wait, if necessary, until the
+     * process represented by this {@code Process} object has
+     * terminated.  This method returns immediately if the subprocess
+     * has already terminated.  If the subprocess has not yet
+     * terminated, the calling thread will be blocked until the
+     * subprocess exits.
+     *
+     * @return the exit value of the subprocess represented by this
+     *         {@code Process} object.  By convention, the value
+     *         {@code 0} indicates normal termination.
+     * @throws InterruptedException if the current thread is
+     *         {@linkplain Thread#interrupt() interrupted} by another
+     *         thread while it is waiting, then the wait is ended and
+     *         an {@link InterruptedException} is thrown.
+     */
+    public abstract int waitFor() throws InterruptedException;
+
+    /**
+     * Causes the current thread to wait, if necessary, until the
+     * subprocess represented by this {@code Process} object has
+     * terminated, or the specified waiting time elapses.
+     *
+     * <p>If the subprocess has already terminated then this method returns
+     * immediately with the value {@code true}.  If the process has not
+     * terminated and the timeout value is less than, or equal to, zero, then
+     * this method returns immediately with the value {@code false}.
+     *
+     * <p>The default implementation of this methods polls the {@code exitValue}
+     * to check if the process has terminated. Concrete implementations of this
+     * class are strongly encouraged to override this method with a more
+     * efficient implementation.
+     *
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the {@code timeout} argument
+     * @return {@code true} if the subprocess has exited and {@code false} if
+     *         the waiting time elapsed before the subprocess has exited.
+     * @throws InterruptedException if the current thread is interrupted
+     *         while waiting.
+     * @throws NullPointerException if unit is null
+     * @since 1.8
+     */
+    public boolean waitFor(long timeout, TimeUnit unit)
+        throws InterruptedException
+    {
+        long startTime = System.nanoTime();
+        long rem = unit.toNanos(timeout);
+
+        do {
+            try {
+                exitValue();
+                return true;
+            } catch(IllegalThreadStateException ex) {
+                if (rem > 0)
+                    Thread.sleep(
+                        Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
+            }
+            rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
+        } while (rem > 0);
+        return false;
+    }
+
+    /**
+     * Returns the exit value for the subprocess.
+     *
+     * @return the exit value of the subprocess represented by this
+     *         {@code Process} object.  By convention, the value
+     *         {@code 0} indicates normal termination.
+     * @throws IllegalThreadStateException if the subprocess represented
+     *         by this {@code Process} object has not yet terminated
+     */
+    public abstract int exitValue();
+
+    /**
+     * Kills the subprocess. Whether the subprocess represented by this
+     * {@code Process} object is forcibly terminated or not is
+     * implementation dependent.
+     */
+    public abstract void destroy();
+
+    /**
+     * Kills the subprocess. The subprocess represented by this
+     * {@code Process} object is forcibly terminated.
+     *
+     * <p>The default implementation of this method invokes {@link #destroy}
+     * and so may not forcibly terminate the process. Concrete implementations
+     * of this class are strongly encouraged to override this method with a
+     * compliant implementation.  Invoking this method on {@code Process}
+     * objects returned by {@link ProcessBuilder#start} and
+     * {@link Runtime#exec} will forcibly terminate the process.
+     *
+     * <p>Note: The subprocess may not terminate immediately.
+     * i.e. {@code isAlive()} may return true for a brief period
+     * after {@code destroyForcibly()} is called. This method
+     * may be chained to {@code waitFor()} if needed.
+     *
+     * @return the {@code Process} object representing the
+     *         subprocess to be forcibly destroyed.
+     * @since 1.8
+     */
+    public Process destroyForcibly() {
+        destroy();
+        return this;
+    }
+
+    /**
+     * Tests whether the subprocess represented by this {@code Process} is
+     * alive.
+     *
+     * @return {@code true} if the subprocess represented by this
+     *         {@code Process} object has not yet terminated.
+     * @since 1.8
+     */
+    public boolean isAlive() {
+        try {
+            exitValue();
+            return false;
+        } catch(IllegalThreadStateException e) {
+            return true;
+        }
+    }
+}
diff --git a/java/lang/ProcessBuilder.java b/java/lang/ProcessBuilder.java
new file mode 100644
index 0000000..fc58abc
--- /dev/null
+++ b/java/lang/ProcessBuilder.java
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is used to create operating system processes.
+ *
+ * <p>Each {@code ProcessBuilder} instance manages a collection
+ * of process attributes.  The {@link #start()} method creates a new
+ * {@link Process} instance with those attributes.  The {@link
+ * #start()} method can be invoked repeatedly from the same instance
+ * to create new subprocesses with identical or related attributes.
+ *
+ * <p>Each process builder manages these process attributes:
+ *
+ * <ul>
+ *
+ * <li>a <i>command</i>, a list of strings which signifies the
+ * external program file to be invoked and its arguments, if any.
+ * Which string lists represent a valid operating system command is
+ * system-dependent.  For example, it is common for each conceptual
+ * argument to be an element in this list, but there are operating
+ * systems where programs are expected to tokenize command line
+ * strings themselves - on such a system a Java implementation might
+ * require commands to contain exactly two elements.
+ *
+ * <li>an <i>environment</i>, which is a system-dependent mapping from
+ * <i>variables</i> to <i>values</i>.  The initial value is a copy of
+ * the environment of the current process (see {@link System#getenv()}).
+ *
+ * <li>a <i>working directory</i>.  The default value is the current
+ * working directory of the current process, usually the directory
+ * named by the system property {@code user.dir}.
+ *
+ * <li><a name="redirect-input">a source of <i>standard input</i></a>.
+ * By default, the subprocess reads input from a pipe.  Java code
+ * can access this pipe via the output stream returned by
+ * {@link Process#getOutputStream()}.  However, standard input may
+ * be redirected to another source using
+ * {@link #redirectInput(Redirect) redirectInput}.
+ * In this case, {@link Process#getOutputStream()} will return a
+ * <i>null output stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link OutputStream#write(int) write} methods always
+ * throw {@code IOException}
+ * <li>the {@link OutputStream#close() close} method does nothing
+ * </ul>
+ *
+ * <li><a name="redirect-output">a destination for <i>standard output</i>
+ * and <i>standard error</i></a>.  By default, the subprocess writes standard
+ * output and standard error to pipes.  Java code can access these pipes
+ * via the input streams returned by {@link Process#getInputStream()} and
+ * {@link Process#getErrorStream()}.  However, standard output and
+ * standard error may be redirected to other destinations using
+ * {@link #redirectOutput(Redirect) redirectOutput} and
+ * {@link #redirectError(Redirect) redirectError}.
+ * In this case, {@link Process#getInputStream()} and/or
+ * {@link Process#getErrorStream()} will return a <i>null input
+ * stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link InputStream#read() read} methods always return
+ * {@code -1}
+ * <li>the {@link InputStream#available() available} method always returns
+ * {@code 0}
+ * <li>the {@link InputStream#close() close} method does nothing
+ * </ul>
+ *
+ * <li>a <i>redirectErrorStream</i> property.  Initially, this property
+ * is {@code false}, meaning that the standard output and error
+ * output of a subprocess are sent to two separate streams, which can
+ * be accessed using the {@link Process#getInputStream()} and {@link
+ * Process#getErrorStream()} methods.
+ *
+ * <p>If the value is set to {@code true}, then:
+ *
+ * <ul>
+ * <li>standard error is merged with the standard output and always sent
+ * to the same destination (this makes it easier to correlate error
+ * messages with the corresponding output)
+ * <li>the common destination of standard error and standard output can be
+ * redirected using
+ * {@link #redirectOutput(Redirect) redirectOutput}
+ * <li>any redirection set by the
+ * {@link #redirectError(Redirect) redirectError}
+ * method is ignored when creating a subprocess
+ * <li>the stream returned from {@link Process#getErrorStream()} will
+ * always be a <a href="#redirect-output">null input stream</a>
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>Modifying a process builder's attributes will affect processes
+ * subsequently started by that object's {@link #start()} method, but
+ * will never affect previously started processes or the Java process
+ * itself.
+ *
+ * <p>Most error checking is performed by the {@link #start()} method.
+ * It is possible to modify the state of an object so that {@link
+ * #start()} will fail.  For example, setting the command attribute to
+ * an empty list will not throw an exception unless {@link #start()}
+ * is invoked.
+ *
+ * <p><strong>Note that this class is not synchronized.</strong>
+ * If multiple threads access a {@code ProcessBuilder} instance
+ * concurrently, and at least one of the threads modifies one of the
+ * attributes structurally, it <i>must</i> be synchronized externally.
+ *
+ * <p>Starting a new process which uses the default working directory
+ * and environment is easy:
+ *
+ * <pre> {@code
+ * Process p = new ProcessBuilder("myCommand", "myArg").start();
+ * }</pre>
+ *
+ * <p>Here is an example that starts a process with a modified working
+ * directory and environment, and redirects standard output and error
+ * to be appended to a log file:
+ *
+ * <pre> {@code
+ * ProcessBuilder pb =
+ *   new ProcessBuilder("myCommand", "myArg1", "myArg2");
+ * Map<String, String> env = pb.environment();
+ * env.put("VAR1", "myValue");
+ * env.remove("OTHERVAR");
+ * env.put("VAR2", env.get("VAR1") + "suffix");
+ * pb.directory(new File("myDir"));
+ * File log = new File("log");
+ * pb.redirectErrorStream(true);
+ * pb.redirectOutput(Redirect.appendTo(log));
+ * Process p = pb.start();
+ * assert pb.redirectInput() == Redirect.PIPE;
+ * assert pb.redirectOutput().file() == log;
+ * assert p.getInputStream().read() == -1;
+ * }</pre>
+ *
+ * <p>To start a process with an explicit set of environment
+ * variables, first call {@link java.util.Map#clear() Map.clear()}
+ * before adding environment variables.
+ *
+ * @author Martin Buchholz
+ * @since 1.5
+ */
+
+public final class ProcessBuilder
+{
+    private List<String> command;
+    private File directory;
+    private Map<String,String> environment;
+    private boolean redirectErrorStream;
+    private Redirect[] redirects;
+
+    /**
+     * Constructs a process builder with the specified operating
+     * system program and arguments.  This constructor does <i>not</i>
+     * make a copy of the {@code command} list.  Subsequent
+     * updates to the list will be reflected in the state of the
+     * process builder.  It is not checked whether
+     * {@code command} corresponds to a valid operating system
+     * command.
+     *
+     * @param  command the list containing the program and its arguments
+     * @throws NullPointerException if the argument is null
+     */
+    public ProcessBuilder(List<String> command) {
+        if (command == null)
+            throw new NullPointerException();
+        this.command = command;
+    }
+
+    /**
+     * Constructs a process builder with the specified operating
+     * system program and arguments.  This is a convenience
+     * constructor that sets the process builder's command to a string
+     * list containing the same strings as the {@code command}
+     * array, in the same order.  It is not checked whether
+     * {@code command} corresponds to a valid operating system
+     * command.
+     *
+     * @param command a string array containing the program and its arguments
+     */
+    public ProcessBuilder(String... command) {
+        this.command = new ArrayList<>(command.length);
+        for (String arg : command)
+            this.command.add(arg);
+    }
+
+    /**
+     * Sets this process builder's operating system program and
+     * arguments.  This method does <i>not</i> make a copy of the
+     * {@code command} list.  Subsequent updates to the list will
+     * be reflected in the state of the process builder.  It is not
+     * checked whether {@code command} corresponds to a valid
+     * operating system command.
+     *
+     * @param  command the list containing the program and its arguments
+     * @return this process builder
+     *
+     * @throws NullPointerException if the argument is null
+     */
+    public ProcessBuilder command(List<String> command) {
+        if (command == null)
+            throw new NullPointerException();
+        this.command = command;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's operating system program and
+     * arguments.  This is a convenience method that sets the command
+     * to a string list containing the same strings as the
+     * {@code command} array, in the same order.  It is not
+     * checked whether {@code command} corresponds to a valid
+     * operating system command.
+     *
+     * @param  command a string array containing the program and its arguments
+     * @return this process builder
+     */
+    public ProcessBuilder command(String... command) {
+        this.command = new ArrayList<>(command.length);
+        for (String arg : command)
+            this.command.add(arg);
+        return this;
+    }
+
+    /**
+     * Returns this process builder's operating system program and
+     * arguments.  The returned list is <i>not</i> a copy.  Subsequent
+     * updates to the list will be reflected in the state of this
+     * process builder.
+     *
+     * @return this process builder's program and its arguments
+     */
+    public List<String> command() {
+        return command;
+    }
+
+    /**
+     * Returns a string map view of this process builder's environment.
+     *
+     * Whenever a process builder is created, the environment is
+     * initialized to a copy of the current process environment (see
+     * {@link System#getenv()}).  Subprocesses subsequently started by
+     * this object's {@link #start()} method will use this map as
+     * their environment.
+     *
+     * <p>The returned object may be modified using ordinary {@link
+     * java.util.Map Map} operations.  These modifications will be
+     * visible to subprocesses started via the {@link #start()}
+     * method.  Two {@code ProcessBuilder} instances always
+     * contain independent process environments, so changes to the
+     * returned map will never be reflected in any other
+     * {@code ProcessBuilder} instance or the values returned by
+     * {@link System#getenv System.getenv}.
+     *
+     * <p>If the system does not support environment variables, an
+     * empty map is returned.
+     *
+     * <p>The returned map does not permit null keys or values.
+     * Attempting to insert or query the presence of a null key or
+     * value will throw a {@link NullPointerException}.
+     * Attempting to query the presence of a key or value which is not
+     * of type {@link String} will throw a {@link ClassCastException}.
+     *
+     * <p>The behavior of the returned map is system-dependent.  A
+     * system may not allow modifications to environment variables or
+     * may forbid certain variable names or values.  For this reason,
+     * attempts to modify the map may fail with
+     * {@link UnsupportedOperationException} or
+     * {@link IllegalArgumentException}
+     * if the modification is not permitted by the operating system.
+     *
+     * <p>Since the external format of environment variable names and
+     * values is system-dependent, there may not be a one-to-one
+     * mapping between them and Java's Unicode strings.  Nevertheless,
+     * the map is implemented in such a way that environment variables
+     * which are not modified by Java code will have an unmodified
+     * native representation in the subprocess.
+     *
+     * <p>The returned map and its collection views may not obey the
+     * general contract of the {@link Object#equals} and
+     * {@link Object#hashCode} methods.
+     *
+     * <p>The returned map is typically case-sensitive on all platforms.
+     *
+     * <p>If a security manager exists, its
+     * {@link SecurityManager#checkPermission checkPermission} method
+     * is called with a
+     * {@link RuntimePermission}{@code ("getenv.*")} permission.
+     * This may result in a {@link SecurityException} being thrown.
+     *
+     * <p>When passing information to a Java subprocess,
+     * <a href=System.html#EnvironmentVSSystemProperties>system properties</a>
+     * are generally preferred over environment variables.
+     *
+     * @return this process builder's environment
+     *
+     * @throws SecurityException
+     *         if a security manager exists and its
+     *         {@link SecurityManager#checkPermission checkPermission}
+     *         method doesn't allow access to the process environment
+     *
+     * @see    Runtime#exec(String[],String[],java.io.File)
+     * @see    System#getenv()
+     */
+    public Map<String,String> environment() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null)
+            security.checkPermission(new RuntimePermission("getenv.*"));
+
+        if (environment == null)
+            environment = ProcessEnvironment.environment();
+
+        assert environment != null;
+
+        return environment;
+    }
+
+    // Only for use by Runtime.exec(...envp...)
+    ProcessBuilder environment(String[] envp) {
+        assert environment == null;
+        if (envp != null) {
+            environment = ProcessEnvironment.emptyEnvironment(envp.length);
+            assert environment != null;
+
+            for (String envstring : envp) {
+                // Before 1.5, we blindly passed invalid envstrings
+                // to the child process.
+                // We would like to throw an exception, but do not,
+                // for compatibility with old broken code.
+
+                // Silently discard any trailing junk.
+                if (envstring.indexOf((int) '\u0000') != -1)
+                    envstring = envstring.replaceFirst("\u0000.*", "");
+
+                int eqlsign =
+                    envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH);
+                // Silently ignore envstrings lacking the required `='.
+                if (eqlsign != -1)
+                    environment.put(envstring.substring(0,eqlsign),
+                                    envstring.substring(eqlsign+1));
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Returns this process builder's working directory.
+     *
+     * Subprocesses subsequently started by this object's {@link
+     * #start()} method will use this as their working directory.
+     * The returned value may be {@code null} -- this means to use
+     * the working directory of the current Java process, usually the
+     * directory named by the system property {@code user.dir},
+     * as the working directory of the child process.
+     *
+     * @return this process builder's working directory
+     */
+    public File directory() {
+        return directory;
+    }
+
+    /**
+     * Sets this process builder's working directory.
+     *
+     * Subprocesses subsequently started by this object's {@link
+     * #start()} method will use this as their working directory.
+     * The argument may be {@code null} -- this means to use the
+     * working directory of the current Java process, usually the
+     * directory named by the system property {@code user.dir},
+     * as the working directory of the child process.
+     *
+     * @param  directory the new working directory
+     * @return this process builder
+     */
+    public ProcessBuilder directory(File directory) {
+        this.directory = directory;
+        return this;
+    }
+
+    // ---------------- I/O Redirection ----------------
+
+    /**
+     * Implements a <a href="#redirect-output">null input stream</a>.
+     */
+    static class NullInputStream extends InputStream {
+        static final NullInputStream INSTANCE = new NullInputStream();
+        private NullInputStream() {}
+        public int read()      { return -1; }
+        public int available() { return 0; }
+    }
+
+    /**
+     * Implements a <a href="#redirect-input">null output stream</a>.
+     */
+    static class NullOutputStream extends OutputStream {
+        static final NullOutputStream INSTANCE = new NullOutputStream();
+        private NullOutputStream() {}
+        public void write(int b) throws IOException {
+            throw new IOException("Stream closed");
+        }
+    }
+
+    /**
+     * Represents a source of subprocess input or a destination of
+     * subprocess output.
+     *
+     * Each {@code Redirect} instance is one of the following:
+     *
+     * <ul>
+     * <li>the special value {@link #PIPE Redirect.PIPE}
+     * <li>the special value {@link #INHERIT Redirect.INHERIT}
+     * <li>a redirection to read from a file, created by an invocation of
+     *     {@link Redirect#from Redirect.from(File)}
+     * <li>a redirection to write to a file,  created by an invocation of
+     *     {@link Redirect#to Redirect.to(File)}
+     * <li>a redirection to append to a file, created by an invocation of
+     *     {@link Redirect#appendTo Redirect.appendTo(File)}
+     * </ul>
+     *
+     * <p>Each of the above categories has an associated unique
+     * {@link Type Type}.
+     *
+     * @since 1.7
+     */
+    public static abstract class Redirect {
+        /**
+         * The type of a {@link Redirect}.
+         */
+        public enum Type {
+            /**
+             * The type of {@link Redirect#PIPE Redirect.PIPE}.
+             */
+            PIPE,
+
+            /**
+             * The type of {@link Redirect#INHERIT Redirect.INHERIT}.
+             */
+            INHERIT,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#from Redirect.from(File)}.
+             */
+            READ,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#to Redirect.to(File)}.
+             */
+            WRITE,
+
+            /**
+             * The type of redirects returned from
+             * {@link Redirect#appendTo Redirect.appendTo(File)}.
+             */
+            APPEND
+        };
+
+        /**
+         * Returns the type of this {@code Redirect}.
+         * @return the type of this {@code Redirect}
+         */
+        public abstract Type type();
+
+        /**
+         * Indicates that subprocess I/O will be connected to the
+         * current Java process over a pipe.
+         *
+         * This is the default handling of subprocess standard I/O.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.PIPE.file() == null &&
+         * Redirect.PIPE.type() == Redirect.Type.PIPE
+         * }</pre>
+         */
+        public static final Redirect PIPE = new Redirect() {
+                public Type type() { return Type.PIPE; }
+                public String toString() { return type().toString(); }};
+
+        /**
+         * Indicates that subprocess I/O source or destination will be the
+         * same as those of the current process.  This is the normal
+         * behavior of most operating system command interpreters (shells).
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.INHERIT.file() == null &&
+         * Redirect.INHERIT.type() == Redirect.Type.INHERIT
+         * }</pre>
+         */
+        public static final Redirect INHERIT = new Redirect() {
+                public Type type() { return Type.INHERIT; }
+                public String toString() { return type().toString(); }};
+
+        /**
+         * Returns the {@link File} source or destination associated
+         * with this redirect, or {@code null} if there is no such file.
+         *
+         * @return the file associated with this redirect,
+         *         or {@code null} if there is no such file
+         */
+        public File file() { return null; }
+
+        /**
+         * When redirected to a destination file, indicates if the output
+         * is to be written to the end of the file.
+         */
+        boolean append() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Returns a redirect to read from the specified file.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.from(file).file() == file &&
+         * Redirect.from(file).type() == Redirect.Type.READ
+         * }</pre>
+         *
+         * @param file The {@code File} for the {@code Redirect}.
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to read from the specified file
+         */
+        public static Redirect from(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.READ; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to read from file \"" + file + "\"";
+                    }
+                };
+        }
+
+        /**
+         * Returns a redirect to write to the specified file.
+         * If the specified file exists when the subprocess is started,
+         * its previous contents will be discarded.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.to(file).file() == file &&
+         * Redirect.to(file).type() == Redirect.Type.WRITE
+         * }</pre>
+         *
+         * @param file The {@code File} for the {@code Redirect}.
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to write to the specified file
+         */
+        public static Redirect to(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.WRITE; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to write to file \"" + file + "\"";
+                    }
+                    boolean append() { return false; }
+                };
+        }
+
+        /**
+         * Returns a redirect to append to the specified file.
+         * Each write operation first advances the position to the
+         * end of the file and then writes the requested data.
+         * Whether the advancement of the position and the writing
+         * of the data are done in a single atomic operation is
+         * system-dependent and therefore unspecified.
+         *
+         * <p>It will always be true that
+         *  <pre> {@code
+         * Redirect.appendTo(file).file() == file &&
+         * Redirect.appendTo(file).type() == Redirect.Type.APPEND
+         * }</pre>
+         *
+         * @param file The {@code File} for the {@code Redirect}.
+         * @throws NullPointerException if the specified file is null
+         * @return a redirect to append to the specified file
+         */
+        public static Redirect appendTo(final File file) {
+            if (file == null)
+                throw new NullPointerException();
+            return new Redirect() {
+                    public Type type() { return Type.APPEND; }
+                    public File file() { return file; }
+                    public String toString() {
+                        return "redirect to append to file \"" + file + "\"";
+                    }
+                    boolean append() { return true; }
+                };
+        }
+
+        /**
+         * Compares the specified object with this {@code Redirect} for
+         * equality.  Returns {@code true} if and only if the two
+         * objects are identical or both objects are {@code Redirect}
+         * instances of the same type associated with non-null equal
+         * {@code File} instances.
+         */
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (! (obj instanceof Redirect))
+                return false;
+            Redirect r = (Redirect) obj;
+            if (r.type() != this.type())
+                return false;
+            assert this.file() != null;
+            return this.file().equals(r.file());
+        }
+
+        /**
+         * Returns a hash code value for this {@code Redirect}.
+         * @return a hash code value for this {@code Redirect}
+         */
+        public int hashCode() {
+            File file = file();
+            if (file == null)
+                return super.hashCode();
+            else
+                return file.hashCode();
+        }
+
+        /**
+         * No public constructors.  Clients must use predefined
+         * static {@code Redirect} instances or factory methods.
+         */
+        private Redirect() {}
+    }
+
+    private Redirect[] redirects() {
+        if (redirects == null)
+            redirects = new Redirect[] {
+                Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
+            };
+        return redirects;
+    }
+
+    /**
+     * Sets this process builder's standard input source.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method obtain their standard input from this source.
+     *
+     * <p>If the source is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the standard input of a
+     * subprocess can be written to using the output stream
+     * returned by {@link Process#getOutputStream()}.
+     * If the source is set to any other value, then
+     * {@link Process#getOutputStream()} will return a
+     * <a href="#redirect-input">null output stream</a>.
+     *
+     * @param  source the new standard input source
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid source
+     *         of data, that is, has type
+     *         {@link Redirect.Type#WRITE WRITE} or
+     *         {@link Redirect.Type#APPEND APPEND}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectInput(Redirect source) {
+        if (source.type() == Redirect.Type.WRITE ||
+            source.type() == Redirect.Type.APPEND)
+            throw new IllegalArgumentException(
+                "Redirect invalid for reading: " + source);
+        redirects()[0] = source;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard output destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method send their standard output to this destination.
+     *
+     * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the standard output of a subprocess
+     * can be read using the input stream returned by {@link
+     * Process#getInputStream()}.
+     * If the destination is set to any other value, then
+     * {@link Process#getInputStream()} will return a
+     * <a href="#redirect-output">null input stream</a>.
+     *
+     * @param  destination the new standard output destination
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid
+     *         destination of data, that is, has type
+     *         {@link Redirect.Type#READ READ}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectOutput(Redirect destination) {
+        if (destination.type() == Redirect.Type.READ)
+            throw new IllegalArgumentException(
+                "Redirect invalid for writing: " + destination);
+        redirects()[1] = destination;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard error destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method send their standard error to this destination.
+     *
+     * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+     * (the initial value), then the error output of a subprocess
+     * can be read using the input stream returned by {@link
+     * Process#getErrorStream()}.
+     * If the destination is set to any other value, then
+     * {@link Process#getErrorStream()} will return a
+     * <a href="#redirect-output">null input stream</a>.
+     *
+     * <p>If the {@link #redirectErrorStream redirectErrorStream}
+     * attribute has been set {@code true}, then the redirection set
+     * by this method has no effect.
+     *
+     * @param  destination the new standard error destination
+     * @return this process builder
+     * @throws IllegalArgumentException
+     *         if the redirect does not correspond to a valid
+     *         destination of data, that is, has type
+     *         {@link Redirect.Type#READ READ}
+     * @since  1.7
+     */
+    public ProcessBuilder redirectError(Redirect destination) {
+        if (destination.type() == Redirect.Type.READ)
+            throw new IllegalArgumentException(
+                "Redirect invalid for writing: " + destination);
+        redirects()[2] = destination;
+        return this;
+    }
+
+    /**
+     * Sets this process builder's standard input source to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectInput(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectInput(Redirect) redirectInput}
+     * {@code (Redirect.from(file))}.
+     *
+     * @param  file the new standard input source
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectInput(File file) {
+        return redirectInput(Redirect.from(file));
+    }
+
+    /**
+     * Sets this process builder's standard output destination to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectOutput(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectOutput(Redirect) redirectOutput}
+     * {@code (Redirect.to(file))}.
+     *
+     * @param  file the new standard output destination
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectOutput(File file) {
+        return redirectOutput(Redirect.to(file));
+    }
+
+    /**
+     * Sets this process builder's standard error destination to a file.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * {@code redirectError(file)}
+     * behaves in exactly the same way as the invocation
+     * {@link #redirectError(Redirect) redirectError}
+     * {@code (Redirect.to(file))}.
+     *
+     * @param  file the new standard error destination
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder redirectError(File file) {
+        return redirectError(Redirect.to(file));
+    }
+
+    /**
+     * Returns this process builder's standard input source.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method obtain their standard input from this source.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard input source
+     * @since  1.7
+     */
+    public Redirect redirectInput() {
+        return (redirects == null) ? Redirect.PIPE : redirects[0];
+    }
+
+    /**
+     * Returns this process builder's standard output destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method redirect their standard output to this destination.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard output destination
+     * @since  1.7
+     */
+    public Redirect redirectOutput() {
+        return (redirects == null) ? Redirect.PIPE : redirects[1];
+    }
+
+    /**
+     * Returns this process builder's standard error destination.
+     *
+     * Subprocesses subsequently started by this object's {@link #start()}
+     * method redirect their standard error to this destination.
+     * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+     *
+     * @return this process builder's standard error destination
+     * @since  1.7
+     */
+    public Redirect redirectError() {
+        return (redirects == null) ? Redirect.PIPE : redirects[2];
+    }
+
+    /**
+     * Sets the source and destination for subprocess standard I/O
+     * to be the same as those of the current Java process.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     *  <pre> {@code
+     * pb.inheritIO()
+     * }</pre>
+     * behaves in exactly the same way as the invocation
+     *  <pre> {@code
+     * pb.redirectInput(Redirect.INHERIT)
+     *   .redirectOutput(Redirect.INHERIT)
+     *   .redirectError(Redirect.INHERIT)
+     * }</pre>
+     *
+     * This gives behavior equivalent to most operating system
+     * command interpreters, or the standard C library function
+     * {@code system()}.
+     *
+     * @return this process builder
+     * @since  1.7
+     */
+    public ProcessBuilder inheritIO() {
+        Arrays.fill(redirects(), Redirect.INHERIT);
+        return this;
+    }
+
+    /**
+     * Tells whether this process builder merges standard error and
+     * standard output.
+     *
+     * <p>If this property is {@code true}, then any error output
+     * generated by subprocesses subsequently started by this object's
+     * {@link #start()} method will be merged with the standard
+     * output, so that both can be read using the
+     * {@link Process#getInputStream()} method.  This makes it easier
+     * to correlate error messages with the corresponding output.
+     * The initial value is {@code false}.
+     *
+     * @return this process builder's {@code redirectErrorStream} property
+     */
+    public boolean redirectErrorStream() {
+        return redirectErrorStream;
+    }
+
+    /**
+     * Sets this process builder's {@code redirectErrorStream} property.
+     *
+     * <p>If this property is {@code true}, then any error output
+     * generated by subprocesses subsequently started by this object's
+     * {@link #start()} method will be merged with the standard
+     * output, so that both can be read using the
+     * {@link Process#getInputStream()} method.  This makes it easier
+     * to correlate error messages with the corresponding output.
+     * The initial value is {@code false}.
+     *
+     * @param  redirectErrorStream the new property value
+     * @return this process builder
+     */
+    public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
+        this.redirectErrorStream = redirectErrorStream;
+        return this;
+    }
+
+    /**
+     * Starts a new process using the attributes of this process builder.
+     *
+     * <p>The new process will
+     * invoke the command and arguments given by {@link #command()},
+     * in a working directory as given by {@link #directory()},
+     * with a process environment as given by {@link #environment()}.
+     *
+     * <p>This method checks that the command is a valid operating
+     * system command.  Which commands are valid is system-dependent,
+     * but at the very least the command must be a non-empty list of
+     * non-null strings.
+     *
+     * <p>A minimal set of system dependent environment variables may
+     * be required to start a process on some operating systems.
+     * As a result, the subprocess may inherit additional environment variable
+     * settings beyond those in the process builder's {@link #environment()}.
+     *
+     * <p>If there is a security manager, its
+     * {@link SecurityManager#checkExec checkExec}
+     * method is called with the first component of this object's
+     * {@code command} array as its argument. This may result in
+     * a {@link SecurityException} being thrown.
+     *
+     * <p>Starting an operating system process is highly system-dependent.
+     * Among the many things that can go wrong are:
+     * <ul>
+     * <li>The operating system program file was not found.
+     * <li>Access to the program file was denied.
+     * <li>The working directory does not exist.
+     * </ul>
+     *
+     * <p>In such cases an exception will be thrown.  The exact nature
+     * of the exception is system-dependent, but it will always be a
+     * subclass of {@link IOException}.
+     *
+     * <p>Subsequent modifications to this process builder will not
+     * affect the returned {@link Process}.
+     *
+     * @return a new {@link Process} object for managing the subprocess
+     *
+     * @throws NullPointerException
+     *         if an element of the command list is null
+     *
+     * @throws IndexOutOfBoundsException
+     *         if the command is an empty list (has size {@code 0})
+     *
+     * @throws SecurityException
+     *         if a security manager exists and
+     *         <ul>
+     *
+     *         <li>its
+     *         {@link SecurityManager#checkExec checkExec}
+     *         method doesn't allow creation of the subprocess, or
+     *
+     *         <li>the standard input to the subprocess was
+     *         {@linkplain #redirectInput redirected from a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkRead checkRead} method
+     *         denies read access to the file, or
+     *
+     *         <li>the standard output or standard error of the
+     *         subprocess was
+     *         {@linkplain #redirectOutput redirected to a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkWrite checkWrite} method
+     *         denies write access to the file
+     *
+     *         </ul>
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @see Runtime#exec(String[], String[], java.io.File)
+     */
+    public Process start() throws IOException {
+        // Must convert to array first -- a malicious user-supplied
+        // list might try to circumvent the security check.
+        String[] cmdarray = command.toArray(new String[command.size()]);
+        cmdarray = cmdarray.clone();
+
+        for (String arg : cmdarray)
+            if (arg == null)
+                throw new NullPointerException();
+        // Throws IndexOutOfBoundsException if command is empty
+        String prog = cmdarray[0];
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null)
+            security.checkExec(prog);
+
+        String dir = directory == null ? null : directory.toString();
+
+        for (int i = 1; i < cmdarray.length; i++) {
+            if (cmdarray[i].indexOf('\u0000') >= 0) {
+                throw new IOException("invalid null character in command");
+            }
+        }
+
+        try {
+            return ProcessImpl.start(cmdarray,
+                                     environment,
+                                     dir,
+                                     redirects,
+                                     redirectErrorStream);
+        } catch (IOException | IllegalArgumentException e) {
+            String exceptionInfo = ": " + e.getMessage();
+            Throwable cause = e;
+            if ((e instanceof IOException) && security != null) {
+                // Can not disclose the fail reason for read-protected files.
+                try {
+                    security.checkRead(prog);
+                } catch (SecurityException se) {
+                    exceptionInfo = "";
+                    cause = se;
+                }
+            }
+            // It's much easier for us to create a high-quality error
+            // message than the low-level C code which found the problem.
+            throw new IOException(
+                "Cannot run program \"" + prog + "\""
+                + (dir == null ? "" : " (in directory \"" + dir + "\")")
+                + exceptionInfo,
+                cause);
+        }
+    }
+}
diff --git a/java/lang/ProcessEnvironment.java b/java/lang/ProcessEnvironment.java
new file mode 100644
index 0000000..08d260c
--- /dev/null
+++ b/java/lang/ProcessEnvironment.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/* We use APIs that access the standard Unix environ array, which
+ * is defined by UNIX98 to look like:
+ *
+ *    char **environ;
+ *
+ * These are unsorted, case-sensitive, null-terminated arrays of bytes
+ * of the form FOO=BAR\000 which are usually encoded in the user's
+ * default encoding (file.encoding is an excellent choice for
+ * encoding/decoding these).  However, even though the user cannot
+ * directly access the underlying byte representation, we take pains
+ * to pass on the child the exact byte representation we inherit from
+ * the parent process for any environment name or value not created by
+ * Javaland.  So we keep track of all the byte representations.
+ *
+ * Internally, we define the types Variable and Value that exhibit
+ * String/byteArray duality.  The internal representation of the
+ * environment then looks like a Map<Variable,Value>.  But we don't
+ * expose this to the user -- we only provide a Map<String,String>
+ * view, although we could also provide a Map<byte[],byte[]> view.
+ *
+ * The non-private methods in this class are not for general use even
+ * within this package.  Instead, they are the system-dependent parts
+ * of the system-independent method of the same name.  Don't even
+ * think of using this class unless your method's name appears below.
+ *
+ * @author  Martin Buchholz
+ * @since   1.5
+ */
+
+package java.lang;
+
+import java.io.*;
+import java.util.*;
+
+
+final class ProcessEnvironment
+{
+    private static final HashMap<Variable,Value> theEnvironment;
+    private static final Map<String,String> theUnmodifiableEnvironment;
+    static final int MIN_NAME_LENGTH = 0;
+
+    static {
+        // We cache the C environment.  This means that subsequent calls
+        // to putenv/setenv from C will not be visible from Java code.
+        byte[][] environ = environ();
+        theEnvironment = new HashMap<>(environ.length/2 + 3);
+        // Read environment variables back to front,
+        // so that earlier variables override later ones.
+        for (int i = environ.length-1; i > 0; i-=2)
+            theEnvironment.put(Variable.valueOf(environ[i-1]),
+                               Value.valueOf(environ[i]));
+
+        theUnmodifiableEnvironment
+            = Collections.unmodifiableMap
+            (new StringEnvironment(theEnvironment));
+    }
+
+    /* Only for use by System.getenv(String) */
+    static String getenv(String name) {
+        return theUnmodifiableEnvironment.get(name);
+    }
+
+    /* Only for use by System.getenv() */
+    static Map<String,String> getenv() {
+        return theUnmodifiableEnvironment;
+    }
+
+    /* Only for use by ProcessBuilder.environment() */
+    @SuppressWarnings("unchecked")
+    static Map<String,String> environment() {
+        return new StringEnvironment
+            ((Map<Variable,Value>)(theEnvironment.clone()));
+    }
+
+    /* Only for use by Runtime.exec(...String[]envp...) */
+    static Map<String,String> emptyEnvironment(int capacity) {
+        return new StringEnvironment(new HashMap<Variable,Value>(capacity));
+    }
+
+    private static native byte[][] environ();
+
+    // This class is not instantiable.
+    private ProcessEnvironment() {}
+
+    // Check that name is suitable for insertion into Environment map
+    private static void validateVariable(String name) {
+        if (name.indexOf('=')      != -1 ||
+            name.indexOf('\u0000') != -1)
+            throw new IllegalArgumentException
+                ("Invalid environment variable name: \"" + name + "\"");
+    }
+
+    // Check that value is suitable for insertion into Environment map
+    private static void validateValue(String value) {
+        if (value.indexOf('\u0000') != -1)
+            throw new IllegalArgumentException
+                ("Invalid environment variable value: \"" + value + "\"");
+    }
+
+    // A class hiding the byteArray-String duality of
+    // text data on Unixoid operating systems.
+    private static abstract class ExternalData {
+        protected final String str;
+        protected final byte[] bytes;
+
+        protected ExternalData(String str, byte[] bytes) {
+            this.str = str;
+            this.bytes = bytes;
+        }
+
+        public byte[] getBytes() {
+            return bytes;
+        }
+
+        public String toString() {
+            return str;
+        }
+
+        public boolean equals(Object o) {
+            return o instanceof ExternalData
+                && arrayEquals(getBytes(), ((ExternalData) o).getBytes());
+        }
+
+        public int hashCode() {
+            return arrayHash(getBytes());
+        }
+    }
+
+    private static class Variable
+        extends ExternalData implements Comparable<Variable>
+    {
+        protected Variable(String str, byte[] bytes) {
+            super(str, bytes);
+        }
+
+        public static Variable valueOfQueryOnly(Object str) {
+            return valueOfQueryOnly((String) str);
+        }
+
+        public static Variable valueOfQueryOnly(String str) {
+            return new Variable(str, str.getBytes());
+        }
+
+        public static Variable valueOf(String str) {
+            validateVariable(str);
+            return valueOfQueryOnly(str);
+        }
+
+        public static Variable valueOf(byte[] bytes) {
+            return new Variable(new String(bytes), bytes);
+        }
+
+        public int compareTo(Variable variable) {
+            return arrayCompare(getBytes(), variable.getBytes());
+        }
+
+        public boolean equals(Object o) {
+            return o instanceof Variable && super.equals(o);
+        }
+    }
+
+    private static class Value
+        extends ExternalData implements Comparable<Value>
+    {
+        protected Value(String str, byte[] bytes) {
+            super(str, bytes);
+        }
+
+        public static Value valueOfQueryOnly(Object str) {
+            return valueOfQueryOnly((String) str);
+        }
+
+        public static Value valueOfQueryOnly(String str) {
+            return new Value(str, str.getBytes());
+        }
+
+        public static Value valueOf(String str) {
+            validateValue(str);
+            return valueOfQueryOnly(str);
+        }
+
+        public static Value valueOf(byte[] bytes) {
+            return new Value(new String(bytes), bytes);
+        }
+
+        public int compareTo(Value value) {
+            return arrayCompare(getBytes(), value.getBytes());
+        }
+
+        public boolean equals(Object o) {
+            return o instanceof Value && super.equals(o);
+        }
+    }
+
+    // This implements the String map view the user sees.
+    private static class StringEnvironment
+        extends AbstractMap<String,String>
+    {
+        private Map<Variable,Value> m;
+        private static String toString(Value v) {
+            return v == null ? null : v.toString();
+        }
+        public StringEnvironment(Map<Variable,Value> m) {this.m = m;}
+        public int size()        {return m.size();}
+        public boolean isEmpty() {return m.isEmpty();}
+        public void clear()      {       m.clear();}
+        public boolean containsKey(Object key) {
+            return m.containsKey(Variable.valueOfQueryOnly(key));
+        }
+        public boolean containsValue(Object value) {
+            return m.containsValue(Value.valueOfQueryOnly(value));
+        }
+        public String get(Object key) {
+            return toString(m.get(Variable.valueOfQueryOnly(key)));
+        }
+        public String put(String key, String value) {
+            return toString(m.put(Variable.valueOf(key),
+                                  Value.valueOf(value)));
+        }
+        public String remove(Object key) {
+            return toString(m.remove(Variable.valueOfQueryOnly(key)));
+        }
+        public Set<String> keySet() {
+            return new StringKeySet(m.keySet());
+        }
+        public Set<Map.Entry<String,String>> entrySet() {
+            return new StringEntrySet(m.entrySet());
+        }
+        public Collection<String> values() {
+            return new StringValues(m.values());
+        }
+
+        // It is technically feasible to provide a byte-oriented view
+        // as follows:
+        //      public Map<byte[],byte[]> asByteArrayMap() {
+        //          return new ByteArrayEnvironment(m);
+        //      }
+
+
+        // Convert to Unix style environ as a monolithic byte array
+        // inspired by the Windows Environment Block, except we work
+        // exclusively with bytes instead of chars, and we need only
+        // one trailing NUL on Unix.
+        // This keeps the JNI as simple and efficient as possible.
+        public byte[] toEnvironmentBlock(int[]envc) {
+            int count = m.size() * 2; // For added '=' and NUL
+            for (Map.Entry<Variable,Value> entry : m.entrySet()) {
+                count += entry.getKey().getBytes().length;
+                count += entry.getValue().getBytes().length;
+            }
+
+            byte[] block = new byte[count];
+
+            int i = 0;
+            for (Map.Entry<Variable,Value> entry : m.entrySet()) {
+                byte[] key   = entry.getKey  ().getBytes();
+                byte[] value = entry.getValue().getBytes();
+                System.arraycopy(key, 0, block, i, key.length);
+                i+=key.length;
+                block[i++] = (byte) '=';
+                System.arraycopy(value, 0, block, i, value.length);
+                i+=value.length + 1;
+                // No need to write NUL byte explicitly
+                //block[i++] = (byte) '\u0000';
+            }
+            envc[0] = m.size();
+            return block;
+        }
+    }
+
+    static byte[] toEnvironmentBlock(Map<String,String> map, int[]envc) {
+        return map == null ? null :
+            ((StringEnvironment)map).toEnvironmentBlock(envc);
+    }
+
+
+    private static class StringEntry
+        implements Map.Entry<String,String>
+    {
+        private final Map.Entry<Variable,Value> e;
+        public StringEntry(Map.Entry<Variable,Value> e) {this.e = e;}
+        public String getKey()   {return e.getKey().toString();}
+        public String getValue() {return e.getValue().toString();}
+        public String setValue(String newValue) {
+            return e.setValue(Value.valueOf(newValue)).toString();
+        }
+        public String toString() {return getKey() + "=" + getValue();}
+        public boolean equals(Object o) {
+            return o instanceof StringEntry
+                && e.equals(((StringEntry)o).e);
+        }
+        public int hashCode()    {return e.hashCode();}
+    }
+
+    private static class StringEntrySet
+        extends AbstractSet<Map.Entry<String,String>>
+    {
+        private final Set<Map.Entry<Variable,Value>> s;
+        public StringEntrySet(Set<Map.Entry<Variable,Value>> s) {this.s = s;}
+        public int size()        {return s.size();}
+        public boolean isEmpty() {return s.isEmpty();}
+        public void clear()      {       s.clear();}
+        public Iterator<Map.Entry<String,String>> iterator() {
+            return new Iterator<Map.Entry<String,String>>() {
+                Iterator<Map.Entry<Variable,Value>> i = s.iterator();
+                public boolean hasNext() {return i.hasNext();}
+                public Map.Entry<String,String> next() {
+                    return new StringEntry(i.next());
+                }
+                public void remove() {i.remove();}
+            };
+        }
+        private static Map.Entry<Variable,Value> vvEntry(final Object o) {
+            if (o instanceof StringEntry)
+                return ((StringEntry)o).e;
+            return new Map.Entry<Variable,Value>() {
+                public Variable getKey() {
+                    return Variable.valueOfQueryOnly(((Map.Entry)o).getKey());
+                }
+                public Value getValue() {
+                    return Value.valueOfQueryOnly(((Map.Entry)o).getValue());
+                }
+                public Value setValue(Value value) {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+        public boolean contains(Object o) { return s.contains(vvEntry(o)); }
+        public boolean remove(Object o)   { return s.remove(vvEntry(o)); }
+        public boolean equals(Object o) {
+            return o instanceof StringEntrySet
+                && s.equals(((StringEntrySet) o).s);
+        }
+        public int hashCode() {return s.hashCode();}
+    }
+
+    private static class StringValues
+          extends AbstractCollection<String>
+    {
+        private final Collection<Value> c;
+        public StringValues(Collection<Value> c) {this.c = c;}
+        public int size()        {return c.size();}
+        public boolean isEmpty() {return c.isEmpty();}
+        public void clear()      {       c.clear();}
+        public Iterator<String> iterator() {
+            return new Iterator<String>() {
+                Iterator<Value> i = c.iterator();
+                public boolean hasNext() {return i.hasNext();}
+                public String next()     {return i.next().toString();}
+                public void remove()     {i.remove();}
+            };
+        }
+        public boolean contains(Object o) {
+            return c.contains(Value.valueOfQueryOnly(o));
+        }
+        public boolean remove(Object o) {
+            return c.remove(Value.valueOfQueryOnly(o));
+        }
+        public boolean equals(Object o) {
+            return o instanceof StringValues
+                && c.equals(((StringValues)o).c);
+        }
+        public int hashCode() {return c.hashCode();}
+    }
+
+    private static class StringKeySet extends AbstractSet<String> {
+        private final Set<Variable> s;
+        public StringKeySet(Set<Variable> s) {this.s = s;}
+        public int size()        {return s.size();}
+        public boolean isEmpty() {return s.isEmpty();}
+        public void clear()      {       s.clear();}
+        public Iterator<String> iterator() {
+            return new Iterator<String>() {
+                Iterator<Variable> i = s.iterator();
+                public boolean hasNext() {return i.hasNext();}
+                public String next()     {return i.next().toString();}
+                public void remove()     {       i.remove();}
+            };
+        }
+        public boolean contains(Object o) {
+            return s.contains(Variable.valueOfQueryOnly(o));
+        }
+        public boolean remove(Object o) {
+            return s.remove(Variable.valueOfQueryOnly(o));
+        }
+    }
+
+    // Replace with general purpose method someday
+    private static int arrayCompare(byte[]x, byte[] y) {
+        int min = x.length < y.length ? x.length : y.length;
+        for (int i = 0; i < min; i++)
+            if (x[i] != y[i])
+                return x[i] - y[i];
+        return x.length - y.length;
+    }
+
+    // Replace with general purpose method someday
+    private static boolean arrayEquals(byte[] x, byte[] y) {
+        if (x.length != y.length)
+            return false;
+        for (int i = 0; i < x.length; i++)
+            if (x[i] != y[i])
+                return false;
+        return true;
+    }
+
+    // Replace with general purpose method someday
+    private static int arrayHash(byte[] x) {
+        int hash = 0;
+        for (int i = 0; i < x.length; i++)
+            hash = 31 * hash + x[i];
+        return hash;
+    }
+
+}
diff --git a/java/lang/ProcessImpl.java b/java/lang/ProcessImpl.java
new file mode 100644
index 0000000..39ea145
--- /dev/null
+++ b/java/lang/ProcessImpl.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2003, 2010, 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;
+
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.lang.ProcessBuilder.Redirect;
+import java.lang.ProcessBuilder.Redirect;
+
+/**
+ * This class is for the exclusive use of ProcessBuilder.start() to
+ * create new processes.
+ *
+ * @author Martin Buchholz
+ * @since   1.5
+ */
+final class ProcessImpl {
+    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+    // private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+    //     = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    private ProcessImpl() {}    // Not instantiable
+
+    private static byte[] toCString(String s) {
+        if (s == null)
+            return null;
+        byte[] bytes = s.getBytes();
+        byte[] result = new byte[bytes.length + 1];
+        System.arraycopy(bytes, 0,
+                         result, 0,
+                         bytes.length);
+        result[result.length-1] = (byte)0;
+        return result;
+    }
+
+    // Only for use by ProcessBuilder.start()
+    static Process start(String[] cmdarray,
+                         java.util.Map<String,String> environment,
+                         String dir,
+                         ProcessBuilder.Redirect[] redirects,
+                         boolean redirectErrorStream)
+        throws IOException
+    {
+        assert cmdarray != null && cmdarray.length > 0;
+
+        // Convert arguments to a contiguous block; it's easier to do
+        // memory management in Java than in C.
+        byte[][] args = new byte[cmdarray.length-1][];
+        int size = args.length; // For added NUL bytes
+        for (int i = 0; i < args.length; i++) {
+            args[i] = cmdarray[i+1].getBytes();
+            size += args[i].length;
+        }
+        byte[] argBlock = new byte[size];
+        int i = 0;
+        for (byte[] arg : args) {
+            System.arraycopy(arg, 0, argBlock, i, arg.length);
+            i += arg.length + 1;
+            // No need to write NUL bytes explicitly
+        }
+
+        int[] envc = new int[1];
+        byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc);
+
+        int[] std_fds;
+
+        FileInputStream  f0 = null;
+        FileOutputStream f1 = null;
+        FileOutputStream f2 = null;
+
+        try {
+            if (redirects == null) {
+                std_fds = new int[] { -1, -1, -1 };
+            } else {
+                std_fds = new int[3];
+
+                if (redirects[0] == Redirect.PIPE)
+                    std_fds[0] = -1;
+                else if (redirects[0] == Redirect.INHERIT)
+                    std_fds[0] = 0;
+                else {
+                    f0 = new FileInputStream(redirects[0].file());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[0] = fdAccess.get(f0.getFD());
+                    std_fds[0] = f0.getFD().getInt$();
+                }
+
+                if (redirects[1] == Redirect.PIPE)
+                    std_fds[1] = -1;
+                else if (redirects[1] == Redirect.INHERIT)
+                    std_fds[1] = 1;
+                else {
+                    f1 = new FileOutputStream(redirects[1].file(),
+                                              redirects[1].append());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[1] = fdAccess.get(f1.getFD());
+                    std_fds[1] = f1.getFD().getInt$();
+                }
+
+                if (redirects[2] == Redirect.PIPE)
+                    std_fds[2] = -1;
+                else if (redirects[2] == Redirect.INHERIT)
+                    std_fds[2] = 2;
+                else {
+                    f2 = new FileOutputStream(redirects[2].file(),
+                                              redirects[2].append());
+                    // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+                    // std_fds[2] = fdAccess.get(f2.getFD());
+                    std_fds[2] = f2.getFD().getInt$();
+                }
+            }
+
+        return new UNIXProcess
+            (toCString(cmdarray[0]),
+             argBlock, args.length,
+             envBlock, envc[0],
+             toCString(dir),
+                 std_fds,
+             redirectErrorStream);
+        } finally {
+            // In theory, close() can throw IOException
+            // (although it is rather unlikely to happen here)
+            try { if (f0 != null) f0.close(); }
+            finally {
+                try { if (f1 != null) f1.close(); }
+                finally { if (f2 != null) f2.close(); }
+            }
+        }
+    }
+}
diff --git a/java/lang/Readable.java b/java/lang/Readable.java
new file mode 100644
index 0000000..c7a3d1a
--- /dev/null
+++ b/java/lang/Readable.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 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;
+
+import java.io.IOException;
+
+/**
+ * A <tt>Readable</tt> is a source of characters. Characters from
+ * a <tt>Readable</tt> are made available to callers of the read
+ * method via a {@link java.nio.CharBuffer CharBuffer}.
+ *
+ * @since 1.5
+ */
+public interface Readable {
+
+    /**
+     * Attempts to read characters into the specified character buffer.
+     * The buffer is used as a repository of characters as-is: the only
+     * changes made are the results of a put operation. No flipping or
+     * rewinding of the buffer is performed.
+     *
+     * @param cb the buffer to read characters into
+     * @return The number of {@code char} values added to the buffer,
+     *                 or -1 if this source of characters is at its end
+     * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if cb is null
+     * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
+     */
+    public int read(java.nio.CharBuffer cb) throws IOException;
+}
diff --git a/java/lang/ReflectiveOperationException.java b/java/lang/ReflectiveOperationException.java
new file mode 100644
index 0000000..a140478
--- /dev/null
+++ b/java/lang/ReflectiveOperationException.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009, 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;
+
+/**
+ * Common superclass of exceptions thrown by reflective operations in
+ * core reflection.
+ *
+ * @see LinkageError
+ * @since 1.7
+ */
+public class ReflectiveOperationException extends Exception {
+    static final long serialVersionUID = 123456789L;
+
+    /**
+     * Constructs a new exception with {@code null} as its detail
+     * message.  The cause is not initialized, and may subsequently be
+     * initialized by a call to {@link #initCause}.
+     */
+    public ReflectiveOperationException() {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     * The cause is not initialized, and may subsequently be
+     * initialized by a call to {@link #initCause}.
+     *
+     * @param   message   the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public ReflectiveOperationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message
+     * and cause.
+     *
+     * <p>Note that the detail message associated with
+     * {@code cause} is <em>not</em> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     */
+    public ReflectiveOperationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of {@code (cause==null ? null : cause.toString())} (which
+     * typically contains the class and detail message of {@code cause}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     */
+    public ReflectiveOperationException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/lang/Runnable.java b/java/lang/Runnable.java
new file mode 100644
index 0000000..b9f1df7
--- /dev/null
+++ b/java/lang/Runnable.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1994, 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;
+
+/**
+ * The <code>Runnable</code> interface should be implemented by any
+ * class whose instances are intended to be executed by a thread. The
+ * class must define a method of no arguments called <code>run</code>.
+ * <p>
+ * This interface is designed to provide a common protocol for objects that
+ * wish to execute code while they are active. For example,
+ * <code>Runnable</code> is implemented by class <code>Thread</code>.
+ * Being active simply means that a thread has been started and has not
+ * yet been stopped.
+ * <p>
+ * In addition, <code>Runnable</code> provides the means for a class to be
+ * active while not subclassing <code>Thread</code>. A class that implements
+ * <code>Runnable</code> can run without subclassing <code>Thread</code>
+ * by instantiating a <code>Thread</code> instance and passing itself in
+ * as the target.  In most cases, the <code>Runnable</code> interface should
+ * be used if you are only planning to override the <code>run()</code>
+ * method and no other <code>Thread</code> methods.
+ * This is important because classes should not be subclassed
+ * unless the programmer intends on modifying or enhancing the fundamental
+ * behavior of the class.
+ *
+ * @author  Arthur van Hoff
+ * @see     java.lang.Thread
+ * @see     java.util.concurrent.Callable
+ * @since   JDK1.0
+ */
+@FunctionalInterface
+public interface Runnable {
+    /**
+     * When an object implementing interface <code>Runnable</code> is used
+     * to create a thread, starting the thread causes the object's
+     * <code>run</code> method to be called in that separately executing
+     * thread.
+     * <p>
+     * The general contract of the method <code>run</code> is that it may
+     * take any action whatsoever.
+     *
+     * @see     java.lang.Thread#run()
+     */
+    public abstract void run();
+}
diff --git a/java/lang/Runtime.java b/java/lang/Runtime.java
new file mode 100644
index 0000000..f5c52e7
--- /dev/null
+++ b/java/lang/Runtime.java
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.*;
+import java.util.StringTokenizer;
+
+import dalvik.system.BlockGuard;
+import sun.reflect.CallerSensitive;
+import java.lang.ref.FinalizerReference;
+import java.util.ArrayList;
+import java.util.List;
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.PathClassLoader;
+import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.util.EmptyArray;
+import static android.system.OsConstants._SC_NPROCESSORS_CONF;
+
+/**
+ * Every Java application has a single instance of class
+ * <code>Runtime</code> that allows the application to interface with
+ * the environment in which the application is running. The current
+ * runtime can be obtained from the <code>getRuntime</code> method.
+ * <p>
+ * An application cannot create its own instance of this class.
+ *
+ * @author  unascribed
+ * @see     java.lang.Runtime#getRuntime()
+ * @since   JDK1.0
+ */
+
+public class Runtime {
+    private static Runtime currentRuntime = new Runtime();
+
+    /**
+     * Holds the list of threads to run when the VM terminates
+     */
+    private List<Thread> shutdownHooks = new ArrayList<Thread>();
+
+    /**
+     * Reflects whether finalization should be run for all objects
+     * when the VM terminates.
+     */
+    private static boolean finalizeOnExit;
+
+    /**
+     * Reflects whether we are already shutting down the VM.
+     */
+    private boolean shuttingDown;
+
+    /**
+     * Reflects whether we are tracing method calls.
+     */
+    private boolean tracingMethods;
+
+    private static native void nativeExit(int code);
+
+    /**
+     * Returns the runtime object associated with the current Java application.
+     * Most of the methods of class <code>Runtime</code> are instance
+     * methods and must be invoked with respect to the current runtime object.
+     *
+     * @return  the <code>Runtime</code> object associated with the current
+     *          Java application.
+     */
+    public static Runtime getRuntime() {
+        return currentRuntime;
+    }
+
+    /** Don't let anyone else instantiate this class */
+    private Runtime() {}
+
+    /**
+     * Terminates the currently running Java virtual machine by initiating its
+     * shutdown sequence.  This method never returns normally.  The argument
+     * serves as a status code; by convention, a nonzero status code indicates
+     * abnormal termination.
+     *
+     * <p> The virtual machine's shutdown sequence consists of two phases.  In
+     * the first phase all registered {@link #addShutdownHook shutdown hooks},
+     * if any, are started in some unspecified order and allowed to run
+     * concurrently until they finish.  In the second phase all uninvoked
+     * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit}
+     * has been enabled.  Once this is done the virtual machine {@link #halt
+     * halts}.
+     *
+     * <p> If this method is invoked after the virtual machine has begun its
+     * shutdown sequence then if shutdown hooks are being run this method will
+     * block indefinitely.  If shutdown hooks have already been run and on-exit
+     * finalization has been enabled then this method halts the virtual machine
+     * with the given status code if the status is nonzero; otherwise, it
+     * blocks indefinitely.
+     *
+     * <p> The <tt>{@link System#exit(int) System.exit}</tt> method is the
+     * conventional and convenient means of invoking this method. <p>
+     *
+     * @param  status
+     *         Termination status.  By convention, a nonzero status code
+     *         indicates abnormal termination.
+     *
+     * @throws SecurityException
+     *         If a security manager is present and its <tt>{@link
+     *         SecurityManager#checkExit checkExit}</tt> method does not permit
+     *         exiting with the specified status
+     *
+     * @see java.lang.SecurityException
+     * @see java.lang.SecurityManager#checkExit(int)
+     * @see #addShutdownHook
+     * @see #removeShutdownHook
+     * @see #runFinalizersOnExit
+     * @see #halt(int)
+     */
+    public void exit(int status) {
+        // Make sure we don't try this several times
+        synchronized(this) {
+            if (!shuttingDown) {
+                shuttingDown = true;
+
+                Thread[] hooks;
+                synchronized (shutdownHooks) {
+                    // create a copy of the hooks
+                    hooks = new Thread[shutdownHooks.size()];
+                    shutdownHooks.toArray(hooks);
+                }
+
+                // Start all shutdown hooks concurrently
+                for (Thread hook : hooks) {
+                    hook.start();
+                }
+
+                // Wait for all shutdown hooks to finish
+                for (Thread hook : hooks) {
+                    try {
+                        hook.join();
+                    } catch (InterruptedException ex) {
+                        // Ignore, since we are at VM shutdown.
+                    }
+                }
+
+                // Ensure finalization on exit, if requested
+                if (finalizeOnExit) {
+                    runFinalization();
+                }
+
+                // Get out of here finally...
+                nativeExit(status);
+            }
+        }
+    }
+
+    /**
+     * Registers a new virtual-machine shutdown hook.
+     *
+     * <p> The Java virtual machine <i>shuts down</i> in response to two kinds
+     * of events:
+     *
+     *   <ul>
+     *
+     *   <li> The program <i>exits</i> normally, when the last non-daemon
+     *   thread exits or when the <tt>{@link #exit exit}</tt> (equivalently,
+     *   {@link System#exit(int) System.exit}) method is invoked, or
+     *
+     *   <li> The virtual machine is <i>terminated</i> in response to a
+     *   user interrupt, such as typing <tt>^C</tt>, or a system-wide event,
+     *   such as user logoff or system shutdown.
+     *
+     *   </ul>
+     *
+     * <p> A <i>shutdown hook</i> is simply an initialized but unstarted
+     * thread.  When the virtual machine begins its shutdown sequence it will
+     * start all registered shutdown hooks in some unspecified order and let
+     * them run concurrently.  When all the hooks have finished it will then
+     * run all uninvoked finalizers if finalization-on-exit has been enabled.
+     * Finally, the virtual machine will halt.  Note that daemon threads will
+     * continue to run during the shutdown sequence, as will non-daemon threads
+     * if shutdown was initiated by invoking the <tt>{@link #exit exit}</tt>
+     * method.
+     *
+     * <p> Once the shutdown sequence has begun it can be stopped only by
+     * invoking the <tt>{@link #halt halt}</tt> method, which forcibly
+     * terminates the virtual machine.
+     *
+     * <p> Once the shutdown sequence has begun it is impossible to register a
+     * new shutdown hook or de-register a previously-registered hook.
+     * Attempting either of these operations will cause an
+     * <tt>{@link IllegalStateException}</tt> to be thrown.
+     *
+     * <p> Shutdown hooks run at a delicate time in the life cycle of a virtual
+     * machine and should therefore be coded defensively.  They should, in
+     * particular, be written to be thread-safe and to avoid deadlocks insofar
+     * as possible.  They should also not rely blindly upon services that may
+     * have registered their own shutdown hooks and therefore may themselves in
+     * the process of shutting down.  Attempts to use other thread-based
+     * services such as the AWT event-dispatch thread, for example, may lead to
+     * deadlocks.
+     *
+     * <p> Shutdown hooks should also finish their work quickly.  When a
+     * program invokes <tt>{@link #exit exit}</tt> the expectation is
+     * that the virtual machine will promptly shut down and exit.  When the
+     * virtual machine is terminated due to user logoff or system shutdown the
+     * underlying operating system may only allow a fixed amount of time in
+     * which to shut down and exit.  It is therefore inadvisable to attempt any
+     * user interaction or to perform a long-running computation in a shutdown
+     * hook.
+     *
+     * <p> Uncaught exceptions are handled in shutdown hooks just as in any
+     * other thread, by invoking the <tt>{@link ThreadGroup#uncaughtException
+     * uncaughtException}</tt> method of the thread's <tt>{@link
+     * ThreadGroup}</tt> object.  The default implementation of this method
+     * prints the exception's stack trace to <tt>{@link System#err}</tt> and
+     * terminates the thread; it does not cause the virtual machine to exit or
+     * halt.
+     *
+     * <p> In rare circumstances the virtual machine may <i>abort</i>, that is,
+     * stop running without shutting down cleanly.  This occurs when the
+     * virtual machine is terminated externally, for example with the
+     * <tt>SIGKILL</tt> signal on Unix or the <tt>TerminateProcess</tt> call on
+     * Microsoft Windows.  The virtual machine may also abort if a native
+     * method goes awry by, for example, corrupting internal data structures or
+     * attempting to access nonexistent memory.  If the virtual machine aborts
+     * then no guarantee can be made about whether or not any shutdown hooks
+     * will be run. <p>
+     *
+     * @param   hook
+     *          An initialized but unstarted <tt>{@link Thread}</tt> object
+     *
+     * @throws  IllegalArgumentException
+     *          If the specified hook has already been registered,
+     *          or if it can be determined that the hook is already running or
+     *          has already been run
+     *
+     * @throws  IllegalStateException
+     *          If the virtual machine is already in the process
+     *          of shutting down
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and it denies
+     *          <tt>{@link RuntimePermission}("shutdownHooks")</tt>
+     *
+     * @see #removeShutdownHook
+     * @see #halt(int)
+     * @see #exit(int)
+     * @since 1.3
+     */
+    public void addShutdownHook(Thread hook) {
+        // Sanity checks
+        if (hook == null) {
+            throw new NullPointerException("hook == null");
+        }
+
+        if (shuttingDown) {
+            throw new IllegalStateException("VM already shutting down");
+        }
+
+        if (hook.started) {
+            throw new IllegalArgumentException("Hook has already been started");
+        }
+
+        synchronized (shutdownHooks) {
+            if (shutdownHooks.contains(hook)) {
+                throw new IllegalArgumentException("Hook already registered.");
+            }
+
+            shutdownHooks.add(hook);
+        }
+    }
+
+    /**
+     * De-registers a previously-registered virtual-machine shutdown hook. <p>
+     *
+     * @param hook the hook to remove
+     * @return <tt>true</tt> if the specified hook had previously been
+     * registered and was successfully de-registered, <tt>false</tt>
+     * otherwise.
+     *
+     * @throws  IllegalStateException
+     *          If the virtual machine is already in the process of shutting
+     *          down
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and it denies
+     *          <tt>{@link RuntimePermission}("shutdownHooks")</tt>
+     *
+     * @see #addShutdownHook
+     * @see #exit(int)
+     * @since 1.3
+     */
+    public boolean removeShutdownHook(Thread hook) {
+        // Sanity checks
+        if (hook == null) {
+            throw new NullPointerException("hook == null");
+        }
+
+        if (shuttingDown) {
+            throw new IllegalStateException("VM already shutting down");
+        }
+
+        synchronized (shutdownHooks) {
+            return shutdownHooks.remove(hook);
+        }
+    }
+
+    /**
+     * Forcibly terminates the currently running Java virtual machine.  This
+     * method never returns normally.
+     *
+     * <p> This method should be used with extreme caution.  Unlike the
+     * <tt>{@link #exit exit}</tt> method, this method does not cause shutdown
+     * hooks to be started and does not run uninvoked finalizers if
+     * finalization-on-exit has been enabled.  If the shutdown sequence has
+     * already been initiated then this method does not wait for any running
+     * shutdown hooks or finalizers to finish their work. <p>
+     *
+     * @param  status
+     *         Termination status.  By convention, a nonzero status code
+     *         indicates abnormal termination.  If the <tt>{@link Runtime#exit
+     *         exit}</tt> (equivalently, <tt>{@link System#exit(int)
+     *         System.exit}</tt>) method has already been invoked then this
+     *         status code will override the status code passed to that method.
+     *
+     * @throws SecurityException
+     *         If a security manager is present and its <tt>{@link
+     *         SecurityManager#checkExit checkExit}</tt> method does not permit
+     *         an exit with the specified status
+     *
+     * @see #exit
+     * @see #addShutdownHook
+     * @see #removeShutdownHook
+     * @since 1.3
+     */
+    public void halt(int status) {
+        nativeExit(status);
+    }
+
+    /**
+     * Enable or disable finalization on exit; doing so specifies that the
+     * finalizers of all objects that have finalizers that have not yet been
+     * automatically invoked are to be run before the Java runtime exits.
+     * By default, finalization on exit is disabled.
+     *
+     * <p>If there is a security manager,
+     * its <code>checkExit</code> method is first called
+     * with 0 as its argument to ensure the exit is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param value true to enable finalization on exit, false to disable
+     * @deprecated  This method is inherently unsafe.  It may result in
+     *      finalizers being called on live objects while other threads are
+     *      concurrently manipulating those objects, resulting in erratic
+     *      behavior or deadlock.
+     *
+     * @throws  SecurityException
+     *        if a security manager exists and its <code>checkExit</code>
+     *        method doesn't allow the exit.
+     *
+     * @see     java.lang.Runtime#exit(int)
+     * @see     java.lang.Runtime#gc()
+     * @see     java.lang.SecurityManager#checkExit(int)
+     * @since   JDK1.1
+     */
+    @Deprecated
+    public static void runFinalizersOnExit(boolean value) {
+        finalizeOnExit = value;
+    }
+
+    /**
+     * Executes the specified string command in a separate process.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * <tt>exec(command)</tt>
+     * behaves in exactly the same way as the invocation
+     * <tt>{@link #exec(String, String[], File) exec}(command, null, null)</tt>.
+     *
+     * @param   command   a specified system command.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>command</code> is <code>null</code>
+     *
+     * @throws  IllegalArgumentException
+     *          If <code>command</code> is empty
+     *
+     * @see     #exec(String[], String[], File)
+     * @see     ProcessBuilder
+     */
+    public Process exec(String command) throws IOException {
+        return exec(command, null, null);
+    }
+
+    /**
+     * Executes the specified string command in a separate process with the
+     * specified environment.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * <tt>exec(command, envp)</tt>
+     * behaves in exactly the same way as the invocation
+     * <tt>{@link #exec(String, String[], File) exec}(command, envp, null)</tt>.
+     *
+     * @param   command   a specified system command.
+     *
+     * @param   envp      array of strings, each element of which
+     *                    has environment variable settings in the format
+     *                    <i>name</i>=<i>value</i>, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the environment of the current process.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>command</code> is <code>null</code>,
+     *          or one of the elements of <code>envp</code> is <code>null</code>
+     *
+     * @throws  IllegalArgumentException
+     *          If <code>command</code> is empty
+     *
+     * @see     #exec(String[], String[], File)
+     * @see     ProcessBuilder
+     */
+    public Process exec(String command, String[] envp) throws IOException {
+        return exec(command, envp, null);
+    }
+
+    /**
+     * Executes the specified string command in a separate process with the
+     * specified environment and working directory.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * <tt>exec(command, envp, dir)</tt>
+     * behaves in exactly the same way as the invocation
+     * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, dir)</tt>,
+     * where <code>cmdarray</code> is an array of all the tokens in
+     * <code>command</code>.
+     *
+     * <p>More precisely, the <code>command</code> string is broken
+     * into tokens using a {@link StringTokenizer} created by the call
+     * <code>new {@link StringTokenizer}(command)</code> with no
+     * further modification of the character categories.  The tokens
+     * produced by the tokenizer are then placed in the new string
+     * array <code>cmdarray</code>, in the same order.
+     *
+     * @param   command   a specified system command.
+     *
+     * @param   envp      array of strings, each element of which
+     *                    has environment variable settings in the format
+     *                    <i>name</i>=<i>value</i>, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the environment of the current process.
+     *
+     * @param   dir       the working directory of the subprocess, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the working directory of the current process.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>command</code> is <code>null</code>,
+     *          or one of the elements of <code>envp</code> is <code>null</code>
+     *
+     * @throws  IllegalArgumentException
+     *          If <code>command</code> is empty
+     *
+     * @see     ProcessBuilder
+     * @since 1.3
+     */
+    public Process exec(String command, String[] envp, File dir)
+        throws IOException {
+        if (command.length() == 0)
+            throw new IllegalArgumentException("Empty command");
+
+        StringTokenizer st = new StringTokenizer(command);
+        String[] cmdarray = new String[st.countTokens()];
+        for (int i = 0; st.hasMoreTokens(); i++)
+            cmdarray[i] = st.nextToken();
+        return exec(cmdarray, envp, dir);
+    }
+
+    /**
+     * Executes the specified command and arguments in a separate process.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * <tt>exec(cmdarray)</tt>
+     * behaves in exactly the same way as the invocation
+     * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, null, null)</tt>.
+     *
+     * @param   cmdarray  array containing the command to call and
+     *                    its arguments.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>cmdarray</code> is <code>null</code>,
+     *          or one of the elements of <code>cmdarray</code> is <code>null</code>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <code>cmdarray</code> is an empty array
+     *          (has length <code>0</code>)
+     *
+     * @see     ProcessBuilder
+     */
+    public Process exec(String cmdarray[]) throws IOException {
+        return exec(cmdarray, null, null);
+    }
+
+    /**
+     * Executes the specified command and arguments in a separate process
+     * with the specified environment.
+     *
+     * <p>This is a convenience method.  An invocation of the form
+     * <tt>exec(cmdarray, envp)</tt>
+     * behaves in exactly the same way as the invocation
+     * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, null)</tt>.
+     *
+     * @param   cmdarray  array containing the command to call and
+     *                    its arguments.
+     *
+     * @param   envp      array of strings, each element of which
+     *                    has environment variable settings in the format
+     *                    <i>name</i>=<i>value</i>, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the environment of the current process.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>cmdarray</code> is <code>null</code>,
+     *          or one of the elements of <code>cmdarray</code> is <code>null</code>,
+     *          or one of the elements of <code>envp</code> is <code>null</code>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <code>cmdarray</code> is an empty array
+     *          (has length <code>0</code>)
+     *
+     * @see     ProcessBuilder
+     */
+    public Process exec(String[] cmdarray, String[] envp) throws IOException {
+        return exec(cmdarray, envp, null);
+    }
+
+
+    /**
+     * Executes the specified command and arguments in a separate process with
+     * the specified environment and working directory.
+     *
+     * <p>Given an array of strings <code>cmdarray</code>, representing the
+     * tokens of a command line, and an array of strings <code>envp</code>,
+     * representing "environment" variable settings, this method creates
+     * a new process in which to execute the specified command.
+     *
+     * <p>This method checks that <code>cmdarray</code> is a valid operating
+     * system command.  Which commands are valid is system-dependent,
+     * but at the very least the command must be a non-empty list of
+     * non-null strings.
+     *
+     * <p>If <tt>envp</tt> is <tt>null</tt>, the subprocess inherits the
+     * environment settings of the current process.
+     *
+     * <p>A minimal set of system dependent environment variables may
+     * be required to start a process on some operating systems.
+     * As a result, the subprocess may inherit additional environment variable
+     * settings beyond those in the specified environment.
+     *
+     * <p>{@link ProcessBuilder#start()} is now the preferred way to
+     * start a process with a modified environment.
+     *
+     * <p>The working directory of the new subprocess is specified by <tt>dir</tt>.
+     * If <tt>dir</tt> is <tt>null</tt>, the subprocess inherits the
+     * current working directory of the current process.
+     *
+     * <p>If a security manager exists, its
+     * {@link SecurityManager#checkExec checkExec}
+     * method is invoked with the first component of the array
+     * <code>cmdarray</code> as its argument. This may result in a
+     * {@link SecurityException} being thrown.
+     *
+     * <p>Starting an operating system process is highly system-dependent.
+     * Among the many things that can go wrong are:
+     * <ul>
+     * <li>The operating system program file was not found.
+     * <li>Access to the program file was denied.
+     * <li>The working directory does not exist.
+     * </ul>
+     *
+     * <p>In such cases an exception will be thrown.  The exact nature
+     * of the exception is system-dependent, but it will always be a
+     * subclass of {@link IOException}.
+     *
+     *
+     * @param   cmdarray  array containing the command to call and
+     *                    its arguments.
+     *
+     * @param   envp      array of strings, each element of which
+     *                    has environment variable settings in the format
+     *                    <i>name</i>=<i>value</i>, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the environment of the current process.
+     *
+     * @param   dir       the working directory of the subprocess, or
+     *                    <tt>null</tt> if the subprocess should inherit
+     *                    the working directory of the current process.
+     *
+     * @return  A new {@link Process} object for managing the subprocess
+     *
+     * @throws  SecurityException
+     *          If a security manager exists and its
+     *          {@link SecurityManager#checkExec checkExec}
+     *          method doesn't allow creation of the subprocess
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  NullPointerException
+     *          If <code>cmdarray</code> is <code>null</code>,
+     *          or one of the elements of <code>cmdarray</code> is <code>null</code>,
+     *          or one of the elements of <code>envp</code> is <code>null</code>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <code>cmdarray</code> is an empty array
+     *          (has length <code>0</code>)
+     *
+     * @see     ProcessBuilder
+     * @since 1.3
+     */
+    public Process exec(String[] cmdarray, String[] envp, File dir)
+        throws IOException {
+        return new ProcessBuilder(cmdarray)
+            .environment(envp)
+            .directory(dir)
+            .start();
+    }
+
+    /**
+     * Returns the number of processors available to the Java virtual machine.
+     *
+     * <p> This value may change during a particular invocation of the virtual
+     * machine.  Applications that are sensitive to the number of available
+     * processors should therefore occasionally poll this property and adjust
+     * their resource usage appropriately. </p>
+     *
+     * @return  the maximum number of processors available to the virtual
+     *          machine; never smaller than one
+     * @since 1.4
+     */
+    public int availableProcessors() {
+        return (int) Libcore.os.sysconf(_SC_NPROCESSORS_CONF);
+    }
+
+    /**
+     * Returns the amount of free memory in the Java Virtual Machine.
+     * Calling the
+     * <code>gc</code> method may result in increasing the value returned
+     * by <code>freeMemory.</code>
+     *
+     * @return  an approximation to the total amount of memory currently
+     *          available for future allocated objects, measured in bytes.
+     */
+    @FastNative
+    public native long freeMemory();
+
+    /**
+     * Returns the total amount of memory in the Java virtual machine.
+     * The value returned by this method may vary over time, depending on
+     * the host environment.
+     * <p>
+     * Note that the amount of memory required to hold an object of any
+     * given type may be implementation-dependent.
+     *
+     * @return  the total amount of memory currently available for current
+     *          and future objects, measured in bytes.
+     */
+    @FastNative
+    public native long totalMemory();
+
+    /**
+     * Returns the maximum amount of memory that the Java virtual machine will
+     * attempt to use.  If there is no inherent limit then the value {@link
+     * java.lang.Long#MAX_VALUE} will be returned.
+     *
+     * @return  the maximum amount of memory that the virtual machine will
+     *          attempt to use, measured in bytes
+     * @since 1.4
+     */
+    @FastNative
+    public native long maxMemory();
+
+    /**
+     * Runs the garbage collector.
+     * Calling this method suggests that the Java virtual machine expend
+     * effort toward recycling unused objects in order to make the memory
+     * they currently occupy available for quick reuse. When control
+     * returns from the method call, the virtual machine has made
+     * its best effort to recycle all discarded objects.
+     * <p>
+     * The name <code>gc</code> stands for "garbage
+     * collector". The virtual machine performs this recycling
+     * process automatically as needed, in a separate thread, even if the
+     * <code>gc</code> method is not invoked explicitly.
+     * <p>
+     * The method {@link System#gc()} is the conventional and convenient
+     * means of invoking this method.
+     */
+    // Android-changed: Added BlockGuard check to gc()
+    // public native void gc();
+    public void gc() {
+        BlockGuard.getThreadPolicy().onExplicitGc();
+        nativeGc();
+    }
+
+    private native void nativeGc();
+
+    /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
+    private static native void runFinalization0();
+
+    /**
+     * Runs the finalization methods of any objects pending finalization.
+     * Calling this method suggests that the Java virtual machine expend
+     * effort toward running the <code>finalize</code> methods of objects
+     * that have been found to be discarded but whose <code>finalize</code>
+     * methods have not yet been run. When control returns from the
+     * method call, the virtual machine has made a best effort to
+     * complete all outstanding finalizations.
+     * <p>
+     * The virtual machine performs the finalization process
+     * automatically as needed, in a separate thread, if the
+     * <code>runFinalization</code> method is not invoked explicitly.
+     * <p>
+     * The method {@link System#runFinalization()} is the conventional
+     * and convenient means of invoking this method.
+     *
+     * @see     java.lang.Object#finalize()
+     */
+    public void runFinalization() {
+        VMRuntime.runFinalization(0);
+    }
+
+    /**
+     * Enables/Disables tracing of instructions.
+     * If the <code>boolean</code> argument is <code>true</code>, this
+     * method suggests that the Java virtual machine emit debugging
+     * information for each instruction in the virtual machine as it
+     * is executed. The format of this information, and the file or other
+     * output stream to which it is emitted, depends on the host environment.
+     * The virtual machine may ignore this request if it does not support
+     * this feature. The destination of the trace output is system
+     * dependent.
+     * <p>
+     * If the <code>boolean</code> argument is <code>false</code>, this
+     * method causes the virtual machine to stop performing the
+     * detailed instruction trace it is performing.
+     *
+     * @param   on   <code>true</code> to enable instruction tracing;
+     *               <code>false</code> to disable this feature.
+     */
+    public void traceInstructions(boolean on) {
+    }
+
+    /**
+     * Enables/Disables tracing of method calls.
+     * If the <code>boolean</code> argument is <code>true</code>, this
+     * method suggests that the Java virtual machine emit debugging
+     * information for each method in the virtual machine as it is
+     * called. The format of this information, and the file or other output
+     * stream to which it is emitted, depends on the host environment. The
+     * virtual machine may ignore this request if it does not support
+     * this feature.
+     * <p>
+     * Calling this method with argument false suggests that the
+     * virtual machine cease emitting per-call debugging information.
+     * <p>
+     * Calling this method on Android Lollipop or later (API level >= 21)
+     * with {@code true} argument will cause it to throw an
+     * {@code UnsupportedOperationException}.
+     *
+     * @param   on   <code>true</code> to enable instruction tracing;
+     *               <code>false</code> to disable this feature.
+     */
+    public void traceMethodCalls(boolean on) {
+        if (on != tracingMethods) {
+            if (on) {
+                VMDebug.startMethodTracing();
+            } else {
+                VMDebug.stopMethodTracing();
+            }
+            tracingMethods = on;
+        }
+    }
+
+    /**
+     * Loads the native library specified by the filename argument.  The filename
+     * argument must be an absolute path name.
+     * (for example
+     * <code>Runtime.getRuntime().load("/home/avh/lib/libX11.so");</code>).
+     *
+     * If the filename argument, when stripped of any platform-specific library
+     * prefix, path, and file extension, indicates a library whose name is,
+     * for example, L, and a native library called L is statically linked
+     * with the VM, then the JNI_OnLoad_L function exported by the library
+     * is invoked rather than attempting to load a dynamic library.
+     * A filename matching the argument does not have to exist in the file
+     * system. See the JNI Specification for more details.
+     *
+     * Otherwise, the filename argument is mapped to a native library image in
+     * an implementation-dependent manner.
+     * <p>
+     * First, if there is a security manager, its <code>checkLink</code>
+     * method is called with the <code>filename</code> as its argument.
+     * This may result in a security exception.
+     * <p>
+     * This is similar to the method {@link #loadLibrary(String)}, but it
+     * accepts a general file name as an argument rather than just a library
+     * name, allowing any file of native code to be loaded.
+     * <p>
+     * The method {@link System#load(String)} is the conventional and
+     * convenient means of invoking this method.
+     *
+     * @param      filename   the file to load.
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @exception  UnsatisfiedLinkError  if either the filename is not an
+     *             absolute path name, the native library is not statically
+     *             linked with the VM, or the library cannot be mapped to
+     *             a native library image by the host system.
+     * @exception  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.Runtime#getRuntime()
+     * @see        java.lang.SecurityException
+     * @see        java.lang.SecurityManager#checkLink(java.lang.String)
+     */
+    @CallerSensitive
+    public void load(String filename) {
+        load0(Reflection.getCallerClass(), filename);
+    }
+
+    /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */
+    private void checkTargetSdkVersionForLoad(String methodName) {
+        final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+        if (targetSdkVersion > 24) {
+            throw new UnsupportedOperationException(methodName + " is not supported on SDK " +
+                                                    targetSdkVersion);
+        }
+    }
+
+    // Fixes b/25859957 regression. Depending on private methods is bad, mkay.
+    void load(String absolutePath, ClassLoader loader) {
+        checkTargetSdkVersionForLoad("java.lang.Runtime#load(String, ClassLoader)");
+
+        java.lang.System.logE("java.lang.Runtime#load(String, ClassLoader)" +
+                              " is private and will be removed in a future Android release");
+        if (absolutePath == null) {
+            throw new NullPointerException("absolutePath == null");
+        }
+        String error = nativeLoad(absolutePath, loader);
+        if (error != null) {
+            throw new UnsatisfiedLinkError(error);
+        }
+    }
+
+    synchronized void load0(Class<?> fromClass, String filename) {
+        if (!(new File(filename).isAbsolute())) {
+            throw new UnsatisfiedLinkError(
+                "Expecting an absolute path of the library: " + filename);
+        }
+        if (filename == null) {
+            throw new NullPointerException("filename == null");
+        }
+        String error = nativeLoad(filename, fromClass.getClassLoader());
+        if (error != null) {
+            throw new UnsatisfiedLinkError(error);
+        }
+    }
+
+    /**
+     * Loads the native library specified by the <code>libname</code>
+     * argument.  The <code>libname</code> argument must not contain any platform
+     * specific prefix, file extension or path. If a native library
+     * called <code>libname</code> is statically linked with the VM, then the
+     * JNI_OnLoad_<code>libname</code> function exported by the library is invoked.
+     * See the JNI Specification for more details.
+     *
+     * Otherwise, the libname argument is loaded from a system library
+     * location and mapped to a native library image in an implementation-
+     * dependent manner.
+     * <p>
+     * First, if there is a security manager, its <code>checkLink</code>
+     * method is called with the <code>libname</code> as its argument.
+     * This may result in a security exception.
+     * <p>
+     * The method {@link System#loadLibrary(String)} is the conventional
+     * and convenient means of invoking this method. If native
+     * methods are to be used in the implementation of a class, a standard
+     * strategy is to put the native code in a library file (call it
+     * <code>LibFile</code>) and then to put a static initializer:
+     * <blockquote><pre>
+     * static { System.loadLibrary("LibFile"); }
+     * </pre></blockquote>
+     * within the class declaration. When the class is loaded and
+     * initialized, the necessary native code implementation for the native
+     * methods will then be loaded as well.
+     * <p>
+     * If this method is called more than once with the same library
+     * name, the second and subsequent calls are ignored.
+     *
+     * @param      libname   the name of the library.
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @exception  UnsatisfiedLinkError if either the libname argument
+     *             contains a file path, the native library is not statically
+     *             linked with the VM,  or the library cannot be mapped to a
+     *             native library image by the host system.
+     * @exception  NullPointerException if <code>libname</code> is
+     *             <code>null</code>
+     * @see        java.lang.SecurityException
+     * @see        java.lang.SecurityManager#checkLink(java.lang.String)
+     */
+    @CallerSensitive
+    public void loadLibrary(String libname) {
+        loadLibrary0(Reflection.getCallerClass(), libname);
+    }
+
+    // BEGIN Android-changed: Different implementation of loadLibrary0(Class, String).
+    /*
+    synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkLink(libname);
+        }
+        if (libname.indexOf((int)File.separatorChar) != -1) {
+            throw new UnsatisfiedLinkError(
+    "Directory separator should not appear in library name: " + libname);
+        }
+        ClassLoader.loadLibrary(fromClass, libname, false);
+    }
+    */
+    void loadLibrary0(Class<?> fromClass, String libname) {
+        ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);
+        loadLibrary0(classLoader, fromClass, libname);
+    }
+
+    /**
+     * Temporarily preserved for backward compatibility. Applications call this
+     * method using reflection.
+     *
+     * **** THIS METHOD WILL BE REMOVED IN A FUTURE ANDROID VERSION ****
+     *
+     * http://b/26217329
+     *
+     * @hide
+     */
+    public void loadLibrary(String libname, ClassLoader classLoader) {
+        checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)");
+        java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" +
+                              " is private and will be removed in a future Android release");
+        // Pass null for callerClass, we don't know it at this point. Passing null preserved
+        // the behavior when we used to not pass the class.
+        loadLibrary0(classLoader, null, libname);
+    }
+
+    // This overload exists for @UnsupportedAppUsage
+    void loadLibrary0(ClassLoader loader, String libname) {
+        // Pass null for callerClass, we don't know it at this point. Passing null preserved
+        // the behavior when we used to not pass the class.
+        loadLibrary0(loader, null, libname);
+    }
+    
+    /**
+     * Loads the shared library {@code libname} in the context of {@code loader} and
+     * {@code callerClass}.
+     *
+     * @param      loader    the class loader that initiated the loading. Used by the
+     *                       underlying linker to determine linker namespace. A {@code null}
+     *                       value represents the boot class loader.
+     * @param      fromClass the class that initiated the loading. Used when loader is
+     *                       {@code null} and ignored in all other cases. When used, it 
+     *                       determines the linker namespace from the class's .dex location.
+     *                       {@code null} indicates the default namespace for the boot 
+     *                       class loader.
+     * @param      libname   the name of the library.
+     */
+    private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) {
+        if (libname.indexOf((int)File.separatorChar) != -1) {
+            throw new UnsatisfiedLinkError(
+    "Directory separator should not appear in library name: " + libname);
+        }
+        String libraryName = libname;
+        // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480
+        // Android's class.getClassLoader() can return BootClassLoader where the RI would
+        // have returned null; therefore we treat BootClassLoader the same as null here.
+        if (loader != null && !(loader instanceof BootClassLoader)) {
+            String filename = loader.findLibrary(libraryName);
+            if (filename == null &&
+                    (loader.getClass() == PathClassLoader.class ||
+                     loader.getClass() == DelegateLastClassLoader.class)) {
+                // Don't give up even if we failed to find the library in the native lib paths.
+                // The underlying dynamic linker might be able to find the lib in one of the linker
+                // namespaces associated with the current linker namespace. In order to give the
+                // dynamic linker a chance, proceed to load the library with its soname, which
+                // is the fileName.
+                // Note that we do this only for PathClassLoader  and DelegateLastClassLoader to
+                // minimize the scope of this behavioral change as much as possible, which might
+                // cause problem like b/143649498. These two class loaders are the only
+                // platform-provided class loaders that can load apps. See the classLoader attribute
+                // of the application tag in app manifest.
+                filename = System.mapLibraryName(libraryName);
+            }
+            if (filename == null) {
+                // It's not necessarily true that the ClassLoader used
+                // System.mapLibraryName, but the default setup does, and it's
+                // misleading to say we didn't find "libMyLibrary.so" when we
+                // actually searched for "liblibMyLibrary.so.so".
+                throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
+                                               System.mapLibraryName(libraryName) + "\"");
+            }
+            String error = nativeLoad(filename, loader);
+            if (error != null) {
+                throw new UnsatisfiedLinkError(error);
+            }
+            return;
+        }
+
+        // We know some apps use mLibPaths directly, potentially assuming it's not null.
+        // Initialize it here to make sure apps see a non-null value.
+        getLibPaths();
+        String filename = System.mapLibraryName(libraryName);
+        String error = nativeLoad(filename, loader, callerClass);
+        if (error != null) {
+            throw new UnsatisfiedLinkError(error);
+        }
+    }
+
+    private volatile String[] mLibPaths = null;
+
+    private String[] getLibPaths() {
+        if (mLibPaths == null) {
+            synchronized(this) {
+                if (mLibPaths == null) {
+                    mLibPaths = initLibPaths();
+                }
+            }
+        }
+        return mLibPaths;
+    }
+
+    private static String[] initLibPaths() {
+        String javaLibraryPath = System.getProperty("java.library.path");
+        if (javaLibraryPath == null) {
+            return EmptyArray.STRING;
+        }
+        String[] paths = javaLibraryPath.split(":");
+        // Add a '/' to the end of each directory so we don't have to do it every time.
+        for (int i = 0; i < paths.length; ++i) {
+            if (!paths[i].endsWith("/")) {
+                paths[i] += "/";
+            }
+        }
+        return paths;
+    }
+
+    private static String nativeLoad(String filename, ClassLoader loader) {
+        return nativeLoad(filename, loader, null);
+    }
+
+    private static native String nativeLoad(String filename, ClassLoader loader, Class<?> caller);
+    // END Android-changed: Different implementation of loadLibrary0(Class, String).
+
+    /**
+     * Creates a localized version of an input stream. This method takes
+     * an <code>InputStream</code> and returns an <code>InputStream</code>
+     * equivalent to the argument in all respects except that it is
+     * localized: as characters in the local character set are read from
+     * the stream, they are automatically converted from the local
+     * character set to Unicode.
+     * <p>
+     * If the argument is already a localized stream, it may be returned
+     * as the result.
+     *
+     * @param      in InputStream to localize
+     * @return     a localized input stream
+     * @see        java.io.InputStream
+     * @see        java.io.BufferedReader#BufferedReader(java.io.Reader)
+     * @see        java.io.InputStreamReader#InputStreamReader(java.io.InputStream)
+     * @deprecated As of JDK&nbsp;1.1, the preferred way to translate a byte
+     * stream in the local encoding into a character stream in Unicode is via
+     * the <code>InputStreamReader</code> and <code>BufferedReader</code>
+     * classes.
+     */
+    @Deprecated
+    public InputStream getLocalizedInputStream(InputStream in) {
+        return in;
+    }
+
+    /**
+     * Creates a localized version of an output stream. This method
+     * takes an <code>OutputStream</code> and returns an
+     * <code>OutputStream</code> equivalent to the argument in all respects
+     * except that it is localized: as Unicode characters are written to
+     * the stream, they are automatically converted to the local
+     * character set.
+     * <p>
+     * If the argument is already a localized stream, it may be returned
+     * as the result.
+     *
+     * @deprecated As of JDK&nbsp;1.1, the preferred way to translate a
+     * Unicode character stream into a byte stream in the local encoding is via
+     * the <code>OutputStreamWriter</code>, <code>BufferedWriter</code>, and
+     * <code>PrintWriter</code> classes.
+     *
+     * @param      out OutputStream to localize
+     * @return     a localized output stream
+     * @see        java.io.OutputStream
+     * @see        java.io.BufferedWriter#BufferedWriter(java.io.Writer)
+     * @see        java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+     * @see        java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+     */
+    @Deprecated
+    public OutputStream getLocalizedOutputStream(OutputStream out) {
+        return out;
+    }
+
+}
diff --git a/java/lang/RuntimeException.java b/java/lang/RuntimeException.java
new file mode 100644
index 0000000..c9731e8
--- /dev/null
+++ b/java/lang/RuntimeException.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1995, 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 java.lang;
+
+/**
+ * {@code RuntimeException} is the superclass of those
+ * exceptions that can be thrown during the normal operation of the
+ * Java Virtual Machine.
+ *
+ * <p>{@code RuntimeException} and its subclasses are <em>unchecked
+ * exceptions</em>.  Unchecked exceptions do <em>not</em> need to be
+ * declared in a method or constructor's {@code throws} clause if they
+ * can be thrown by the execution of the method or constructor and
+ * propagate outside the method or constructor boundary.
+ *
+ * @author  Frank Yellin
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since   JDK1.0
+ */
+public class RuntimeException extends Exception {
+    static final long serialVersionUID = -7034897190745766939L;
+
+    /** Constructs a new runtime exception with {@code null} as its
+     * detail message.  The cause is not initialized, and may subsequently be
+     * initialized by a call to {@link #initCause}.
+     */
+    public RuntimeException() {
+        super();
+    }
+
+    /** Constructs a new runtime exception with the specified detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     *
+     * @param   message   the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public RuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new runtime exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this runtime exception's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public RuntimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /** Constructs a new runtime exception with the specified cause and a
+     * detail message of <tt>(cause==null ? null : cause.toString())</tt>
+     * (which typically contains the class and detail message of
+     * <tt>cause</tt>).  This constructor is useful for runtime exceptions
+     * that are little more than wrappers for other throwables.
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public RuntimeException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new runtime exception with the specified detail
+     * message, cause, suppression enabled or disabled, and writable
+     * stack trace enabled or disabled.
+     *
+     * @param  message the detail message.
+     * @param cause the cause.  (A {@code null} value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @param enableSuppression whether or not suppression is enabled
+     *                          or disabled
+     * @param writableStackTrace whether or not the stack trace should
+     *                           be writable
+     *
+     * @since 1.7
+     */
+    protected RuntimeException(String message, Throwable cause,
+                               boolean enableSuppression,
+                               boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/java/lang/RuntimePermission.java b/java/lang/RuntimePermission.java
new file mode 100644
index 0000000..2d05ba1
--- /dev/null
+++ b/java/lang/RuntimePermission.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1997, 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;
+
+import java.security.*;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class RuntimePermission extends BasicPermission {
+
+    private static final long serialVersionUID = 7399184964622342223L;
+
+    public RuntimePermission(String name)
+    {
+        super(name);
+    }
+
+    public RuntimePermission(String name, String actions)
+    {
+        super(name, actions);
+    }
+}
diff --git a/java/lang/SafeVarargs.java b/java/lang/SafeVarargs.java
new file mode 100644
index 0000000..6fcd48e
--- /dev/null
+++ b/java/lang/SafeVarargs.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, 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;
+
+import java.lang.annotation.*;
+
+/**
+ * A programmer assertion that the body of the annotated method or
+ * constructor does not perform potentially unsafe operations on its
+ * varargs parameter.  Applying this annotation to a method or
+ * constructor suppresses unchecked warnings about a
+ * <i>non-reifiable</i> variable arity (vararg) type and suppresses
+ * unchecked warnings about parameterized array creation at call
+ * sites.
+ *
+ * <p> In addition to the usage restrictions imposed by its {@link
+ * Target @Target} meta-annotation, compilers are required to implement
+ * additional usage restrictions on this annotation type; it is a
+ * compile-time error if a method or constructor declaration is
+ * annotated with a {@code @SafeVarargs} annotation, and either:
+ * <ul>
+ * <li>  the declaration is a fixed arity method or constructor
+ *
+ * <li> the declaration is a variable arity method that is neither
+ * {@code static} nor {@code final}.
+ *
+ * </ul>
+ *
+ * <p> Compilers are encouraged to issue warnings when this annotation
+ * type is applied to a method or constructor declaration where:
+ *
+ * <ul>
+ *
+ * <li> The variable arity parameter has a reifiable element type,
+ * which includes primitive types, {@code Object}, and {@code String}.
+ * (The unchecked warnings this annotation type suppresses already do
+ * not occur for a reifiable element type.)
+ *
+ * <li> The body of the method or constructor declaration performs
+ * potentially unsafe operations, such as an assignment to an element
+ * of the variable arity parameter's array that generates an unchecked
+ * warning.  Some unsafe operations do not trigger an unchecked
+ * warning.  For example, the aliasing in
+ *
+ * <blockquote><pre>
+ * &#64;SafeVarargs // Not actually safe!
+ * static void m(List&lt;String&gt;... stringLists) {
+ *   Object[] array = stringLists;
+ *   List&lt;Integer&gt; tmpList = Arrays.asList(42);
+ *   array[0] = tmpList; // Semantically invalid, but compiles without warnings
+ *   String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
+ * }
+ * </pre></blockquote>
+ *
+ * leads to a {@code ClassCastException} at runtime.
+ *
+ * <p>Future versions of the platform may mandate compiler errors for
+ * such unsafe operations.
+ *
+ * </ul>
+ *
+ * @since 1.7
+ * @jls 4.7 Reifiable Types
+ * @jls 8.4.1 Formal Parameters
+ * @jls 9.6.3.7 @SafeVarargs
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
+public @interface SafeVarargs {}
diff --git a/java/lang/SecurityException.java b/java/lang/SecurityException.java
new file mode 100644
index 0000000..7e07178
--- /dev/null
+++ b/java/lang/SecurityException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1995, 2003, 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;
+
+/**
+ * Thrown by the security manager to indicate a security violation.
+ *
+ * @author  unascribed
+ * @see     java.lang.SecurityManager
+ * @since   JDK1.0
+ */
+public class SecurityException extends RuntimeException {
+
+    private static final long serialVersionUID = 6878364983674394167L;
+
+    /**
+     * Constructs a <code>SecurityException</code> with no detail  message.
+     */
+    public SecurityException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>SecurityException</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public SecurityException(String s) {
+        super(s);
+    }
+
+    /**
+     * Creates a <code>SecurityException</code> with the specified
+     * detail message and cause.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *        by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A <tt>null</tt> value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public SecurityException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a <code>SecurityException</code> with the specified cause
+     * and a detail message of <tt>(cause==null ? null : cause.toString())</tt>
+     * (which typically contains the class and detail message of
+     * <tt>cause</tt>).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *        {@link #getCause()} method).  (A <tt>null</tt> value is permitted,
+     *        and indicates that the cause is nonexistent or unknown.)
+     * @since 1.5
+     */
+    public SecurityException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/lang/SecurityManager.java b/java/lang/SecurityManager.java
new file mode 100644
index 0000000..b7053e0
--- /dev/null
+++ b/java/lang/SecurityManager.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2006, 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;
+
+import java.security.*;
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// SecurityManager can only check access by Java code, so it can be bypassed by using
+// native code.  Applications should rely on Android permissions, process separation,
+// other other methods for security purposes.
+/**
+ * Legacy security code; do not use.
+ *
+ * <p>Security managers do <i>not</i> provide a secure environment for
+ * executing untrusted code and are unsupported on Android. Untrusted code
+ * cannot be safely isolated within a single VM on Android. Application
+ * developers can assume that there's no SecurityManager installed,
+ * i.e. {@link java.lang.System#getSecurityManager()} will return null.
+ */
+public
+class SecurityManager {
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected boolean inCheck;
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    public boolean getInCheck() {
+        return inCheck;
+    }
+
+    public SecurityManager() {
+
+    }
+
+    protected Class[] getClassContext() {
+        return null;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected ClassLoader currentClassLoader()
+    {
+        return null;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected Class<?> currentLoadedClass() {
+        return null;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected int classDepth(String name) {
+        return -1;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected int classLoaderDepth()
+    {
+        return -1;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected boolean inClass(String name) {
+        return false;
+    }
+
+    /**
+     * @deprecated Use {@link #checkPermission} instead.
+     */
+    @Deprecated
+    protected boolean inClassLoader() {
+        return false;
+    }
+
+    public Object getSecurityContext() {
+        return null;
+    }
+
+    public void checkPermission(Permission perm) {
+
+    }
+
+    public void checkPermission(Permission perm, Object context) {
+
+    }
+
+    public void checkCreateClassLoader() {
+
+    }
+
+    public void checkAccess(Thread t) { }
+
+    public void checkAccess(ThreadGroup g) { }
+
+    public void checkExit(int status) { }
+
+    public void checkExec(String cmd) { }
+
+    public void checkLink(String lib) { }
+
+    public void checkRead(FileDescriptor fd) { }
+
+    public void checkRead(String file) { }
+
+    public void checkRead(String file, Object context) { }
+
+    public void checkWrite(FileDescriptor fd) { }
+
+    public void checkWrite(String file) { }
+
+    public void checkDelete(String file) { }
+
+    public void checkConnect(String host, int port) { }
+
+    public void checkConnect(String host, int port, Object context) { }
+
+    public void checkListen(int port) { }
+
+    public void checkAccept(String host, int port) { }
+
+    public void checkMulticast(InetAddress maddr) { }
+
+    /**
+     * @deprecated use {@link #checkMulticast(java.net.InetAddress)} instead.
+     */
+    @Deprecated
+    public void checkMulticast(InetAddress maddr, byte ttl) { }
+
+    public void checkPropertiesAccess() { }
+
+    public void checkPropertyAccess(String key) { }
+
+    public boolean checkTopLevelWindow(Object window) {
+        return true;
+    }
+
+    public void checkPrintJobAccess() { }
+
+    public void checkSystemClipboardAccess() { }
+
+    public void checkAwtEventQueueAccess() { }
+
+    public void checkPackageAccess(String pkg) { }
+
+    public void checkPackageDefinition(String pkg) { }
+
+    public void checkSetFactory() { }
+
+    public void checkMemberAccess(Class<?> clazz, int which) { }
+
+    public void checkSecurityAccess(String target) { }
+
+    /**
+     * Returns the current thread's thread group.
+     */
+    public ThreadGroup getThreadGroup() {
+        return Thread.currentThread().getThreadGroup();
+    }
+
+}
diff --git a/java/lang/Short.java b/java/lang/Short.java
new file mode 100644
index 0000000..9fb3913
--- /dev/null
+++ b/java/lang/Short.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 1996, 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;
+
+/**
+ * The {@code Short} class wraps a value of primitive type {@code
+ * short} in an object.  An object of type {@code Short} contains a
+ * single field whose type is {@code short}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * a {@code short} to a {@code String} and a {@code String} to a
+ * {@code short}, as well as other constants and methods useful when
+ * dealing with a {@code short}.
+ *
+ * @author  Nakul Saraiya
+ * @author  Joseph D. Darcy
+ * @see     java.lang.Number
+ * @since   JDK1.1
+ */
+public final class Short extends Number implements Comparable<Short> {
+
+    /**
+     * A constant holding the minimum value a {@code short} can
+     * have, -2<sup>15</sup>.
+     */
+    public static final short   MIN_VALUE = -32768;
+
+    /**
+     * A constant holding the maximum value a {@code short} can
+     * have, 2<sup>15</sup>-1.
+     */
+    public static final short   MAX_VALUE = 32767;
+
+    /**
+     * The {@code Class} instance representing the primitive type
+     * {@code short}.
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Short>    TYPE = (Class<Short>) Class.getPrimitiveClass("short");
+
+    /**
+     * Returns a new {@code String} object representing the
+     * specified {@code short}. The radix is assumed to be 10.
+     *
+     * @param s the {@code short} to be converted
+     * @return the string representation of the specified {@code short}
+     * @see java.lang.Integer#toString(int)
+     */
+    public static String toString(short s) {
+        return Integer.toString((int)s, 10);
+    }
+
+    /**
+     * Parses the string argument as a signed {@code short} in the
+     * radix specified by the second argument. The characters in the
+     * string must all be digits, of the specified radix (as
+     * determined by whether {@link java.lang.Character#digit(char,
+     * int)} returns a nonnegative value) except that the first
+     * character may be an ASCII minus sign {@code '-'}
+     * ({@code '\u005Cu002D'}) to indicate a negative value or an
+     * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+     * indicate a positive value.  The resulting {@code short} value
+     * is returned.
+     *
+     * <p>An exception of type {@code NumberFormatException} is
+     * thrown if any of the following situations occurs:
+     * <ul>
+     * <li> The first argument is {@code null} or is a string of
+     * length zero.
+     *
+     * <li> The radix is either smaller than {@link
+     * java.lang.Character#MIN_RADIX} or larger than {@link
+     * java.lang.Character#MAX_RADIX}.
+     *
+     * <li> Any character of the string is not a digit of the
+     * specified radix, except that the first character may be a minus
+     * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+     * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+     * string is longer than length 1.
+     *
+     * <li> The value represented by the string is not a value of type
+     * {@code short}.
+     * </ul>
+     *
+     * @param s         the {@code String} containing the
+     *                  {@code short} representation to be parsed
+     * @param radix     the radix to be used while parsing {@code s}
+     * @return          the {@code short} represented by the string
+     *                  argument in the specified radix.
+     * @throws          NumberFormatException If the {@code String}
+     *                  does not contain a parsable {@code short}.
+     */
+    public static short parseShort(String s, int radix)
+        throws NumberFormatException {
+        int i = Integer.parseInt(s, radix);
+        if (i < MIN_VALUE || i > MAX_VALUE)
+            throw new NumberFormatException(
+                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
+        return (short)i;
+    }
+
+    /**
+     * Parses the string argument as a signed decimal {@code
+     * short}. The characters in the string must all be decimal
+     * digits, except that the first character may be an ASCII minus
+     * sign {@code '-'} ({@code '\u005Cu002D'}) to indicate a
+     * negative value or an ASCII plus sign {@code '+'}
+     * ({@code '\u005Cu002B'}) to indicate a positive value.  The
+     * resulting {@code short} value is returned, exactly as if the
+     * argument and the radix 10 were given as arguments to the {@link
+     * #parseShort(java.lang.String, int)} method.
+     *
+     * @param s a {@code String} containing the {@code short}
+     *          representation to be parsed
+     * @return  the {@code short} value represented by the
+     *          argument in decimal.
+     * @throws  NumberFormatException If the string does not
+     *          contain a parsable {@code short}.
+     */
+    public static short parseShort(String s) throws NumberFormatException {
+        return parseShort(s, 10);
+    }
+
+    /**
+     * Returns a {@code Short} object holding the value
+     * extracted from the specified {@code String} when parsed
+     * with the radix given by the second argument. The first argument
+     * is interpreted as representing a signed {@code short} in
+     * the radix specified by the second argument, exactly as if the
+     * argument were given to the {@link #parseShort(java.lang.String,
+     * int)} method. The result is a {@code Short} object that
+     * represents the {@code short} value specified by the string.
+     *
+     * <p>In other words, this method returns a {@code Short} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     *  {@code new Short(Short.parseShort(s, radix))}
+     * </blockquote>
+     *
+     * @param s         the string to be parsed
+     * @param radix     the radix to be used in interpreting {@code s}
+     * @return          a {@code Short} object holding the value
+     *                  represented by the string argument in the
+     *                  specified radix.
+     * @throws          NumberFormatException If the {@code String} does
+     *                  not contain a parsable {@code short}.
+     */
+    public static Short valueOf(String s, int radix)
+        throws NumberFormatException {
+        return valueOf(parseShort(s, radix));
+    }
+
+    /**
+     * Returns a {@code Short} object holding the
+     * value given by the specified {@code String}. The argument
+     * is interpreted as representing a signed decimal
+     * {@code short}, exactly as if the argument were given to
+     * the {@link #parseShort(java.lang.String)} method. The result is
+     * a {@code Short} object that represents the
+     * {@code short} value specified by the string.
+     *
+     * <p>In other words, this method returns a {@code Short} object
+     * equal to the value of:
+     *
+     * <blockquote>
+     *  {@code new Short(Short.parseShort(s))}
+     * </blockquote>
+     *
+     * @param s the string to be parsed
+     * @return  a {@code Short} object holding the value
+     *          represented by the string argument
+     * @throws  NumberFormatException If the {@code String} does
+     *          not contain a parsable {@code short}.
+     */
+    public static Short valueOf(String s) throws NumberFormatException {
+        return valueOf(s, 10);
+    }
+
+    private static class ShortCache {
+        private ShortCache(){}
+
+        static final Short cache[] = new Short[-(-128) + 127 + 1];
+
+        static {
+            for(int i = 0; i < cache.length; i++)
+                cache[i] = new Short((short)(i - 128));
+        }
+    }
+
+    /**
+     * Returns a {@code Short} instance representing the specified
+     * {@code short} value.
+     * If a new {@code Short} instance is not required, this method
+     * should generally be used in preference to the constructor
+     * {@link #Short(short)}, as this method is likely to yield
+     * significantly better space and time performance by caching
+     * frequently requested values.
+     *
+     * This method will always cache values in the range -128 to 127,
+     * inclusive, and may cache other values outside of this range.
+     *
+     * @param  s a short value.
+     * @return a {@code Short} instance representing {@code s}.
+     * @since  1.5
+     */
+    public static Short valueOf(short s) {
+        final int offset = 128;
+        int sAsInt = s;
+        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
+            return ShortCache.cache[sAsInt + offset];
+        }
+        return new Short(s);
+    }
+
+    /**
+     * Decodes a {@code String} into a {@code Short}.
+     * Accepts decimal, hexadecimal, and octal numbers given by
+     * the following grammar:
+     *
+     * <blockquote>
+     * <dl>
+     * <dt><i>DecodableString:</i>
+     * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+     * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+     *
+     * <dt><i>Sign:</i>
+     * <dd>{@code -}
+     * <dd>{@code +}
+     * </dl>
+     * </blockquote>
+     *
+     * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+     * are as defined in section 3.10.1 of
+     * <cite>The Java&trade; Language Specification</cite>,
+     * except that underscores are not accepted between digits.
+     *
+     * <p>The sequence of characters following an optional
+     * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+     * "{@code #}", or leading zero) is parsed as by the {@code
+     * Short.parseShort} method with the indicated radix (10, 16, or
+     * 8).  This sequence of characters must represent a positive
+     * value or a {@link NumberFormatException} will be thrown.  The
+     * result is negated if first character of the specified {@code
+     * String} is the minus sign.  No whitespace characters are
+     * permitted in the {@code String}.
+     *
+     * @param     nm the {@code String} to decode.
+     * @return    a {@code Short} object holding the {@code short}
+     *            value represented by {@code nm}
+     * @throws    NumberFormatException  if the {@code String} does not
+     *            contain a parsable {@code short}.
+     * @see java.lang.Short#parseShort(java.lang.String, int)
+     */
+    public static Short decode(String nm) throws NumberFormatException {
+        int i = Integer.decode(nm);
+        if (i < MIN_VALUE || i > MAX_VALUE)
+            throw new NumberFormatException(
+                    "Value " + i + " out of range from input " + nm);
+        return valueOf((short)i);
+    }
+
+    /**
+     * The value of the {@code Short}.
+     *
+     * @serial
+     */
+    private final short value;
+
+    /**
+     * Constructs a newly allocated {@code Short} object that
+     * represents the specified {@code short} value.
+     *
+     * @param value     the value to be represented by the
+     *                  {@code Short}.
+     */
+    public Short(short value) {
+        this.value = value;
+    }
+
+    /**
+     * Constructs a newly allocated {@code Short} object that
+     * represents the {@code short} value indicated by the
+     * {@code String} parameter. The string is converted to a
+     * {@code short} value in exactly the manner used by the
+     * {@code parseShort} method for radix 10.
+     *
+     * @param s the {@code String} to be converted to a
+     *          {@code Short}
+     * @throws  NumberFormatException If the {@code String}
+     *          does not contain a parsable {@code short}.
+     * @see     java.lang.Short#parseShort(java.lang.String, int)
+     */
+    public Short(String s) throws NumberFormatException {
+        this.value = parseShort(s, 10);
+    }
+
+    /**
+     * Returns the value of this {@code Short} as a {@code byte} after
+     * a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
+     */
+    public byte byteValue() {
+        return (byte)value;
+    }
+
+    /**
+     * Returns the value of this {@code Short} as a
+     * {@code short}.
+     */
+    public short shortValue() {
+        return value;
+    }
+
+    /**
+     * Returns the value of this {@code Short} as an {@code int} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public int intValue() {
+        return (int)value;
+    }
+
+    /**
+     * Returns the value of this {@code Short} as a {@code long} after
+     * a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public long longValue() {
+        return (long)value;
+    }
+
+    /**
+     * Returns the value of this {@code Short} as a {@code float}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public float floatValue() {
+        return (float)value;
+    }
+
+    /**
+     * Returns the value of this {@code Short} as a {@code double}
+     * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
+     */
+    public double doubleValue() {
+        return (double)value;
+    }
+
+    /**
+     * Returns a {@code String} object representing this
+     * {@code Short}'s value.  The value is converted to signed
+     * decimal representation and returned as a string, exactly as if
+     * the {@code short} value were given as an argument to the
+     * {@link java.lang.Short#toString(short)} method.
+     *
+     * @return  a string representation of the value of this object in
+     *          base&nbsp;10.
+     */
+    public String toString() {
+        return Integer.toString((int)value);
+    }
+
+    /**
+     * Returns a hash code for this {@code Short}; equal to the result
+     * of invoking {@code intValue()}.
+     *
+     * @return a hash code value for this {@code Short}
+     */
+    @Override
+    public int hashCode() {
+        return Short.hashCode(value);
+    }
+
+    /**
+     * Returns a hash code for a {@code short} value; compatible with
+     * {@code Short.hashCode()}.
+     *
+     * @param value the value to hash
+     * @return a hash code value for a {@code short} value.
+     * @since 1.8
+     */
+    public static int hashCode(short value) {
+        return (int)value;
+    }
+
+    /**
+     * Compares this object to the specified object.  The result is
+     * {@code true} if and only if the argument is not
+     * {@code null} and is a {@code Short} object that
+     * contains the same {@code short} value as this object.
+     *
+     * @param obj       the object to compare with
+     * @return          {@code true} if the objects are the same;
+     *                  {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Short) {
+            return value == ((Short)obj).shortValue();
+        }
+        return false;
+    }
+
+    /**
+     * Compares two {@code Short} objects numerically.
+     *
+     * @param   anotherShort   the {@code Short} to be compared.
+     * @return  the value {@code 0} if this {@code Short} is
+     *          equal to the argument {@code Short}; a value less than
+     *          {@code 0} if this {@code Short} is numerically less
+     *          than the argument {@code Short}; and a value greater than
+     *           {@code 0} if this {@code Short} is numerically
+     *           greater than the argument {@code Short} (signed
+     *           comparison).
+     * @since   1.2
+     */
+    public int compareTo(Short anotherShort) {
+        return compare(this.value, anotherShort.value);
+    }
+
+    /**
+     * Compares two {@code short} values numerically.
+     * The value returned is identical to what would be returned by:
+     * <pre>
+     *    Short.valueOf(x).compareTo(Short.valueOf(y))
+     * </pre>
+     *
+     * @param  x the first {@code short} to compare
+     * @param  y the second {@code short} to compare
+     * @return the value {@code 0} if {@code x == y};
+     *         a value less than {@code 0} if {@code x < y}; and
+     *         a value greater than {@code 0} if {@code x > y}
+     * @since 1.7
+     */
+    public static int compare(short x, short y) {
+        return x - y;
+    }
+
+    /**
+     * The number of bits used to represent a {@code short} value in two's
+     * complement binary form.
+     * @since 1.5
+     */
+    public static final int SIZE = 16;
+
+    /**
+     * The number of bytes used to represent a {@code short} value in two's
+     * complement binary form.
+     *
+     * @since 1.8
+     */
+    public static final int BYTES = SIZE / Byte.SIZE;
+
+    /**
+     * Returns the value obtained by reversing the order of the bytes in the
+     * two's complement representation of the specified {@code short} value.
+     *
+     * @param i the value whose bytes are to be reversed
+     * @return the value obtained by reversing (or, equivalently, swapping)
+     *     the bytes in the specified {@code short} value.
+     * @since 1.5
+     */
+    public static short reverseBytes(short i) {
+        return (short) (((i & 0xFF00) >> 8) | (i << 8));
+    }
+
+
+    /**
+     * Converts the argument to an {@code int} by an unsigned
+     * conversion.  In an unsigned conversion to an {@code int}, the
+     * high-order 16 bits of the {@code int} are zero and the
+     * low-order 16 bits are equal to the bits of the {@code short} argument.
+     *
+     * Consequently, zero and positive {@code short} values are mapped
+     * to a numerically equal {@code int} value and negative {@code
+     * short} values are mapped to an {@code int} value equal to the
+     * input plus 2<sup>16</sup>.
+     *
+     * @param  x the value to convert to an unsigned {@code int}
+     * @return the argument converted to {@code int} by an unsigned
+     *         conversion
+     * @since 1.8
+     */
+    public static int toUnsignedInt(short x) {
+        return ((int) x) & 0xffff;
+    }
+
+    /**
+     * Converts the argument to a {@code long} by an unsigned
+     * conversion.  In an unsigned conversion to a {@code long}, the
+     * high-order 48 bits of the {@code long} are zero and the
+     * low-order 16 bits are equal to the bits of the {@code short} argument.
+     *
+     * Consequently, zero and positive {@code short} values are mapped
+     * to a numerically equal {@code long} value and negative {@code
+     * short} values are mapped to a {@code long} value equal to the
+     * input plus 2<sup>16</sup>.
+     *
+     * @param  x the value to convert to an unsigned {@code long}
+     * @return the argument converted to {@code long} by an unsigned
+     *         conversion
+     * @since 1.8
+     */
+    public static long toUnsignedLong(short x) {
+        return ((long) x) & 0xffffL;
+    }
+
+    /** use serialVersionUID from JDK 1.1. for interoperability */
+    private static final long serialVersionUID = 7515723908773894738L;
+}
diff --git a/java/lang/StackOverflowError.java b/java/lang/StackOverflowError.java
new file mode 100644
index 0000000..73fd8c1
--- /dev/null
+++ b/java/lang/StackOverflowError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when a stack overflow occurs because an application
+ * recurses too deeply.
+ *
+ * @author unascribed
+ * @since   JDK1.0
+ */
+public
+class StackOverflowError extends VirtualMachineError {
+    private static final long serialVersionUID = 8609175038441759607L;
+
+    /**
+     * Constructs a <code>StackOverflowError</code> with no detail message.
+     */
+    public StackOverflowError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>StackOverflowError</code> with the specified
+     * detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public StackOverflowError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/StackTraceElement.java b/java/lang/StackTraceElement.java
new file mode 100644
index 0000000..e3dad88
--- /dev/null
+++ b/java/lang/StackTraceElement.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2000, 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;
+
+import java.util.Objects;
+
+/**
+ * An element in a stack trace, as returned by {@link
+ * Throwable#getStackTrace()}.  Each element represents a single stack frame.
+ * All stack frames except for the one at the top of the stack represent
+ * a method invocation.  The frame at the top of the stack represents the
+ * execution point at which the stack trace was generated.  Typically,
+ * this is the point at which the throwable corresponding to the stack trace
+ * was created.
+ *
+ * @since  1.4
+ * @author Josh Bloch
+ */
+public final class StackTraceElement implements java.io.Serializable {
+    // Normally initialized by VM (public constructor added in 1.5)
+    private String declaringClass;
+    private String methodName;
+    private String fileName;
+    private int    lineNumber;
+
+    /**
+     * Creates a stack trace element representing the specified execution
+     * point.
+     *
+     * @param declaringClass the fully qualified name of the class containing
+     *        the execution point represented by the stack trace element
+     * @param methodName the name of the method containing the execution point
+     *        represented by the stack trace element
+     * @param fileName the name of the file containing the execution point
+     *         represented by the stack trace element, or {@code null} if
+     *         this information is unavailable
+     * @param lineNumber the line number of the source line containing the
+     *         execution point represented by this stack trace element, or
+     *         a negative number if this information is unavailable. A value
+     *         of -2 indicates that the method containing the execution point
+     *         is a native method
+     * @throws NullPointerException if {@code declaringClass} or
+     *         {@code methodName} is null
+     * @since 1.5
+     */
+    public StackTraceElement(String declaringClass, String methodName,
+                             String fileName, int lineNumber) {
+        this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+        this.methodName     = Objects.requireNonNull(methodName, "Method name is null");
+        this.fileName       = fileName;
+        this.lineNumber     = lineNumber;
+    }
+
+    /**
+     * Returns the name of the source file containing the execution point
+     * represented by this stack trace element.  Generally, this corresponds
+     * to the {@code SourceFile} attribute of the relevant {@code class}
+     * file (as per <i>The Java Virtual Machine Specification</i>, Section
+     * 4.7.7).  In some systems, the name may refer to some source code unit
+     * other than a file, such as an entry in source repository.
+     *
+     * @return the name of the file containing the execution point
+     *         represented by this stack trace element, or {@code null} if
+     *         this information is unavailable.
+     */
+    public String getFileName() {
+        return fileName;
+    }
+
+    /**
+     * Returns the line number of the source line containing the execution
+     * point represented by this stack trace element.  Generally, this is
+     * derived from the {@code LineNumberTable} attribute of the relevant
+     * {@code class} file (as per <i>The Java Virtual Machine
+     * Specification</i>, Section 4.7.8).
+     *
+     * @return the line number of the source line containing the execution
+     *         point represented by this stack trace element, or a negative
+     *         number if this information is unavailable.
+     */
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    /**
+     * Returns the fully qualified name of the class containing the
+     * execution point represented by this stack trace element.
+     *
+     * @return the fully qualified name of the {@code Class} containing
+     *         the execution point represented by this stack trace element.
+     */
+    public String getClassName() {
+        return declaringClass;
+    }
+
+    /**
+     * Returns the name of the method containing the execution point
+     * represented by this stack trace element.  If the execution point is
+     * contained in an instance or class initializer, this method will return
+     * the appropriate <i>special method name</i>, {@code <init>} or
+     * {@code <clinit>}, as per Section 3.9 of <i>The Java Virtual
+     * Machine Specification</i>.
+     *
+     * @return the name of the method containing the execution point
+     *         represented by this stack trace element.
+     */
+    public String getMethodName() {
+        return methodName;
+    }
+
+    /**
+     * Returns true if the method containing the execution point
+     * represented by this stack trace element is a native method.
+     *
+     * @return {@code true} if the method containing the execution point
+     *         represented by this stack trace element is a native method.
+     */
+    public boolean isNativeMethod() {
+        return lineNumber == -2;
+    }
+
+    /**
+     * Returns a string representation of this stack trace element.  The
+     * format of this string depends on the implementation, but the following
+     * examples may be regarded as typical:
+     * <ul>
+     * <li>
+     *   {@code "MyClass.mash(MyClass.java:9)"} - Here, {@code "MyClass"}
+     *   is the <i>fully-qualified name</i> of the class containing the
+     *   execution point represented by this stack trace element,
+     *   {@code "mash"} is the name of the method containing the execution
+     *   point, {@code "MyClass.java"} is the source file containing the
+     *   execution point, and {@code "9"} is the line number of the source
+     *   line containing the execution point.
+     * <li>
+     *   {@code "MyClass.mash(MyClass.java)"} - As above, but the line
+     *   number is unavailable.
+     * <li>
+     *   {@code "MyClass.mash(Unknown Source)"} - As above, but neither
+     *   the file name nor the line  number are available.
+     * <li>
+     *   {@code "MyClass.mash(Native Method)"} - As above, but neither
+     *   the file name nor the line  number are available, and the method
+     *   containing the execution point is known to be a native method.
+     * </ul>
+     * @see    Throwable#printStackTrace()
+     */
+    public String toString() {
+        // BEGIN Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+        // http://b/30183883
+        // The only behavior change is that "Unknown Source" is followed by a number
+        // (the value of the dex program counter, dex_pc), which never occurs on the
+        // RI. This value isn't a line number, but can be useful for debugging and
+        // avoids the need to ship line number information along with the dex code to
+        // get an accurate stack trace.
+        // Formatting it in this way might be more digestible to automated tools that
+        // are not specifically written to expect this behavior.
+        /*
+        return getClassName() + "." + methodName +
+            (isNativeMethod() ? "(Native Method)" :
+             (fileName != null && lineNumber >= 0 ?
+              "(" + fileName + ":" + lineNumber + ")" :
+              (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
+        */
+        StringBuilder result = new StringBuilder();
+        result.append(getClassName()).append(".").append(methodName);
+        if (isNativeMethod()) {
+            result.append("(Native Method)");
+        } else if (fileName != null) {
+            if (lineNumber >= 0) {
+                result.append("(").append(fileName).append(":").append(lineNumber).append(")");
+            } else {
+                result.append("(").append(fileName).append(")");
+            }
+        } else {
+            if (lineNumber >= 0) {
+                // The line number is actually the dex pc.
+                result.append("(Unknown Source:").append(lineNumber).append(")");
+            } else {
+                result.append("(Unknown Source)");
+            }
+        }
+        return result.toString();
+        // END Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+    }
+
+    /**
+     * Returns true if the specified object is another
+     * {@code StackTraceElement} instance representing the same execution
+     * point as this instance.  Two stack trace elements {@code a} and
+     * {@code b} are equal if and only if:
+     * <pre>{@code
+     *     equals(a.getFileName(), b.getFileName()) &&
+     *     a.getLineNumber() == b.getLineNumber()) &&
+     *     equals(a.getClassName(), b.getClassName()) &&
+     *     equals(a.getMethodName(), b.getMethodName())
+     * }</pre>
+     * where {@code equals} has the semantics of {@link
+     * java.util.Objects#equals(Object, Object) Objects.equals}.
+     *
+     * @param  obj the object to be compared with this stack trace element.
+     * @return true if the specified object is another
+     *         {@code StackTraceElement} instance representing the same
+     *         execution point as this instance.
+     */
+    public boolean equals(Object obj) {
+        if (obj==this)
+            return true;
+        if (!(obj instanceof StackTraceElement))
+            return false;
+        StackTraceElement e = (StackTraceElement)obj;
+        return e.declaringClass.equals(declaringClass) &&
+            e.lineNumber == lineNumber &&
+            Objects.equals(methodName, e.methodName) &&
+            Objects.equals(fileName, e.fileName);
+    }
+
+    /**
+     * Returns a hash code value for this stack trace element.
+     */
+    public int hashCode() {
+        int result = 31*declaringClass.hashCode() + methodName.hashCode();
+        result = 31*result + Objects.hashCode(fileName);
+        result = 31*result + lineNumber;
+        return result;
+    }
+
+    private static final long serialVersionUID = 6992337162326171013L;
+}
diff --git a/java/lang/StrictMath.java b/java/lang/StrictMath.java
new file mode 100644
index 0000000..ae4af2b
--- /dev/null
+++ b/java/lang/StrictMath.java
@@ -0,0 +1,1710 @@
+/*
+ * Copyright (c) 1999, 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;
+import java.util.Random;
+import sun.misc.DoubleConsts;
+
+/**
+ * The class {@code StrictMath} contains methods for performing basic
+ * numeric operations such as the elementary exponential, logarithm,
+ * square root, and trigonometric functions.
+ *
+ * <p>To help ensure portability of Java programs, the definitions of
+ * some of the numeric functions in this package require that they
+ * produce the same results as certain published algorithms. These
+ * algorithms are available from the well-known network library
+ * {@code netlib} as the package "Freely Distributable Math
+ * Library," <a
+ * href="ftp://ftp.netlib.org/fdlibm.tar">{@code fdlibm}</a>. These
+ * algorithms, which are written in the C programming language, are
+ * then to be understood as executed with all floating-point
+ * operations following the rules of Java floating-point arithmetic.
+ *
+ * <p>The Java math library is defined with respect to
+ * {@code fdlibm} version 5.3. Where {@code fdlibm} provides
+ * more than one definition for a function (such as
+ * {@code acos}), use the "IEEE 754 core function" version
+ * (residing in a file whose name begins with the letter
+ * {@code e}).  The methods which require {@code fdlibm}
+ * semantics are {@code sin}, {@code cos}, {@code tan},
+ * {@code asin}, {@code acos}, {@code atan},
+ * {@code exp}, {@code log}, {@code log10},
+ * {@code cbrt}, {@code atan2}, {@code pow},
+ * {@code sinh}, {@code cosh}, {@code tanh},
+ * {@code hypot}, {@code expm1}, and {@code log1p}.
+ *
+ * <p>
+ * The platform uses signed two's complement integer arithmetic with
+ * int and long primitive types.  The developer should choose
+ * the primitive type to ensure that arithmetic operations consistently
+ * produce correct results, which in some cases means the operations
+ * will not overflow the range of values of the computation.
+ * The best practice is to choose the primitive type and algorithm to avoid
+ * overflow. In cases where the size is {@code int} or {@code long} and
+ * overflow errors need to be detected, the methods {@code addExact},
+ * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * throw an {@code ArithmeticException} when the results overflow.
+ * For other arithmetic operations such as divide, absolute value,
+ * increment, decrement, and negation overflow occurs only with
+ * a specific minimum or maximum value and should be checked against
+ * the minimum or maximum as appropriate.
+ *
+ * @author  unascribed
+ * @author  Joseph D. Darcy
+ * @since   1.3
+ */
+
+public final class StrictMath {
+
+    /**
+     * Don't let anyone instantiate this class.
+     */
+    private StrictMath() {}
+
+    /**
+     * The {@code double} value that is closer than any other to
+     * <i>e</i>, the base of the natural logarithms.
+     */
+    public static final double E = 2.7182818284590452354;
+
+    /**
+     * The {@code double} value that is closer than any other to
+     * <i>pi</i>, the ratio of the circumference of a circle to its
+     * diameter.
+     */
+    public static final double PI = 3.14159265358979323846;
+
+    /**
+     * Returns the trigonometric sine of an angle. Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the
+     * result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * @param   a   an angle, in radians.
+     * @return  the sine of the argument.
+     */
+    public static native double sin(double a);
+
+    /**
+     * Returns the trigonometric cosine of an angle. Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the
+     * result is NaN.</ul>
+     *
+     * @param   a   an angle, in radians.
+     * @return  the cosine of the argument.
+     */
+    public static native double cos(double a);
+
+    /**
+     * Returns the trigonometric tangent of an angle. Special cases:
+     * <ul><li>If the argument is NaN or an infinity, then the result
+     * is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * @param   a   an angle, in radians.
+     * @return  the tangent of the argument.
+     */
+    public static native double tan(double a);
+
+    /**
+     * Returns the arc sine of a value; the returned angle is in the
+     * range -<i>pi</i>/2 through <i>pi</i>/2.  Special cases:
+     * <ul><li>If the argument is NaN or its absolute value is greater
+     * than 1, then the result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * @param   a   the value whose arc sine is to be returned.
+     * @return  the arc sine of the argument.
+     */
+    public static native double asin(double a);
+
+    /**
+     * Returns the arc cosine of a value; the returned angle is in the
+     * range 0.0 through <i>pi</i>.  Special case:
+     * <ul><li>If the argument is NaN or its absolute value is greater
+     * than 1, then the result is NaN.</ul>
+     *
+     * @param   a   the value whose arc cosine is to be returned.
+     * @return  the arc cosine of the argument.
+     */
+    public static native double acos(double a);
+
+    /**
+     * Returns the arc tangent of a value; the returned angle is in the
+     * range -<i>pi</i>/2 through <i>pi</i>/2.  Special cases:
+     * <ul><li>If the argument is NaN, then the result is NaN.
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.</ul>
+     *
+     * @param   a   the value whose arc tangent is to be returned.
+     * @return  the arc tangent of the argument.
+     */
+    public static native double atan(double a);
+
+    /**
+     * Converts an angle measured in degrees to an approximately
+     * equivalent angle measured in radians.  The conversion from
+     * degrees to radians is generally inexact.
+     *
+     * @param   angdeg   an angle, in degrees
+     * @return  the measurement of the angle {@code angdeg}
+     *          in radians.
+     */
+    public static strictfp double toRadians(double angdeg) {
+        // Do not delegate to Math.toRadians(angdeg) because
+        // this method has the strictfp modifier.
+        return angdeg / 180.0 * PI;
+    }
+
+    /**
+     * Converts an angle measured in radians to an approximately
+     * equivalent angle measured in degrees.  The conversion from
+     * radians to degrees is generally inexact; users should
+     * <i>not</i> expect {@code cos(toRadians(90.0))} to exactly
+     * equal {@code 0.0}.
+     *
+     * @param   angrad   an angle, in radians
+     * @return  the measurement of the angle {@code angrad}
+     *          in degrees.
+     */
+    public static strictfp double toDegrees(double angrad) {
+        // Do not delegate to Math.toDegrees(angrad) because
+        // this method has the strictfp modifier.
+        return angrad * 180.0 / PI;
+    }
+
+    /**
+     * Returns Euler's number <i>e</i> raised to the power of a
+     * {@code double} value. Special cases:
+     * <ul><li>If the argument is NaN, the result is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is negative infinity, then the result is
+     * positive zero.</ul>
+     *
+     * @param   a   the exponent to raise <i>e</i> to.
+     * @return  the value <i>e</i><sup>{@code a}</sup>,
+     *          where <i>e</i> is the base of the natural logarithms.
+     */
+    public static native double exp(double a);
+
+    /**
+     * Returns the natural logarithm (base <i>e</i>) of a {@code double}
+     * value. Special cases:
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is negative infinity.</ul>
+     *
+     * @param   a   a value
+     * @return  the value ln&nbsp;{@code a}, the natural logarithm of
+     *          {@code a}.
+     */
+    public static native double log(double a);
+
+
+    /**
+     * Returns the base 10 logarithm of a {@code double} value.
+     * Special cases:
+     *
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is negative infinity.
+     * <li> If the argument is equal to 10<sup><i>n</i></sup> for
+     * integer <i>n</i>, then the result is <i>n</i>.
+     * </ul>
+     *
+     * @param   a   a value
+     * @return  the base 10 logarithm of  {@code a}.
+     * @since 1.5
+     */
+    public static native double log10(double a);
+
+    /**
+     * Returns the correctly rounded positive square root of a
+     * {@code double} value.
+     * Special cases:
+     * <ul><li>If the argument is NaN or less than zero, then the result
+     * is NaN.
+     * <li>If the argument is positive infinity, then the result is positive
+     * infinity.
+     * <li>If the argument is positive zero or negative zero, then the
+     * result is the same as the argument.</ul>
+     * Otherwise, the result is the {@code double} value closest to
+     * the true mathematical square root of the argument value.
+     *
+     * @param   a   a value.
+     * @return  the positive square root of {@code a}.
+     */
+    public static native double sqrt(double a);
+
+    /**
+     * Returns the cube root of a {@code double} value.  For
+     * positive finite {@code x}, {@code cbrt(-x) ==
+     * -cbrt(x)}; that is, the cube root of a negative value is
+     * the negative of the cube root of that value's magnitude.
+     * Special cases:
+     *
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is an infinity
+     * with the same sign as the argument.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * @param   a   a value.
+     * @return  the cube root of {@code a}.
+     * @since 1.5
+     */
+    public static native double cbrt(double a);
+
+    /**
+     * Computes the remainder operation on two arguments as prescribed
+     * by the IEEE 754 standard.
+     * The remainder value is mathematically equal to
+     * <code>f1&nbsp;-&nbsp;f2</code>&nbsp;&times;&nbsp;<i>n</i>,
+     * where <i>n</i> is the mathematical integer closest to the exact
+     * mathematical value of the quotient {@code f1/f2}, and if two
+     * mathematical integers are equally close to {@code f1/f2},
+     * then <i>n</i> is the integer that is even. If the remainder is
+     * zero, its sign is the same as the sign of the first argument.
+     * Special cases:
+     * <ul><li>If either argument is NaN, or the first argument is infinite,
+     * or the second argument is positive zero or negative zero, then the
+     * result is NaN.
+     * <li>If the first argument is finite and the second argument is
+     * infinite, then the result is the same as the first argument.</ul>
+     *
+     * @param   f1   the dividend.
+     * @param   f2   the divisor.
+     * @return  the remainder when {@code f1} is divided by
+     *          {@code f2}.
+     */
+    public static native double IEEEremainder(double f1, double f2);
+
+    /**
+     * Returns the smallest (closest to negative infinity)
+     * {@code double} value that is greater than or equal to the
+     * argument and is equal to a mathematical integer. Special cases:
+     * <ul><li>If the argument value is already equal to a
+     * mathematical integer, then the result is the same as the
+     * argument.  <li>If the argument is NaN or an infinity or
+     * positive zero or negative zero, then the result is the same as
+     * the argument.  <li>If the argument value is less than zero but
+     * greater than -1.0, then the result is negative zero.</ul> Note
+     * that the value of {@code StrictMath.ceil(x)} is exactly the
+     * value of {@code -StrictMath.floor(-x)}.
+     *
+     * @param   a   a value.
+     * @return  the smallest (closest to negative infinity)
+     *          floating-point value that is greater than or equal to
+     *          the argument and is equal to a mathematical integer.
+     */
+    public static double ceil(double a) {
+        return floorOrCeil(a, -0.0, 1.0, 1.0);
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code double} value that is less than or equal to the
+     * argument and is equal to a mathematical integer. Special cases:
+     * <ul><li>If the argument value is already equal to a
+     * mathematical integer, then the result is the same as the
+     * argument.  <li>If the argument is NaN or an infinity or
+     * positive zero or negative zero, then the result is the same as
+     * the argument.</ul>
+     *
+     * @param   a   a value.
+     * @return  the largest (closest to positive infinity)
+     *          floating-point value that less than or equal to the argument
+     *          and is equal to a mathematical integer.
+     */
+    public static double floor(double a) {
+        return floorOrCeil(a, -1.0, 0.0, -1.0);
+    }
+
+    /**
+     * Internal method to share logic between floor and ceil.
+     *
+     * @param a the value to be floored or ceiled
+     * @param negativeBoundary result for values in (-1, 0)
+     * @param positiveBoundary result for values in (0, 1)
+     * @param increment value to add when the argument is non-integral
+     */
+    private static double floorOrCeil(double a,
+                                      double negativeBoundary,
+                                      double positiveBoundary,
+                                      double sign) {
+        int exponent = Math.getExponent(a);
+
+        if (exponent < 0) {
+            /*
+             * Absolute value of argument is less than 1.
+             * floorOrceil(-0.0) => -0.0
+             * floorOrceil(+0.0) => +0.0
+             */
+            return ((a == 0.0) ? a :
+                    ( (a < 0.0) ?  negativeBoundary : positiveBoundary) );
+        } else if (exponent >= 52) {
+            /*
+             * Infinity, NaN, or a value so large it must be integral.
+             */
+            return a;
+        }
+        // Else the argument is either an integral value already XOR it
+        // has to be rounded to one.
+        assert exponent >= 0 && exponent <= 51;
+
+        long doppel = Double.doubleToRawLongBits(a);
+        long mask   = DoubleConsts.SIGNIF_BIT_MASK >> exponent;
+
+        if ( (mask & doppel) == 0L )
+            return a; // integral value
+        else {
+            double result = Double.longBitsToDouble(doppel & (~mask));
+            if (sign*a > 0.0)
+                result = result + sign;
+            return result;
+        }
+    }
+
+    /**
+     * Returns the {@code double} value that is closest in value
+     * to the argument and is equal to a mathematical integer. If two
+     * {@code double} values that are mathematical integers are
+     * equally close to the value of the argument, the result is the
+     * integer value that is even. Special cases:
+     * <ul><li>If the argument value is already equal to a mathematical
+     * integer, then the result is the same as the argument.
+     * <li>If the argument is NaN or an infinity or positive zero or negative
+     * zero, then the result is the same as the argument.</ul>
+     *
+     * @param   a   a value.
+     * @return  the closest floating-point value to {@code a} that is
+     *          equal to a mathematical integer.
+     * @author Joseph D. Darcy
+     */
+    public static double rint(double a) {
+        /*
+         * If the absolute value of a is not less than 2^52, it
+         * is either a finite integer (the double format does not have
+         * enough significand bits for a number that large to have any
+         * fractional portion), an infinity, or a NaN.  In any of
+         * these cases, rint of the argument is the argument.
+         *
+         * Otherwise, the sum (twoToThe52 + a ) will properly round
+         * away any fractional portion of a since ulp(twoToThe52) ==
+         * 1.0; subtracting out twoToThe52 from this sum will then be
+         * exact and leave the rounded integer portion of a.
+         *
+         * This method does *not* need to be declared strictfp to get
+         * fully reproducible results.  Whether or not a method is
+         * declared strictfp can only make a difference in the
+         * returned result if some operation would overflow or
+         * underflow with strictfp semantics.  The operation
+         * (twoToThe52 + a ) cannot overflow since large values of a
+         * are screened out; the add cannot underflow since twoToThe52
+         * is too large.  The subtraction ((twoToThe52 + a ) -
+         * twoToThe52) will be exact as discussed above and thus
+         * cannot overflow or meaningfully underflow.  Finally, the
+         * last multiply in the return statement is by plus or minus
+         * 1.0, which is exact too.
+         */
+        double twoToThe52 = (double)(1L << 52); // 2^52
+        double sign = Math.copySign(1.0, a); // preserve sign info
+        a = Math.abs(a);
+
+        if (a < twoToThe52) { // E_min <= ilogb(a) <= 51
+            a = ((twoToThe52 + a ) - twoToThe52);
+        }
+
+        return sign * a; // restore original sign
+    }
+
+    /**
+     * Returns the angle <i>theta</i> from the conversion of rectangular
+     * coordinates ({@code x},&nbsp;{@code y}) to polar
+     * coordinates (r,&nbsp;<i>theta</i>).
+     * This method computes the phase <i>theta</i> by computing an arc tangent
+     * of {@code y/x} in the range of -<i>pi</i> to <i>pi</i>. Special
+     * cases:
+     * <ul><li>If either argument is NaN, then the result is NaN.
+     * <li>If the first argument is positive zero and the second argument
+     * is positive, or the first argument is positive and finite and the
+     * second argument is positive infinity, then the result is positive
+     * zero.
+     * <li>If the first argument is negative zero and the second argument
+     * is positive, or the first argument is negative and finite and the
+     * second argument is positive infinity, then the result is negative zero.
+     * <li>If the first argument is positive zero and the second argument
+     * is negative, or the first argument is positive and finite and the
+     * second argument is negative infinity, then the result is the
+     * {@code double} value closest to <i>pi</i>.
+     * <li>If the first argument is negative zero and the second argument
+     * is negative, or the first argument is negative and finite and the
+     * second argument is negative infinity, then the result is the
+     * {@code double} value closest to -<i>pi</i>.
+     * <li>If the first argument is positive and the second argument is
+     * positive zero or negative zero, or the first argument is positive
+     * infinity and the second argument is finite, then the result is the
+     * {@code double} value closest to <i>pi</i>/2.
+     * <li>If the first argument is negative and the second argument is
+     * positive zero or negative zero, or the first argument is negative
+     * infinity and the second argument is finite, then the result is the
+     * {@code double} value closest to -<i>pi</i>/2.
+     * <li>If both arguments are positive infinity, then the result is the
+     * {@code double} value closest to <i>pi</i>/4.
+     * <li>If the first argument is positive infinity and the second argument
+     * is negative infinity, then the result is the {@code double}
+     * value closest to 3*<i>pi</i>/4.
+     * <li>If the first argument is negative infinity and the second argument
+     * is positive infinity, then the result is the {@code double} value
+     * closest to -<i>pi</i>/4.
+     * <li>If both arguments are negative infinity, then the result is the
+     * {@code double} value closest to -3*<i>pi</i>/4.</ul>
+     *
+     * @param   y   the ordinate coordinate
+     * @param   x   the abscissa coordinate
+     * @return  the <i>theta</i> component of the point
+     *          (<i>r</i>,&nbsp;<i>theta</i>)
+     *          in polar coordinates that corresponds to the point
+     *          (<i>x</i>,&nbsp;<i>y</i>) in Cartesian coordinates.
+     */
+    public static native double atan2(double y, double x);
+
+
+    /**
+     * Returns the value of the first argument raised to the power of the
+     * second argument. Special cases:
+     *
+     * <ul><li>If the second argument is positive or negative zero, then the
+     * result is 1.0.
+     * <li>If the second argument is 1.0, then the result is the same as the
+     * first argument.
+     * <li>If the second argument is NaN, then the result is NaN.
+     * <li>If the first argument is NaN and the second argument is nonzero,
+     * then the result is NaN.
+     *
+     * <li>If
+     * <ul>
+     * <li>the absolute value of the first argument is greater than 1
+     * and the second argument is positive infinity, or
+     * <li>the absolute value of the first argument is less than 1 and
+     * the second argument is negative infinity,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the absolute value of the first argument is greater than 1 and
+     * the second argument is negative infinity, or
+     * <li>the absolute value of the
+     * first argument is less than 1 and the second argument is positive
+     * infinity,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If the absolute value of the first argument equals 1 and the
+     * second argument is infinite, then the result is NaN.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is positive zero and the second argument
+     * is greater than zero, or
+     * <li>the first argument is positive infinity and the second
+     * argument is less than zero,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is positive zero and the second argument
+     * is less than zero, or
+     * <li>the first argument is positive infinity and the second
+     * argument is greater than zero,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is greater than zero but not a finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is less than zero but not a finite odd integer,
+     * </ul>
+     * then the result is positive zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is a positive finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is a negative finite odd integer,
+     * </ul>
+     * then the result is negative zero.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is less than zero but not a finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is greater than zero but not a finite odd integer,
+     * </ul>
+     * then the result is positive infinity.
+     *
+     * <li>If
+     * <ul>
+     * <li>the first argument is negative zero and the second argument
+     * is a negative finite odd integer, or
+     * <li>the first argument is negative infinity and the second
+     * argument is a positive finite odd integer,
+     * </ul>
+     * then the result is negative infinity.
+     *
+     * <li>If the first argument is finite and less than zero
+     * <ul>
+     * <li> if the second argument is a finite even integer, the
+     * result is equal to the result of raising the absolute value of
+     * the first argument to the power of the second argument
+     *
+     * <li>if the second argument is a finite odd integer, the result
+     * is equal to the negative of the result of raising the absolute
+     * value of the first argument to the power of the second
+     * argument
+     *
+     * <li>if the second argument is finite and not an integer, then
+     * the result is NaN.
+     * </ul>
+     *
+     * <li>If both arguments are integers, then the result is exactly equal
+     * to the mathematical result of raising the first argument to the power
+     * of the second argument if that result can in fact be represented
+     * exactly as a {@code double} value.</ul>
+     *
+     * <p>(In the foregoing descriptions, a floating-point value is
+     * considered to be an integer if and only if it is finite and a
+     * fixed point of the method {@link #ceil ceil} or,
+     * equivalently, a fixed point of the method {@link #floor
+     * floor}. A value is a fixed point of a one-argument
+     * method if and only if the result of applying the method to the
+     * value is equal to the value.)
+     *
+     * @param   a   base.
+     * @param   b   the exponent.
+     * @return  the value {@code a}<sup>{@code b}</sup>.
+     */
+    public static native double pow(double a, double b);
+
+    /**
+     * Returns the closest {@code int} to the argument, with ties
+     * rounding to positive infinity.
+     *
+     * <p>Special cases:
+     * <ul><li>If the argument is NaN, the result is 0.
+     * <li>If the argument is negative infinity or any value less than or
+     * equal to the value of {@code Integer.MIN_VALUE}, the result is
+     * equal to the value of {@code Integer.MIN_VALUE}.
+     * <li>If the argument is positive infinity or any value greater than or
+     * equal to the value of {@code Integer.MAX_VALUE}, the result is
+     * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+     *
+     * @param   a   a floating-point value to be rounded to an integer.
+     * @return  the value of the argument rounded to the nearest
+     *          {@code int} value.
+     * @see     java.lang.Integer#MAX_VALUE
+     * @see     java.lang.Integer#MIN_VALUE
+     */
+    public static int round(float a) {
+        return Math.round(a);
+    }
+
+    /**
+     * Returns the closest {@code long} to the argument, with ties
+     * rounding to positive infinity.
+     *
+     * <p>Special cases:
+     * <ul><li>If the argument is NaN, the result is 0.
+     * <li>If the argument is negative infinity or any value less than or
+     * equal to the value of {@code Long.MIN_VALUE}, the result is
+     * equal to the value of {@code Long.MIN_VALUE}.
+     * <li>If the argument is positive infinity or any value greater than or
+     * equal to the value of {@code Long.MAX_VALUE}, the result is
+     * equal to the value of {@code Long.MAX_VALUE}.</ul>
+     *
+     * @param   a  a floating-point value to be rounded to a
+     *          {@code long}.
+     * @return  the value of the argument rounded to the nearest
+     *          {@code long} value.
+     * @see     java.lang.Long#MAX_VALUE
+     * @see     java.lang.Long#MIN_VALUE
+     */
+    public static long round(double a) {
+        return Math.round(a);
+    }
+
+    private static final class RandomNumberGeneratorHolder {
+        static final Random randomNumberGenerator = new Random();
+    }
+
+    /**
+     * Returns a {@code double} value with a positive sign, greater
+     * than or equal to {@code 0.0} and less than {@code 1.0}.
+     * Returned values are chosen pseudorandomly with (approximately)
+     * uniform distribution from that range.
+     *
+     * <p>When this method is first called, it creates a single new
+     * pseudorandom-number generator, exactly as if by the expression
+     *
+     * <blockquote>{@code new java.util.Random()}</blockquote>
+     *
+     * This new pseudorandom-number generator is used thereafter for
+     * all calls to this method and is used nowhere else.
+     *
+     * <p>This method is properly synchronized to allow correct use by
+     * more than one thread. However, if many threads need to generate
+     * pseudorandom numbers at a great rate, it may reduce contention
+     * for each thread to have its own pseudorandom-number generator.
+     *
+     * @return  a pseudorandom {@code double} greater than or equal
+     * to {@code 0.0} and less than {@code 1.0}.
+     * @see Random#nextDouble()
+     */
+    public static double random() {
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
+    }
+
+    /**
+     * Returns the sum of its arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#addExact(int,int)
+     * @since 1.8
+     */
+    public static int addExact(int x, int y) {
+        return Math.addExact(x, y);
+    }
+
+    /**
+     * Returns the sum of its arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#addExact(long,long)
+     * @since 1.8
+     */
+    public static long addExact(long x, long y) {
+        return Math.addExact(x, y);
+    }
+
+    /**
+     * Returns the difference of the arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#subtractExact(int,int)
+     * @since 1.8
+     */
+    public static int subtractExact(int x, int y) {
+        return Math.subtractExact(x, y);
+    }
+
+    /**
+     * Returns the difference of the arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value to subtract from the first
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#subtractExact(long,long)
+     * @since 1.8
+     */
+    public static long subtractExact(long x, long y) {
+        return Math.subtractExact(x, y);
+    }
+
+    /**
+     * Returns the product of the arguments,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#multiplyExact(int,int)
+     * @since 1.8
+     */
+    public static int multiplyExact(int x, int y) {
+        return Math.multiplyExact(x, y);
+    }
+
+    /**
+     * Returns the product of the arguments,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#multiplyExact(long,long)
+     * @since 1.8
+     */
+    public static long multiplyExact(long x, long y) {
+        return Math.multiplyExact(x, y);
+    }
+
+    /**
+     * Returns the value of the {@code long} argument;
+     * throwing an exception if the value overflows an {@code int}.
+     *
+     * @param value the long value
+     * @return the argument as an int
+     * @throws ArithmeticException if the {@code argument} overflows an int
+     * @see Math#toIntExact(long)
+     * @since 1.8
+     */
+    public static int toIntExact(long value) {
+        return Math.toIntExact(value);
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
+     * the result is equal to the {@code Integer.MIN_VALUE}.
+     * <p>
+     * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
+     * a comparison to the integer division {@code /} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorDiv(int, int)
+     * @see Math#floor(double)
+     * @since 1.8
+     */
+    public static int floorDiv(int x, int y) {
+        return Math.floorDiv(x, y);
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
+     * the result is equal to the {@code Long.MIN_VALUE}.
+     * <p>
+     * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
+     * a comparison to the integer division {@code /} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorDiv(long, long)
+     * @see Math#floor(double)
+     * @since 1.8
+     */
+    public static long floorDiv(long x, long y) {
+        return Math.floorDiv(x, y);
+    }
+
+    /**
+     * Returns the floor modulus of the {@code int} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
+     * a comparison to the {@code %} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorMod(int, int)
+     * @see StrictMath#floorDiv(int, int)
+     * @since 1.8
+     */
+    public static int floorMod(int x, int y) {
+        return Math.floorMod(x , y);
+    }
+    /**
+     * Returns the floor modulus of the {@code long} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
+     * a comparison to the {@code %} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorMod(long, long)
+     * @see StrictMath#floorDiv(long, long)
+     * @since 1.8
+     */
+    public static long floorMod(long x, long y) {
+        return Math.floorMod(x, y);
+    }
+
+    /**
+     * Returns the absolute value of an {@code int} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     *
+     * <p>Note that if the argument is equal to the value of
+     * {@link Integer#MIN_VALUE}, the most negative representable
+     * {@code int} value, the result is that same value, which is
+     * negative.
+     *
+     * @param   a   the  argument whose absolute value is to be determined.
+     * @return  the absolute value of the argument.
+     */
+    public static int abs(int a) {
+        return Math.abs(a);
+    }
+
+    /**
+     * Returns the absolute value of a {@code long} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     *
+     * <p>Note that if the argument is equal to the value of
+     * {@link Long#MIN_VALUE}, the most negative representable
+     * {@code long} value, the result is that same value, which
+     * is negative.
+     *
+     * @param   a   the  argument whose absolute value is to be determined.
+     * @return  the absolute value of the argument.
+     */
+    public static long abs(long a) {
+        return Math.abs(a);
+    }
+
+    /**
+     * Returns the absolute value of a {@code float} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     * Special cases:
+     * <ul><li>If the argument is positive zero or negative zero, the
+     * result is positive zero.
+     * <li>If the argument is infinite, the result is positive infinity.
+     * <li>If the argument is NaN, the result is NaN.</ul>
+     * In other words, the result is the same as the value of the expression:
+     * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static float abs(float a) {
+        return Math.abs(a);
+    }
+
+    /**
+     * Returns the absolute value of a {@code double} value.
+     * If the argument is not negative, the argument is returned.
+     * If the argument is negative, the negation of the argument is returned.
+     * Special cases:
+     * <ul><li>If the argument is positive zero or negative zero, the result
+     * is positive zero.
+     * <li>If the argument is infinite, the result is positive infinity.
+     * <li>If the argument is NaN, the result is NaN.</ul>
+     * In other words, the result is the same as the value of the expression:
+     * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+     *
+     * @param   a   the argument whose absolute value is to be determined
+     * @return  the absolute value of the argument.
+     */
+    public static double abs(double a) {
+        return Math.abs(a);
+    }
+
+    /**
+     * Returns the greater of two {@code int} values. That is, the
+     * result is the argument closer to the value of
+     * {@link Integer#MAX_VALUE}. If the arguments have the same value,
+     * the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static int max(int a, int b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the greater of two {@code long} values. That is, the
+     * result is the argument closer to the value of
+     * {@link Long#MAX_VALUE}. If the arguments have the same value,
+     * the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+        */
+    public static long max(long a, long b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the greater of two {@code float} values.  That is,
+     * the result is the argument closer to positive infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other negative zero, the
+     * result is positive zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static float max(float a, float b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the greater of two {@code double} values.  That
+     * is, the result is the argument closer to positive infinity. If
+     * the arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other negative zero, the
+     * result is positive zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the larger of {@code a} and {@code b}.
+     */
+    public static double max(double a, double b) {
+        return Math.max(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code int} values. That is,
+     * the result the argument closer to the value of
+     * {@link Integer#MIN_VALUE}.  If the arguments have the same
+     * value, the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static int min(int a, int b) {
+        return Math.min(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code long} values. That is,
+     * the result is the argument closer to the value of
+     * {@link Long#MIN_VALUE}. If the arguments have the same
+     * value, the result is that same value.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static long min(long a, long b) {
+        return Math.min(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code float} values.  That is,
+     * the result is the value closer to negative infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero.  If
+     * one argument is positive zero and the other is negative zero,
+     * the result is negative zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b.}
+     */
+    public static float min(float a, float b) {
+        return Math.min(a, b);
+    }
+
+    /**
+     * Returns the smaller of two {@code double} values.  That
+     * is, the result is the value closer to negative infinity. If the
+     * arguments have the same value, the result is that same
+     * value. If either value is NaN, then the result is NaN.  Unlike
+     * the numerical comparison operators, this method considers
+     * negative zero to be strictly smaller than positive zero. If one
+     * argument is positive zero and the other is negative zero, the
+     * result is negative zero.
+     *
+     * @param   a   an argument.
+     * @param   b   another argument.
+     * @return  the smaller of {@code a} and {@code b}.
+     */
+    public static double min(double a, double b) {
+        return Math.min(a, b);
+    }
+
+    /**
+     * Returns the size of an ulp of the argument.  An ulp, unit in
+     * the last place, of a {@code double} value is the positive
+     * distance between this floating-point value and the {@code
+     * double} value next larger in magnitude.  Note that for non-NaN
+     * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive or negative infinity, then the
+     * result is positive infinity.
+     * <li> If the argument is positive or negative zero, then the result is
+     * {@code Double.MIN_VALUE}.
+     * <li> If the argument is &plusmn;{@code Double.MAX_VALUE}, then
+     * the result is equal to 2<sup>971</sup>.
+     * </ul>
+     *
+     * @param d the floating-point value whose ulp is to be returned
+     * @return the size of an ulp of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static double ulp(double d) {
+        return Math.ulp(d);
+    }
+
+    /**
+     * Returns the size of an ulp of the argument.  An ulp, unit in
+     * the last place, of a {@code float} value is the positive
+     * distance between this floating-point value and the {@code
+     * float} value next larger in magnitude.  Note that for non-NaN
+     * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive or negative infinity, then the
+     * result is positive infinity.
+     * <li> If the argument is positive or negative zero, then the result is
+     * {@code Float.MIN_VALUE}.
+     * <li> If the argument is &plusmn;{@code Float.MAX_VALUE}, then
+     * the result is equal to 2<sup>104</sup>.
+     * </ul>
+     *
+     * @param f the floating-point value whose ulp is to be returned
+     * @return the size of an ulp of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static float ulp(float f) {
+        return Math.ulp(f);
+    }
+
+    /**
+     * Returns the signum function of the argument; zero if the argument
+     * is zero, 1.0 if the argument is greater than zero, -1.0 if the
+     * argument is less than zero.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive zero or negative zero, then the
+     *      result is the same as the argument.
+     * </ul>
+     *
+     * @param d the floating-point value whose signum is to be returned
+     * @return the signum function of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static double signum(double d) {
+        return Math.signum(d);
+    }
+
+    /**
+     * Returns the signum function of the argument; zero if the argument
+     * is zero, 1.0f if the argument is greater than zero, -1.0f if the
+     * argument is less than zero.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, then the result is NaN.
+     * <li> If the argument is positive zero or negative zero, then the
+     *      result is the same as the argument.
+     * </ul>
+     *
+     * @param f the floating-point value whose signum is to be returned
+     * @return the signum function of the argument
+     * @author Joseph D. Darcy
+     * @since 1.5
+     */
+    public static float signum(float f) {
+        return Math.signum(f);
+    }
+
+    /**
+     * Returns the hyperbolic sine of a {@code double} value.
+     * The hyperbolic sine of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/2
+     * where <i>e</i> is {@linkplain Math#E Euler's number}.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is an infinity
+     * with the same sign as the argument.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * @param   x The number whose hyperbolic sine is to be returned.
+     * @return  The hyperbolic sine of {@code x}.
+     * @since 1.5
+     */
+    public static native double sinh(double x);
+
+    /**
+     * Returns the hyperbolic cosine of a {@code double} value.
+     * The hyperbolic cosine of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>)/2
+     * where <i>e</i> is {@linkplain Math#E Euler's number}.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is infinite, then the result is positive
+     * infinity.
+     *
+     * <li>If the argument is zero, then the result is {@code 1.0}.
+     *
+     * </ul>
+     *
+     * @param   x The number whose hyperbolic cosine is to be returned.
+     * @return  The hyperbolic cosine of {@code x}.
+     * @since 1.5
+     */
+    public static native double cosh(double x);
+
+    /**
+     * Returns the hyperbolic tangent of a {@code double} value.
+     * The hyperbolic tangent of <i>x</i> is defined to be
+     * (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/(<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>),
+     * in other words, {@linkplain Math#sinh
+     * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}.  Note
+     * that the absolute value of the exact tanh is always less than
+     * 1.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN, then the result is NaN.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * {@code +1.0}.
+     *
+     * <li>If the argument is negative infinity, then the result is
+     * {@code -1.0}.
+     *
+     * </ul>
+     *
+     * @param   x The number whose hyperbolic tangent is to be returned.
+     * @return  The hyperbolic tangent of {@code x}.
+     * @since 1.5
+     */
+    public static native double tanh(double x);
+
+    /**
+     * Returns sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * without intermediate overflow or underflow.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li> If either argument is infinite, then the result
+     * is positive infinity.
+     *
+     * <li> If either argument is NaN and neither argument is infinite,
+     * then the result is NaN.
+     *
+     * </ul>
+     *
+     * @param x a value
+     * @param y a value
+     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     * without intermediate overflow or underflow
+     * @since 1.5
+     */
+    public static native double hypot(double x, double y);
+
+    /**
+     * Returns <i>e</i><sup>x</sup>&nbsp;-1.  Note that for values of
+     * <i>x</i> near 0, the exact sum of
+     * {@code expm1(x)}&nbsp;+&nbsp;1 is much closer to the true
+     * result of <i>e</i><sup>x</sup> than {@code exp(x)}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li>If the argument is NaN, the result is NaN.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     *
+     * <li>If the argument is negative infinity, then the result is
+     * -1.0.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * @param   x   the exponent to raise <i>e</i> to in the computation of
+     *              <i>e</i><sup>{@code x}</sup>&nbsp;-1.
+     * @return  the value <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1.
+     * @since 1.5
+     */
+    public static native double expm1(double x);
+
+    /**
+     * Returns the natural logarithm of the sum of the argument and 1.
+     * Note that for small values {@code x}, the result of
+     * {@code log1p(x)} is much closer to the true result of ln(1
+     * + {@code x}) than the floating-point evaluation of
+     * {@code log(1.0+x)}.
+     *
+     * <p>Special cases:
+     * <ul>
+     *
+     * <li>If the argument is NaN or less than -1, then the result is
+     * NaN.
+     *
+     * <li>If the argument is positive infinity, then the result is
+     * positive infinity.
+     *
+     * <li>If the argument is negative one, then the result is
+     * negative infinity.
+     *
+     * <li>If the argument is zero, then the result is a zero with the
+     * same sign as the argument.
+     *
+     * </ul>
+     *
+     * @param   x   a value
+     * @return the value ln({@code x}&nbsp;+&nbsp;1), the natural
+     * log of {@code x}&nbsp;+&nbsp;1
+     * @since 1.5
+     */
+    public static native double log1p(double x);
+
+    /**
+     * Returns the first floating-point argument with the sign of the
+     * second floating-point argument.  For this method, a NaN
+     * {@code sign} argument is always treated as if it were
+     * positive.
+     *
+     * @param magnitude  the parameter providing the magnitude of the result
+     * @param sign   the parameter providing the sign of the result
+     * @return a value with the magnitude of {@code magnitude}
+     * and the sign of {@code sign}.
+     * @since 1.6
+     */
+    public static double copySign(double magnitude, double sign) {
+        return Math.copySign(magnitude, (Double.isNaN(sign)?1.0d:sign));
+    }
+
+    /**
+     * Returns the first floating-point argument with the sign of the
+     * second floating-point argument.  For this method, a NaN
+     * {@code sign} argument is always treated as if it were
+     * positive.
+     *
+     * @param magnitude  the parameter providing the magnitude of the result
+     * @param sign   the parameter providing the sign of the result
+     * @return a value with the magnitude of {@code magnitude}
+     * and the sign of {@code sign}.
+     * @since 1.6
+     */
+    public static float copySign(float magnitude, float sign) {
+        return Math.copySign(magnitude, (Float.isNaN(sign)?1.0f:sign));
+    }
+    /**
+     * Returns the unbiased exponent used in the representation of a
+     * {@code float}.  Special cases:
+     *
+     * <ul>
+     * <li>If the argument is NaN or infinite, then the result is
+     * {@link Float#MAX_EXPONENT} + 1.
+     * <li>If the argument is zero or subnormal, then the result is
+     * {@link Float#MIN_EXPONENT} -1.
+     * </ul>
+     * @param f a {@code float} value
+     * @return the unbiased exponent of the argument
+     * @since 1.6
+     */
+    public static int getExponent(float f) {
+        return Math.getExponent(f);
+    }
+
+    /**
+     * Returns the unbiased exponent used in the representation of a
+     * {@code double}.  Special cases:
+     *
+     * <ul>
+     * <li>If the argument is NaN or infinite, then the result is
+     * {@link Double#MAX_EXPONENT} + 1.
+     * <li>If the argument is zero or subnormal, then the result is
+     * {@link Double#MIN_EXPONENT} -1.
+     * </ul>
+     * @param d a {@code double} value
+     * @return the unbiased exponent of the argument
+     * @since 1.6
+     */
+    public static int getExponent(double d) {
+        return Math.getExponent(d);
+    }
+
+    /**
+     * Returns the floating-point number adjacent to the first
+     * argument in the direction of the second argument.  If both
+     * arguments compare as equal the second argument is returned.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If either argument is a NaN, then NaN is returned.
+     *
+     * <li> If both arguments are signed zeros, {@code direction}
+     * is returned unchanged (as implied by the requirement of
+     * returning the second argument if the arguments compare as
+     * equal).
+     *
+     * <li> If {@code start} is
+     * &plusmn;{@link Double#MIN_VALUE} and {@code direction}
+     * has a value such that the result should have a smaller
+     * magnitude, then a zero with the same sign as {@code start}
+     * is returned.
+     *
+     * <li> If {@code start} is infinite and
+     * {@code direction} has a value such that the result should
+     * have a smaller magnitude, {@link Double#MAX_VALUE} with the
+     * same sign as {@code start} is returned.
+     *
+     * <li> If {@code start} is equal to &plusmn;
+     * {@link Double#MAX_VALUE} and {@code direction} has a
+     * value such that the result should have a larger magnitude, an
+     * infinity with same sign as {@code start} is returned.
+     * </ul>
+     *
+     * @param start  starting floating-point value
+     * @param direction value indicating which of
+     * {@code start}'s neighbors or {@code start} should
+     * be returned
+     * @return The floating-point number adjacent to {@code start} in the
+     * direction of {@code direction}.
+     * @since 1.6
+     */
+    public static double nextAfter(double start, double direction) {
+        return Math.nextAfter(start, direction);
+    }
+
+    /**
+     * Returns the floating-point number adjacent to the first
+     * argument in the direction of the second argument.  If both
+     * arguments compare as equal a value equivalent to the second argument
+     * is returned.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If either argument is a NaN, then NaN is returned.
+     *
+     * <li> If both arguments are signed zeros, a value equivalent
+     * to {@code direction} is returned.
+     *
+     * <li> If {@code start} is
+     * &plusmn;{@link Float#MIN_VALUE} and {@code direction}
+     * has a value such that the result should have a smaller
+     * magnitude, then a zero with the same sign as {@code start}
+     * is returned.
+     *
+     * <li> If {@code start} is infinite and
+     * {@code direction} has a value such that the result should
+     * have a smaller magnitude, {@link Float#MAX_VALUE} with the
+     * same sign as {@code start} is returned.
+     *
+     * <li> If {@code start} is equal to &plusmn;
+     * {@link Float#MAX_VALUE} and {@code direction} has a
+     * value such that the result should have a larger magnitude, an
+     * infinity with same sign as {@code start} is returned.
+     * </ul>
+     *
+     * @param start  starting floating-point value
+     * @param direction value indicating which of
+     * {@code start}'s neighbors or {@code start} should
+     * be returned
+     * @return The floating-point number adjacent to {@code start} in the
+     * direction of {@code direction}.
+     * @since 1.6
+     */
+    public static float nextAfter(float start, double direction) {
+        return Math.nextAfter(start, direction);
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code d} in
+     * the direction of positive infinity.  This method is
+     * semantically equivalent to {@code nextAfter(d,
+     * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
+     * implementation may run faster than its equivalent
+     * {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is positive infinity, the result is
+     * positive infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@link Double#MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param d starting floating-point value
+     * @return The adjacent floating-point value closer to positive
+     * infinity.
+     * @since 1.6
+     */
+    public static double nextUp(double d) {
+        return Math.nextUp(d);
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code f} in
+     * the direction of positive infinity.  This method is
+     * semantically equivalent to {@code nextAfter(f,
+     * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
+     * implementation may run faster than its equivalent
+     * {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is positive infinity, the result is
+     * positive infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@link Float#MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param f starting floating-point value
+     * @return The adjacent floating-point value closer to positive
+     * infinity.
+     * @since 1.6
+     */
+    public static float nextUp(float f) {
+        return Math.nextUp(f);
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code d} in
+     * the direction of negative infinity.  This method is
+     * semantically equivalent to {@code nextAfter(d,
+     * Double.NEGATIVE_INFINITY)}; however, a
+     * {@code nextDown} implementation may run faster than its
+     * equivalent {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is negative infinity, the result is
+     * negative infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@code -Double.MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param d  starting floating-point value
+     * @return The adjacent floating-point value closer to negative
+     * infinity.
+     * @since 1.8
+     */
+    public static double nextDown(double d) {
+        return Math.nextDown(d);
+    }
+
+    /**
+     * Returns the floating-point value adjacent to {@code f} in
+     * the direction of negative infinity.  This method is
+     * semantically equivalent to {@code nextAfter(f,
+     * Float.NEGATIVE_INFINITY)}; however, a
+     * {@code nextDown} implementation may run faster than its
+     * equivalent {@code nextAfter} call.
+     *
+     * <p>Special Cases:
+     * <ul>
+     * <li> If the argument is NaN, the result is NaN.
+     *
+     * <li> If the argument is negative infinity, the result is
+     * negative infinity.
+     *
+     * <li> If the argument is zero, the result is
+     * {@code -Float.MIN_VALUE}
+     *
+     * </ul>
+     *
+     * @param f  starting floating-point value
+     * @return The adjacent floating-point value closer to negative
+     * infinity.
+     * @since 1.8
+     */
+    public static float nextDown(float f) {
+        return Math.nextDown(f);
+    }
+
+    /**
+     * Returns {@code d} &times;
+     * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+     * by a single correctly rounded floating-point multiply to a
+     * member of the double value set.  See the Java
+     * Language Specification for a discussion of floating-point
+     * value sets.  If the exponent of the result is between {@link
+     * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
+     * answer is calculated exactly.  If the exponent of the result
+     * would be larger than {@code Double.MAX_EXPONENT}, an
+     * infinity is returned.  Note that if the result is subnormal,
+     * precision may be lost; that is, when {@code scalb(x, n)}
+     * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+     * <i>x</i>.  When the result is non-NaN, the result has the same
+     * sign as {@code d}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If the first argument is NaN, NaN is returned.
+     * <li> If the first argument is infinite, then an infinity of the
+     * same sign is returned.
+     * <li> If the first argument is zero, then a zero of the same
+     * sign is returned.
+     * </ul>
+     *
+     * @param d number to be scaled by a power of two.
+     * @param scaleFactor power of 2 used to scale {@code d}
+     * @return {@code d} &times; 2<sup>{@code scaleFactor}</sup>
+     * @since 1.6
+     */
+    public static double scalb(double d, int scaleFactor) {
+        return Math.scalb(d, scaleFactor);
+    }
+
+    /**
+     * Returns {@code f} &times;
+     * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+     * by a single correctly rounded floating-point multiply to a
+     * member of the float value set.  See the Java
+     * Language Specification for a discussion of floating-point
+     * value sets.  If the exponent of the result is between {@link
+     * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
+     * answer is calculated exactly.  If the exponent of the result
+     * would be larger than {@code Float.MAX_EXPONENT}, an
+     * infinity is returned.  Note that if the result is subnormal,
+     * precision may be lost; that is, when {@code scalb(x, n)}
+     * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+     * <i>x</i>.  When the result is non-NaN, the result has the same
+     * sign as {@code f}.
+     *
+     * <p>Special cases:
+     * <ul>
+     * <li> If the first argument is NaN, NaN is returned.
+     * <li> If the first argument is infinite, then an infinity of the
+     * same sign is returned.
+     * <li> If the first argument is zero, then a zero of the same
+     * sign is returned.
+     * </ul>
+     *
+     * @param f number to be scaled by a power of two.
+     * @param scaleFactor power of 2 used to scale {@code f}
+     * @return {@code f} &times; 2<sup>{@code scaleFactor}</sup>
+     * @since 1.6
+     */
+    public static float scalb(float f, int scaleFactor) {
+        return Math.scalb(f, scaleFactor);
+    }
+}
diff --git a/java/lang/String.annotated.java b/java/lang/String.annotated.java
new file mode 100644
index 0000000..a8cf1de
--- /dev/null
+++ b/java/lang/String.annotated.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.StringJoiner;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Comparator;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
+
+public String() { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.String original) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public String(int[] codePoints, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuffer buffer) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuilder builder) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public native char charAt(int index);
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object anObject) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+
+public boolean equalsIgnoreCase(@libcore.util.Nullable java.lang.String anotherString) { throw new RuntimeException("Stub!"); }
+
+public native int compareTo(@libcore.util.NonNull java.lang.String anotherString);
+
+public int compareToIgnoreCase(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(boolean ignoreCase, int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix, int toffset) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix) { throw new RuntimeException("Stub!"); }
+
+public boolean endsWith(@libcore.util.NonNull java.lang.String suffix) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int beginIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.CharSequence subSequence(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.String concat(@libcore.util.NonNull java.lang.String str);
+
[email protected] public java.lang.String replace(char oldChar, char newChar) { throw new RuntimeException("Stub!"); }
+
+public boolean matches(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.NonNull java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replaceFirst(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replaceAll(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replace(@libcore.util.NonNull java.lang.CharSequence target, @libcore.util.NonNull java.lang.CharSequence replacement) { throw new RuntimeException("Stub!"); }
+
+public [email protected] String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex, int limit) { throw new RuntimeException("Stub!"); }
+
+public [email protected] String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, [email protected] CharSequence @libcore.util.Nullable ... elements) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, @libcore.util.NonNull java.lang.Iterable<? extends @libcore.util.Nullable java.lang.CharSequence> elements) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toLowerCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toLowerCase() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toUpperCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toUpperCase() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String trim() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public native char[] toCharArray();
+
[email protected] public static java.lang.String format(@libcore.util.NonNull java.lang.String format, [email protected] Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String format(@libcore.util.NonNull java.util.Locale l, @libcore.util.NonNull java.lang.String format, [email protected] Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String copyValueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String copyValueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.String intern();
+
+public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+static { CASE_INSENSITIVE_ORDER = null; }
+}
diff --git a/java/lang/String.java b/java/lang/String.java
new file mode 100644
index 0000000..2ba7b1f
--- /dev/null
+++ b/java/lang/String.java
@@ -0,0 +1,3104 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.ObjectStreamField;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.ByteBuffer;
+import java.util.Comparator;
+import java.util.Formatter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import libcore.util.CharsetUtils;
+
+/**
+ * The {@code String} class represents character strings. All
+ * string literals in Java programs, such as {@code "abc"}, are
+ * implemented as instances of this class.
+ * <p>
+ * Strings are constant; their values cannot be changed after they
+ * are created. String buffers support mutable strings.
+ * Because String objects are immutable they can be shared. For example:
+ * <blockquote><pre>
+ *     String str = "abc";
+ * </pre></blockquote><p>
+ * is equivalent to:
+ * <blockquote><pre>
+ *     char data[] = {'a', 'b', 'c'};
+ *     String str = new String(data);
+ * </pre></blockquote><p>
+ * Here are some more examples of how strings can be used:
+ * <blockquote><pre>
+ *     System.out.println("abc");
+ *     String cde = "cde";
+ *     System.out.println("abc" + cde);
+ *     String c = "abc".substring(2,3);
+ *     String d = cde.substring(1, 2);
+ * </pre></blockquote>
+ * <p>
+ * The class {@code String} includes methods for examining
+ * individual characters of the sequence, for comparing strings, for
+ * searching strings, for extracting substrings, and for creating a
+ * copy of a string with all characters translated to uppercase or to
+ * lowercase. Case mapping is based on the Unicode Standard version
+ * specified by the {@link java.lang.Character Character} class.
+ * <p>
+ * The Java language provides special support for the string
+ * concatenation operator (&nbsp;+&nbsp;), and for conversion of
+ * other objects to strings. String concatenation is implemented
+ * through the {@code StringBuilder}(or {@code StringBuffer})
+ * class and its {@code append} method.
+ * String conversions are implemented through the method
+ * {@code toString}, defined by {@code Object} and
+ * inherited by all classes in Java. For additional information on
+ * string concatenation and conversion, see Gosling, Joy, and Steele,
+ * <i>The Java Language Specification</i>.
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * <p>A {@code String} represents a string in the UTF-16 format
+ * in which <em>supplementary characters</em> are represented by <em>surrogate
+ * pairs</em> (see the section <a href="Character.html#unicode">Unicode
+ * Character Representations</a> in the {@code Character} class for
+ * more information).
+ * Index values refer to {@code char} code units, so a supplementary
+ * character uses two positions in a {@code String}.
+ * <p>The {@code String} class provides methods for dealing with
+ * Unicode code points (i.e., characters), in addition to those for
+ * dealing with Unicode code units (i.e., {@code char} values).
+ *
+ * @author  Lee Boynton
+ * @author  Arthur van Hoff
+ * @author  Martin Buchholz
+ * @author  Ulf Zibis
+ * @see     java.lang.Object#toString()
+ * @see     java.lang.StringBuffer
+ * @see     java.lang.StringBuilder
+ * @see     java.nio.charset.Charset
+ * @since   JDK1.0
+ */
+
+public final class String
+    implements java.io.Serializable, Comparable<String>, CharSequence {
+
+    // BEGIN Android-changed: The character data is managed by the runtime.
+    // We only keep track of the length here and compression here. This has several consequences
+    // throughout this class:
+    //  - References to value[i] are replaced by charAt(i).
+    //  - References to value.length are replaced by calls to length().
+    //  - Sometimes the result of length() is assigned to a local variable to avoid repeated calls.
+    //  - We skip several attempts at optimization where the values field was assigned to a local
+    //    variable to avoid the getfield opcode.
+    // These changes are not all marked individually.
+    //
+    // private final char value[];
+    //
+    // If STRING_COMPRESSION_ENABLED, count stores the length shifted one bit to the left with the
+    // lowest bit used to indicate whether or not the bytes are compressed (see GetFlaggedCount in
+    // the native code).
+    private final int count;
+    // END Android-changed: The character data is managed by the runtime.
+
+    // Android-changed: We make use of new StringIndexOutOfBoundsException constructor signatures.
+    // These improve some error messages. These changes are not all marked individually.
+
+    /** Cache the hash code for the string */
+    private int hash; // Default to 0
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -6849794470754667710L;
+
+    /**
+     * Class String is special cased within the Serialization Stream Protocol.
+     *
+     * A String instance is written into an ObjectOutputStream according to
+     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
+     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
+     */
+    private static final ObjectStreamField[] serialPersistentFields =
+        new ObjectStreamField[0];
+
+    /**
+     * Initializes a newly created {@code String} object so that it represents
+     * an empty character sequence.  Note that use of this constructor is
+     * unnecessary since Strings are immutable.
+     */
+    public String() {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Initializes a newly created {@code String} object so that it represents
+     * the same sequence of characters as the argument; in other words, the
+     * newly created string is a copy of the argument string. Unless an
+     * explicit copy of {@code original} is needed, use of this constructor is
+     * unnecessary since Strings are immutable.
+     *
+     * @param  original
+     *         A {@code String}
+     */
+    public String(String original) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new {@code String} so that it represents the sequence of
+     * characters currently contained in the character array argument. The
+     * contents of the character array are copied; subsequent modification of
+     * the character array does not affect the newly created string.
+     *
+     * @param  value
+     *         The initial value of the string
+     */
+    public String(char value[]) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new {@code String} that contains characters from a subarray
+     * of the character array argument. The {@code offset} argument is the
+     * index of the first character of the subarray and the {@code count}
+     * argument specifies the length of the subarray. The contents of the
+     * subarray are copied; subsequent modification of the character array does
+     * not affect the newly created string.
+     *
+     * @param  value
+     *         Array that is the source of characters
+     *
+     * @param  offset
+     *         The initial offset
+     *
+     * @param  count
+     *         The length
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} and {@code count} arguments index
+     *          characters outside the bounds of the {@code value} array
+     */
+    public String(char value[], int offset, int count) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new {@code String} that contains characters from a subarray
+     * of the <a href="Character.html#unicode">Unicode code point</a> array
+     * argument.  The {@code offset} argument is the index of the first code
+     * point of the subarray and the {@code count} argument specifies the
+     * length of the subarray.  The contents of the subarray are converted to
+     * {@code char}s; subsequent modification of the {@code int} array does not
+     * affect the newly created string.
+     *
+     * @param  codePoints
+     *         Array that is the source of Unicode code points
+     *
+     * @param  offset
+     *         The initial offset
+     *
+     * @param  count
+     *         The length
+     *
+     * @throws  IllegalArgumentException
+     *          If any invalid Unicode code point is found in {@code
+     *          codePoints}
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} and {@code count} arguments index
+     *          characters outside the bounds of the {@code codePoints} array
+     *
+     * @since  1.5
+     */
+    public String(int[] codePoints, int offset, int count) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new {@code String} constructed from a subarray of an array
+     * of 8-bit integer values.
+     *
+     * <p> The {@code offset} argument is the index of the first byte of the
+     * subarray, and the {@code count} argument specifies the length of the
+     * subarray.
+     *
+     * <p> Each {@code byte} in the subarray is converted to a {@code char} as
+     * specified in the method above.
+     *
+     * @deprecated This method does not properly convert bytes into characters.
+     * As of JDK&nbsp;1.1, the preferred way to do this is via the
+     * {@code String} constructors that take a {@link
+     * java.nio.charset.Charset}, charset name, or that use the platform's
+     * default charset.
+     *
+     * @param  ascii
+     *         The bytes to be converted to characters
+     *
+     * @param  hibyte
+     *         The top 8 bits of each 16-bit Unicode code unit
+     *
+     * @param  offset
+     *         The initial offset
+     * @param  count
+     *         The length
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} or {@code count} argument is invalid
+     *
+     * @see  #String(byte[], int)
+     * @see  #String(byte[], int, int, java.lang.String)
+     * @see  #String(byte[], int, int, java.nio.charset.Charset)
+     * @see  #String(byte[], int, int)
+     * @see  #String(byte[], java.lang.String)
+     * @see  #String(byte[], java.nio.charset.Charset)
+     * @see  #String(byte[])
+     */
+    @Deprecated
+    public String(byte ascii[], int hibyte, int offset, int count) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new {@code String} containing characters constructed from
+     * an array of 8-bit integer values. Each character <i>c</i>in the
+     * resulting string is constructed from the corresponding component
+     * <i>b</i> in the byte array such that:
+     *
+     * <blockquote><pre>
+     *     <b><i>c</i></b> == (char)(((hibyte &amp; 0xff) &lt;&lt; 8)
+     *                         | (<b><i>b</i></b> &amp; 0xff))
+     * </pre></blockquote>
+     *
+     * @deprecated  This method does not properly convert bytes into
+     * characters.  As of JDK&nbsp;1.1, the preferred way to do this is via the
+     * {@code String} constructors that take a {@link
+     * java.nio.charset.Charset}, charset name, or that use the platform's
+     * default charset.
+     *
+     * @param  ascii
+     *         The bytes to be converted to characters
+     *
+     * @param  hibyte
+     *         The top 8 bits of each 16-bit Unicode code unit
+     *
+     * @see  #String(byte[], int, int, java.lang.String)
+     * @see  #String(byte[], int, int, java.nio.charset.Charset)
+     * @see  #String(byte[], int, int)
+     * @see  #String(byte[], java.lang.String)
+     * @see  #String(byte[], java.nio.charset.Charset)
+     * @see  #String(byte[])
+     */
+    @Deprecated
+    public String(byte ascii[], int hibyte) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified subarray of
+     * bytes using the specified charset.  The length of the new {@code String}
+     * is a function of the charset, and hence may not be equal to the length
+     * of the subarray.
+     *
+     * <p> The behavior of this constructor when the given bytes are not valid
+     * in the given charset is unspecified.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @param  offset
+     *         The index of the first byte to decode
+     *
+     * @param  length
+     *         The number of bytes to decode
+
+     * @param  charsetName
+     *         The name of a supported {@linkplain java.nio.charset.Charset
+     *         charset}
+     *
+     * @throws  UnsupportedEncodingException
+     *          If the named charset is not supported
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} and {@code length} arguments index
+     *          characters outside the bounds of the {@code bytes} array
+     *
+     * @since  JDK1.1
+     */
+    public String(byte bytes[], int offset, int length, String charsetName)
+            throws UnsupportedEncodingException {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified subarray of
+     * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
+     * The length of the new {@code String} is a function of the charset, and
+     * hence may not be equal to the length of the subarray.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with this charset's default replacement string.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @param  offset
+     *         The index of the first byte to decode
+     *
+     * @param  length
+     *         The number of bytes to decode
+     *
+     * @param  charset
+     *         The {@linkplain java.nio.charset.Charset charset} to be used to
+     *         decode the {@code bytes}
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} and {@code length} arguments index
+     *          characters outside the bounds of the {@code bytes} array
+     *
+     * @since  1.6
+     */
+    public String(byte bytes[], int offset, int length, Charset charset) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified array of bytes
+     * using the specified {@linkplain java.nio.charset.Charset charset}.  The
+     * length of the new {@code String} is a function of the charset, and hence
+     * may not be equal to the length of the byte array.
+     *
+     * <p> The behavior of this constructor when the given bytes are not valid
+     * in the given charset is unspecified.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @param  charsetName
+     *         The name of a supported {@linkplain java.nio.charset.Charset
+     *         charset}
+     *
+     * @throws  UnsupportedEncodingException
+     *          If the named charset is not supported
+     *
+     * @since  JDK1.1
+     */
+    public String(byte bytes[], String charsetName)
+            throws UnsupportedEncodingException {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified array of
+     * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
+     * The length of the new {@code String} is a function of the charset, and
+     * hence may not be equal to the length of the byte array.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with this charset's default replacement string.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @param  charset
+     *         The {@linkplain java.nio.charset.Charset charset} to be used to
+     *         decode the {@code bytes}
+     *
+     * @since  1.6
+     */
+    public String(byte bytes[], Charset charset) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified subarray of
+     * bytes using the platform's default charset.  The length of the new
+     * {@code String} is a function of the charset, and hence may not be equal
+     * to the length of the subarray.
+     *
+     * <p> The behavior of this constructor when the given bytes are not valid
+     * in the default charset is unspecified.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @param  offset
+     *         The index of the first byte to decode
+     *
+     * @param  length
+     *         The number of bytes to decode
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the {@code offset} and the {@code length} arguments index
+     *          characters outside the bounds of the {@code bytes} array
+     *
+     * @since  JDK1.1
+     */
+    public String(byte bytes[], int offset, int length) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Constructs a new {@code String} by decoding the specified array of bytes
+     * using the platform's default charset.  The length of the new {@code
+     * String} is a function of the charset, and hence may not be equal to the
+     * length of the byte array.
+     *
+     * <p> The behavior of this constructor when the given bytes are not valid
+     * in the default charset is unspecified.  The {@link
+     * java.nio.charset.CharsetDecoder} class should be used when more control
+     * over the decoding process is required.
+     *
+     * @param  bytes
+     *         The bytes to be decoded into characters
+     *
+     * @since  JDK1.1
+     */
+    public String(byte bytes[]) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new string that contains the sequence of characters
+     * currently contained in the string buffer argument. The contents of the
+     * string buffer are copied; subsequent modification of the string buffer
+     * does not affect the newly created string.
+     *
+     * @param  buffer
+     *         A {@code StringBuffer}
+     */
+    public String(StringBuffer buffer) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    /**
+     * Allocates a new string that contains the sequence of characters
+     * currently contained in the string builder argument. The contents of the
+     * string builder are copied; subsequent modification of the string builder
+     * does not affect the newly created string.
+     *
+     * <p> This constructor is provided to ease migration to {@code
+     * StringBuilder}. Obtaining a string from a string builder via the {@code
+     * toString} method is likely to run faster and is generally preferred.
+     *
+     * @param   builder
+     *          A {@code StringBuilder}
+     *
+     * @since  1.5
+     */
+    public String(StringBuilder builder) {
+        // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+
+    // Android-removed: Unused package-private constructor String(char[] value, boolean share).
+
+    // BEGIN Android-added: Constructor for internal use.
+    // Not implemented in java as all calls are intercepted by the runtime.
+    /**
+     * Package private constructor
+     *
+     * @deprecated Use {@link #String(char[],int,int)} instead.
+     */
+    @Deprecated
+    String(int offset, int count, char[] value) {
+        throw new UnsupportedOperationException("Use StringFactory instead.");
+    }
+    // END Android-added: Constructor for internal use.
+
+    /**
+     * Returns the length of this string.
+     * The length is equal to the number of <a href="Character.html#unicode">Unicode
+     * code units</a> in the string.
+     *
+     * @return  the length of the sequence of characters represented by this
+     *          object.
+     */
+    public int length() {
+        // BEGIN Android-changed: Get length from count field rather than value array (see above).
+        // return value.length;
+        final boolean STRING_COMPRESSION_ENABLED = true;
+        if (STRING_COMPRESSION_ENABLED) {
+            // For the compression purposes (save the characters as 8-bit if all characters
+            // are ASCII), the least significant bit of "count" is used as the compression flag.
+            return (count >>> 1);
+        } else {
+            return count;
+        }
+        // END Android-changed: Get length from count field rather than value array (see above).
+    }
+
+    /**
+     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
+     *
+     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
+     * {@code false}
+     *
+     * @since 1.6
+     */
+    public boolean isEmpty() {
+        // Android-changed: Get length from count field rather than value array (see above).
+        // Empty string has {@code count == 0} with or without string compression enabled.
+        // return value.length == 0;
+        return count == 0;
+    }
+
+    /**
+     * Returns the {@code char} value at the
+     * specified index. An index ranges from {@code 0} to
+     * {@code length() - 1}. The first {@code char} value of the sequence
+     * is at index {@code 0}, the next at index {@code 1},
+     * and so on, as for array indexing.
+     *
+     * <p>If the {@code char} value specified by the index is a
+     * <a href="Character.html#unicode">surrogate</a>, the surrogate
+     * value is returned.
+     *
+     * @param      index   the index of the {@code char} value.
+     * @return     the {@code char} value at the specified index of this string.
+     *             The first {@code char} value is at index {@code 0}.
+     * @exception  IndexOutOfBoundsException  if the {@code index}
+     *             argument is negative or not less than the length of this
+     *             string.
+     */
+    // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+    @FastNative
+    public native char charAt(int index);
+    // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+    /**
+     * Returns the character (Unicode code point) at the specified
+     * index. The index refers to {@code char} values
+     * (Unicode code units) and ranges from {@code 0} to
+     * {@link #length()}{@code  - 1}.
+     *
+     * <p> If the {@code char} value specified at the given index
+     * is in the high-surrogate range, the following index is less
+     * than the length of this {@code String}, and the
+     * {@code char} value at the following index is in the
+     * low-surrogate range, then the supplementary code point
+     * corresponding to this surrogate pair is returned. Otherwise,
+     * the {@code char} value at the given index is returned.
+     *
+     * @param      index the index to the {@code char} values
+     * @return     the code point value of the character at the
+     *             {@code index}
+     * @exception  IndexOutOfBoundsException  if the {@code index}
+     *             argument is negative or not less than the length of this
+     *             string.
+     * @since      1.5
+     */
+    public int codePointAt(int index) {
+        if ((index < 0) || (index >= length())) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        // Android-changed: Skip codePointAtImpl optimization that needs access to java chars.
+        return Character.codePointAt(this, index);
+    }
+
+    /**
+     * Returns the character (Unicode code point) before the specified
+     * index. The index refers to {@code char} values
+     * (Unicode code units) and ranges from {@code 1} to {@link
+     * CharSequence#length() length}.
+     *
+     * <p> If the {@code char} value at {@code (index - 1)}
+     * is in the low-surrogate range, {@code (index - 2)} is not
+     * negative, and the {@code char} value at {@code (index -
+     * 2)} is in the high-surrogate range, then the
+     * supplementary code point value of the surrogate pair is
+     * returned. If the {@code char} value at {@code index -
+     * 1} is an unpaired low-surrogate or a high-surrogate, the
+     * surrogate value is returned.
+     *
+     * @param     index the index following the code point that should be returned
+     * @return    the Unicode code point value before the given index.
+     * @exception IndexOutOfBoundsException if the {@code index}
+     *            argument is less than 1 or greater than the length
+     *            of this string.
+     * @since     1.5
+     */
+    public int codePointBefore(int index) {
+        int i = index - 1;
+        if ((i < 0) || (i >= length())) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        // Android-changed: Skip codePointBeforeImpl optimization that needs access to java chars.
+        return Character.codePointBefore(this, index);
+    }
+
+    /**
+     * Returns the number of Unicode code points in the specified text
+     * range of this {@code String}. The text range begins at the
+     * specified {@code beginIndex} and extends to the
+     * {@code char} at index {@code endIndex - 1}. Thus the
+     * length (in {@code char}s) of the text range is
+     * {@code endIndex-beginIndex}. Unpaired surrogates within
+     * the text range count as one code point each.
+     *
+     * @param beginIndex the index to the first {@code char} of
+     * the text range.
+     * @param endIndex the index after the last {@code char} of
+     * the text range.
+     * @return the number of Unicode code points in the specified text
+     * range
+     * @exception IndexOutOfBoundsException if the
+     * {@code beginIndex} is negative, or {@code endIndex}
+     * is larger than the length of this {@code String}, or
+     * {@code beginIndex} is larger than {@code endIndex}.
+     * @since  1.5
+     */
+    public int codePointCount(int beginIndex, int endIndex) {
+        if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) {
+            throw new IndexOutOfBoundsException();
+        }
+        // Android-changed: Skip codePointCountImpl optimization that needs access to java chars.
+        return Character.codePointCount(this, beginIndex, endIndex);
+    }
+
+    /**
+     * Returns the index within this {@code String} that is
+     * offset from the given {@code index} by
+     * {@code codePointOffset} code points. Unpaired surrogates
+     * within the text range given by {@code index} and
+     * {@code codePointOffset} count as one code point each.
+     *
+     * @param index the index to be offset
+     * @param codePointOffset the offset in code points
+     * @return the index within this {@code String}
+     * @exception IndexOutOfBoundsException if {@code index}
+     *   is negative or larger then the length of this
+     *   {@code String}, or if {@code codePointOffset} is positive
+     *   and the substring starting with {@code index} has fewer
+     *   than {@code codePointOffset} code points,
+     *   or if {@code codePointOffset} is negative and the substring
+     *   before {@code index} has fewer than the absolute value
+     *   of {@code codePointOffset} code points.
+     * @since 1.5
+     */
+    public int offsetByCodePoints(int index, int codePointOffset) {
+        if (index < 0 || index > length()) {
+            throw new IndexOutOfBoundsException();
+        }
+        // Android-changed: Skip offsetByCodePointsImpl optimization that needs access to java chars
+        return Character.offsetByCodePoints(this, index, codePointOffset);
+    }
+
+    /**
+     * Copy characters from this string into dst starting at dstBegin.
+     * This method doesn't perform any range checking.
+     */
+    void getChars(char dst[], int dstBegin) {
+        // Android-changed: Replace arraycopy with native call since chars are managed by runtime.
+        getCharsNoCheck(0, length(), dst, dstBegin);
+    }
+
+    /**
+     * Copies characters from this string into the destination character
+     * array.
+     * <p>
+     * The first character to be copied is at index {@code srcBegin};
+     * the last character to be copied is at index {@code srcEnd-1}
+     * (thus the total number of characters to be copied is
+     * {@code srcEnd-srcBegin}). The characters are copied into the
+     * subarray of {@code dst} starting at index {@code dstBegin}
+     * and ending at index:
+     * <blockquote><pre>
+     *     dstBegin + (srcEnd-srcBegin) - 1
+     * </pre></blockquote>
+     *
+     * @param      srcBegin   index of the first character in the string
+     *                        to copy.
+     * @param      srcEnd     index after the last character in the string
+     *                        to copy.
+     * @param      dst        the destination array.
+     * @param      dstBegin   the start offset in the destination array.
+     * @exception IndexOutOfBoundsException If any of the following
+     *            is true:
+     *            <ul><li>{@code srcBegin} is negative.
+     *            <li>{@code srcBegin} is greater than {@code srcEnd}
+     *            <li>{@code srcEnd} is greater than the length of this
+     *                string
+     *            <li>{@code dstBegin} is negative
+     *            <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
+     *                {@code dst.length}</ul>
+     */
+    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
+        // BEGIN Android-changed: Implement in terms of length() and native getCharsNoCheck method.
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+
+        if (srcBegin < 0) {
+            throw new StringIndexOutOfBoundsException(this, srcBegin);
+        }
+        if (srcEnd > length()) {
+            throw new StringIndexOutOfBoundsException(this, srcEnd);
+        }
+
+        int n = srcEnd - srcBegin;
+        if (srcEnd < srcBegin) {
+            throw new StringIndexOutOfBoundsException(this, srcBegin, n);
+        }
+
+        if (dstBegin < 0) {
+            throw new ArrayIndexOutOfBoundsException("dstBegin < 0. dstBegin=" + dstBegin);
+        }
+        // dstBegin can be equal to dst.length, but only in the case where zero chars are to be
+        // copied.
+        if (dstBegin > dst.length) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "dstBegin > dst.length. dstBegin=" + dstBegin + ", dst.length=" + dst.length);
+        }
+        if (n > dst.length - dstBegin) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "n > dst.length - dstBegin. n=" + n + ", dst.length=" + dst.length
+                            + "dstBegin=" + dstBegin);
+        }
+
+        getCharsNoCheck(srcBegin, srcEnd, dst, dstBegin);
+        // END Android-changed: Implement in terms of length() and native getCharsNoCheck method.
+    }
+
+    // BEGIN Android-added: Native method to access char storage managed by runtime.
+    /**
+     * getChars without bounds checks, for use by other classes
+     * within the java.lang package only.  The caller is responsible for
+     * ensuring that start >= 0 && start <= end && end <= count.
+     */
+    @FastNative
+    native void getCharsNoCheck(int start, int end, char[] buffer, int index);
+    // END Android-added: Native method to access char storage managed by runtime.
+
+    /**
+     * Copies characters from this string into the destination byte array. Each
+     * byte receives the 8 low-order bits of the corresponding character. The
+     * eight high-order bits of each character are not copied and do not
+     * participate in the transfer in any way.
+     *
+     * <p> The first character to be copied is at index {@code srcBegin}; the
+     * last character to be copied is at index {@code srcEnd-1}.  The total
+     * number of characters to be copied is {@code srcEnd-srcBegin}. The
+     * characters, converted to bytes, are copied into the subarray of {@code
+     * dst} starting at index {@code dstBegin} and ending at index:
+     *
+     * <blockquote><pre>
+     *     dstBegin + (srcEnd-srcBegin) - 1
+     * </pre></blockquote>
+     *
+     * @deprecated  This method does not properly convert characters into
+     * bytes.  As of JDK&nbsp;1.1, the preferred way to do this is via the
+     * {@link #getBytes()} method, which uses the platform's default charset.
+     *
+     * @param  srcBegin
+     *         Index of the first character in the string to copy
+     *
+     * @param  srcEnd
+     *         Index after the last character in the string to copy
+     *
+     * @param  dst
+     *         The destination array
+     *
+     * @param  dstBegin
+     *         The start offset in the destination array
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If any of the following is true:
+     *          <ul>
+     *            <li> {@code srcBegin} is negative
+     *            <li> {@code srcBegin} is greater than {@code srcEnd}
+     *            <li> {@code srcEnd} is greater than the length of this String
+     *            <li> {@code dstBegin} is negative
+     *            <li> {@code dstBegin+(srcEnd-srcBegin)} is larger than {@code
+     *                 dst.length}
+     *          </ul>
+     */
+    @Deprecated
+    public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+        if (srcBegin < 0) {
+            throw new StringIndexOutOfBoundsException(this, srcBegin);
+        }
+        if (srcEnd > length()) {
+            throw new StringIndexOutOfBoundsException(this, srcEnd);
+        }
+        if (srcBegin > srcEnd) {
+            throw new StringIndexOutOfBoundsException(this, srcEnd - srcBegin);
+        }
+
+        int j = dstBegin;
+        int n = srcEnd;
+        int i = srcBegin;
+
+        while (i < n) {
+            dst[j++] = (byte)charAt(i++);
+        }
+    }
+
+    /**
+     * Encodes this {@code String} into a sequence of bytes using the named
+     * charset, storing the result into a new byte array.
+     *
+     * <p> The behavior of this method when this string cannot be encoded in
+     * the given charset is unspecified.  The {@link
+     * java.nio.charset.CharsetEncoder} class should be used when more control
+     * over the encoding process is required.
+     *
+     * @param  charsetName
+     *         The name of a supported {@linkplain java.nio.charset.Charset
+     *         charset}
+     *
+     * @return  The resultant byte array
+     *
+     * @throws  UnsupportedEncodingException
+     *          If the named charset is not supported
+     *
+     * @since  JDK1.1
+     */
+    public byte[] getBytes(String charsetName)
+            throws UnsupportedEncodingException {
+        if (charsetName == null) throw new NullPointerException();
+        // Android-changed: Skip StringCoding optimization that needs access to java chars.
+        // return StringCoding.encode(charsetName, value, 0, value.length);
+        return getBytes(Charset.forNameUEE(charsetName));
+    }
+
+    /**
+     * Encodes this {@code String} into a sequence of bytes using the given
+     * {@linkplain java.nio.charset.Charset charset}, storing the result into a
+     * new byte array.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with this charset's default replacement byte array.  The
+     * {@link java.nio.charset.CharsetEncoder} class should be used when more
+     * control over the encoding process is required.
+     *
+     * @param  charset
+     *         The {@linkplain java.nio.charset.Charset} to be used to encode
+     *         the {@code String}
+     *
+     * @return  The resultant byte array
+     *
+     * @since  1.6
+     */
+    public byte[] getBytes(Charset charset) {
+        // BEGIN Android-changed: Skip StringCoding optimization that needs access to java chars.
+        // if (charset == null) throw new NullPointerException();
+        // return StringCoding.encode(charset, value, 0, value.length);
+        if (charset == null) {
+            throw new NullPointerException("charset == null");
+        }
+
+        final int len = length();
+        final String name = charset.name();
+        if ("UTF-8".equals(name)) {
+            return CharsetUtils.toUtf8Bytes(this, 0, len);
+        } else if ("ISO-8859-1".equals(name)) {
+            return CharsetUtils.toIsoLatin1Bytes(this, 0, len);
+        } else if ("US-ASCII".equals(name)) {
+            return CharsetUtils.toAsciiBytes(this, 0, len);
+        } else if ("UTF-16BE".equals(name)) {
+            return CharsetUtils.toBigEndianUtf16Bytes(this, 0, len);
+        }
+
+        ByteBuffer buffer = charset.encode(this);
+        byte[] bytes = new byte[buffer.limit()];
+        buffer.get(bytes);
+        return bytes;
+        // END Android-changed: Skip StringCoding optimization that needs access to java chars.
+    }
+
+    /**
+     * Encodes this {@code String} into a sequence of bytes using the
+     * platform's default charset, storing the result into a new byte array.
+     *
+     * <p> The behavior of this method when this string cannot be encoded in
+     * the default charset is unspecified.  The {@link
+     * java.nio.charset.CharsetEncoder} class should be used when more control
+     * over the encoding process is required.
+     *
+     * @return  The resultant byte array
+     *
+     * @since      JDK1.1
+     */
+    public byte[] getBytes() {
+        // Android-changed: Skip StringCoding optimization that needs access to java chars.
+        // return StringCoding.encode(value, 0, value.length);
+        return getBytes(Charset.defaultCharset());
+    }
+
+    /**
+     * Compares this string to the specified object.  The result is {@code
+     * true} if and only if the argument is not {@code null} and is a {@code
+     * String} object that represents the same sequence of characters as this
+     * object.
+     *
+     * @param  anObject
+     *         The object to compare this {@code String} against
+     *
+     * @return  {@code true} if the given object represents a {@code String}
+     *          equivalent to this string, {@code false} otherwise
+     *
+     * @see  #compareTo(String)
+     * @see  #equalsIgnoreCase(String)
+     */
+    public boolean equals(Object anObject) {
+        if (this == anObject) {
+            return true;
+        }
+        if (anObject instanceof String) {
+            String anotherString = (String)anObject;
+            int n = length();
+            if (n == anotherString.length()) {
+                int i = 0;
+                while (n-- != 0) {
+                    if (charAt(i) != anotherString.charAt(i))
+                            return false;
+                    i++;
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Compares this string to the specified {@code StringBuffer}.  The result
+     * is {@code true} if and only if this {@code String} represents the same
+     * sequence of characters as the specified {@code StringBuffer}. This method
+     * synchronizes on the {@code StringBuffer}.
+     *
+     * @param  sb
+     *         The {@code StringBuffer} to compare this {@code String} against
+     *
+     * @return  {@code true} if this {@code String} represents the same
+     *          sequence of characters as the specified {@code StringBuffer},
+     *          {@code false} otherwise
+     *
+     * @since  1.4
+     */
+    public boolean contentEquals(StringBuffer sb) {
+        return contentEquals((CharSequence)sb);
+    }
+
+    private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
+        char v2[] = sb.getValue();
+        int n = length();
+        if (n != sb.length()) {
+            return false;
+        }
+        for (int i = 0; i < n; i++) {
+            if (charAt(i) != v2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares this string to the specified {@code CharSequence}.  The
+     * result is {@code true} if and only if this {@code String} represents the
+     * same sequence of char values as the specified sequence. Note that if the
+     * {@code CharSequence} is a {@code StringBuffer} then the method
+     * synchronizes on it.
+     *
+     * @param  cs
+     *         The sequence to compare this {@code String} against
+     *
+     * @return  {@code true} if this {@code String} represents the same
+     *          sequence of char values as the specified sequence, {@code
+     *          false} otherwise
+     *
+     * @since  1.5
+     */
+    public boolean contentEquals(CharSequence cs) {
+        // Argument is a StringBuffer, StringBuilder
+        if (cs instanceof AbstractStringBuilder) {
+            if (cs instanceof StringBuffer) {
+                synchronized(cs) {
+                   return nonSyncContentEquals((AbstractStringBuilder)cs);
+                }
+            } else {
+                return nonSyncContentEquals((AbstractStringBuilder)cs);
+            }
+        }
+        // Argument is a String
+        if (cs instanceof String) {
+            return equals(cs);
+        }
+        // Argument is a generic CharSequence
+        int n = length();
+        if (n != cs.length()) {
+            return false;
+        }
+        for (int i = 0; i < n; i++) {
+            if (charAt(i) != cs.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares this {@code String} to another {@code String}, ignoring case
+     * considerations.  Two strings are considered equal ignoring case if they
+     * are of the same length and corresponding characters in the two strings
+     * are equal ignoring case.
+     *
+     * <p> Two characters {@code c1} and {@code c2} are considered the same
+     * ignoring case if at least one of the following is true:
+     * <ul>
+     *   <li> The two characters are the same (as compared by the
+     *        {@code ==} operator)
+     *   <li> Applying the method {@link
+     *        java.lang.Character#toUpperCase(char)} to each character
+     *        produces the same result
+     *   <li> Applying the method {@link
+     *        java.lang.Character#toLowerCase(char)} to each character
+     *        produces the same result
+     * </ul>
+     *
+     * @param  anotherString
+     *         The {@code String} to compare this {@code String} against
+     *
+     * @return  {@code true} if the argument is not {@code null} and it
+     *          represents an equivalent {@code String} ignoring case; {@code
+     *          false} otherwise
+     *
+     * @see  #equals(Object)
+     */
+    public boolean equalsIgnoreCase(String anotherString) {
+        final int len = length();
+        return (this == anotherString) ? true
+                : (anotherString != null)
+                && (anotherString.length() == len)
+                && regionMatches(true, 0, anotherString, 0, len);
+    }
+
+    /**
+     * Compares two strings lexicographically.
+     * The comparison is based on the Unicode value of each character in
+     * the strings. The character sequence represented by this
+     * {@code String} object is compared lexicographically to the
+     * character sequence represented by the argument string. The result is
+     * a negative integer if this {@code String} object
+     * lexicographically precedes the argument string. The result is a
+     * positive integer if this {@code String} object lexicographically
+     * follows the argument string. The result is zero if the strings
+     * are equal; {@code compareTo} returns {@code 0} exactly when
+     * the {@link #equals(Object)} method would return {@code true}.
+     * <p>
+     * This is the definition of lexicographic ordering. If two strings are
+     * different, then either they have different characters at some index
+     * that is a valid index for both strings, or their lengths are different,
+     * or both. If they have different characters at one or more index
+     * positions, let <i>k</i> be the smallest such index; then the string
+     * whose character at position <i>k</i> has the smaller value, as
+     * determined by using the &lt; operator, lexicographically precedes the
+     * other string. In this case, {@code compareTo} returns the
+     * difference of the two character values at position {@code k} in
+     * the two string -- that is, the value:
+     * <blockquote><pre>
+     * this.charAt(k)-anotherString.charAt(k)
+     * </pre></blockquote>
+     * If there is no index position at which they differ, then the shorter
+     * string lexicographically precedes the longer string. In this case,
+     * {@code compareTo} returns the difference of the lengths of the
+     * strings -- that is, the value:
+     * <blockquote><pre>
+     * this.length()-anotherString.length()
+     * </pre></blockquote>
+     *
+     * @param   anotherString   the {@code String} to be compared.
+     * @return  the value {@code 0} if the argument string is equal to
+     *          this string; a value less than {@code 0} if this string
+     *          is lexicographically less than the string argument; and a
+     *          value greater than {@code 0} if this string is
+     *          lexicographically greater than the string argument.
+     */
+    // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+    @FastNative
+    public native int compareTo(String anotherString);
+    // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+    /**
+     * A Comparator that orders {@code String} objects as by
+     * {@code compareToIgnoreCase}. This comparator is serializable.
+     * <p>
+     * Note that this Comparator does <em>not</em> take locale into account,
+     * and will result in an unsatisfactory ordering for certain locales.
+     * The java.text package provides <em>Collators</em> to allow
+     * locale-sensitive ordering.
+     *
+     * @see     java.text.Collator#compare(String, String)
+     * @since   1.2
+     */
+    public static final Comparator<String> CASE_INSENSITIVE_ORDER
+                                         = new CaseInsensitiveComparator();
+    private static class CaseInsensitiveComparator
+            implements Comparator<String>, java.io.Serializable {
+        // use serialVersionUID from JDK 1.2.2 for interoperability
+        private static final long serialVersionUID = 8575799808933029326L;
+
+        public int compare(String s1, String s2) {
+            int n1 = s1.length();
+            int n2 = s2.length();
+            int min = Math.min(n1, n2);
+            for (int i = 0; i < min; i++) {
+                char c1 = s1.charAt(i);
+                char c2 = s2.charAt(i);
+                if (c1 != c2) {
+                    c1 = Character.toUpperCase(c1);
+                    c2 = Character.toUpperCase(c2);
+                    if (c1 != c2) {
+                        c1 = Character.toLowerCase(c1);
+                        c2 = Character.toLowerCase(c2);
+                        if (c1 != c2) {
+                            // No overflow because of numeric promotion
+                            return c1 - c2;
+                        }
+                    }
+                }
+            }
+            return n1 - n2;
+        }
+
+        /** Replaces the de-serialized object. */
+        private Object readResolve() { return CASE_INSENSITIVE_ORDER; }
+    }
+
+    /**
+     * Compares two strings lexicographically, ignoring case
+     * differences. This method returns an integer whose sign is that of
+     * calling {@code compareTo} with normalized versions of the strings
+     * where case differences have been eliminated by calling
+     * {@code Character.toLowerCase(Character.toUpperCase(character))} on
+     * each character.
+     * <p>
+     * Note that this method does <em>not</em> take locale into account,
+     * and will result in an unsatisfactory ordering for certain locales.
+     * The java.text package provides <em>collators</em> to allow
+     * locale-sensitive ordering.
+     *
+     * @param   str   the {@code String} to be compared.
+     * @return  a negative integer, zero, or a positive integer as the
+     *          specified String is greater than, equal to, or less
+     *          than this String, ignoring case considerations.
+     * @see     java.text.Collator#compare(String, String)
+     * @since   1.2
+     */
+    public int compareToIgnoreCase(String str) {
+        return CASE_INSENSITIVE_ORDER.compare(this, str);
+    }
+
+    /**
+     * Tests if two string regions are equal.
+     * <p>
+     * A substring of this {@code String} object is compared to a substring
+     * of the argument other. The result is true if these substrings
+     * represent identical character sequences. The substring of this
+     * {@code String} object to be compared begins at index {@code toffset}
+     * and has length {@code len}. The substring of other to be compared
+     * begins at index {@code ooffset} and has length {@code len}. The
+     * result is {@code false} if and only if at least one of the following
+     * is true:
+     * <ul><li>{@code toffset} is negative.
+     * <li>{@code ooffset} is negative.
+     * <li>{@code toffset+len} is greater than the length of this
+     * {@code String} object.
+     * <li>{@code ooffset+len} is greater than the length of the other
+     * argument.
+     * <li>There is some nonnegative integer <i>k</i> less than {@code len}
+     * such that:
+     * {@code this.charAt(toffset + }<i>k</i>{@code ) != other.charAt(ooffset + }
+     * <i>k</i>{@code )}
+     * </ul>
+     *
+     * @param   toffset   the starting offset of the subregion in this string.
+     * @param   other     the string argument.
+     * @param   ooffset   the starting offset of the subregion in the string
+     *                    argument.
+     * @param   len       the number of characters to compare.
+     * @return  {@code true} if the specified subregion of this string
+     *          exactly matches the specified subregion of the string argument;
+     *          {@code false} otherwise.
+     */
+    public boolean regionMatches(int toffset, String other, int ooffset,
+            int len) {
+        int to = toffset;
+        int po = ooffset;
+        // Note: toffset, ooffset, or len might be near -1>>>1.
+        if ((ooffset < 0) || (toffset < 0)
+                || (toffset > (long)length() - len)
+                || (ooffset > (long)other.length() - len)) {
+            return false;
+        }
+        while (len-- > 0) {
+            if (charAt(to++) != other.charAt(po++)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Tests if two string regions are equal.
+     * <p>
+     * A substring of this {@code String} object is compared to a substring
+     * of the argument {@code other}. The result is {@code true} if these
+     * substrings represent character sequences that are the same, ignoring
+     * case if and only if {@code ignoreCase} is true. The substring of
+     * this {@code String} object to be compared begins at index
+     * {@code toffset} and has length {@code len}. The substring of
+     * {@code other} to be compared begins at index {@code ooffset} and
+     * has length {@code len}. The result is {@code false} if and only if
+     * at least one of the following is true:
+     * <ul><li>{@code toffset} is negative.
+     * <li>{@code ooffset} is negative.
+     * <li>{@code toffset+len} is greater than the length of this
+     * {@code String} object.
+     * <li>{@code ooffset+len} is greater than the length of the other
+     * argument.
+     * <li>{@code ignoreCase} is {@code false} and there is some nonnegative
+     * integer <i>k</i> less than {@code len} such that:
+     * <blockquote><pre>
+     * this.charAt(toffset+k) != other.charAt(ooffset+k)
+     * </pre></blockquote>
+     * <li>{@code ignoreCase} is {@code true} and there is some nonnegative
+     * integer <i>k</i> less than {@code len} such that:
+     * <blockquote><pre>
+     * Character.toLowerCase(this.charAt(toffset+k)) !=
+     Character.toLowerCase(other.charAt(ooffset+k))
+     * </pre></blockquote>
+     * and:
+     * <blockquote><pre>
+     * Character.toUpperCase(this.charAt(toffset+k)) !=
+     *         Character.toUpperCase(other.charAt(ooffset+k))
+     * </pre></blockquote>
+     * </ul>
+     *
+     * @param   ignoreCase   if {@code true}, ignore case when comparing
+     *                       characters.
+     * @param   toffset      the starting offset of the subregion in this
+     *                       string.
+     * @param   other        the string argument.
+     * @param   ooffset      the starting offset of the subregion in the string
+     *                       argument.
+     * @param   len          the number of characters to compare.
+     * @return  {@code true} if the specified subregion of this string
+     *          matches the specified subregion of the string argument;
+     *          {@code false} otherwise. Whether the matching is exact
+     *          or case insensitive depends on the {@code ignoreCase}
+     *          argument.
+     */
+    public boolean regionMatches(boolean ignoreCase, int toffset,
+            String other, int ooffset, int len) {
+        int to = toffset;
+        int po = ooffset;
+        // Note: toffset, ooffset, or len might be near -1>>>1.
+        if ((ooffset < 0) || (toffset < 0)
+                || (toffset > (long)length() - len)
+                || (ooffset > (long)other.length() - len)) {
+            return false;
+        }
+        while (len-- > 0) {
+            char c1 = charAt(to++);
+            char c2 = other.charAt(po++);
+            if (c1 == c2) {
+                continue;
+            }
+            if (ignoreCase) {
+                // If characters don't match but case may be ignored,
+                // try converting both characters to uppercase.
+                // If the results match, then the comparison scan should
+                // continue.
+                char u1 = Character.toUpperCase(c1);
+                char u2 = Character.toUpperCase(c2);
+                if (u1 == u2) {
+                    continue;
+                }
+                // Unfortunately, conversion to uppercase does not work properly
+                // for the Georgian alphabet, which has strange rules about case
+                // conversion.  So we need to make one last check before
+                // exiting.
+                if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+                    continue;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Tests if the substring of this string beginning at the
+     * specified index starts with the specified prefix.
+     *
+     * @param   prefix    the prefix.
+     * @param   toffset   where to begin looking in this string.
+     * @return  {@code true} if the character sequence represented by the
+     *          argument is a prefix of the substring of this object starting
+     *          at index {@code toffset}; {@code false} otherwise.
+     *          The result is {@code false} if {@code toffset} is
+     *          negative or greater than the length of this
+     *          {@code String} object; otherwise the result is the same
+     *          as the result of the expression
+     *          <pre>
+     *          this.substring(toffset).startsWith(prefix)
+     *          </pre>
+     */
+    public boolean startsWith(String prefix, int toffset) {
+        int to = toffset;
+        int po = 0;
+        int pc = prefix.length();
+        // Note: toffset might be near -1>>>1.
+        if ((toffset < 0) || (toffset > length() - pc)) {
+            return false;
+        }
+        while (--pc >= 0) {
+            if (charAt(to++) != prefix.charAt(po++)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Tests if this string starts with the specified prefix.
+     *
+     * @param   prefix   the prefix.
+     * @return  {@code true} if the character sequence represented by the
+     *          argument is a prefix of the character sequence represented by
+     *          this string; {@code false} otherwise.
+     *          Note also that {@code true} will be returned if the
+     *          argument is an empty string or is equal to this
+     *          {@code String} object as determined by the
+     *          {@link #equals(Object)} method.
+     * @since   1. 0
+     */
+    public boolean startsWith(String prefix) {
+        return startsWith(prefix, 0);
+    }
+
+    /**
+     * Tests if this string ends with the specified suffix.
+     *
+     * @param   suffix   the suffix.
+     * @return  {@code true} if the character sequence represented by the
+     *          argument is a suffix of the character sequence represented by
+     *          this object; {@code false} otherwise. Note that the
+     *          result will be {@code true} if the argument is the
+     *          empty string or is equal to this {@code String} object
+     *          as determined by the {@link #equals(Object)} method.
+     */
+    public boolean endsWith(String suffix) {
+        return startsWith(suffix, length() - suffix.length());
+    }
+
+    /**
+     * Returns a hash code for this string. The hash code for a
+     * {@code String} object is computed as
+     * <blockquote><pre>
+     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+     * </pre></blockquote>
+     * using {@code int} arithmetic, where {@code s[i]} is the
+     * <i>i</i>th character of the string, {@code n} is the length of
+     * the string, and {@code ^} indicates exponentiation.
+     * (The hash value of the empty string is zero.)
+     *
+     * @return  a hash code value for this object.
+     */
+    public int hashCode() {
+        int h = hash;
+        final int len = length();
+        if (h == 0 && len > 0) {
+            for (int i = 0; i < len; i++) {
+                h = 31 * h + charAt(i);
+            }
+            hash = h;
+        }
+        return h;
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of
+     * the specified character. If a character with value
+     * {@code ch} occurs in the character sequence represented by
+     * this {@code String} object, then the index (in Unicode
+     * code units) of the first such occurrence is returned. For
+     * values of {@code ch} in the range from 0 to 0xFFFF
+     * (inclusive), this is the smallest value <i>k</i> such that:
+     * <blockquote><pre>
+     * this.charAt(<i>k</i>) == ch
+     * </pre></blockquote>
+     * is true. For other values of {@code ch}, it is the
+     * smallest value <i>k</i> such that:
+     * <blockquote><pre>
+     * this.codePointAt(<i>k</i>) == ch
+     * </pre></blockquote>
+     * is true. In either case, if no such character occurs in this
+     * string, then {@code -1} is returned.
+     *
+     * @param   ch   a character (Unicode code point).
+     * @return  the index of the first occurrence of the character in the
+     *          character sequence represented by this object, or
+     *          {@code -1} if the character does not occur.
+     */
+    public int indexOf(int ch) {
+        return indexOf(ch, 0);
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of the
+     * specified character, starting the search at the specified index.
+     * <p>
+     * If a character with value {@code ch} occurs in the
+     * character sequence represented by this {@code String}
+     * object at an index no smaller than {@code fromIndex}, then
+     * the index of the first such occurrence is returned. For values
+     * of {@code ch} in the range from 0 to 0xFFFF (inclusive),
+     * this is the smallest value <i>k</i> such that:
+     * <blockquote><pre>
+     * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
+     * </pre></blockquote>
+     * is true. For other values of {@code ch}, it is the
+     * smallest value <i>k</i> such that:
+     * <blockquote><pre>
+     * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
+     * </pre></blockquote>
+     * is true. In either case, if no such character occurs in this
+     * string at or after position {@code fromIndex}, then
+     * {@code -1} is returned.
+     *
+     * <p>
+     * There is no restriction on the value of {@code fromIndex}. If it
+     * is negative, it has the same effect as if it were zero: this entire
+     * string may be searched. If it is greater than the length of this
+     * string, it has the same effect as if it were equal to the length of
+     * this string: {@code -1} is returned.
+     *
+     * <p>All indices are specified in {@code char} values
+     * (Unicode code units).
+     *
+     * @param   ch          a character (Unicode code point).
+     * @param   fromIndex   the index to start the search from.
+     * @return  the index of the first occurrence of the character in the
+     *          character sequence represented by this object that is greater
+     *          than or equal to {@code fromIndex}, or {@code -1}
+     *          if the character does not occur.
+     */
+    public int indexOf(int ch, int fromIndex) {
+        final int max = length();
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        } else if (fromIndex >= max) {
+            // Note: fromIndex might be near -1>>>1.
+            return -1;
+        }
+
+        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // handle most cases here (ch is a BMP code point or a
+            // negative value (invalid code point))
+            for (int i = fromIndex; i < max; i++) {
+                if (charAt(i) == ch) {
+                    return i;
+                }
+            }
+            return -1;
+        } else {
+            return indexOfSupplementary(ch, fromIndex);
+        }
+    }
+
+    /**
+     * Handles (rare) calls of indexOf with a supplementary character.
+     */
+    private int indexOfSupplementary(int ch, int fromIndex) {
+        if (Character.isValidCodePoint(ch)) {
+            final char hi = Character.highSurrogate(ch);
+            final char lo = Character.lowSurrogate(ch);
+            final int max = length() - 1;
+            for (int i = fromIndex; i < max; i++) {
+                if (charAt(i) == hi && charAt(i + 1) == lo) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index within this string of the last occurrence of
+     * the specified character. For values of {@code ch} in the
+     * range from 0 to 0xFFFF (inclusive), the index (in Unicode code
+     * units) returned is the largest value <i>k</i> such that:
+     * <blockquote><pre>
+     * this.charAt(<i>k</i>) == ch
+     * </pre></blockquote>
+     * is true. For other values of {@code ch}, it is the
+     * largest value <i>k</i> such that:
+     * <blockquote><pre>
+     * this.codePointAt(<i>k</i>) == ch
+     * </pre></blockquote>
+     * is true.  In either case, if no such character occurs in this
+     * string, then {@code -1} is returned.  The
+     * {@code String} is searched backwards starting at the last
+     * character.
+     *
+     * @param   ch   a character (Unicode code point).
+     * @return  the index of the last occurrence of the character in the
+     *          character sequence represented by this object, or
+     *          {@code -1} if the character does not occur.
+     */
+    public int lastIndexOf(int ch) {
+        return lastIndexOf(ch, length() - 1);
+    }
+
+    /**
+     * Returns the index within this string of the last occurrence of
+     * the specified character, searching backward starting at the
+     * specified index. For values of {@code ch} in the range
+     * from 0 to 0xFFFF (inclusive), the index returned is the largest
+     * value <i>k</i> such that:
+     * <blockquote><pre>
+     * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
+     * </pre></blockquote>
+     * is true. For other values of {@code ch}, it is the
+     * largest value <i>k</i> such that:
+     * <blockquote><pre>
+     * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
+     * </pre></blockquote>
+     * is true. In either case, if no such character occurs in this
+     * string at or before position {@code fromIndex}, then
+     * {@code -1} is returned.
+     *
+     * <p>All indices are specified in {@code char} values
+     * (Unicode code units).
+     *
+     * @param   ch          a character (Unicode code point).
+     * @param   fromIndex   the index to start the search from. There is no
+     *          restriction on the value of {@code fromIndex}. If it is
+     *          greater than or equal to the length of this string, it has
+     *          the same effect as if it were equal to one less than the
+     *          length of this string: this entire string may be searched.
+     *          If it is negative, it has the same effect as if it were -1:
+     *          -1 is returned.
+     * @return  the index of the last occurrence of the character in the
+     *          character sequence represented by this object that is less
+     *          than or equal to {@code fromIndex}, or {@code -1}
+     *          if the character does not occur before that point.
+     */
+    public int lastIndexOf(int ch, int fromIndex) {
+        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // handle most cases here (ch is a BMP code point or a
+            // negative value (invalid code point))
+            int i = Math.min(fromIndex, length() - 1);
+            for (; i >= 0; i--) {
+                if (charAt(i) == ch) {
+                    return i;
+                }
+            }
+            return -1;
+        } else {
+            return lastIndexOfSupplementary(ch, fromIndex);
+        }
+    }
+
+    /**
+     * Handles (rare) calls of lastIndexOf with a supplementary character.
+     */
+    private int lastIndexOfSupplementary(int ch, int fromIndex) {
+        if (Character.isValidCodePoint(ch)) {
+            char hi = Character.highSurrogate(ch);
+            char lo = Character.lowSurrogate(ch);
+            int i = Math.min(fromIndex, length() - 2);
+            for (; i >= 0; i--) {
+                if (charAt(i) == hi && charAt(i + 1) == lo) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of the
+     * specified substring.
+     *
+     * <p>The returned index is the smallest value <i>k</i> for which:
+     * <blockquote><pre>
+     * this.startsWith(str, <i>k</i>)
+     * </pre></blockquote>
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
+     *
+     * @param   str   the substring to search for.
+     * @return  the index of the first occurrence of the specified substring,
+     *          or {@code -1} if there is no such occurrence.
+     */
+    public int indexOf(String str) {
+        return indexOf(str, 0);
+    }
+
+    /**
+     * Returns the index within this string of the first occurrence of the
+     * specified substring, starting at the specified index.
+     *
+     * <p>The returned index is the smallest value <i>k</i> for which:
+     * <blockquote><pre>
+     * <i>k</i> &gt;= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
+     * </pre></blockquote>
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
+     *
+     * @param   str         the substring to search for.
+     * @param   fromIndex   the index from which to start the search.
+     * @return  the index of the first occurrence of the specified substring,
+     *          starting at the specified index,
+     *          or {@code -1} if there is no such occurrence.
+     */
+    public int indexOf(String str, int fromIndex) {
+        // Android-changed: Delegate to the static indexOf method below.
+        return indexOf(this, str, fromIndex);
+    }
+
+    // BEGIN Android-added: Private static indexOf method that takes String parameters.
+    // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
+    /**
+     * The source is the string being searched, and the target is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    private static int indexOf(String source, String target, int fromIndex) {
+        final int sourceLength = source.length();
+        final int targetLength = target.length();
+        if (fromIndex >= sourceLength) {
+            return (targetLength == 0 ? sourceLength : -1);
+        }
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        }
+        if (targetLength == 0) {
+            return fromIndex;
+        }
+
+        char first = target.charAt(0);
+        int max = (sourceLength - targetLength);
+
+        for (int i = fromIndex; i <= max; i++) {
+            /* Look for first character. */
+            if (source.charAt(i)!= first) {
+                while (++i <= max && source.charAt(i) != first);
+            }
+
+            /* Found first character, now look at the rest of v2 */
+            if (i <= max) {
+                int j = i + 1;
+                int end = j + targetLength - 1;
+                for (int k = 1; j < end && source.charAt(j)
+                         == target.charAt(k); j++, k++);
+
+                if (j == end) {
+                    /* Found whole string. */
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+    // END Android-added: Private static indexOf method that takes String parameters.
+
+    /**
+     * Code shared by String and AbstractStringBuilder to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int indexOf(char[] source, int sourceOffset, int sourceCount,
+            String target, int fromIndex) {
+        return indexOf(source, sourceOffset, sourceCount,
+                       target.toCharArray(), 0, target.length(),
+                       fromIndex);
+    }
+
+    /**
+     * Code shared by String and StringBuffer to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   targetOffset offset of the target string.
+     * @param   targetCount  count of the target string.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int indexOf(char[] source, int sourceOffset, int sourceCount,
+            char[] target, int targetOffset, int targetCount,
+            int fromIndex) {
+        if (fromIndex >= sourceCount) {
+            return (targetCount == 0 ? sourceCount : -1);
+        }
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        }
+        if (targetCount == 0) {
+            return fromIndex;
+        }
+
+        char first = target[targetOffset];
+        int max = sourceOffset + (sourceCount - targetCount);
+
+        for (int i = sourceOffset + fromIndex; i <= max; i++) {
+            /* Look for first character. */
+            if (source[i] != first) {
+                while (++i <= max && source[i] != first);
+            }
+
+            /* Found first character, now look at the rest of v2 */
+            if (i <= max) {
+                int j = i + 1;
+                int end = j + targetCount - 1;
+                for (int k = targetOffset + 1; j < end && source[j]
+                        == target[k]; j++, k++);
+
+                if (j == end) {
+                    /* Found whole string. */
+                    return i - sourceOffset;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index within this string of the last occurrence of the
+     * specified substring.  The last occurrence of the empty string ""
+     * is considered to occur at the index value {@code this.length()}.
+     *
+     * <p>The returned index is the largest value <i>k</i> for which:
+     * <blockquote><pre>
+     * this.startsWith(str, <i>k</i>)
+     * </pre></blockquote>
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
+     *
+     * @param   str   the substring to search for.
+     * @return  the index of the last occurrence of the specified substring,
+     *          or {@code -1} if there is no such occurrence.
+     */
+    public int lastIndexOf(String str) {
+        return lastIndexOf(str, length());
+    }
+
+    /**
+     * Returns the index within this string of the last occurrence of the
+     * specified substring, searching backward starting at the specified index.
+     *
+     * <p>The returned index is the largest value <i>k</i> for which:
+     * <blockquote><pre>
+     * <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
+     * </pre></blockquote>
+     * If no such value of <i>k</i> exists, then {@code -1} is returned.
+     *
+     * @param   str         the substring to search for.
+     * @param   fromIndex   the index to start the search from.
+     * @return  the index of the last occurrence of the specified substring,
+     *          searching backward from the specified index,
+     *          or {@code -1} if there is no such occurrence.
+     */
+    public int lastIndexOf(String str, int fromIndex) {
+        // Android-changed: Change parameters to static lastIndexOf to match new signature below.
+        return lastIndexOf(this, str, fromIndex);
+    }
+
+    // BEGIN Android-added: Private static lastIndexOf method that takes String parameters.
+    // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
+    /**
+     * The source is the string being searched, and the target is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    private static int lastIndexOf(String source, String target, int fromIndex) {
+        /*
+         * Check arguments; return immediately where possible. For
+         * consistency, don't check for null str.
+         */
+        final int sourceLength = source.length();
+        final int targetLength = target.length();
+        int rightIndex = sourceLength - targetLength;
+        if (fromIndex < 0) {
+            return -1;
+        }
+        if (fromIndex > rightIndex) {
+            fromIndex = rightIndex;
+        }
+        /* Empty string always matches. */
+        if (targetLength == 0) {
+            return fromIndex;
+        }
+
+        int strLastIndex = targetLength - 1;
+        char strLastChar = target.charAt(strLastIndex);
+        int min = targetLength - 1;
+        int i = min + fromIndex;
+
+        startSearchForLastChar:
+        while (true) {
+            while (i >= min && source.charAt(i) != strLastChar) {
+                i--;
+            }
+            if (i < min) {
+                return -1;
+            }
+            int j = i - 1;
+            int start = j - (targetLength - 1);
+            int k = strLastIndex - 1;
+
+            while (j > start) {
+                if (source.charAt(j--) != target.charAt(k--)) {
+                    i--;
+                    continue startSearchForLastChar;
+                }
+            }
+            return start + 1;
+        }
+    }
+    // END Android-added: Private static lastIndexOf method that takes String parameters.
+
+    /**
+     * Code shared by String and AbstractStringBuilder to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+            String target, int fromIndex) {
+        return lastIndexOf(source, sourceOffset, sourceCount,
+                       target.toCharArray(), 0, target.length(),
+                       fromIndex);
+    }
+
+    /**
+     * Code shared by String and StringBuffer to do searches. The
+     * source is the character array being searched, and the target
+     * is the string being searched for.
+     *
+     * @param   source       the characters being searched.
+     * @param   sourceOffset offset of the source string.
+     * @param   sourceCount  count of the source string.
+     * @param   target       the characters being searched for.
+     * @param   targetOffset offset of the target string.
+     * @param   targetCount  count of the target string.
+     * @param   fromIndex    the index to begin searching from.
+     */
+    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+            char[] target, int targetOffset, int targetCount,
+            int fromIndex) {
+        /*
+         * Check arguments; return immediately where possible. For
+         * consistency, don't check for null str.
+         */
+        int rightIndex = sourceCount - targetCount;
+        if (fromIndex < 0) {
+            return -1;
+        }
+        if (fromIndex > rightIndex) {
+            fromIndex = rightIndex;
+        }
+        /* Empty string always matches. */
+        if (targetCount == 0) {
+            return fromIndex;
+        }
+
+        int strLastIndex = targetOffset + targetCount - 1;
+        char strLastChar = target[strLastIndex];
+        int min = sourceOffset + targetCount - 1;
+        int i = min + fromIndex;
+
+    startSearchForLastChar:
+        while (true) {
+            while (i >= min && source[i] != strLastChar) {
+                i--;
+            }
+            if (i < min) {
+                return -1;
+            }
+            int j = i - 1;
+            int start = j - (targetCount - 1);
+            int k = strLastIndex - 1;
+
+            while (j > start) {
+                if (source[j--] != target[k--]) {
+                    i--;
+                    continue startSearchForLastChar;
+                }
+            }
+            return start - sourceOffset + 1;
+        }
+    }
+
+    /**
+     * Returns a string that is a substring of this string. The
+     * substring begins with the character at the specified index and
+     * extends to the end of this string. <p>
+     * Examples:
+     * <blockquote><pre>
+     * "unhappy".substring(2) returns "happy"
+     * "Harbison".substring(3) returns "bison"
+     * "emptiness".substring(9) returns "" (an empty string)
+     * </pre></blockquote>
+     *
+     * @param      beginIndex   the beginning index, inclusive.
+     * @return     the specified substring.
+     * @exception  IndexOutOfBoundsException  if
+     *             {@code beginIndex} is negative or larger than the
+     *             length of this {@code String} object.
+     */
+    public String substring(int beginIndex) {
+        if (beginIndex < 0) {
+            throw new StringIndexOutOfBoundsException(this, beginIndex);
+        }
+        int subLen = length() - beginIndex;
+        if (subLen < 0) {
+            throw new StringIndexOutOfBoundsException(this, beginIndex);
+        }
+        // Android-changed: Use native fastSubstring instead of String constructor.
+        return (beginIndex == 0) ? this : fastSubstring(beginIndex, subLen);
+    }
+
+    /**
+     * Returns a string that is a substring of this string. The
+     * substring begins at the specified {@code beginIndex} and
+     * extends to the character at index {@code endIndex - 1}.
+     * Thus the length of the substring is {@code endIndex-beginIndex}.
+     * <p>
+     * Examples:
+     * <blockquote><pre>
+     * "hamburger".substring(4, 8) returns "urge"
+     * "smiles".substring(1, 5) returns "mile"
+     * </pre></blockquote>
+     *
+     * @param      beginIndex   the beginning index, inclusive.
+     * @param      endIndex     the ending index, exclusive.
+     * @return     the specified substring.
+     * @exception  IndexOutOfBoundsException  if the
+     *             {@code beginIndex} is negative, or
+     *             {@code endIndex} is larger than the length of
+     *             this {@code String} object, or
+     *             {@code beginIndex} is larger than
+     *             {@code endIndex}.
+     */
+    public String substring(int beginIndex, int endIndex) {
+        if (beginIndex < 0) {
+            throw new StringIndexOutOfBoundsException(this, beginIndex);
+        }
+        if (endIndex > length()) {
+            throw new StringIndexOutOfBoundsException(this, endIndex);
+        }
+        int subLen = endIndex - beginIndex;
+        if (subLen < 0) {
+            throw new StringIndexOutOfBoundsException(subLen);
+        }
+
+        // Android-changed: Use native fastSubstring instead of String constructor.
+        return ((beginIndex == 0) && (endIndex == length())) ? this
+                : fastSubstring(beginIndex, subLen);
+    }
+
+    // BEGIN Android-added: Native method to access char storage managed by runtime.
+    @FastNative
+    private native String fastSubstring(int start, int length);
+    // END Android-added: Native method to access char storage managed by runtime.
+
+    /**
+     * Returns a character sequence that is a subsequence of this sequence.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <blockquote><pre>
+     * str.subSequence(begin,&nbsp;end)</pre></blockquote>
+     *
+     * behaves in exactly the same way as the invocation
+     *
+     * <blockquote><pre>
+     * str.substring(begin,&nbsp;end)</pre></blockquote>
+     *
+     * @apiNote
+     * This method is defined so that the {@code String} class can implement
+     * the {@link CharSequence} interface.
+     *
+     * @param   beginIndex   the begin index, inclusive.
+     * @param   endIndex     the end index, exclusive.
+     * @return  the specified subsequence.
+     *
+     * @throws  IndexOutOfBoundsException
+     *          if {@code beginIndex} or {@code endIndex} is negative,
+     *          if {@code endIndex} is greater than {@code length()},
+     *          or if {@code beginIndex} is greater than {@code endIndex}
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public CharSequence subSequence(int beginIndex, int endIndex) {
+        return this.substring(beginIndex, endIndex);
+    }
+
+    /**
+     * Concatenates the specified string to the end of this string.
+     * <p>
+     * If the length of the argument string is {@code 0}, then this
+     * {@code String} object is returned. Otherwise, a
+     * {@code String} object is returned that represents a character
+     * sequence that is the concatenation of the character sequence
+     * represented by this {@code String} object and the character
+     * sequence represented by the argument string.<p>
+     * Examples:
+     * <blockquote><pre>
+     * "cares".concat("s") returns "caress"
+     * "to".concat("get").concat("her") returns "together"
+     * </pre></blockquote>
+     *
+     * @param   str   the {@code String} that is concatenated to the end
+     *                of this {@code String}.
+     * @return  a string that represents the concatenation of this object's
+     *          characters followed by the string argument's characters.
+     */
+    // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+    @FastNative
+    public native String concat(String str);
+    // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+    /**
+     * Returns a string resulting from replacing all occurrences of
+     * {@code oldChar} in this string with {@code newChar}.
+     * <p>
+     * If the character {@code oldChar} does not occur in the
+     * character sequence represented by this {@code String} object,
+     * then a reference to this {@code String} object is returned.
+     * Otherwise, a {@code String} object is returned that
+     * represents a character sequence identical to the character sequence
+     * represented by this {@code String} object, except that every
+     * occurrence of {@code oldChar} is replaced by an occurrence
+     * of {@code newChar}.
+     * <p>
+     * Examples:
+     * <blockquote><pre>
+     * "mesquite in your cellar".replace('e', 'o')
+     *         returns "mosquito in your collar"
+     * "the war of baronets".replace('r', 'y')
+     *         returns "the way of bayonets"
+     * "sparring with a purple porpoise".replace('p', 't')
+     *         returns "starring with a turtle tortoise"
+     * "JonL".replace('q', 'x') returns "JonL" (no change)
+     * </pre></blockquote>
+     *
+     * @param   oldChar   the old character.
+     * @param   newChar   the new character.
+     * @return  a string derived from this string by replacing every
+     *          occurrence of {@code oldChar} with {@code newChar}.
+     */
+    public String replace(char oldChar, char newChar) {
+        // BEGIN Android-changed: Replace with implementation using native doReplace method.
+        if (oldChar != newChar) {
+            final int len = length();
+            for (int i = 0; i < len; ++i) {
+                if (charAt(i) == oldChar) {
+                    return doReplace(oldChar, newChar);
+                }
+            }
+        }
+        // END Android-changed: Replace with implementation using native doReplace method.
+        return this;
+    }
+
+    // BEGIN Android-added: Native method to access char storage managed by runtime.
+    // Implementation of replace(char oldChar, char newChar) called when we found a match.
+    @FastNative
+    private native String doReplace(char oldChar, char newChar);
+    // END Android-added: Native method to access char storage managed by runtime.
+
+    /**
+     * Tells whether or not this string matches the given <a
+     * href="../util/regex/Pattern.html#sum">regular expression</a>.
+     *
+     * <p> An invocation of this method of the form
+     * <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the
+     * same result as the expression
+     *
+     * <blockquote>
+     * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence)
+     * matches(<i>regex</i>, <i>str</i>)}
+     * </blockquote>
+     *
+     * @param   regex
+     *          the regular expression to which this string is to be matched
+     *
+     * @return  {@code true} if, and only if, this string matches the
+     *          given regular expression
+     *
+     * @throws  PatternSyntaxException
+     *          if the regular expression's syntax is invalid
+     *
+     * @see java.util.regex.Pattern
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public boolean matches(String regex) {
+        return Pattern.matches(regex, this);
+    }
+
+    /**
+     * Returns true if and only if this string contains the specified
+     * sequence of char values.
+     *
+     * @param s the sequence to search for
+     * @return true if this string contains {@code s}, false otherwise
+     * @since 1.5
+     */
+    public boolean contains(CharSequence s) {
+        return indexOf(s.toString()) > -1;
+    }
+
+    /**
+     * Replaces the first substring of this string that matches the given <a
+     * href="../util/regex/Pattern.html#sum">regular expression</a> with the
+     * given replacement.
+     *
+     * <p> An invocation of this method of the form
+     * <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
+     * yields exactly the same result as the expression
+     *
+     * <blockquote>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+     * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
+     * </code>
+     * </blockquote>
+     *
+     *<p>
+     * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
+     * replacement string may cause the results to be different than if it were
+     * being treated as a literal replacement string; see
+     * {@link java.util.regex.Matcher#replaceFirst}.
+     * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special
+     * meaning of these characters, if desired.
+     *
+     * @param   regex
+     *          the regular expression to which this string is to be matched
+     * @param   replacement
+     *          the string to be substituted for the first match
+     *
+     * @return  The resulting {@code String}
+     *
+     * @throws  PatternSyntaxException
+     *          if the regular expression's syntax is invalid
+     *
+     * @see java.util.regex.Pattern
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public String replaceFirst(String regex, String replacement) {
+        return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
+    }
+
+    /**
+     * Replaces each substring of this string that matches the given <a
+     * href="../util/regex/Pattern.html#sum">regular expression</a> with the
+     * given replacement.
+     *
+     * <p> An invocation of this method of the form
+     * <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
+     * yields exactly the same result as the expression
+     *
+     * <blockquote>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+     * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
+     * </code>
+     * </blockquote>
+     *
+     *<p>
+     * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
+     * replacement string may cause the results to be different than if it were
+     * being treated as a literal replacement string; see
+     * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
+     * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special
+     * meaning of these characters, if desired.
+     *
+     * @param   regex
+     *          the regular expression to which this string is to be matched
+     * @param   replacement
+     *          the string to be substituted for each match
+     *
+     * @return  The resulting {@code String}
+     *
+     * @throws  PatternSyntaxException
+     *          if the regular expression's syntax is invalid
+     *
+     * @see java.util.regex.Pattern
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public String replaceAll(String regex, String replacement) {
+        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
+    }
+
+    /**
+     * Replaces each substring of this string that matches the literal target
+     * sequence with the specified literal replacement sequence. The
+     * replacement proceeds from the beginning of the string to the end, for
+     * example, replacing "aa" with "b" in the string "aaa" will result in
+     * "ba" rather than "ab".
+     *
+     * @param  target The sequence of char values to be replaced
+     * @param  replacement The replacement sequence of char values
+     * @return  The resulting string
+     * @since 1.5
+     */
+    public String replace(CharSequence target, CharSequence replacement) {
+        // BEGIN Android-changed: Replace regex-based implementation with a bespoke one.
+        if (target == null) {
+            throw new NullPointerException("target == null");
+        }
+
+        if (replacement == null) {
+            throw new NullPointerException("replacement == null");
+        }
+
+        String replacementStr = replacement.toString();
+        String targetStr = target.toString();
+
+        // Special case when target == "". This is a pretty nonsensical transformation and nobody
+        // should be hitting this.
+        //
+        // See commit 870b23b3febc85 and http://code.google.com/p/android/issues/detail?id=8807
+        // An empty target is inserted at the start of the string, the end of the string and
+        // between all characters.
+        final int len = length();
+        if (targetStr.isEmpty()) {
+            // Note that overallocates by |replacement.size()| if |this| is the empty string, but
+            // that should be a rare case within an already nonsensical case.
+            StringBuilder sb = new StringBuilder(replacementStr.length() * (len + 2) + len);
+            sb.append(replacementStr);
+            for (int i = 0; i < len; ++i) {
+                sb.append(charAt(i));
+                sb.append(replacementStr);
+            }
+
+            return sb.toString();
+        }
+
+        // This is the "regular" case.
+        int lastMatch = 0;
+        StringBuilder sb = null;
+        for (;;) {
+            int currentMatch = indexOf(this, targetStr, lastMatch);
+            if (currentMatch == -1) {
+                break;
+            }
+
+            if (sb == null) {
+                sb = new StringBuilder(len);
+            }
+
+            sb.append(this, lastMatch, currentMatch);
+            sb.append(replacementStr);
+            lastMatch = currentMatch + targetStr.length();
+        }
+
+        if (sb != null) {
+            sb.append(this, lastMatch, len);
+            return sb.toString();
+        } else {
+            return this;
+        }
+        // END Android-changed: Replace regex-based implementation with a bespoke one.
+    }
+
+    /**
+     * Splits this string around matches of the given
+     * <a href="../util/regex/Pattern.html#sum">regular expression</a>.
+     *
+     * <p> The array returned by this method contains each substring of this
+     * string that is terminated by another substring that matches the given
+     * expression or is terminated by the end of the string.  The substrings in
+     * the array are in the order in which they occur in this string.  If the
+     * expression does not match any part of the input then the resulting array
+     * has just one element, namely this string.
+     *
+     * <p> When there is a positive-width match at the beginning of this
+     * string then an empty leading substring is included at the beginning
+     * of the resulting array. A zero-width match at the beginning however
+     * never produces such empty leading substring.
+     *
+     * <p> The {@code limit} parameter controls the number of times the
+     * pattern is applied and therefore affects the length of the resulting
+     * array.  If the limit <i>n</i> is greater than zero then the pattern
+     * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
+     * length will be no greater than <i>n</i>, and the array's last entry
+     * will contain all input beyond the last matched delimiter.  If <i>n</i>
+     * is non-positive then the pattern will be applied as many times as
+     * possible and the array can have any length.  If <i>n</i> is zero then
+     * the pattern will be applied as many times as possible, the array can
+     * have any length, and trailing empty strings will be discarded.
+     *
+     * <p> The string {@code "boo:and:foo"}, for example, yields the
+     * following results with these parameters:
+     *
+     * <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
+     * <tr>
+     *     <th>Regex</th>
+     *     <th>Limit</th>
+     *     <th>Result</th>
+     * </tr>
+     * <tr><td align=center>:</td>
+     *     <td align=center>2</td>
+     *     <td>{@code { "boo", "and:foo" }}</td></tr>
+     * <tr><td align=center>:</td>
+     *     <td align=center>5</td>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
+     * <tr><td align=center>:</td>
+     *     <td align=center>-2</td>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
+     * <tr><td align=center>o</td>
+     *     <td align=center>5</td>
+     *     <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
+     * <tr><td align=center>o</td>
+     *     <td align=center>-2</td>
+     *     <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
+     * <tr><td align=center>o</td>
+     *     <td align=center>0</td>
+     *     <td>{@code { "b", "", ":and:f" }}</td></tr>
+     * </table></blockquote>
+     *
+     * <p> An invocation of this method of the form
+     * <i>str.</i>{@code split(}<i>regex</i>{@code ,}&nbsp;<i>n</i>{@code )}
+     * yields the same result as the expression
+     *
+     * <blockquote>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>,&nbsp;<i>n</i>)
+     * </code>
+     * </blockquote>
+     *
+     *
+     * @param  regex
+     *         the delimiting regular expression
+     *
+     * @param  limit
+     *         the result threshold, as described above
+     *
+     * @return  the array of strings computed by splitting this string
+     *          around matches of the given regular expression
+     *
+     * @throws  PatternSyntaxException
+     *          if the regular expression's syntax is invalid
+     *
+     * @see java.util.regex.Pattern
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public String[] split(String regex, int limit) {
+        // BEGIN Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method.
+        // Try fast splitting without allocating Pattern object
+        String[] fast = Pattern.fastSplit(regex, this, limit);
+        if (fast != null) {
+            return fast;
+        }
+        // END Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method.
+        return Pattern.compile(regex).split(this, limit);
+    }
+
+    /**
+     * Splits this string around matches of the given <a
+     * href="../util/regex/Pattern.html#sum">regular expression</a>.
+     *
+     * <p> This method works as if by invoking the two-argument {@link
+     * #split(String, int) split} method with the given expression and a limit
+     * argument of zero.  Trailing empty strings are therefore not included in
+     * the resulting array.
+     *
+     * <p> The string {@code "boo:and:foo"}, for example, yields the following
+     * results with these expressions:
+     *
+     * <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
+     * <tr>
+     *  <th>Regex</th>
+     *  <th>Result</th>
+     * </tr>
+     * <tr><td align=center>:</td>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
+     * <tr><td align=center>o</td>
+     *     <td>{@code { "b", "", ":and:f" }}</td></tr>
+     * </table></blockquote>
+     *
+     *
+     * @param  regex
+     *         the delimiting regular expression
+     *
+     * @return  the array of strings computed by splitting this string
+     *          around matches of the given regular expression
+     *
+     * @throws  PatternSyntaxException
+     *          if the regular expression's syntax is invalid
+     *
+     * @see java.util.regex.Pattern
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public String[] split(String regex) {
+        return split(regex, 0);
+    }
+
+    /**
+     * Returns a new String composed of copies of the
+     * {@code CharSequence elements} joined together with a copy of
+     * the specified {@code delimiter}.
+     *
+     * <blockquote>For example,
+     * <pre>{@code
+     *     String message = String.join("-", "Java", "is", "cool");
+     *     // message returned is: "Java-is-cool"
+     * }</pre></blockquote>
+     *
+     * Note that if an element is null, then {@code "null"} is added.
+     *
+     * @param  delimiter the delimiter that separates each element
+     * @param  elements the elements to join together.
+     *
+     * @return a new {@code String} that is composed of the {@code elements}
+     *         separated by the {@code delimiter}
+     *
+     * @throws NullPointerException If {@code delimiter} or {@code elements}
+     *         is {@code null}
+     *
+     * @see java.util.StringJoiner
+     * @since 1.8
+     */
+    public static String join(CharSequence delimiter, CharSequence... elements) {
+        Objects.requireNonNull(delimiter);
+        Objects.requireNonNull(elements);
+        // Number of elements not likely worth Arrays.stream overhead.
+        StringJoiner joiner = new StringJoiner(delimiter);
+        for (CharSequence cs: elements) {
+            joiner.add(cs);
+        }
+        return joiner.toString();
+    }
+
+    /**
+     * Returns a new {@code String} composed of copies of the
+     * {@code CharSequence elements} joined together with a copy of the
+     * specified {@code delimiter}.
+     *
+     * <blockquote>For example,
+     * <pre>{@code
+     *     List<String> strings = new LinkedList<>();
+     *     strings.add("Java");strings.add("is");
+     *     strings.add("cool");
+     *     String message = String.join(" ", strings);
+     *     //message returned is: "Java is cool"
+     *
+     *     Set<String> strings = new LinkedHashSet<>();
+     *     strings.add("Java"); strings.add("is");
+     *     strings.add("very"); strings.add("cool");
+     *     String message = String.join("-", strings);
+     *     //message returned is: "Java-is-very-cool"
+     * }</pre></blockquote>
+     *
+     * Note that if an individual element is {@code null}, then {@code "null"} is added.
+     *
+     * @param  delimiter a sequence of characters that is used to separate each
+     *         of the {@code elements} in the resulting {@code String}
+     * @param  elements an {@code Iterable} that will have its {@code elements}
+     *         joined together.
+     *
+     * @return a new {@code String} that is composed from the {@code elements}
+     *         argument
+     *
+     * @throws NullPointerException If {@code delimiter} or {@code elements}
+     *         is {@code null}
+     *
+     * @see    #join(CharSequence,CharSequence...)
+     * @see    java.util.StringJoiner
+     * @since 1.8
+     */
+    public static String join(CharSequence delimiter,
+            Iterable<? extends CharSequence> elements) {
+        Objects.requireNonNull(delimiter);
+        Objects.requireNonNull(elements);
+        StringJoiner joiner = new StringJoiner(delimiter);
+        for (CharSequence cs: elements) {
+            joiner.add(cs);
+        }
+        return joiner.toString();
+    }
+
+    /**
+     * Converts all of the characters in this {@code String} to lower
+     * case using the rules of the given {@code Locale}.  Case mapping is based
+     * on the Unicode Standard version specified by the {@link java.lang.Character Character}
+     * class. Since case mappings are not always 1:1 char mappings, the resulting
+     * {@code String} may be a different length than the original {@code String}.
+     * <p>
+     * Examples of lowercase  mappings are in the following table:
+     * <table border="1" summary="Lowercase mapping examples showing language code of locale, upper case, lower case, and description">
+     * <tr>
+     *   <th>Language Code of Locale</th>
+     *   <th>Upper Case</th>
+     *   <th>Lower Case</th>
+     *   <th>Description</th>
+     * </tr>
+     * <tr>
+     *   <td>tr (Turkish)</td>
+     *   <td>&#92;u0130</td>
+     *   <td>&#92;u0069</td>
+     *   <td>capital letter I with dot above -&gt; small letter i</td>
+     * </tr>
+     * <tr>
+     *   <td>tr (Turkish)</td>
+     *   <td>&#92;u0049</td>
+     *   <td>&#92;u0131</td>
+     *   <td>capital letter I -&gt; small letter dotless i </td>
+     * </tr>
+     * <tr>
+     *   <td>(all)</td>
+     *   <td>French Fries</td>
+     *   <td>french fries</td>
+     *   <td>lowercased all chars in String</td>
+     * </tr>
+     * <tr>
+     *   <td>(all)</td>
+     *   <td><img src="doc-files/capiota.gif" alt="capiota"><img src="doc-files/capchi.gif" alt="capchi">
+     *       <img src="doc-files/captheta.gif" alt="captheta"><img src="doc-files/capupsil.gif" alt="capupsil">
+     *       <img src="doc-files/capsigma.gif" alt="capsigma"></td>
+     *   <td><img src="doc-files/iota.gif" alt="iota"><img src="doc-files/chi.gif" alt="chi">
+     *       <img src="doc-files/theta.gif" alt="theta"><img src="doc-files/upsilon.gif" alt="upsilon">
+     *       <img src="doc-files/sigma1.gif" alt="sigma"></td>
+     *   <td>lowercased all chars in String</td>
+     * </tr>
+     * </table>
+     *
+     * @param locale use the case transformation rules for this locale
+     * @return the {@code String}, converted to lowercase.
+     * @see     java.lang.String#toLowerCase()
+     * @see     java.lang.String#toUpperCase()
+     * @see     java.lang.String#toUpperCase(Locale)
+     * @since   1.1
+     */
+    public String toLowerCase(Locale locale) {
+        // Android-changed: Replace custom code with call to new CaseMapper class.
+        return CaseMapper.toLowerCase(locale, this);
+    }
+
+    /**
+     * Converts all of the characters in this {@code String} to lower
+     * case using the rules of the default locale. This is equivalent to calling
+     * {@code toLowerCase(Locale.getDefault())}.
+     * <p>
+     * <b>Note:</b> This method is locale sensitive, and may produce unexpected
+     * results if used for strings that are intended to be interpreted locale
+     * independently.
+     * Examples are programming language identifiers, protocol keys, and HTML
+     * tags.
+     * For instance, {@code "TITLE".toLowerCase()} in a Turkish locale
+     * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the
+     * LATIN SMALL LETTER DOTLESS I character.
+     * To obtain correct results for locale insensitive strings, use
+     * {@code toLowerCase(Locale.ROOT)}.
+     * <p>
+     * @return  the {@code String}, converted to lowercase.
+     * @see     java.lang.String#toLowerCase(Locale)
+     */
+    public String toLowerCase() {
+        return toLowerCase(Locale.getDefault());
+    }
+
+    /**
+     * Converts all of the characters in this {@code String} to upper
+     * case using the rules of the given {@code Locale}. Case mapping is based
+     * on the Unicode Standard version specified by the {@link java.lang.Character Character}
+     * class. Since case mappings are not always 1:1 char mappings, the resulting
+     * {@code String} may be a different length than the original {@code String}.
+     * <p>
+     * Examples of locale-sensitive and 1:M case mappings are in the following table.
+     *
+     * <table border="1" summary="Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description.">
+     * <tr>
+     *   <th>Language Code of Locale</th>
+     *   <th>Lower Case</th>
+     *   <th>Upper Case</th>
+     *   <th>Description</th>
+     * </tr>
+     * <tr>
+     *   <td>tr (Turkish)</td>
+     *   <td>&#92;u0069</td>
+     *   <td>&#92;u0130</td>
+     *   <td>small letter i -&gt; capital letter I with dot above</td>
+     * </tr>
+     * <tr>
+     *   <td>tr (Turkish)</td>
+     *   <td>&#92;u0131</td>
+     *   <td>&#92;u0049</td>
+     *   <td>small letter dotless i -&gt; capital letter I</td>
+     * </tr>
+     * <tr>
+     *   <td>(all)</td>
+     *   <td>&#92;u00df</td>
+     *   <td>&#92;u0053 &#92;u0053</td>
+     *   <td>small letter sharp s -&gt; two letters: SS</td>
+     * </tr>
+     * <tr>
+     *   <td>(all)</td>
+     *   <td>Fahrvergn&uuml;gen</td>
+     *   <td>FAHRVERGN&Uuml;GEN</td>
+     *   <td></td>
+     * </tr>
+     * </table>
+     * @param locale use the case transformation rules for this locale
+     * @return the {@code String}, converted to uppercase.
+     * @see     java.lang.String#toUpperCase()
+     * @see     java.lang.String#toLowerCase()
+     * @see     java.lang.String#toLowerCase(Locale)
+     * @since   1.1
+     */
+    public String toUpperCase(Locale locale) {
+        // Android-changed: Replace custom code with call to new CaseMapper class.
+        return CaseMapper.toUpperCase(locale, this, length());
+    }
+
+    /**
+     * Converts all of the characters in this {@code String} to upper
+     * case using the rules of the default locale. This method is equivalent to
+     * {@code toUpperCase(Locale.getDefault())}.
+     * <p>
+     * <b>Note:</b> This method is locale sensitive, and may produce unexpected
+     * results if used for strings that are intended to be interpreted locale
+     * independently.
+     * Examples are programming language identifiers, protocol keys, and HTML
+     * tags.
+     * For instance, {@code "title".toUpperCase()} in a Turkish locale
+     * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the
+     * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
+     * To obtain correct results for locale insensitive strings, use
+     * {@code toUpperCase(Locale.ROOT)}.
+     * <p>
+     * @return  the {@code String}, converted to uppercase.
+     * @see     java.lang.String#toUpperCase(Locale)
+     */
+    public String toUpperCase() {
+        return toUpperCase(Locale.getDefault());
+    }
+
+    /**
+     * Returns a string whose value is this string, with any leading and trailing
+     * whitespace removed.
+     * <p>
+     * If this {@code String} object represents an empty character
+     * sequence, or the first and last characters of character sequence
+     * represented by this {@code String} object both have codes
+     * greater than {@code '\u005Cu0020'} (the space character), then a
+     * reference to this {@code String} object is returned.
+     * <p>
+     * Otherwise, if there is no character with a code greater than
+     * {@code '\u005Cu0020'} in the string, then a
+     * {@code String} object representing an empty string is
+     * returned.
+     * <p>
+     * Otherwise, let <i>k</i> be the index of the first character in the
+     * string whose code is greater than {@code '\u005Cu0020'}, and let
+     * <i>m</i> be the index of the last character in the string whose code
+     * is greater than {@code '\u005Cu0020'}. A {@code String}
+     * object is returned, representing the substring of this string that
+     * begins with the character at index <i>k</i> and ends with the
+     * character at index <i>m</i>-that is, the result of
+     * {@code this.substring(k, m + 1)}.
+     * <p>
+     * This method may be used to trim whitespace (as defined above) from
+     * the beginning and end of a string.
+     *
+     * @return  A string whose value is this string, with any leading and trailing white
+     *          space removed, or this string if it has no leading or
+     *          trailing white space.
+     */
+    public String trim() {
+        int len = length();
+        int st = 0;
+
+        while ((st < len) && (charAt(st) <= ' ')) {
+            st++;
+        }
+        while ((st < len) && (charAt(len - 1) <= ' ')) {
+            len--;
+        }
+        return ((st > 0) || (len < length())) ? substring(st, len) : this;
+    }
+
+    /**
+     * This object (which is already a string!) is itself returned.
+     *
+     * @return  the string itself.
+     */
+    public String toString() {
+        return this;
+    }
+
+    /**
+     * Converts this string to a new character array.
+     *
+     * @return  a newly allocated character array whose length is the length
+     *          of this string and whose contents are initialized to contain
+     *          the character sequence represented by this string.
+     */
+    // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+    @FastNative
+    public native char[] toCharArray();
+    // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+
+    /**
+     * Returns a formatted string using the specified format string and
+     * arguments.
+     *
+     * <p> The locale always used is the one returned by {@link
+     * java.util.Locale#getDefault() Locale.getDefault()}.
+     *
+     * @param  format
+     *         A <a href="../util/Formatter.html#syntax">format string</a>
+     *
+     * @param  args
+     *         Arguments referenced by the format specifiers in the format
+     *         string.  If there are more arguments than format specifiers, the
+     *         extra arguments are ignored.  The number of arguments is
+     *         variable and may be zero.  The maximum number of arguments is
+     *         limited by the maximum dimension of a Java array as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *         The behaviour on a
+     *         {@code null} argument depends on the <a
+     *         href="../util/Formatter.html#syntax">conversion</a>.
+     *
+     * @throws  java.util.IllegalFormatException
+     *          If a format string contains an illegal syntax, a format
+     *          specifier that is incompatible with the given arguments,
+     *          insufficient arguments given the format string, or other
+     *          illegal conditions.  For specification of all possible
+     *          formatting errors, see the <a
+     *          href="../util/Formatter.html#detail">Details</a> section of the
+     *          formatter class specification.
+     *
+     * @return  A formatted string
+     *
+     * @see  java.util.Formatter
+     * @since  1.5
+     */
+    public static String format(String format, Object... args) {
+        return new Formatter().format(format, args).toString();
+    }
+
+    /**
+     * Returns a formatted string using the specified locale, format string,
+     * and arguments.
+     *
+     * @param  l
+     *         The {@linkplain java.util.Locale locale} to apply during
+     *         formatting.  If {@code l} is {@code null} then no localization
+     *         is applied.
+     *
+     * @param  format
+     *         A <a href="../util/Formatter.html#syntax">format string</a>
+     *
+     * @param  args
+     *         Arguments referenced by the format specifiers in the format
+     *         string.  If there are more arguments than format specifiers, the
+     *         extra arguments are ignored.  The number of arguments is
+     *         variable and may be zero.  The maximum number of arguments is
+     *         limited by the maximum dimension of a Java array as defined by
+     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
+     *         The behaviour on a
+     *         {@code null} argument depends on the
+     *         <a href="../util/Formatter.html#syntax">conversion</a>.
+     *
+     * @throws  java.util.IllegalFormatException
+     *          If a format string contains an illegal syntax, a format
+     *          specifier that is incompatible with the given arguments,
+     *          insufficient arguments given the format string, or other
+     *          illegal conditions.  For specification of all possible
+     *          formatting errors, see the <a
+     *          href="../util/Formatter.html#detail">Details</a> section of the
+     *          formatter class specification
+     *
+     * @return  A formatted string
+     *
+     * @see  java.util.Formatter
+     * @since  1.5
+     */
+    public static String format(Locale l, String format, Object... args) {
+        return new Formatter(l).format(format, args).toString();
+    }
+
+    /**
+     * Returns the string representation of the {@code Object} argument.
+     *
+     * @param   obj   an {@code Object}.
+     * @return  if the argument is {@code null}, then a string equal to
+     *          {@code "null"}; otherwise, the value of
+     *          {@code obj.toString()} is returned.
+     * @see     java.lang.Object#toString()
+     */
+    public static String valueOf(Object obj) {
+        return (obj == null) ? "null" : obj.toString();
+    }
+
+    /**
+     * Returns the string representation of the {@code char} array
+     * argument. The contents of the character array are copied; subsequent
+     * modification of the character array does not affect the returned
+     * string.
+     *
+     * @param   data     the character array.
+     * @return  a {@code String} that contains the characters of the
+     *          character array.
+     */
+    public static String valueOf(char data[]) {
+        return new String(data);
+    }
+
+    /**
+     * Returns the string representation of a specific subarray of the
+     * {@code char} array argument.
+     * <p>
+     * The {@code offset} argument is the index of the first
+     * character of the subarray. The {@code count} argument
+     * specifies the length of the subarray. The contents of the subarray
+     * are copied; subsequent modification of the character array does not
+     * affect the returned string.
+     *
+     * @param   data     the character array.
+     * @param   offset   initial offset of the subarray.
+     * @param   count    length of the subarray.
+     * @return  a {@code String} that contains the characters of the
+     *          specified subarray of the character array.
+     * @exception IndexOutOfBoundsException if {@code offset} is
+     *          negative, or {@code count} is negative, or
+     *          {@code offset+count} is larger than
+     *          {@code data.length}.
+     */
+    public static String valueOf(char data[], int offset, int count) {
+        return new String(data, offset, count);
+    }
+
+    /**
+     * Equivalent to {@link #valueOf(char[], int, int)}.
+     *
+     * @param   data     the character array.
+     * @param   offset   initial offset of the subarray.
+     * @param   count    length of the subarray.
+     * @return  a {@code String} that contains the characters of the
+     *          specified subarray of the character array.
+     * @exception IndexOutOfBoundsException if {@code offset} is
+     *          negative, or {@code count} is negative, or
+     *          {@code offset+count} is larger than
+     *          {@code data.length}.
+     */
+    public static String copyValueOf(char data[], int offset, int count) {
+        return new String(data, offset, count);
+    }
+
+    /**
+     * Equivalent to {@link #valueOf(char[])}.
+     *
+     * @param   data   the character array.
+     * @return  a {@code String} that contains the characters of the
+     *          character array.
+     */
+    public static String copyValueOf(char data[]) {
+        return new String(data);
+    }
+
+    /**
+     * Returns the string representation of the {@code boolean} argument.
+     *
+     * @param   b   a {@code boolean}.
+     * @return  if the argument is {@code true}, a string equal to
+     *          {@code "true"} is returned; otherwise, a string equal to
+     *          {@code "false"} is returned.
+     */
+    public static String valueOf(boolean b) {
+        return b ? "true" : "false";
+    }
+
+    /**
+     * Returns the string representation of the {@code char}
+     * argument.
+     *
+     * @param   c   a {@code char}.
+     * @return  a string of length {@code 1} containing
+     *          as its single character the argument {@code c}.
+     */
+    public static String valueOf(char c) {
+        // Android-changed: Replace constructor call with call to StringFactory class.
+        // There is currently no String(char[], boolean) on Android to call. http://b/79902155
+        // char data[] = {c};
+        // return new String(data, true);
+        return StringFactory.newStringFromChars(0, 1, new char[] { c });
+    }
+
+    /**
+     * Returns the string representation of the {@code int} argument.
+     * <p>
+     * The representation is exactly the one returned by the
+     * {@code Integer.toString} method of one argument.
+     *
+     * @param   i   an {@code int}.
+     * @return  a string representation of the {@code int} argument.
+     * @see     java.lang.Integer#toString(int, int)
+     */
+    public static String valueOf(int i) {
+        return Integer.toString(i);
+    }
+
+    /**
+     * Returns the string representation of the {@code long} argument.
+     * <p>
+     * The representation is exactly the one returned by the
+     * {@code Long.toString} method of one argument.
+     *
+     * @param   l   a {@code long}.
+     * @return  a string representation of the {@code long} argument.
+     * @see     java.lang.Long#toString(long)
+     */
+    public static String valueOf(long l) {
+        return Long.toString(l);
+    }
+
+    /**
+     * Returns the string representation of the {@code float} argument.
+     * <p>
+     * The representation is exactly the one returned by the
+     * {@code Float.toString} method of one argument.
+     *
+     * @param   f   a {@code float}.
+     * @return  a string representation of the {@code float} argument.
+     * @see     java.lang.Float#toString(float)
+     */
+    public static String valueOf(float f) {
+        return Float.toString(f);
+    }
+
+    /**
+     * Returns the string representation of the {@code double} argument.
+     * <p>
+     * The representation is exactly the one returned by the
+     * {@code Double.toString} method of one argument.
+     *
+     * @param   d   a {@code double}.
+     * @return  a  string representation of the {@code double} argument.
+     * @see     java.lang.Double#toString(double)
+     */
+    public static String valueOf(double d) {
+        return Double.toString(d);
+    }
+
+    /**
+     * Returns a canonical representation for the string object.
+     * <p>
+     * A pool of strings, initially empty, is maintained privately by the
+     * class {@code String}.
+     * <p>
+     * When the intern method is invoked, if the pool already contains a
+     * string equal to this {@code String} object as determined by
+     * the {@link #equals(Object)} method, then the string from the pool is
+     * returned. Otherwise, this {@code String} object is added to the
+     * pool and a reference to this {@code String} object is returned.
+     * <p>
+     * It follows that for any two strings {@code s} and {@code t},
+     * {@code s.intern() == t.intern()} is {@code true}
+     * if and only if {@code s.equals(t)} is {@code true}.
+     * <p>
+     * All literal strings and string-valued constant expressions are
+     * interned. String literals are defined in section 3.10.5 of the
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * @return  a string that has the same contents as this string, but is
+     *          guaranteed to be from a pool of unique strings.
+     */
+    // BEGIN Android-changed: Annotate native method as @FastNative.
+    @FastNative
+    // END Android-changed: Annotate native method as @FastNative.
+    public native String intern();
+}
diff --git a/java/lang/StringBuffer.annotated.java b/java/lang/StringBuffer.annotated.java
new file mode 100644
index 0000000..4baff67
--- /dev/null
+++ b/java/lang/StringBuffer.annotated.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1994, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuffer implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuffer() { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+public synchronized int length() { throw new RuntimeException("Stub!"); }
+
+public synchronized int capacity() { throw new RuntimeException("Stub!"); }
+
+public synchronized void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public synchronized void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public synchronized char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public synchronized int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public synchronized void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(long lng) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer reverse() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/StringBuffer.java b/java/lang/StringBuffer.java
new file mode 100644
index 0000000..6781f11
--- /dev/null
+++ b/java/lang/StringBuffer.java
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 1994, 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;
+
+import java.util.Arrays;
+
+/**
+ * A thread-safe, mutable sequence of characters.
+ * A string buffer is like a {@link String}, but can be modified. At any
+ * point in time it contains some particular sequence of characters, but
+ * the length and content of the sequence can be changed through certain
+ * method calls.
+ * <p>
+ * String buffers are safe for use by multiple threads. The methods
+ * are synchronized where necessary so that all the operations on any
+ * particular instance behave as if they occur in some serial order
+ * that is consistent with the order of the method calls made by each of
+ * the individual threads involved.
+ * <p>
+ * The principal operations on a {@code StringBuffer} are the
+ * {@code append} and {@code insert} methods, which are
+ * overloaded so as to accept data of any type. Each effectively
+ * converts a given datum to a string and then appends or inserts the
+ * characters of that string to the string buffer. The
+ * {@code append} method always adds these characters at the end
+ * of the buffer; the {@code insert} method adds the characters at
+ * a specified point.
+ * <p>
+ * For example, if {@code z} refers to a string buffer object
+ * whose current contents are {@code "start"}, then
+ * the method call {@code z.append("le")} would cause the string
+ * buffer to contain {@code "startle"}, whereas
+ * {@code z.insert(4, "le")} would alter the string buffer to
+ * contain {@code "starlet"}.
+ * <p>
+ * In general, if sb refers to an instance of a {@code StringBuffer},
+ * then {@code sb.append(x)} has the same effect as
+ * {@code sb.insert(sb.length(), x)}.
+ * <p>
+ * Whenever an operation occurs involving a source sequence (such as
+ * appending or inserting from a source sequence), this class synchronizes
+ * only on the string buffer performing the operation, not on the source.
+ * Note that while {@code StringBuffer} is designed to be safe to use
+ * concurrently from multiple threads, if the constructor or the
+ * {@code append} or {@code insert} operation is passed a source sequence
+ * that is shared across threads, the calling code must ensure
+ * that the operation has a consistent and unchanging view of the source
+ * sequence for the duration of the operation.
+ * This could be satisfied by the caller holding a lock during the
+ * operation's call, by using an immutable source sequence, or by not
+ * sharing the source sequence across threads.
+ * <p>
+ * Every string buffer has a capacity. As long as the length of the
+ * character sequence contained in the string buffer does not exceed
+ * the capacity, it is not necessary to allocate a new internal
+ * buffer array. If the internal buffer overflows, it is
+ * automatically made larger.
+ * <p>
+ * Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ * <p>
+ * As of  release JDK 5, this class has been supplemented with an equivalent
+ * class designed for use by a single thread, {@link StringBuilder}.  The
+ * {@code StringBuilder} class should generally be used in preference to
+ * this one, as it supports all of the same operations but it is faster, as
+ * it performs no synchronization.
+ *
+ * @author      Arthur van Hoff
+ * @see     java.lang.StringBuilder
+ * @see     java.lang.String
+ * @since   JDK1.0
+ */
+ public final class StringBuffer
+    extends AbstractStringBuilder
+    implements java.io.Serializable, CharSequence
+{
+
+    /**
+     * A cache of the last value returned by toString. Cleared
+     * whenever the StringBuffer is modified.
+     */
+    private transient char[] toStringCache;
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    static final long serialVersionUID = 3388685877147921107L;
+
+    /**
+     * Constructs a string buffer with no characters in it and an
+     * initial capacity of 16 characters.
+     */
+    public StringBuffer() {
+        super(16);
+    }
+
+    /**
+     * Constructs a string buffer with no characters in it and
+     * the specified initial capacity.
+     *
+     * @param      capacity  the initial capacity.
+     * @exception  NegativeArraySizeException  if the {@code capacity}
+     *               argument is less than {@code 0}.
+     */
+    public StringBuffer(int capacity) {
+        super(capacity);
+    }
+
+    /**
+     * Constructs a string buffer initialized to the contents of the
+     * specified string. The initial capacity of the string buffer is
+     * {@code 16} plus the length of the string argument.
+     *
+     * @param   str   the initial contents of the buffer.
+     */
+    public StringBuffer(String str) {
+        super(str.length() + 16);
+        append(str);
+    }
+
+    /**
+     * Constructs a string buffer that contains the same characters
+     * as the specified {@code CharSequence}. The initial capacity of
+     * the string buffer is {@code 16} plus the length of the
+     * {@code CharSequence} argument.
+     * <p>
+     * If the length of the specified {@code CharSequence} is
+     * less than or equal to zero, then an empty buffer of capacity
+     * {@code 16} is returned.
+     *
+     * @param      seq   the sequence to copy.
+     * @since 1.5
+     */
+    public StringBuffer(CharSequence seq) {
+        this(seq.length() + 16);
+        append(seq);
+    }
+
+    @Override
+    public synchronized int length() {
+        return count;
+    }
+
+    @Override
+    public synchronized int capacity() {
+        return value.length;
+    }
+
+
+    @Override
+    public synchronized void ensureCapacity(int minimumCapacity) {
+        super.ensureCapacity(minimumCapacity);
+    }
+
+    /**
+     * @since      1.5
+     */
+    @Override
+    public synchronized void trimToSize() {
+        super.trimToSize();
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @see        #length()
+     */
+    @Override
+    public synchronized void setLength(int newLength) {
+        toStringCache = null;
+        super.setLength(newLength);
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @see        #length()
+     */
+    @Override
+    public synchronized char charAt(int index) {
+        if ((index < 0) || (index >= count))
+            throw new StringIndexOutOfBoundsException(index);
+        return value[index];
+    }
+
+    /**
+     * @since      1.5
+     */
+    @Override
+    public synchronized int codePointAt(int index) {
+        return super.codePointAt(index);
+    }
+
+    /**
+     * @since     1.5
+     */
+    @Override
+    public synchronized int codePointBefore(int index) {
+        return super.codePointBefore(index);
+    }
+
+    /**
+     * @since     1.5
+     */
+    @Override
+    public synchronized int codePointCount(int beginIndex, int endIndex) {
+        return super.codePointCount(beginIndex, endIndex);
+    }
+
+    /**
+     * @since     1.5
+     */
+    @Override
+    public synchronized int offsetByCodePoints(int index, int codePointOffset) {
+        return super.offsetByCodePoints(index, codePointOffset);
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
+                                      int dstBegin)
+    {
+        super.getChars(srcBegin, srcEnd, dst, dstBegin);
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @see        #length()
+     */
+    @Override
+    public synchronized void setCharAt(int index, char ch) {
+        if ((index < 0) || (index >= count))
+            throw new StringIndexOutOfBoundsException(index);
+        toStringCache = null;
+        value[index] = ch;
+    }
+
+    @Override
+    public synchronized StringBuffer append(Object obj) {
+        toStringCache = null;
+        super.append(String.valueOf(obj));
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(String str) {
+        toStringCache = null;
+        super.append(str);
+        return this;
+    }
+
+    /**
+     * Appends the specified {@code StringBuffer} to this sequence.
+     * <p>
+     * The characters of the {@code StringBuffer} argument are appended,
+     * in order, to the contents of this {@code StringBuffer}, increasing the
+     * length of this {@code StringBuffer} by the length of the argument.
+     * If {@code sb} is {@code null}, then the four characters
+     * {@code "null"} are appended to this {@code StringBuffer}.
+     * <p>
+     * Let <i>n</i> be the length of the old character sequence, the one
+     * contained in the {@code StringBuffer} just prior to execution of the
+     * {@code append} method. Then the character at index <i>k</i> in
+     * the new character sequence is equal to the character at index <i>k</i>
+     * in the old character sequence, if <i>k</i> is less than <i>n</i>;
+     * otherwise, it is equal to the character at index <i>k-n</i> in the
+     * argument {@code sb}.
+     * <p>
+     * This method synchronizes on {@code this}, the destination
+     * object, but does not synchronize on the source ({@code sb}).
+     *
+     * @param   sb   the {@code StringBuffer} to append.
+     * @return  a reference to this object.
+     * @since 1.4
+     */
+    public synchronized StringBuffer append(StringBuffer sb) {
+        toStringCache = null;
+        super.append(sb);
+        return this;
+    }
+
+    /**
+     * @since 1.8
+     */
+    @Override
+    synchronized StringBuffer append(AbstractStringBuilder asb) {
+        toStringCache = null;
+        super.append(asb);
+        return this;
+    }
+
+    /**
+     * Appends the specified {@code CharSequence} to this
+     * sequence.
+     * <p>
+     * The characters of the {@code CharSequence} argument are appended,
+     * in order, increasing the length of this sequence by the length of the
+     * argument.
+     *
+     * <p>The result of this method is exactly the same as if it were an
+     * invocation of this.append(s, 0, s.length());
+     *
+     * <p>This method synchronizes on {@code this}, the destination
+     * object, but does not synchronize on the source ({@code s}).
+     *
+     * <p>If {@code s} is {@code null}, then the four characters
+     * {@code "null"} are appended.
+     *
+     * @param   s the {@code CharSequence} to append.
+     * @return  a reference to this object.
+     * @since 1.5
+     */
+    @Override
+    public synchronized StringBuffer append(CharSequence s) {
+        toStringCache = null;
+        super.append(s);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @since      1.5
+     */
+    @Override
+    public synchronized StringBuffer append(CharSequence s, int start, int end)
+    {
+        toStringCache = null;
+        super.append(s, start, end);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(char[] str) {
+        toStringCache = null;
+        super.append(str);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized StringBuffer append(char[] str, int offset, int len) {
+        toStringCache = null;
+        super.append(str, offset, len);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(boolean b) {
+        toStringCache = null;
+        super.append(b);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(char c) {
+        toStringCache = null;
+        super.append(c);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(int i) {
+        toStringCache = null;
+        super.append(i);
+        return this;
+    }
+
+    /**
+     * @since 1.5
+     */
+    @Override
+    public synchronized StringBuffer appendCodePoint(int codePoint) {
+        toStringCache = null;
+        super.appendCodePoint(codePoint);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(long lng) {
+        toStringCache = null;
+        super.append(lng);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(float f) {
+        toStringCache = null;
+        super.append(f);
+        return this;
+    }
+
+    @Override
+    public synchronized StringBuffer append(double d) {
+        toStringCache = null;
+        super.append(d);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized StringBuffer delete(int start, int end) {
+        toStringCache = null;
+        super.delete(start, end);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized StringBuffer deleteCharAt(int index) {
+        toStringCache = null;
+        super.deleteCharAt(index);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized StringBuffer replace(int start, int end, String str) {
+        toStringCache = null;
+        super.replace(start, end, str);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized String substring(int start) {
+        return substring(start, count);
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @since      1.4
+     */
+    @Override
+    public synchronized CharSequence subSequence(int start, int end) {
+        return super.substring(start, end);
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized String substring(int start, int end) {
+        return super.substring(start, end);
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     * @since      1.2
+     */
+    @Override
+    public synchronized StringBuffer insert(int index, char[] str, int offset,
+                                            int len)
+    {
+        toStringCache = null;
+        super.insert(index, str, offset, len);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized StringBuffer insert(int offset, Object obj) {
+        toStringCache = null;
+        super.insert(offset, String.valueOf(obj));
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized StringBuffer insert(int offset, String str) {
+        toStringCache = null;
+        super.insert(offset, str);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized StringBuffer insert(int offset, char[] str) {
+        toStringCache = null;
+        super.insert(offset, str);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @since      1.5
+     */
+    @Override
+    public StringBuffer insert(int dstOffset, CharSequence s) {
+        // Note, synchronization achieved via invocations of other StringBuffer methods
+        // after narrowing of s to specific type
+        // Ditto for toStringCache clearing
+        super.insert(dstOffset, s);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @since      1.5
+     */
+    @Override
+    public synchronized StringBuffer insert(int dstOffset, CharSequence s,
+            int start, int end)
+    {
+        toStringCache = null;
+        super.insert(dstOffset, s, start, end);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public  StringBuffer insert(int offset, boolean b) {
+        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+        // after conversion of b to String by super class method
+        // Ditto for toStringCache clearing
+        super.insert(offset, b);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public synchronized StringBuffer insert(int offset, char c) {
+        toStringCache = null;
+        super.insert(offset, c);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuffer insert(int offset, int i) {
+        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+        // after conversion of i to String by super class method
+        // Ditto for toStringCache clearing
+        super.insert(offset, i);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuffer insert(int offset, long l) {
+        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+        // after conversion of l to String by super class method
+        // Ditto for toStringCache clearing
+        super.insert(offset, l);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuffer insert(int offset, float f) {
+        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+        // after conversion of f to String by super class method
+        // Ditto for toStringCache clearing
+        super.insert(offset, f);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuffer insert(int offset, double d) {
+        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+        // after conversion of d to String by super class method
+        // Ditto for toStringCache clearing
+        super.insert(offset, d);
+        return this;
+    }
+
+    /**
+     * @since      1.4
+     */
+    @Override
+    public int indexOf(String str) {
+        // Note, synchronization achieved via invocations of other StringBuffer methods
+        return super.indexOf(str);
+    }
+
+    /**
+     * @since      1.4
+     */
+    @Override
+    public synchronized int indexOf(String str, int fromIndex) {
+        return super.indexOf(str, fromIndex);
+    }
+
+    /**
+     * @since      1.4
+     */
+    @Override
+    public int lastIndexOf(String str) {
+        // Note, synchronization achieved via invocations of other StringBuffer methods
+        return lastIndexOf(str, count);
+    }
+
+    /**
+     * @since      1.4
+     */
+    @Override
+    public synchronized int lastIndexOf(String str, int fromIndex) {
+        return super.lastIndexOf(str, fromIndex);
+    }
+
+    /**
+     * @since   JDK1.0.2
+     */
+    @Override
+    public synchronized StringBuffer reverse() {
+        toStringCache = null;
+        super.reverse();
+        return this;
+    }
+
+    @Override
+    public synchronized String toString() {
+        if (toStringCache == null) {
+            toStringCache = Arrays.copyOfRange(value, 0, count);
+        }
+        return new String(toStringCache, 0, count);
+    }
+
+    /**
+     * Serializable fields for StringBuffer.
+     *
+     * @serialField value  char[]
+     *              The backing character array of this StringBuffer.
+     * @serialField count int
+     *              The number of characters in this StringBuffer.
+     * @serialField shared  boolean
+     *              A flag indicating whether the backing array is shared.
+     *              The value is ignored upon deserialization.
+     */
+    private static final java.io.ObjectStreamField[] serialPersistentFields =
+    {
+        new java.io.ObjectStreamField("value", char[].class),
+        new java.io.ObjectStreamField("count", Integer.TYPE),
+        new java.io.ObjectStreamField("shared", Boolean.TYPE),
+    };
+
+    /**
+     * readObject is called to restore the state of the StringBuffer from
+     * a stream.
+     */
+    private synchronized void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+        java.io.ObjectOutputStream.PutField fields = s.putFields();
+        fields.put("value", value);
+        fields.put("count", count);
+        fields.put("shared", false);
+        s.writeFields();
+    }
+
+    /**
+     * readObject is called to restore the state of the StringBuffer from
+     * a stream.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        java.io.ObjectInputStream.GetField fields = s.readFields();
+        value = (char[])fields.get("value", null);
+        count = fields.get("count", 0);
+    }
+}
diff --git a/java/lang/StringBuilder.annotated.java b/java/lang/StringBuilder.annotated.java
new file mode 100644
index 0000000..6fdde8a
--- /dev/null
+++ b/java/lang/StringBuilder.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuilder implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuilder() { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(long lng) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder reverse() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public int capacity() { throw new RuntimeException("Stub!"); }
+
+public void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/StringBuilder.java b/java/lang/StringBuilder.java
new file mode 100644
index 0000000..325c9c5
--- /dev/null
+++ b/java/lang/StringBuilder.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 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;
+
+
+/**
+ * A mutable sequence of characters.  This class provides an API compatible
+ * with {@code StringBuffer}, but with no guarantee of synchronization.
+ * This class is designed for use as a drop-in replacement for
+ * {@code StringBuffer} in places where the string buffer was being
+ * used by a single thread (as is generally the case).   Where possible,
+ * it is recommended that this class be used in preference to
+ * {@code StringBuffer} as it will be faster under most implementations.
+ *
+ * <p>The principal operations on a {@code StringBuilder} are the
+ * {@code append} and {@code insert} methods, which are
+ * overloaded so as to accept data of any type. Each effectively
+ * converts a given datum to a string and then appends or inserts the
+ * characters of that string to the string builder. The
+ * {@code append} method always adds these characters at the end
+ * of the builder; the {@code insert} method adds the characters at
+ * a specified point.
+ * <p>
+ * For example, if {@code z} refers to a string builder object
+ * whose current contents are "{@code start}", then
+ * the method call {@code z.append("le")} would cause the string
+ * builder to contain "{@code startle}", whereas
+ * {@code z.insert(4, "le")} would alter the string builder to
+ * contain "{@code starlet}".
+ * <p>
+ * In general, if sb refers to an instance of a {@code StringBuilder},
+ * then {@code sb.append(x)} has the same effect as
+ * {@code sb.insert(sb.length(), x)}.
+ * <p>
+ * Every string builder has a capacity. As long as the length of the
+ * character sequence contained in the string builder does not exceed
+ * the capacity, it is not necessary to allocate a new internal
+ * buffer. If the internal buffer overflows, it is automatically made larger.
+ *
+ * <p>Instances of {@code StringBuilder} are not safe for
+ * use by multiple threads. If such synchronization is required then it is
+ * recommended that {@link java.lang.StringBuffer} be used.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author      Michael McCloskey
+ * @see         java.lang.StringBuffer
+ * @see         java.lang.String
+ * @since       1.5
+ */
+public final class StringBuilder
+    extends AbstractStringBuilder
+    implements java.io.Serializable, CharSequence
+{
+
+    /** use serialVersionUID for interoperability */
+    static final long serialVersionUID = 4383685877147921099L;
+
+    /**
+     * Constructs a string builder with no characters in it and an
+     * initial capacity of 16 characters.
+     */
+    public StringBuilder() {
+        super(16);
+    }
+
+    /**
+     * Constructs a string builder with no characters in it and an
+     * initial capacity specified by the {@code capacity} argument.
+     *
+     * @param      capacity  the initial capacity.
+     * @throws     NegativeArraySizeException  if the {@code capacity}
+     *               argument is less than {@code 0}.
+     */
+    public StringBuilder(int capacity) {
+        super(capacity);
+    }
+
+    /**
+     * Constructs a string builder initialized to the contents of the
+     * specified string. The initial capacity of the string builder is
+     * {@code 16} plus the length of the string argument.
+     *
+     * @param   str   the initial contents of the buffer.
+     */
+    public StringBuilder(String str) {
+        super(str.length() + 16);
+        append(str);
+    }
+
+    /**
+     * Constructs a string builder that contains the same characters
+     * as the specified {@code CharSequence}. The initial capacity of
+     * the string builder is {@code 16} plus the length of the
+     * {@code CharSequence} argument.
+     *
+     * @param      seq   the sequence to copy.
+     */
+    public StringBuilder(CharSequence seq) {
+        this(seq.length() + 16);
+        append(seq);
+    }
+
+    @Override
+    public StringBuilder append(Object obj) {
+        return append(String.valueOf(obj));
+    }
+
+    @Override
+    public StringBuilder append(String str) {
+        super.append(str);
+        return this;
+    }
+
+    /**
+     * Appends the specified {@code StringBuffer} to this sequence.
+     * <p>
+     * The characters of the {@code StringBuffer} argument are appended,
+     * in order, to this sequence, increasing the
+     * length of this sequence by the length of the argument.
+     * If {@code sb} is {@code null}, then the four characters
+     * {@code "null"} are appended to this sequence.
+     * <p>
+     * Let <i>n</i> be the length of this character sequence just prior to
+     * execution of the {@code append} method. Then the character at index
+     * <i>k</i> in the new character sequence is equal to the character at
+     * index <i>k</i> in the old character sequence, if <i>k</i> is less than
+     * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
+     * in the argument {@code sb}.
+     *
+     * @param   sb   the {@code StringBuffer} to append.
+     * @return  a reference to this object.
+     */
+    public StringBuilder append(StringBuffer sb) {
+        super.append(sb);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(CharSequence s) {
+        super.append(s);
+        return this;
+    }
+
+    /**
+     * @throws     IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder append(CharSequence s, int start, int end) {
+        super.append(s, start, end);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(char[] str) {
+        super.append(str);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder append(char[] str, int offset, int len) {
+        super.append(str, offset, len);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(boolean b) {
+        super.append(b);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(char c) {
+        super.append(c);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(int i) {
+        super.append(i);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(long lng) {
+        super.append(lng);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(float f) {
+        super.append(f);
+        return this;
+    }
+
+    @Override
+    public StringBuilder append(double d) {
+        super.append(d);
+        return this;
+    }
+
+    /**
+     * @since 1.5
+     */
+    @Override
+    public StringBuilder appendCodePoint(int codePoint) {
+        super.appendCodePoint(codePoint);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder delete(int start, int end) {
+        super.delete(start, end);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder deleteCharAt(int index) {
+        super.deleteCharAt(index);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder replace(int start, int end, String str) {
+        super.replace(start, end, str);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int index, char[] str, int offset,
+                                int len)
+    {
+        super.insert(index, str, offset, len);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, Object obj) {
+            super.insert(offset, obj);
+            return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, String str) {
+        super.insert(offset, str);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, char[] str) {
+        super.insert(offset, str);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int dstOffset, CharSequence s) {
+            super.insert(dstOffset, s);
+            return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int dstOffset, CharSequence s,
+                                int start, int end)
+    {
+        super.insert(dstOffset, s, start, end);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, boolean b) {
+        super.insert(offset, b);
+        return this;
+    }
+
+    /**
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, char c) {
+        super.insert(offset, c);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, int i) {
+        super.insert(offset, i);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, long l) {
+        super.insert(offset, l);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, float f) {
+        super.insert(offset, f);
+        return this;
+    }
+
+    /**
+     * @throws StringIndexOutOfBoundsException {@inheritDoc}
+     */
+    @Override
+    public StringBuilder insert(int offset, double d) {
+        super.insert(offset, d);
+        return this;
+    }
+
+    @Override
+    public int indexOf(String str) {
+        return super.indexOf(str);
+    }
+
+    @Override
+    public int indexOf(String str, int fromIndex) {
+        return super.indexOf(str, fromIndex);
+    }
+
+    @Override
+    public int lastIndexOf(String str) {
+        return super.lastIndexOf(str);
+    }
+
+    @Override
+    public int lastIndexOf(String str, int fromIndex) {
+        return super.lastIndexOf(str, fromIndex);
+    }
+
+    @Override
+    public StringBuilder reverse() {
+        super.reverse();
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        // BEGIN Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+        if (count == 0) {
+            return "";
+        }
+        // END Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+        // Create a copy, don't share the array
+        return new String(value, 0, count);
+    }
+
+    /**
+     * Save the state of the {@code StringBuilder} instance to a stream
+     * (that is, serialize it).
+     *
+     * @serialData the number of characters currently stored in the string
+     *             builder ({@code int}), followed by the characters in the
+     *             string builder ({@code char[]}).   The length of the
+     *             {@code char} array may be greater than the number of
+     *             characters currently stored in the string builder, in which
+     *             case extra characters are ignored.
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+        s.defaultWriteObject();
+        s.writeInt(count);
+        s.writeObject(value);
+    }
+
+    /**
+     * readObject is called to restore the state of the StringBuffer from
+     * a stream.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        count = s.readInt();
+        value = (char[]) s.readObject();
+    }
+
+}
diff --git a/java/lang/StringFactory.java b/java/lang/StringFactory.java
new file mode 100644
index 0000000..6ef664b
--- /dev/null
+++ b/java/lang/StringFactory.java
@@ -0,0 +1,296 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.lang;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Comparator;
+import libcore.util.CharsetUtils;
+import libcore.util.EmptyArray;
+
+/**
+ * Class used to generate strings instead of calling String.&lt;init&gt;.
+ *
+ * @hide
+ */
+public final class StringFactory {
+
+    // TODO: Remove once native methods are in place.
+    private static final char REPLACEMENT_CHAR = (char) 0xfffd;
+
+    public static String newEmptyString() {
+        return newStringFromChars(EmptyArray.CHAR, 0, 0);
+    }
+
+    public static String newStringFromBytes(byte[] data) {
+        return newStringFromBytes(data, 0, data.length);
+    }
+
+    public static String newStringFromBytes(byte[] data, int high) {
+        return newStringFromBytes(data, high, 0, data.length);
+    }
+
+    public static String newStringFromBytes(byte[] data, int offset, int byteCount) {
+        return newStringFromBytes(data, offset, byteCount, Charset.defaultCharset());
+    }
+
+    @FastNative
+    public static native String newStringFromBytes(byte[] data, int high, int offset, int byteCount);
+
+    public static String newStringFromBytes(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
+        return newStringFromBytes(data, offset, byteCount, Charset.forNameUEE(charsetName));
+    }
+
+    public static String newStringFromBytes(byte[] data, String charsetName) throws UnsupportedEncodingException {
+        return newStringFromBytes(data, 0, data.length, Charset.forNameUEE(charsetName));
+    }
+
+    private static final int[] TABLE_UTF8_NEEDED = new int[] {
+    //      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
+            0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 0xcf
+            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 0xdf
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 0xef
+            3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0 - 0xff
+    };
+
+    // TODO: Implement this method natively.
+    public static String newStringFromBytes(byte[] data, int offset, int byteCount, Charset charset) {
+        if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
+            throw new StringIndexOutOfBoundsException(data.length, offset, byteCount);
+        }
+
+        char[] value;
+        int length;
+
+        // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed.
+        String canonicalCharsetName = charset.name();
+        if (canonicalCharsetName.equals("UTF-8")) {
+            /*
+            This code converts a UTF-8 byte sequence to a Java String (UTF-16).
+            It implements the W3C recommended UTF-8 decoder.
+            https://www.w3.org/TR/encoding/#utf-8-decoder
+
+            Unicode 3.2 Well-Formed UTF-8 Byte Sequences
+            Code Points        First  Second Third Fourth
+            U+0000..U+007F     00..7F
+            U+0080..U+07FF     C2..DF 80..BF
+            U+0800..U+0FFF     E0     A0..BF 80..BF
+            U+1000..U+CFFF     E1..EC 80..BF 80..BF
+            U+D000..U+D7FF     ED     80..9F 80..BF
+            U+E000..U+FFFF     EE..EF 80..BF 80..BF
+            U+10000..U+3FFFF   F0     90..BF 80..BF 80..BF
+            U+40000..U+FFFFF   F1..F3 80..BF 80..BF 80..BF
+            U+100000..U+10FFFF F4     80..8F 80..BF 80..BF
+
+            Please refer to Unicode as the authority.
+            p.126 Table 3-7 in http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
+
+            Handling Malformed Input
+            The maximal subpart should be replaced by a single U+FFFD. Maximal subpart is
+            the longest code unit subsequence starting at an unconvertible offset that is either
+            1) the initial subsequence of a well-formed code unit sequence, or
+            2) a subsequence of length one:
+            One U+FFFD should be emitted for every sequence of bytes that is an incomplete prefix
+            of a valid sequence, and with the conversion to restart after the incomplete sequence.
+
+            For example, in byte sequence "41 C0 AF 41 F4 80 80 41", the maximal subparts are
+            "C0", "AF", and "F4 80 80". "F4 80 80" can be the initial subsequence of "F4 80 80 80",
+            but "C0" can't be the initial subsequence of any well-formed code unit sequence.
+            Thus, the output should be "A\ufffd\ufffdA\ufffdA".
+
+            Please refer to section "Best Practices for Using U+FFFD." in
+            http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
+            */
+            byte[] d = data;
+            char[] v = new char[byteCount];
+
+            int idx = offset;
+            int last = offset + byteCount;
+            int s = 0;
+
+            int codePoint = 0;
+            int utf8BytesSeen = 0;
+            int utf8BytesNeeded = 0;
+            int lowerBound = 0x80;
+            int upperBound = 0xbf;
+
+            while (idx < last) {
+                int b = d[idx++] & 0xff;
+                if (utf8BytesNeeded == 0) {
+                    if ((b & 0x80) == 0) { // ASCII char. 0xxxxxxx
+                        v[s++] = (char) b;
+                        continue;
+                    }
+
+                    if ((b & 0x40) == 0) { // 10xxxxxx is illegal as first byte
+                        v[s++] = REPLACEMENT_CHAR;
+                        continue;
+                    }
+
+                    // 11xxxxxx
+                    int tableLookupIndex = b & 0x3f;
+                    utf8BytesNeeded = TABLE_UTF8_NEEDED[tableLookupIndex];
+                    if (utf8BytesNeeded == 0) {
+                        v[s++] = REPLACEMENT_CHAR;
+                        continue;
+                    }
+
+                    // utf8BytesNeeded
+                    // 1: b & 0x1f
+                    // 2: b & 0x0f
+                    // 3: b & 0x07
+                    codePoint = b & (0x3f >> utf8BytesNeeded);
+                    if (b == 0xe0) {
+                        lowerBound = 0xa0;
+                    } else if (b == 0xed) {
+                        upperBound = 0x9f;
+                    } else if (b == 0xf0) {
+                        lowerBound = 0x90;
+                    } else if (b == 0xf4) {
+                        upperBound = 0x8f;
+                    }
+                } else {
+                    if (b < lowerBound || b > upperBound) {
+                        // The bytes seen are ill-formed. Substitute them with U+FFFD
+                        v[s++] = REPLACEMENT_CHAR;
+                        codePoint = 0;
+                        utf8BytesNeeded = 0;
+                        utf8BytesSeen = 0;
+                        lowerBound = 0x80;
+                        upperBound = 0xbf;
+                        /*
+                         * According to the Unicode Standard,
+                         * "a UTF-8 conversion process is required to never consume well-formed
+                         * subsequences as part of its error handling for ill-formed subsequences"
+                         * The current byte could be part of well-formed subsequences. Reduce the
+                         * index by 1 to parse it in next loop.
+                         */
+                        idx--;
+                        continue;
+                    }
+
+                    lowerBound = 0x80;
+                    upperBound = 0xbf;
+                    codePoint = (codePoint << 6) | (b & 0x3f);
+                    utf8BytesSeen++;
+                    if (utf8BytesNeeded != utf8BytesSeen) {
+                        continue;
+                    }
+
+                    // Encode chars from U+10000 up as surrogate pairs
+                    if (codePoint < 0x10000) {
+                        v[s++] = (char) codePoint;
+                    } else {
+                        v[s++] = (char) ((codePoint >> 10) + 0xd7c0);
+                        v[s++] = (char) ((codePoint & 0x3ff) + 0xdc00);
+                    }
+
+                    utf8BytesSeen = 0;
+                    utf8BytesNeeded = 0;
+                    codePoint = 0;
+                }
+            }
+
+            // The bytes seen are ill-formed. Substitute them by U+FFFD
+            if (utf8BytesNeeded != 0) {
+                v[s++] = REPLACEMENT_CHAR;
+            }
+
+            if (s == byteCount) {
+                // We guessed right, so we can use our temporary array as-is.
+                value = v;
+                length = s;
+            } else {
+                // Our temporary array was too big, so reallocate and copy.
+                value = new char[s];
+                length = s;
+                System.arraycopy(v, 0, value, 0, s);
+            }
+        } else if (canonicalCharsetName.equals("ISO-8859-1")) {
+            value = new char[byteCount];
+            length = byteCount;
+            CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value);
+        } else if (canonicalCharsetName.equals("US-ASCII")) {
+            value = new char[byteCount];
+            length = byteCount;
+            CharsetUtils.asciiBytesToChars(data, offset, byteCount, value);
+        } else {
+            CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
+            length = cb.length();
+            // The call to newStringFromChars below will copy length bytes out of value, so it does
+            // not matter that cb.array().length may be > cb.length() or that a Charset could keep a
+            // reference to the CharBuffer it returns and later mutate it.
+            value = cb.array();
+        }
+        return newStringFromChars(value, 0, length);
+    }
+
+    public static String newStringFromBytes(byte[] data, Charset charset) {
+        return newStringFromBytes(data, 0, data.length, charset);
+    }
+
+    public static String newStringFromChars(char[] data) {
+        return newStringFromChars(data, 0, data.length);
+    }
+
+    public static String newStringFromChars(char[] data, int offset, int charCount) {
+        if ((offset | charCount) < 0 || charCount > data.length - offset) {
+            throw new StringIndexOutOfBoundsException(data.length, offset, charCount);
+        }
+        return newStringFromChars(offset, charCount, data);
+    }
+
+    // The char array passed as {@code java_data} must not be a null reference.
+    @FastNative
+    static native String newStringFromChars(int offset, int charCount, char[] data);
+
+    @FastNative
+    public static native String newStringFromString(String toCopy);
+
+    public static String newStringFromStringBuffer(StringBuffer stringBuffer) {
+        synchronized (stringBuffer) {
+            return newStringFromChars(stringBuffer.getValue(), 0, stringBuffer.length());
+        }
+    }
+
+    // TODO: Implement this method natively.
+    public static String newStringFromCodePoints(int[] codePoints, int offset, int count) {
+        if (codePoints == null) {
+            throw new NullPointerException("codePoints == null");
+        }
+        if ((offset | count) < 0 || count > codePoints.length - offset) {
+            throw new StringIndexOutOfBoundsException(codePoints.length, offset, count);
+        }
+        char[] value = new char[count * 2];
+        int end = offset + count;
+        int length = 0;
+        for (int i = offset; i < end; i++) {
+            length += Character.toChars(codePoints[i], value, length);
+        }
+        return newStringFromChars(value, 0, length);
+    }
+
+    public static String newStringFromStringBuilder(StringBuilder stringBuilder) {
+        return newStringFromChars(stringBuilder.getValue(), 0, stringBuilder.length());
+    }
+}
diff --git a/java/lang/StringIndexOutOfBoundsException.java b/java/lang/StringIndexOutOfBoundsException.java
new file mode 100644
index 0000000..a40bd29
--- /dev/null
+++ b/java/lang/StringIndexOutOfBoundsException.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+/**
+ * Thrown by {@code String} methods to indicate that an index
+ * is either negative or greater than the size of the string.  For
+ * some methods such as the charAt method, this exception also is
+ * thrown when the index is equal to the size of the string.
+ *
+ * @author  unascribed
+ * @see     java.lang.String#charAt(int)
+ * @since   JDK1.0
+ */
+public
+class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
+    private static final long serialVersionUID = -6762910422159637258L;
+
+    /**
+     * Constructs a {@code StringIndexOutOfBoundsException} with no
+     * detail message.
+     *
+     * @since   JDK1.0.
+     */
+    public StringIndexOutOfBoundsException() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code StringIndexOutOfBoundsException} with
+     * the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public StringIndexOutOfBoundsException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a new {@code StringIndexOutOfBoundsException}
+     * class with an argument indicating the illegal index.
+     *
+     * @param   index   the illegal index.
+     */
+    public StringIndexOutOfBoundsException(int index) {
+        super("String index out of range: " + index);
+    }
+
+    // BEGIN Android-added: Additional constructors for internal use.
+    /**
+     * Used internally for consistent high-quality error reporting.
+     * @hide
+     */
+    StringIndexOutOfBoundsException(String s, int index) {
+        this(s.length(), index);
+    }
+
+    /**
+     * Used internally for consistent high-quality error reporting.
+     * @hide
+     */
+    StringIndexOutOfBoundsException(int sourceLength, int index) {
+        super("length=" + sourceLength + "; index=" + index);
+    }
+
+    /**
+     * Used internally for consistent high-quality error reporting.
+     * @hide
+     */
+    StringIndexOutOfBoundsException(String s, int offset, int count) {
+        this(s.length(), offset, count);
+    }
+
+    /**
+     * Used internally for consistent high-quality error reporting.
+     * @hide
+     */
+    StringIndexOutOfBoundsException(int sourceLength, int offset,
+            int count) {
+        super("length=" + sourceLength + "; regionStart=" + offset
+                + "; regionLength=" + count);
+    }
+    // END Android-added: Additional constructors for internal use.
+}
diff --git a/java/lang/SuppressWarnings.java b/java/lang/SuppressWarnings.java
new file mode 100644
index 0000000..d315ddb
--- /dev/null
+++ b/java/lang/SuppressWarnings.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2004, 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;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * Indicates that the named compiler warnings should be suppressed in the
+ * annotated element (and in all program elements contained in the annotated
+ * element).  Note that the set of warnings suppressed in a given element is
+ * a superset of the warnings suppressed in all containing elements.  For
+ * example, if you annotate a class to suppress one warning and annotate a
+ * method to suppress another, both warnings will be suppressed in the method.
+ *
+ * <p>As a matter of style, programmers should always use this annotation
+ * on the most deeply nested element where it is effective.  If you want to
+ * suppress a warning in a particular method, you should annotate that
+ * method rather than its class.
+ *
+ * @author Josh Bloch
+ * @since 1.5
+ * @jls 4.8 Raw Types
+ * @jls 4.12.2 Variables of Reference Type
+ * @jls 5.1.9 Unchecked Conversion
+ * @jls 5.5.2 Checked Casts and Unchecked Casts
+ * @jls 9.6.3.5 @SuppressWarnings
+ */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface SuppressWarnings {
+    /**
+     * The set of warnings that are to be suppressed by the compiler in the
+     * annotated element.  Duplicate names are permitted.  The second and
+     * successive occurrences of a name are ignored.  The presence of
+     * unrecognized warning names is <i>not</i> an error: Compilers must
+     * ignore any warning names they do not recognize.  They are, however,
+     * free to emit a warning if an annotation contains an unrecognized
+     * warning name.
+     *
+     * <p> The string {@code "unchecked"} is used to suppress
+     * unchecked warnings. Compiler vendors should document the
+     * additional warning names they support in conjunction with this
+     * annotation type. They are encouraged to cooperate to ensure
+     * that the same names work across multiple compilers.
+     * @return the set of warnings to be suppressed
+     */
+    String[] value();
+}
diff --git a/java/lang/System.annotated.java b/java/lang/System.annotated.java
new file mode 100644
index 0000000..918b3da
--- /dev/null
+++ b/java/lang/System.annotated.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.io.*;
+import java.nio.channels.spi.SelectorProvider;
+import java.nio.channels.Channel;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class System {
+
+System() { throw new RuntimeException("Stub!"); }
+
+public static void setIn(java.io.InputStream in) { throw new RuntimeException("Stub!"); }
+
+public static void setOut(java.io.PrintStream out) { throw new RuntimeException("Stub!"); }
+
+public static void setErr(java.io.PrintStream err) { throw new RuntimeException("Stub!"); }
+
+public static java.io.Console console() { throw new RuntimeException("Stub!"); }
+
+public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static void setSecurityManager(java.lang.SecurityManager s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.SecurityManager getSecurityManager() { throw new RuntimeException("Stub!"); }
+
+public static native long currentTimeMillis();
+
+public static native long nanoTime();
+
+public static native void arraycopy(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+public static int identityHashCode(java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Properties getProperties() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String lineSeparator() { throw new RuntimeException("Stub!"); }
+
+public static void setProperties(java.util.Properties props) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key, java.lang.String def) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String setProperty(java.lang.String key, java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String clearProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getenv(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.String,java.lang.String> getenv() { throw new RuntimeException("Stub!"); }
+
+public static void exit(int status) { throw new RuntimeException("Stub!"); }
+
+public static void gc() { throw new RuntimeException("Stub!"); }
+
+public static void runFinalization() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public static void runFinalizersOnExit(boolean value) { throw new RuntimeException("Stub!"); }
+
+public static void load(java.lang.String filename) { throw new RuntimeException("Stub!"); }
+
+public static void loadLibrary(java.lang.String libname) { throw new RuntimeException("Stub!"); }
+
+public static native java.lang.String mapLibraryName(java.lang.String libname);
+
+public static final java.io.PrintStream err;
+static { err = null; }
+
+public static final java.io.InputStream in;
+static { in = null; }
+
+public static final java.io.PrintStream out;
+static { out = null; }
+
[email protected]
+public static void logE(String message, Throwable th) { throw new RuntimeException("Stub!"); }
+
+}
+
diff --git a/java/lang/System.java b/java/lang/System.java
new file mode 100644
index 0000000..352d9ec
--- /dev/null
+++ b/java/lang/System.java
@@ -0,0 +1,1774 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import com.android.icu.util.Icu4cMetadata;
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+import android.system.ErrnoException;
+import android.system.StructPasswd;
+import android.system.StructUtsname;
+import dalvik.system.VMRuntime;
+import java.io.*;
+import java.nio.channels.Channel;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import libcore.io.Libcore;
+import libcore.timezone.TimeZoneDataFiles;
+
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.security.util.SecurityConstants;
+/**
+ * The <code>System</code> class contains several useful class fields
+ * and methods. It cannot be instantiated.
+ *
+ * <p>Among the facilities provided by the <code>System</code> class
+ * are standard input, standard output, and error output streams;
+ * access to externally defined properties and environment
+ * variables; a means of loading files and libraries; and a utility
+ * method for quickly copying a portion of an array.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public final class System {
+    /** Don't let anyone instantiate this class */
+    private System() {
+    }
+
+    /**
+     * The "standard" input stream. This stream is already
+     * open and ready to supply input data. Typically this stream
+     * corresponds to keyboard input or another input source specified by
+     * the host environment or user.
+     */
+    public final static InputStream in;
+
+    /**
+     * The "standard" output stream. This stream is already
+     * open and ready to accept output data. Typically this stream
+     * corresponds to display output or another output destination
+     * specified by the host environment or user.
+     * <p>
+     * For simple stand-alone Java applications, a typical way to write
+     * a line of output data is:
+     * <blockquote><pre>
+     *     System.out.println(data)
+     * </pre></blockquote>
+     * <p>
+     * See the <code>println</code> methods in class <code>PrintStream</code>.
+     *
+     * @see     java.io.PrintStream#println()
+     * @see     java.io.PrintStream#println(boolean)
+     * @see     java.io.PrintStream#println(char)
+     * @see     java.io.PrintStream#println(char[])
+     * @see     java.io.PrintStream#println(double)
+     * @see     java.io.PrintStream#println(float)
+     * @see     java.io.PrintStream#println(int)
+     * @see     java.io.PrintStream#println(long)
+     * @see     java.io.PrintStream#println(java.lang.Object)
+     * @see     java.io.PrintStream#println(java.lang.String)
+     */
+    public final static PrintStream out;
+
+    /**
+     * The "standard" error output stream. This stream is already
+     * open and ready to accept output data.
+     * <p>
+     * Typically this stream corresponds to display output or another
+     * output destination specified by the host environment or user. By
+     * convention, this output stream is used to display error messages
+     * or other information that should come to the immediate attention
+     * of a user even if the principal output stream, the value of the
+     * variable <code>out</code>, has been redirected to a file or other
+     * destination that is typically not continuously monitored.
+     */
+    public final static PrintStream err;
+
+    /**
+     * Dedicated lock for GC / Finalization logic.
+     */
+    private static final Object LOCK = new Object();
+
+    /**
+     * Whether or not we need to do a GC before running the finalizers.
+     */
+    private static boolean runGC;
+
+    /**
+     * If we just ran finalization, we might want to do a GC to free the finalized objects.
+     * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
+     */
+    private static boolean justRanFinalization;
+
+    /**
+     * Reassigns the "standard" input stream.
+     *
+     * <p>First, if there is a security manager, its <code>checkPermission</code>
+     * method is called with a <code>RuntimePermission("setIO")</code> permission
+     *  to see if it's ok to reassign the "standard" input stream.
+     * <p>
+     *
+     * @param in the new standard input stream.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        <code>checkPermission</code> method doesn't allow
+     *        reassigning of the standard input stream.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     *
+     * @since   JDK1.1
+     */
+    public static void setIn(InputStream in) {
+        setIn0(in);
+    }
+
+    /**
+     * Reassigns the "standard" output stream.
+     *
+     * <p>First, if there is a security manager, its <code>checkPermission</code>
+     * method is called with a <code>RuntimePermission("setIO")</code> permission
+     *  to see if it's ok to reassign the "standard" output stream.
+     *
+     * @param out the new standard output stream
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        <code>checkPermission</code> method doesn't allow
+     *        reassigning of the standard output stream.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     *
+     * @since   JDK1.1
+     */
+    public static void setOut(PrintStream out) {
+        setOut0(out);
+    }
+
+    /**
+     * Reassigns the "standard" error output stream.
+     *
+     * <p>First, if there is a security manager, its <code>checkPermission</code>
+     * method is called with a <code>RuntimePermission("setIO")</code> permission
+     *  to see if it's ok to reassign the "standard" error output stream.
+     *
+     * @param err the new standard error output stream.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        <code>checkPermission</code> method doesn't allow
+     *        reassigning of the standard error output stream.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     *
+     * @since   JDK1.1
+     */
+    public static void setErr(PrintStream err) {
+        setErr0(err);
+    }
+
+    private static volatile Console cons = null;
+    /**
+     * Returns the unique {@link java.io.Console Console} object associated
+     * with the current Java virtual machine, if any.
+     *
+     * @return  The system console, if any, otherwise <tt>null</tt>.
+     *
+     * @since   1.6
+     */
+     public static Console console() {
+         // Android-changed: Added proper double checked locking for cons access
+         if (cons == null) {
+             synchronized (System.class) {
+                 if (cons == null) {
+                     cons = Console.console();
+                 }
+             }
+         }
+         return cons;
+     }
+
+    /**
+     * Returns the channel inherited from the entity that created this
+     * Java virtual machine.
+     *
+     * <p> This method returns the channel obtained by invoking the
+     * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
+     * inheritedChannel} method of the system-wide default
+     * {@link java.nio.channels.spi.SelectorProvider} object. </p>
+     *
+     * <p> In addition to the network-oriented channels described in
+     * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
+     * inheritedChannel}, this method may return other kinds of
+     * channels in the future.
+     *
+     * @return  The inherited channel, if any, otherwise <tt>null</tt>.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  SecurityException
+     *          If a security manager is present and it does not
+     *          permit access to the channel.
+     *
+     * @since 1.5
+     */
+    public static Channel inheritedChannel() throws IOException {
+        return SelectorProvider.provider().inheritedChannel();
+    }
+
+    private static native void setIn0(InputStream in);
+    private static native void setOut0(PrintStream out);
+    private static native void setErr0(PrintStream err);
+
+    /**
+     * Throws {@code SecurityException} (except in case {@code sm == null}).
+     *
+     * <p>Security managers do <i>not</i> provide a secure environment for
+     * executing untrusted code and are unsupported on Android. Untrusted code
+     * cannot be safely isolated within a single VM on Android, so this method
+     * <i>always</i> throws a {@code SecurityException} when passed a non-null SecurityManager
+     *
+     * @param s a security manager
+     * @throws SecurityException always, unless {@code sm == null}
+     */
+    public static
+    void setSecurityManager(final SecurityManager s) {
+        if (s != null) {
+            throw new SecurityException();
+        }
+    }
+
+    /**
+     * Always returns {@code null} in Android
+     *
+     * @return  {@code null} in Android
+     */
+    public static SecurityManager getSecurityManager() {
+        // No-op on android.
+        return null;
+    }
+
+    /**
+     * Returns the current time in milliseconds.  Note that
+     * while the unit of time of the return value is a millisecond,
+     * the granularity of the value depends on the underlying
+     * operating system and may be larger.  For example, many
+     * operating systems measure time in units of tens of
+     * milliseconds.
+     *
+     * <p> See the description of the class <code>Date</code> for
+     * a discussion of slight discrepancies that may arise between
+     * "computer time" and coordinated universal time (UTC).
+     *
+     * @return  the difference, measured in milliseconds, between
+     *          the current time and midnight, January 1, 1970 UTC.
+     * @see     java.util.Date
+     */
+    @CriticalNative
+    public static native long currentTimeMillis();
+
+    /**
+     * Returns the current value of the running Java Virtual Machine's
+     * high-resolution time source, in nanoseconds.
+     *
+     * <p>This method can only be used to measure elapsed time and is
+     * not related to any other notion of system or wall-clock time.
+     * The value returned represents nanoseconds since some fixed but
+     * arbitrary <i>origin</i> time (perhaps in the future, so values
+     * may be negative).  The same origin is used by all invocations of
+     * this method in an instance of a Java virtual machine; other
+     * virtual machine instances are likely to use a different origin.
+     *
+     * <p>This method provides nanosecond precision, but not necessarily
+     * nanosecond resolution (that is, how frequently the value changes)
+     * - no guarantees are made except that the resolution is at least as
+     * good as that of {@link #currentTimeMillis()}.
+     *
+     * <p>Differences in successive calls that span greater than
+     * approximately 292 years (2<sup>63</sup> nanoseconds) will not
+     * correctly compute elapsed time due to numerical overflow.
+     *
+     * <p>The values returned by this method become meaningful only when
+     * the difference between two such values, obtained within the same
+     * instance of a Java virtual machine, is computed.
+     *
+     * <p> For example, to measure how long some code takes to execute:
+     *  <pre> {@code
+     * long startTime = System.nanoTime();
+     * // ... the code being measured ...
+     * long estimatedTime = System.nanoTime() - startTime;}</pre>
+     *
+     * <p>To compare two nanoTime values
+     *  <pre> {@code
+     * long t0 = System.nanoTime();
+     * ...
+     * long t1 = System.nanoTime();}</pre>
+     *
+     * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
+     * because of the possibility of numerical overflow.
+     *
+     * @return the current value of the running Java Virtual Machine's
+     *         high-resolution time source, in nanoseconds
+     * @since 1.5
+     */
+    @CriticalNative
+    public static native long nanoTime();
+
+    /**
+     * Copies an array from the specified source array, beginning at the
+     * specified position, to the specified position of the destination array.
+     * A subsequence of array components are copied from the source
+     * array referenced by <code>src</code> to the destination array
+     * referenced by <code>dest</code>. The number of components copied is
+     * equal to the <code>length</code> argument. The components at
+     * positions <code>srcPos</code> through
+     * <code>srcPos+length-1</code> in the source array are copied into
+     * positions <code>destPos</code> through
+     * <code>destPos+length-1</code>, respectively, of the destination
+     * array.
+     * <p>
+     * If the <code>src</code> and <code>dest</code> arguments refer to the
+     * same array object, then the copying is performed as if the
+     * components at positions <code>srcPos</code> through
+     * <code>srcPos+length-1</code> were first copied to a temporary
+     * array with <code>length</code> components and then the contents of
+     * the temporary array were copied into positions
+     * <code>destPos</code> through <code>destPos+length-1</code> of the
+     * destination array.
+     * <p>
+     * If <code>dest</code> is <code>null</code>, then a
+     * <code>NullPointerException</code> is thrown.
+     * <p>
+     * If <code>src</code> is <code>null</code>, then a
+     * <code>NullPointerException</code> is thrown and the destination
+     * array is not modified.
+     * <p>
+     * Otherwise, if any of the following is true, an
+     * <code>ArrayStoreException</code> is thrown and the destination is
+     * not modified:
+     * <ul>
+     * <li>The <code>src</code> argument refers to an object that is not an
+     *     array.
+     * <li>The <code>dest</code> argument refers to an object that is not an
+     *     array.
+     * <li>The <code>src</code> argument and <code>dest</code> argument refer
+     *     to arrays whose component types are different primitive types.
+     * <li>The <code>src</code> argument refers to an array with a primitive
+     *    component type and the <code>dest</code> argument refers to an array
+     *     with a reference component type.
+     * <li>The <code>src</code> argument refers to an array with a reference
+     *    component type and the <code>dest</code> argument refers to an array
+     *     with a primitive component type.
+     * </ul>
+     * <p>
+     * Otherwise, if any of the following is true, an
+     * <code>IndexOutOfBoundsException</code> is
+     * thrown and the destination is not modified:
+     * <ul>
+     * <li>The <code>srcPos</code> argument is negative.
+     * <li>The <code>destPos</code> argument is negative.
+     * <li>The <code>length</code> argument is negative.
+     * <li><code>srcPos+length</code> is greater than
+     *     <code>src.length</code>, the length of the source array.
+     * <li><code>destPos+length</code> is greater than
+     *     <code>dest.length</code>, the length of the destination array.
+     * </ul>
+     * <p>
+     * Otherwise, if any actual component of the source array from
+     * position <code>srcPos</code> through
+     * <code>srcPos+length-1</code> cannot be converted to the component
+     * type of the destination array by assignment conversion, an
+     * <code>ArrayStoreException</code> is thrown. In this case, let
+     * <b><i>k</i></b> be the smallest nonnegative integer less than
+     * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
+     * cannot be converted to the component type of the destination
+     * array; when the exception is thrown, source array components from
+     * positions <code>srcPos</code> through
+     * <code>srcPos+</code><i>k</i><code>-1</code>
+     * will already have been copied to destination array positions
+     * <code>destPos</code> through
+     * <code>destPos+</code><i>k</I><code>-1</code> and no other
+     * positions of the destination array will have been modified.
+     * (Because of the restrictions already itemized, this
+     * paragraph effectively applies only to the situation where both
+     * arrays have component types that are reference types.)
+     *
+     * @param      src      the source array.
+     * @param      srcPos   starting position in the source array.
+     * @param      dest     the destination array.
+     * @param      destPos  starting position in the destination data.
+     * @param      length   the number of array elements to be copied.
+     * @exception  IndexOutOfBoundsException  if copying would cause
+     *               access of data outside array bounds.
+     * @exception  ArrayStoreException  if an element in the <code>src</code>
+     *               array could not be stored into the <code>dest</code> array
+     *               because of a type mismatch.
+     * @exception  NullPointerException if either <code>src</code> or
+     *               <code>dest</code> is <code>null</code>.
+     */
+    @FastNative
+    public static native void arraycopy(Object src,  int  srcPos,
+                                        Object dest, int destPos,
+                                        int length);
+
+
+    // BEGIN Android-changed
+    /**
+     * The char array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The char[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
+            // Copy char by char for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The char[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyCharUnchecked(char[] src, int srcPos,
+        char[] dst, int dstPos, int length);
+
+    /**
+     * The byte array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The byte[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) {
+            // Copy byte by byte for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyByteUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The byte[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyByteUnchecked(byte[] src, int srcPos,
+        byte[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The short[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) {
+            // Copy short by short for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyShortUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The short[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyShortUnchecked(short[] src, int srcPos,
+        short[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The int[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) {
+            // Copy int by int for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyIntUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The int[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyIntUnchecked(int[] src, int srcPos,
+        int[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The long[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) {
+            // Copy long by long for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for longer arrays.
+            arraycopyLongUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The long[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyLongUnchecked(long[] src, int srcPos,
+        long[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The float[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) {
+            // Copy float by float for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The float[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyFloatUnchecked(float[] src, int srcPos,
+        float[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The double[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) {
+            // Copy double by double for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The double[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyDoubleUnchecked(double[] src, int srcPos,
+        double[] dst, int dstPos, int length);
+
+    /**
+     * The short array length threshold below which to use a Java
+     * (non-native) version of arraycopy() instead of the native
+     * version. See b/7103825.
+     */
+    private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32;
+
+    /**
+     * The boolean[] specialized version of arraycopy().
+     * Note: This method is required for runtime ART compiler optimizations.
+     * Do not remove or change the signature.
+     */
+    @SuppressWarnings("unused")
+    private static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+        if (src == null) {
+            throw new NullPointerException("src == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        if (srcPos < 0 || dstPos < 0 || length < 0 ||
+            srcPos > src.length - length || dstPos > dst.length - length) {
+            throw new ArrayIndexOutOfBoundsException(
+                "src.length=" + src.length + " srcPos=" + srcPos +
+                " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+        }
+        if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) {
+            // Copy boolean by boolean for shorter arrays.
+            if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+                // Copy backward (to avoid overwriting elements before
+                // they are copied in case of an overlap on the same
+                // array.)
+                for (int i = length - 1; i >= 0; --i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            } else {
+                // Copy forward.
+                for (int i = 0; i < length; ++i) {
+                    dst[dstPos + i] = src[srcPos + i];
+                }
+            }
+        } else {
+            // Call the native version for floater arrays.
+            arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length);
+        }
+    }
+
+    /**
+     * The boolean[] specialized, unchecked, native version of
+     * arraycopy(). This assumes error checking has been done.
+     */
+    @FastNative
+    private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos,
+        boolean[] dst, int dstPos, int length);
+    // END Android-changed
+
+    /**
+     * Returns the same hash code for the given object as
+     * would be returned by the default method hashCode(),
+     * whether or not the given object's class overrides
+     * hashCode().
+     * The hash code for the null reference is zero.
+     *
+     * @param x object for which the hashCode is to be calculated
+     * @return  the hashCode
+     * @since   JDK1.1
+     */
+    public static int identityHashCode(Object x) {
+        if (x == null) {
+            return 0;
+        }
+        return Object.identityHashCode(x);
+    }
+
+    /**
+     * System properties. The following properties are guaranteed to be defined:
+     * <dl>
+     * <dt>java.version         <dd>Java version number
+     * <dt>java.vendor          <dd>Java vendor specific string
+     * <dt>java.vendor.url      <dd>Java vendor URL
+     * <dt>java.home            <dd>Java installation directory
+     * <dt>java.class.version   <dd>Java class version number
+     * <dt>java.class.path      <dd>Java classpath
+     * <dt>os.name              <dd>Operating System Name
+     * <dt>os.arch              <dd>Operating System Architecture
+     * <dt>os.version           <dd>Operating System Version
+     * <dt>file.separator       <dd>File separator ("/" on Unix)
+     * <dt>path.separator       <dd>Path separator (":" on Unix)
+     * <dt>line.separator       <dd>Line separator ("\n" on Unix)
+     * <dt>user.name            <dd>User account name
+     * <dt>user.home            <dd>User home directory
+     * <dt>user.dir             <dd>User's current working directory
+     * </dl>
+     */
+
+    private static Properties props;
+    private static Properties unchangeableProps;
+
+    private static native String[] specialProperties();
+
+    static final class PropertiesWithNonOverrideableDefaults extends Properties {
+        PropertiesWithNonOverrideableDefaults(Properties defaults) {
+            super(defaults);
+        }
+
+        @Override
+        public Object put(Object key, Object value) {
+            if (defaults.containsKey(key)) {
+                logE("Ignoring attempt to set property \"" + key +
+                        "\" to value \"" + value + "\".");
+                return defaults.get(key);
+            }
+
+            return super.put(key, value);
+        }
+
+        @Override
+        public Object remove(Object key) {
+            if (defaults.containsKey(key)) {
+                logE("Ignoring attempt to remove property \"" + key + "\".");
+                return null;
+            }
+
+            return super.remove(key);
+        }
+    }
+
+    private static void parsePropertyAssignments(Properties p, String[] assignments) {
+        for (String assignment : assignments) {
+            int split = assignment.indexOf('=');
+            String key = assignment.substring(0, split);
+            String value = assignment.substring(split + 1);
+            p.put(key, value);
+        }
+    }
+
+    private static Properties initUnchangeableSystemProperties() {
+        VMRuntime runtime = VMRuntime.getRuntime();
+        Properties p = new Properties();
+
+        // Set non-static properties.
+        p.put("java.boot.class.path", runtime.bootClassPath());
+        p.put("java.class.path", runtime.classPath());
+
+        // TODO: does this make any sense? Should we just leave java.home unset?
+        String javaHome = getenv("JAVA_HOME");
+        if (javaHome == null) {
+            javaHome = "/system";
+        }
+        p.put("java.home", javaHome);
+
+        p.put("java.vm.version", runtime.vmVersion());
+
+        try {
+            StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
+            p.put("user.name", passwd.pw_name);
+        } catch (ErrnoException exception) {
+            throw new AssertionError(exception);
+        }
+
+        StructUtsname info = Libcore.os.uname();
+        p.put("os.arch", info.machine);
+        // os.name was previously hardcoded to "Linux", but was reverted due to support
+        // for Fuchsia. b/121268567 shows initialization regressions.
+        p.put("os.name", info.sysname);
+        p.put("os.version", info.release);
+
+        // Android-added: Undocumented properties that exist only on Android.
+        p.put("android.icu.library.version", Icu4cMetadata.getIcuVersion());
+        p.put("android.icu.unicode.version", Icu4cMetadata.getUnicodeVersion());
+        p.put("android.icu.cldr.version", Icu4cMetadata.getCldrVersion());
+
+        // Property override for ICU4J : this is the location of the ICU4C data. This
+        // is prioritized over the properties in ICUConfig.properties. The issue with using
+        // that is that it doesn't play well with jarjar and it needs complicated build rules
+        // to change its default value.
+        String icuDataPath = TimeZoneDataFiles.generateIcuDataPath();
+        p.put("android.icu.impl.ICUBinary.dataPath", icuDataPath);
+
+        parsePropertyAssignments(p, specialProperties());
+
+        // Override built-in properties with settings from the command line.
+        // Note: it is not possible to override hardcoded values.
+        parsePropertyAssignments(p, runtime.properties());
+
+
+        // Set static hardcoded properties.
+        // These come last, as they must be guaranteed to agree with what a backend compiler
+        // may assume when compiling the boot image on Android.
+        for (String[] pair : AndroidHardcodedSystemProperties.STATIC_PROPERTIES) {
+            if (p.containsKey(pair[0])) {
+                logE("Ignoring command line argument: -D" + pair[0]);
+            }
+            if (pair[1] == null) {
+                p.remove(pair[0]);
+            } else {
+                p.put(pair[0], pair[1]);
+            }
+        }
+
+        return p;
+    }
+
+    private static Properties initProperties() {
+        Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
+        setDefaultChangeableProperties(p);
+        return p;
+    }
+
+    private static Properties setDefaultChangeableProperties(Properties p) {
+        // On Android, each app gets its own temporary directory.
+        // (See android.app.ActivityThread.) This is just a fallback default,
+        // useful only on the host.
+        // We check first if the property has not been set already: note that it
+        // can only be set from the command line through the '-Djava.io.tmpdir=' option.
+        if (!unchangeableProps.containsKey("java.io.tmpdir")) {
+            p.put("java.io.tmpdir", "/tmp");
+        }
+
+        // Android has always had an empty "user.home" (see docs for getProperty).
+        // This is not useful for normal android apps which need to use android specific
+        // APIs such as {@code Context.getFilesDir} and {@code Context.getCacheDir} but
+        // we make it changeable for backward compatibility, so that they can change it
+        // to a writeable location if required.
+        // We check first if the property has not been set already: note that it
+        // can only be set from the command line through the '-Duser.home=' option.
+        if (!unchangeableProps.containsKey("user.home")) {
+            p.put("user.home", "");
+        }
+
+        return p;
+    }
+
+    /**
+     * Inits an unchangeable system property with the given value.
+     *
+     * This is called from native code when the environment needs to change under native
+     * bridge emulation.
+     *
+     * @hide also visible for tests.
+     */
+    public static void setUnchangeableSystemProperty(String key, String value) {
+        checkKey(key);
+        unchangeableProps.put(key, value);
+    }
+
+    private static void addLegacyLocaleSystemProperties() {
+        final String locale = getProperty("user.locale", "");
+        if (!locale.isEmpty()) {
+            Locale l = Locale.forLanguageTag(locale);
+            setUnchangeableSystemProperty("user.language", l.getLanguage());
+            setUnchangeableSystemProperty("user.region", l.getCountry());
+            setUnchangeableSystemProperty("user.variant", l.getVariant());
+        } else {
+            // If "user.locale" isn't set we fall back to our old defaults of
+            // language="en" and region="US" (if unset) and don't attempt to set it.
+            // The Locale class will fall back to using user.language and
+            // user.region if unset.
+            final String language = getProperty("user.language", "");
+            final String region = getProperty("user.region", "");
+
+            if (language.isEmpty()) {
+                setUnchangeableSystemProperty("user.language", "en");
+            }
+
+            if (region.isEmpty()) {
+                setUnchangeableSystemProperty("user.region", "US");
+            }
+        }
+    }
+
+    /**
+     * Determines the current system properties.
+     *
+     *
+     * <p>The following properties are always provided by the Dalvik VM:</p>
+     * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+     * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+     *     <td><b>Name</b></td>        <td><b>Meaning</b></td>                    <td><b>Example</b></td></tr>
+     * <tr><td>file.separator</td>     <td>{@link java.io.File#separator}</td>    <td>{@code /}</td></tr>
+     *
+     * <tr><td>java.class.path</td>    <td>System class path</td>                 <td>{@code .}</td></tr>
+     * <tr><td>java.class.version</td> <td>(Not useful on Android)</td>           <td>{@code 50.0}</td></tr>
+     * <tr><td>java.compiler</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
+     * <tr><td>java.ext.dirs</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
+     * <tr><td>java.home</td>          <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr>
+     * <tr><td>java.io.tmpdir</td>     <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr>
+     * <tr><td>java.library.path</td>  <td>Search path for JNI libraries</td>     <td>{@code /vendor/lib:/system/lib}</td></tr>
+     * <tr><td>java.vendor</td>        <td>Human-readable VM vendor</td>          <td>{@code The Android Project}</td></tr>
+     * <tr><td>java.vendor.url</td>    <td>URL for VM vendor's web site</td>      <td>{@code http://www.android.com/}</td></tr>
+     * <tr><td>java.version</td>       <td>(Not useful on Android)</td>           <td>{@code 0}</td></tr>
+     *
+     * <tr><td>java.specification.version</td>    <td>VM libraries version</td>        <td>{@code 0.9}</td></tr>
+     * <tr><td>java.specification.vendor</td>     <td>VM libraries vendor</td>         <td>{@code The Android Project}</td></tr>
+     * <tr><td>java.specification.name</td>       <td>VM libraries name</td>           <td>{@code Dalvik Core Library}</td></tr>
+     * <tr><td>java.vm.version</td>               <td>VM implementation version</td>   <td>{@code 1.2.0}</td></tr>
+     * <tr><td>java.vm.vendor</td>                <td>VM implementation vendor</td>    <td>{@code The Android Project}</td></tr>
+     * <tr><td>java.vm.name</td>                  <td>VM implementation name</td>      <td>{@code Dalvik}</td></tr>
+     * <tr><td>java.vm.specification.version</td> <td>VM specification version</td>    <td>{@code 0.9}</td></tr>
+     * <tr><td>java.vm.specification.vendor</td>  <td>VM specification vendor</td>     <td>{@code The Android Project}</td></tr>
+     * <tr><td>java.vm.specification.name</td>    <td>VM specification name</td>       <td>{@code Dalvik Virtual Machine Specification}</td></tr>
+     *
+     * <tr><td>line.separator</td>     <td>The system line separator</td>         <td>{@code \n}</td></tr>
+     *
+     * <tr><td>os.arch</td>            <td>OS architecture</td>                   <td>{@code armv7l}</td></tr>
+     * <tr><td>os.name</td>            <td>OS (kernel) name</td>                  <td>{@code Linux}</td></tr>
+     * <tr><td>os.version</td>         <td>OS (kernel) version</td>               <td>{@code 2.6.32.9-g103d848}</td></tr>
+     *
+     * <tr><td>path.separator</td>     <td>See {@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr>
+     *
+     * <tr><td>user.dir</td>           <td>Base of non-absolute paths</td>        <td>{@code /}</td></tr>
+     * <tr><td>user.home</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
+     * <tr><td>user.name</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
+     *
+     * </table>
+     * <p>
+     * Multiple paths in a system property value are separated by the path
+     * separator character of the platform.
+     * <p>
+     * Note that even if the security manager does not permit the
+     * <code>getProperties</code> operation, it may choose to permit the
+     * {@link #getProperty(String)} operation.
+     *
+     * @return     the system properties
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPropertiesAccess</code> method doesn't allow access
+     *              to the system properties.
+     * @see        #setProperties
+     * @see        java.lang.SecurityException
+     * @see        java.lang.SecurityManager#checkPropertiesAccess()
+     * @see        java.util.Properties
+     */
+    public static Properties getProperties() {
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+
+        return props;
+    }
+
+    /**
+     * Returns the system-dependent line separator string.  It always
+     * returns the same value - the initial value of the {@linkplain
+     * #getProperty(String) system property} {@code line.separator}.
+     *
+     * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
+     * Windows systems it returns {@code "\r\n"}.
+     *
+     * @return the system-dependent line separator string
+     * @since 1.7
+     */
+    public static String lineSeparator() {
+        return lineSeparator;
+    }
+
+    private static String lineSeparator;
+
+
+    // Comment replaced with android one.
+    /**
+     * Attempts to set all system properties. Copies all properties from
+     * {@code p} and discards system properties that are read only and cannot
+     * be modified. See {@link #getProperty} for a list of such properties.
+     */
+    public static void setProperties(Properties props) {
+        Properties baseProperties = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
+        if (props != null) {
+            baseProperties.putAll(props);
+        } else {
+            setDefaultChangeableProperties(baseProperties);
+        }
+
+        System.props = baseProperties;
+    }
+
+    /**
+     * Gets the system property indicated by the specified key.
+     * <p>
+     * First, if there is a security manager, its
+     * <code>checkPropertyAccess</code> method is called with the key as
+     * its argument. This may result in a SecurityException.
+     * <p>
+     * If there is no current set of system properties, a set of system
+     * properties is first created and initialized in the same manner as
+     * for the <code>getProperties</code> method.
+     *
+     * @param      key   the name of the system property.
+     * @return     the string value of the system property,
+     *             or <code>null</code> if there is no property with that key.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPropertyAccess</code> method doesn't allow
+     *              access to the specified system property.
+     * @exception  NullPointerException if <code>key</code> is
+     *             <code>null</code>.
+     * @exception  IllegalArgumentException if <code>key</code> is empty.
+     * @see        #setProperty
+     * @see        java.lang.SecurityException
+     * @see        java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+     * @see        java.lang.System#getProperties()
+     */
+    public static String getProperty(String key) {
+        checkKey(key);
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertyAccess(key);
+        }
+
+        return props.getProperty(key);
+    }
+
+    /**
+     * Gets the system property indicated by the specified key.
+     * <p>
+     * First, if there is a security manager, its
+     * <code>checkPropertyAccess</code> method is called with the
+     * <code>key</code> as its argument.
+     * <p>
+     * If there is no current set of system properties, a set of system
+     * properties is first created and initialized in the same manner as
+     * for the <code>getProperties</code> method.
+     *
+     * @param      key   the name of the system property.
+     * @param      def   a default value.
+     * @return     the string value of the system property,
+     *             or the default value if there is no property with that key.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPropertyAccess</code> method doesn't allow
+     *             access to the specified system property.
+     * @exception  NullPointerException if <code>key</code> is
+     *             <code>null</code>.
+     * @exception  IllegalArgumentException if <code>key</code> is empty.
+     * @see        #setProperty
+     * @see        java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+     * @see        java.lang.System#getProperties()
+     */
+    public static String getProperty(String key, String def) {
+        checkKey(key);
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertyAccess(key);
+        }
+
+        return props.getProperty(key, def);
+    }
+
+    /**
+     * Sets the system property indicated by the specified key.
+     * <p>
+     * First, if a security manager exists, its
+     * <code>SecurityManager.checkPermission</code> method
+     * is called with a <code>PropertyPermission(key, "write")</code>
+     * permission. This may result in a SecurityException being thrown.
+     * If no exception is thrown, the specified property is set to the given
+     * value.
+     * <p>
+     *
+     * @param      key   the name of the system property.
+     * @param      value the value of the system property.
+     * @return     the previous value of the system property,
+     *             or <code>null</code> if it did not have one.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPermission</code> method doesn't allow
+     *             setting of the specified property.
+     * @exception  NullPointerException if <code>key</code> or
+     *             <code>value</code> is <code>null</code>.
+     * @exception  IllegalArgumentException if <code>key</code> is empty.
+     * @see        #getProperty
+     * @see        java.lang.System#getProperty(java.lang.String)
+     * @see        java.lang.System#getProperty(java.lang.String, java.lang.String)
+     * @see        java.util.PropertyPermission
+     * @see        SecurityManager#checkPermission
+     * @since      1.2
+     */
+    public static String setProperty(String key, String value) {
+        checkKey(key);
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new PropertyPermission(key,
+                SecurityConstants.PROPERTY_WRITE_ACTION));
+        }
+
+        return (String) props.setProperty(key, value);
+    }
+
+    /**
+     * Removes the system property indicated by the specified key.
+     * <p>
+     * First, if a security manager exists, its
+     * <code>SecurityManager.checkPermission</code> method
+     * is called with a <code>PropertyPermission(key, "write")</code>
+     * permission. This may result in a SecurityException being thrown.
+     * If no exception is thrown, the specified property is removed.
+     * <p>
+     *
+     * @param      key   the name of the system property to be removed.
+     * @return     the previous string value of the system property,
+     *             or <code>null</code> if there was no property with that key.
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPropertyAccess</code> method doesn't allow
+     *              access to the specified system property.
+     * @exception  NullPointerException if <code>key</code> is
+     *             <code>null</code>.
+     * @exception  IllegalArgumentException if <code>key</code> is empty.
+     * @see        #getProperty
+     * @see        #setProperty
+     * @see        java.util.Properties
+     * @see        java.lang.SecurityException
+     * @see        java.lang.SecurityManager#checkPropertiesAccess()
+     * @since 1.5
+     */
+    public static String clearProperty(String key) {
+        checkKey(key);
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new PropertyPermission(key, "write"));
+        }
+
+        return (String) props.remove(key);
+    }
+
+    private static void checkKey(String key) {
+        if (key == null) {
+            throw new NullPointerException("key can't be null");
+        }
+        if (key.equals("")) {
+            throw new IllegalArgumentException("key can't be empty");
+        }
+    }
+
+    /**
+     * Gets the value of the specified environment variable. An
+     * environment variable is a system-dependent external named
+     * value.
+     *
+     * <p>If a security manager exists, its
+     * {@link SecurityManager#checkPermission checkPermission}
+     * method is called with a
+     * <code>{@link RuntimePermission}("getenv."+name)</code>
+     * permission.  This may result in a {@link SecurityException}
+     * being thrown.  If no exception is thrown the value of the
+     * variable <code>name</code> is returned.
+     *
+     * <p><a name="EnvironmentVSSystemProperties"><i>System
+     * properties</i> and <i>environment variables</i></a> are both
+     * conceptually mappings between names and values.  Both
+     * mechanisms can be used to pass user-defined information to a
+     * Java process.  Environment variables have a more global effect,
+     * because they are visible to all descendants of the process
+     * which defines them, not just the immediate Java subprocess.
+     * They can have subtly different semantics, such as case
+     * insensitivity, on different operating systems.  For these
+     * reasons, environment variables are more likely to have
+     * unintended side effects.  It is best to use system properties
+     * where possible.  Environment variables should be used when a
+     * global effect is desired, or when an external system interface
+     * requires an environment variable (such as <code>PATH</code>).
+     *
+     * <p>On UNIX systems the alphabetic case of <code>name</code> is
+     * typically significant, while on Microsoft Windows systems it is
+     * typically not.  For example, the expression
+     * <code>System.getenv("FOO").equals(System.getenv("foo"))</code>
+     * is likely to be true on Microsoft Windows.
+     *
+     * @param  name the name of the environment variable
+     * @return the string value of the variable, or <code>null</code>
+     *         if the variable is not defined in the system environment
+     * @throws NullPointerException if <code>name</code> is <code>null</code>
+     * @throws SecurityException
+     *         if a security manager exists and its
+     *         {@link SecurityManager#checkPermission checkPermission}
+     *         method doesn't allow access to the environment variable
+     *         <code>name</code>
+     * @see    #getenv()
+     * @see    ProcessBuilder#environment()
+     */
+    public static String getenv(String name) {
+        if (name == null) {
+            throw new NullPointerException("name == null");
+        }
+
+        return Libcore.os.getenv(name);
+    }
+
+
+    /**
+     * Returns an unmodifiable string map view of the current system environment.
+     * The environment is a system-dependent mapping from names to
+     * values which is passed from parent to child processes.
+     *
+     * <p>If the system does not support environment variables, an
+     * empty map is returned.
+     *
+     * <p>The returned map will never contain null keys or values.
+     * Attempting to query the presence of a null key or value will
+     * throw a {@link NullPointerException}.  Attempting to query
+     * the presence of a key or value which is not of type
+     * {@link String} will throw a {@link ClassCastException}.
+     *
+     * <p>The returned map and its collection views may not obey the
+     * general contract of the {@link Object#equals} and
+     * {@link Object#hashCode} methods.
+     *
+     * <p>The returned map is typically case-sensitive on all platforms.
+     *
+     * <p>If a security manager exists, its
+     * {@link SecurityManager#checkPermission checkPermission}
+     * method is called with a
+     * <code>{@link RuntimePermission}("getenv.*")</code>
+     * permission.  This may result in a {@link SecurityException} being
+     * thrown.
+     *
+     * <p>When passing information to a Java subprocess,
+     * <a href=#EnvironmentVSSystemProperties>system properties</a>
+     * are generally preferred over environment variables.
+     *
+     * @return the environment as a map of variable names to values
+     * @throws SecurityException
+     *         if a security manager exists and its
+     *         {@link SecurityManager#checkPermission checkPermission}
+     *         method doesn't allow access to the process environment
+     * @see    #getenv(String)
+     * @see    ProcessBuilder#environment()
+     * @since  1.5
+     */
+    public static java.util.Map<String,String> getenv() {
+        SecurityManager sm = getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("getenv.*"));
+        }
+
+        return ProcessEnvironment.getenv();
+    }
+
+    /**
+     * Terminates the currently running Java Virtual Machine. The
+     * argument serves as a status code; by convention, a nonzero status
+     * code indicates abnormal termination.
+     * <p>
+     * This method calls the <code>exit</code> method in class
+     * <code>Runtime</code>. This method never returns normally.
+     * <p>
+     * The call <code>System.exit(n)</code> is effectively equivalent to
+     * the call:
+     * <blockquote><pre>
+     * Runtime.getRuntime().exit(n)
+     * </pre></blockquote>
+     *
+     * @param      status   exit status.
+     * @throws  SecurityException
+     *        if a security manager exists and its <code>checkExit</code>
+     *        method doesn't allow exit with the specified status.
+     * @see        java.lang.Runtime#exit(int)
+     */
+    public static void exit(int status) {
+        Runtime.getRuntime().exit(status);
+    }
+
+    /**
+     * Runs the garbage collector.
+     * <p>
+     * Calling the <code>gc</code> method suggests that the Java Virtual
+     * Machine expend effort toward recycling unused objects in order to
+     * make the memory they currently occupy available for quick reuse.
+     * When control returns from the method call, the Java Virtual
+     * Machine has made a best effort to reclaim space from all discarded
+     * objects.
+     * <p>
+     * The call <code>System.gc()</code> is effectively equivalent to the
+     * call:
+     * <blockquote><pre>
+     * Runtime.getRuntime().gc()
+     * </pre></blockquote>
+     *
+     * @see     java.lang.Runtime#gc()
+     */
+    public static void gc() {
+        boolean shouldRunGC;
+        synchronized (LOCK) {
+            shouldRunGC = justRanFinalization;
+            if (shouldRunGC) {
+                justRanFinalization = false;
+            } else {
+                runGC = true;
+            }
+        }
+        if (shouldRunGC) {
+            Runtime.getRuntime().gc();
+        }
+    }
+
+    /**
+     * Runs the finalization methods of any objects pending finalization.
+     * <p>
+     * Calling this method suggests that the Java Virtual Machine expend
+     * effort toward running the <code>finalize</code> methods of objects
+     * that have been found to be discarded but whose <code>finalize</code>
+     * methods have not yet been run. When control returns from the
+     * method call, the Java Virtual Machine has made a best effort to
+     * complete all outstanding finalizations.
+     * <p>
+     * The call <code>System.runFinalization()</code> is effectively
+     * equivalent to the call:
+     * <blockquote><pre>
+     * Runtime.getRuntime().runFinalization()
+     * </pre></blockquote>
+     *
+     * @see     java.lang.Runtime#runFinalization()
+     */
+    public static void runFinalization() {
+        boolean shouldRunGC;
+        synchronized (LOCK) {
+            shouldRunGC = runGC;
+            runGC = false;
+        }
+        if (shouldRunGC) {
+            Runtime.getRuntime().gc();
+        }
+        Runtime.getRuntime().runFinalization();
+        synchronized (LOCK) {
+            justRanFinalization = true;
+        }
+    }
+
+    /**
+     * Enable or disable finalization on exit; doing so specifies that the
+     * finalizers of all objects that have finalizers that have not yet been
+     * automatically invoked are to be run before the Java runtime exits.
+     * By default, finalization on exit is disabled.
+     *
+     * <p>If there is a security manager,
+     * its <code>checkExit</code> method is first called
+     * with 0 as its argument to ensure the exit is allowed.
+     * This could result in a SecurityException.
+     *
+     * @deprecated  This method is inherently unsafe.  It may result in
+     *      finalizers being called on live objects while other threads are
+     *      concurrently manipulating those objects, resulting in erratic
+     *      behavior or deadlock.
+     * @param value indicating enabling or disabling of finalization
+     * @throws  SecurityException
+     *        if a security manager exists and its <code>checkExit</code>
+     *        method doesn't allow the exit.
+     *
+     * @see     java.lang.Runtime#exit(int)
+     * @see     java.lang.Runtime#gc()
+     * @see     java.lang.SecurityManager#checkExit(int)
+     * @since   JDK1.1
+     */
+    @Deprecated
+    public static void runFinalizersOnExit(boolean value) {
+        Runtime.runFinalizersOnExit(value);
+    }
+
+    /**
+     * Loads the native library specified by the filename argument.  The filename
+     * argument must be an absolute path name.
+     *
+     * If the filename argument, when stripped of any platform-specific library
+     * prefix, path, and file extension, indicates a library whose name is,
+     * for example, L, and a native library called L is statically linked
+     * with the VM, then the JNI_OnLoad_L function exported by the library
+     * is invoked rather than attempting to load a dynamic library.
+     * A filename matching the argument does not have to exist in the
+     * file system.
+     * See the JNI Specification for more details.
+     *
+     * Otherwise, the filename argument is mapped to a native library image in
+     * an implementation-dependent manner.
+     *
+     * <p>
+     * The call <code>System.load(name)</code> is effectively equivalent
+     * to the call:
+     * <blockquote><pre>
+     * Runtime.getRuntime().load(name)
+     * </pre></blockquote>
+     *
+     * @param      filename   the file to load.
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @exception  UnsatisfiedLinkError  if either the filename is not an
+     *             absolute path name, the native library is not statically
+     *             linked with the VM, or the library cannot be mapped to
+     *             a native library image by the host system.
+     * @exception  NullPointerException if <code>filename</code> is
+     *             <code>null</code>
+     * @see        java.lang.Runtime#load(java.lang.String)
+     * @see        java.lang.SecurityManager#checkLink(java.lang.String)
+     */
+    @CallerSensitive
+    public static void load(String filename) {
+        Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
+    }
+
+    /**
+     * Loads the native library specified by the <code>libname</code>
+     * argument.  The <code>libname</code> argument must not contain any platform
+     * specific prefix, file extension or path. If a native library
+     * called <code>libname</code> is statically linked with the VM, then the
+     * JNI_OnLoad_<code>libname</code> function exported by the library is invoked.
+     * See the JNI Specification for more details.
+     *
+     * Otherwise, the libname argument is loaded from a system library
+     * location and mapped to a native library image in an implementation-
+     * dependent manner.
+     * <p>
+     * The call <code>System.loadLibrary(name)</code> is effectively
+     * equivalent to the call
+     * <blockquote><pre>
+     * Runtime.getRuntime().loadLibrary(name)
+     * </pre></blockquote>
+     *
+     * @param      libname   the name of the library.
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkLink</code> method doesn't allow
+     *             loading of the specified dynamic library
+     * @exception  UnsatisfiedLinkError if either the libname argument
+     *             contains a file path, the native library is not statically
+     *             linked with the VM,  or the library cannot be mapped to a
+     *             native library image by the host system.
+     * @exception  NullPointerException if <code>libname</code> is
+     *             <code>null</code>
+     * @see        java.lang.Runtime#loadLibrary(java.lang.String)
+     * @see        java.lang.SecurityManager#checkLink(java.lang.String)
+     */
+    @CallerSensitive
+    public static void loadLibrary(String libname) {
+        Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
+    }
+
+    /**
+     * Maps a library name into a platform-specific string representing
+     * a native library.
+     *
+     * @param      libname the name of the library.
+     * @return     a platform-dependent native library name.
+     * @exception  NullPointerException if <code>libname</code> is
+     *             <code>null</code>
+     * @see        java.lang.System#loadLibrary(java.lang.String)
+     * @see        java.lang.ClassLoader#findLibrary(java.lang.String)
+     * @since      1.2
+     */
+    public static native String mapLibraryName(String libname);
+
+    /**
+     * Create PrintStream for stdout/err based on encoding.
+     */
+    private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
+       if (enc != null) {
+            try {
+                return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
+            } catch (UnsupportedEncodingException uee) {}
+        }
+        return new PrintStream(new BufferedOutputStream(fos, 128), true);
+    }
+
+
+    /**
+     * Initialize the system class.  Called after thread initialization.
+     */
+    static {
+        unchangeableProps = initUnchangeableSystemProperties();
+        props = initProperties();
+        addLegacyLocaleSystemProperties();
+        sun.misc.Version.initSystemProperties();
+
+        // TODO: Confirm that this isn't something super important.
+        // sun.misc.VM.saveAndRemoveProperties(props);
+
+        lineSeparator = props.getProperty("line.separator");
+
+        FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
+        FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
+        FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
+        // BEGIN Android-changed: lower buffer size.
+        // in = new BufferedInputStream(fdIn);
+        in = new BufferedInputStream(fdIn, 128);
+        // END Android-changed: lower buffer size.
+        out = newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"));
+        err = newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"));
+
+        // Initialize any miscellenous operating system settings that need to be
+        // set for the class libraries. Currently this is no-op everywhere except
+        // for Windows where the process-wide error mode is set before the java.io
+        // classes are used.
+        sun.misc.VM.initializeOSEnvironment();
+
+        // Subsystems that are invoked during initialization can invoke
+        // sun.misc.VM.isBooted() in order to avoid doing things that should
+        // wait until the application class loader has been set up.
+        // IMPORTANT: Ensure that this remains the last initialization action!
+        sun.misc.VM.booted();
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logE(String message) {
+        log('E', message, null);
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logE(String message, Throwable th) {
+        log('E', message, th);
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logI(String message) {
+        log('I', message, null);
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logI(String message, Throwable th) {
+        log('I', message, th);
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logW(String message) {
+        log('W', message, null);
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public static void logW(String message, Throwable th) {
+        log('W', message, th);
+    }
+
+    private static native void log(char type, String message, Throwable th);
+}
diff --git a/java/lang/Thread.annotated.java b/java/lang/Thread.annotated.java
new file mode 100644
index 0000000..2499518
--- /dev/null
+++ b/java/lang/Thread.annotated.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.Map;
+import java.util.concurrent.locks.LockSupport;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Thread implements java.lang.Runnable {
+
+public Thread() { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name, long stackSize) { throw new RuntimeException("Stub!"); }
+
+public static native java.lang.Thread currentThread();
+
+public static native void yield();
+
+public static void sleep(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void sleep(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public synchronized void start() { throw new RuntimeException("Stub!"); }
+
+public void run() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void stop() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final synchronized void stop(java.lang.Throwable obj) { throw new RuntimeException("Stub!"); }
+
+public void interrupt() { throw new RuntimeException("Stub!"); }
+
+public static native boolean interrupted();
+
+public native boolean isInterrupted();
+
+@Deprecated
+public void destroy() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAlive() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void suspend() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void resume() { throw new RuntimeException("Stub!"); }
+
+public final void setPriority(int newPriority) { throw new RuntimeException("Stub!"); }
+
+public final int getPriority() { throw new RuntimeException("Stub!"); }
+
+public final synchronized void setName(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.ThreadGroup getThreadGroup() { throw new RuntimeException("Stub!"); }
+
+public static int activeCount() { throw new RuntimeException("Stub!"); }
+
+public static int enumerate(java.lang.Thread[] tarray) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public int countStackFrames() { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void dumpStack() { throw new RuntimeException("Stub!"); }
+
+public final void setDaemon(boolean on) { throw new RuntimeException("Stub!"); }
+
+public final boolean isDaemon() { throw new RuntimeException("Stub!"); }
+
+public final void checkAccess() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getContextClassLoader() { throw new RuntimeException("Stub!"); }
+
+public void setContextClassLoader(java.lang.ClassLoader cl) { throw new RuntimeException("Stub!"); }
+
+public static native boolean holdsLock(java.lang.Object obj);
+
+public java.lang.StackTraceElement[] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces() { throw new RuntimeException("Stub!"); }
+
+public long getId() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.State getState() { throw new RuntimeException("Stub!"); }
+
+public static void setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public void setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static final int MAX_PRIORITY = 10; // 0xa
+
+public static final int MIN_PRIORITY = 1; // 0x1
+
+public static final int NORM_PRIORITY = 5; // 0x5
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum State {
+NEW,
+RUNNABLE,
+BLOCKED,
+WAITING,
+TIMED_WAITING,
+TERMINATED;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
[email protected]
+public static interface UncaughtExceptionHandler {
+
+public void uncaughtException(java.lang.Thread t, java.lang.Throwable e);
+}
+
+}
+
diff --git a/java/lang/Thread.java b/java/lang/Thread.java
new file mode 100644
index 0000000..699a1ac
--- /dev/null
+++ b/java/lang/Thread.java
@@ -0,0 +1,2353 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.LockSupport;
+import sun.nio.ch.Interruptible;
+import sun.reflect.CallerSensitive;
+import dalvik.system.RuntimeHooks;
+import dalvik.system.ThreadPrioritySetter;
+import dalvik.system.VMStack;
+import libcore.util.EmptyArray;
+
+
+/**
+ * A <i>thread</i> is a thread of execution in a program. The Java
+ * Virtual Machine allows an application to have multiple threads of
+ * execution running concurrently.
+ * <p>
+ * Every thread has a priority. Threads with higher priority are
+ * executed in preference to threads with lower priority. Each thread
+ * may or may not also be marked as a daemon. When code running in
+ * some thread creates a new <code>Thread</code> object, the new
+ * thread has its priority initially set equal to the priority of the
+ * creating thread, and is a daemon thread if and only if the
+ * creating thread is a daemon.
+ * <p>
+ * When a Java Virtual Machine starts up, there is usually a single
+ * non-daemon thread (which typically calls the method named
+ * <code>main</code> of some designated class). The Java Virtual
+ * Machine continues to execute threads until either of the following
+ * occurs:
+ * <ul>
+ * <li>The <code>exit</code> method of class <code>Runtime</code> has been
+ *     called and the security manager has permitted the exit operation
+ *     to take place.
+ * <li>All threads that are not daemon threads have died, either by
+ *     returning from the call to the <code>run</code> method or by
+ *     throwing an exception that propagates beyond the <code>run</code>
+ *     method.
+ * </ul>
+ * <p>
+ * There are two ways to create a new thread of execution. One is to
+ * declare a class to be a subclass of <code>Thread</code>. This
+ * subclass should override the <code>run</code> method of class
+ * <code>Thread</code>. An instance of the subclass can then be
+ * allocated and started. For example, a thread that computes primes
+ * larger than a stated value could be written as follows:
+ * <hr><blockquote><pre>
+ *     class PrimeThread extends Thread {
+ *         long minPrime;
+ *         PrimeThread(long minPrime) {
+ *             this.minPrime = minPrime;
+ *         }
+ *
+ *         public void run() {
+ *             // compute primes larger than minPrime
+ *             &nbsp;.&nbsp;.&nbsp;.
+ *         }
+ *     }
+ * </pre></blockquote><hr>
+ * <p>
+ * The following code would then create a thread and start it running:
+ * <blockquote><pre>
+ *     PrimeThread p = new PrimeThread(143);
+ *     p.start();
+ * </pre></blockquote>
+ * <p>
+ * The other way to create a thread is to declare a class that
+ * implements the <code>Runnable</code> interface. That class then
+ * implements the <code>run</code> method. An instance of the class can
+ * then be allocated, passed as an argument when creating
+ * <code>Thread</code>, and started. The same example in this other
+ * style looks like the following:
+ * <hr><blockquote><pre>
+ *     class PrimeRun implements Runnable {
+ *         long minPrime;
+ *         PrimeRun(long minPrime) {
+ *             this.minPrime = minPrime;
+ *         }
+ *
+ *         public void run() {
+ *             // compute primes larger than minPrime
+ *             &nbsp;.&nbsp;.&nbsp;.
+ *         }
+ *     }
+ * </pre></blockquote><hr>
+ * <p>
+ * The following code would then create a thread and start it running:
+ * <blockquote><pre>
+ *     PrimeRun p = new PrimeRun(143);
+ *     new Thread(p).start();
+ * </pre></blockquote>
+ * <p>
+ * Every thread has a name for identification purposes. More than
+ * one thread may have the same name. If a name is not specified when
+ * a thread is created, a new name is generated for it.
+ * <p>
+ * Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author  unascribed
+ * @see     Runnable
+ * @see     Runtime#exit(int)
+ * @see     #run()
+ * @see     #stop()
+ * @since   JDK1.0
+ */
+public
+class Thread implements Runnable {
+    // Android-removed: registerNatives() not used on Android.
+    /*
+    /* Make sure registerNatives is the first thing <clinit> does. *
+    private static native void registerNatives();
+    static {
+        registerNatives();
+    }
+    */
+
+    // BEGIN Android-added: Android specific fields lock, nativePeer.
+    /**
+     * The synchronization object responsible for this thread's join/sleep/park operations.
+     */
+    private final Object lock = new Object();
+
+    /**
+     * Reference to the native thread object.
+     *
+     * <p>Is 0 if the native thread has not yet been created/started, or has been destroyed.
+     */
+    private volatile long nativePeer;
+    // END Android-added: Android specific fields lock, nativePeer.
+
+    private volatile String name;
+    private int            priority;
+    private Thread         threadQ;
+    private long           eetop;
+
+    /* Whether or not to single_step this thread. */
+    private boolean     single_step;
+
+    /* Whether or not the thread is a daemon thread. */
+    private boolean     daemon = false;
+
+    /* JVM state */
+    private boolean     stillborn = false;
+
+    /* What will be run. */
+    private Runnable target;
+
+    /* The group of this thread */
+    private ThreadGroup group;
+
+    /* The context ClassLoader for this thread */
+    private ClassLoader contextClassLoader;
+
+    /* The inherited AccessControlContext of this thread */
+    private AccessControlContext inheritedAccessControlContext;
+
+    /* For autonumbering anonymous threads. */
+    private static int threadInitNumber;
+    private static synchronized int nextThreadNum() {
+        return threadInitNumber++;
+    }
+
+    /* ThreadLocal values pertaining to this thread. This map is maintained
+     * by the ThreadLocal class. */
+    ThreadLocal.ThreadLocalMap threadLocals = null;
+
+    /*
+     * InheritableThreadLocal values pertaining to this thread. This map is
+     * maintained by the InheritableThreadLocal class.
+     */
+    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
+
+    /*
+     * The requested stack size for this thread, or 0 if the creator did
+     * not specify a stack size.  It is up to the VM to do whatever it
+     * likes with this number; some VMs will ignore it.
+     */
+    private long stackSize;
+
+    // BEGIN Android-changed: Keep track of whether this thread was unparked while not alive.
+    /*
+    /*
+     * JVM-private state that persists after native thread termination.
+     *
+    private long nativeParkEventPointer;
+    */
+    /**
+     * Indicates whether this thread was unpark()ed while not alive, in which case start()ing
+     * it should leave it in unparked state. This field is read and written by native code in
+     * the runtime, guarded by thread_list_lock. See http://b/28845097#comment49
+     */
+    private boolean unparkedBeforeStart;
+    // END Android-changed: Keep track of whether this thread was unparked while not alive.
+
+    /*
+     * Thread ID
+     */
+    private long tid;
+
+    /* For generating thread ID */
+    private static long threadSeqNumber;
+
+
+    // Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /** True if this thread is managed by {@link Daemons}. */
+    private boolean systemDaemon = false;
+
+    /* Java thread status for tools,
+     * initialized to indicate thread 'not yet started'
+     */
+
+    // BEGIN Android-changed: Replace unused threadStatus field with started field.
+    // Upstream this is modified by the native code and read in the start() and getState() methods
+    // but in Android it is unused. The threadStatus is essentially an internal representation of
+    // the Thread.State enum. Android uses two sources for that information, the native thread
+    // state and the started field. The reason two sources are needed is because the native thread
+    // is created when the thread is started and destroyed when the thread is stopped. That means
+    // that the native thread state does not exist before the Thread has started (in State.NEW) or
+    // after it has been stopped (in State.TERMINATED). In that case (i.e. when the nativePeer = 0)
+    // the started field differentiates between the two states, i.e. if started = false then the
+    // thread is in State.NEW and if started = true then the thread is in State.TERMINATED.
+    // private volatile int threadStatus = 0;
+    /**
+     * True if the the Thread has been started, even it has since been stopped.
+     */
+    boolean started = false;
+    // END Android-changed: Replace unused threadStatus field with started field.
+
+
+    private static synchronized long nextThreadID() {
+        return ++threadSeqNumber;
+    }
+
+    /**
+     * The argument supplied to the current call to
+     * java.util.concurrent.locks.LockSupport.park.
+     * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
+     * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
+     */
+    volatile Object parkBlocker;
+
+    /* The object in which this thread is blocked in an interruptible I/O
+     * operation, if any.  The blocker's interrupt method should be invoked
+     * after setting this thread's interrupt status.
+     */
+    private volatile Interruptible blocker;
+    private final Object blockerLock = new Object();
+
+    // Android-changed: Make blockedOn() @hide public, for internal use.
+    // Changed comment to reflect usage on Android
+    /* Set the blocker field; used by java.nio.channels.spi.AbstractInterruptibleChannel
+     */
+    /** @hide */
+    public void blockedOn(Interruptible b) {
+        synchronized (blockerLock) {
+            blocker = b;
+        }
+    }
+
+    /**
+     * The minimum priority that a thread can have.
+     */
+    public final static int MIN_PRIORITY = 1;
+
+   /**
+     * The default priority that is assigned to a thread.
+     */
+    public final static int NORM_PRIORITY = 5;
+
+    /**
+     * The maximum priority that a thread can have.
+     */
+    public final static int MAX_PRIORITY = 10;
+
+    /**
+     * Returns a reference to the currently executing thread object.
+     *
+     * @return  the currently executing thread.
+     */
+    @FastNative
+    public static native Thread currentThread();
+
+    /**
+     * A hint to the scheduler that the current thread is willing to yield
+     * its current use of a processor. The scheduler is free to ignore this
+     * hint.
+     *
+     * <p> Yield is a heuristic attempt to improve relative progression
+     * between threads that would otherwise over-utilise a CPU. Its use
+     * should be combined with detailed profiling and benchmarking to
+     * ensure that it actually has the desired effect.
+     *
+     * <p> It is rarely appropriate to use this method. It may be useful
+     * for debugging or testing purposes, where it may help to reproduce
+     * bugs due to race conditions. It may also be useful when designing
+     * concurrency control constructs such as the ones in the
+     * {@link java.util.concurrent.locks} package.
+     */
+    public static native void yield();
+
+    /**
+     * Causes the currently executing thread to sleep (temporarily cease
+     * execution) for the specified number of milliseconds, subject to
+     * the precision and accuracy of system timers and schedulers. The thread
+     * does not lose ownership of any monitors.
+     *
+     * @param  millis
+     *         the length of time to sleep in milliseconds
+     *
+     * @throws  IllegalArgumentException
+     *          if the value of {@code millis} is negative
+     *
+     * @throws  InterruptedException
+     *          if any thread has interrupted the current thread. The
+     *          <i>interrupted status</i> of the current thread is
+     *          cleared when this exception is thrown.
+     */
+    // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+    public static void sleep(long millis) throws InterruptedException {
+        sleep(millis, 0);
+    }
+
+    @FastNative
+    private static native void sleep(Object lock, long millis, int nanos)
+        throws InterruptedException;
+    // END Android-changed: Implement sleep() methods using a shared native implementation.
+
+    /**
+     * Causes the currently executing thread to sleep (temporarily cease
+     * execution) for the specified number of milliseconds plus the specified
+     * number of nanoseconds, subject to the precision and accuracy of system
+     * timers and schedulers. The thread does not lose ownership of any
+     * monitors.
+     *
+     * @param  millis
+     *         the length of time to sleep in milliseconds
+     *
+     * @param  nanos
+     *         {@code 0-999999} additional nanoseconds to sleep
+     *
+     * @throws  IllegalArgumentException
+     *          if the value of {@code millis} is negative, or the value of
+     *          {@code nanos} is not in the range {@code 0-999999}
+     *
+     * @throws  InterruptedException
+     *          if any thread has interrupted the current thread. The
+     *          <i>interrupted status</i> of the current thread is
+     *          cleared when this exception is thrown.
+     */
+    public static void sleep(long millis, int nanos)
+    throws InterruptedException {
+        // BEGIN Android-changed: Improve exception messages.
+        /*
+        if (millis < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+        */
+        if (millis < 0) {
+            throw new IllegalArgumentException("millis < 0: " + millis);
+        }
+        if (nanos < 0) {
+            throw new IllegalArgumentException("nanos < 0: " + nanos);
+        }
+        if (nanos > 999999) {
+            throw new IllegalArgumentException("nanos > 999999: " + nanos);
+        }
+        // END Android-changed: Improve exception messages.
+
+        // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+        // Attempt nanosecond rather than millisecond accuracy for sleep();
+        // RI code rounds to the nearest millisecond.
+        /*
+        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+            millis++;
+        }
+
+        sleep(millis);
+        */
+        // The JLS 3rd edition, section 17.9 says: "...sleep for zero
+        // time...need not have observable effects."
+        if (millis == 0 && nanos == 0) {
+            // ...but we still have to handle being interrupted.
+            if (Thread.interrupted()) {
+              throw new InterruptedException();
+            }
+            return;
+        }
+
+        final int nanosPerMilli = 1000000;
+        long start = System.nanoTime();
+        long duration = (millis * nanosPerMilli) + nanos;
+
+        Object lock = currentThread().lock;
+
+        // The native sleep(...) method actually performs a special type of wait, which may return
+        // early, so loop until sleep duration passes.
+        synchronized (lock) {
+            while (true) {
+                sleep(lock, millis, nanos);
+
+                long now = System.nanoTime();
+                long elapsed = now - start;
+
+                if (elapsed >= duration) {
+                    break;
+                }
+
+                duration -= elapsed;
+                start = now;
+                millis = duration / nanosPerMilli;
+                nanos = (int) (duration % nanosPerMilli);
+            }
+        }
+        // END Android-changed: Implement sleep() methods using a shared native implementation.
+    }
+
+    /**
+     * Initializes a Thread with the current AccessControlContext.
+     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
+     */
+    private void init(ThreadGroup g, Runnable target, String name,
+                      long stackSize) {
+        init(g, target, name, stackSize, null);
+    }
+
+    /**
+     * Initializes a Thread.
+     *
+     * @param g the Thread group
+     * @param target the object whose run() method gets called
+     * @param name the name of the new Thread
+     * @param stackSize the desired stack size for the new thread, or
+     *        zero to indicate that this parameter is to be ignored.
+     * @param acc the AccessControlContext to inherit, or
+     *            AccessController.getContext() if null
+     */
+    private void init(ThreadGroup g, Runnable target, String name,
+                      long stackSize, AccessControlContext acc) {
+        if (name == null) {
+            throw new NullPointerException("name cannot be null");
+        }
+
+        this.name = name;
+
+        Thread parent = currentThread();
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager security = System.getSecurityManager();
+        if (g == null) {
+            // Android-changed: SecurityManager stubbed out on Android
+            /*
+            /* Determine if it's an applet or not *
+
+            /* If there is a security manager, ask the security manager
+               what to do. *
+            if (security != null) {
+                g = security.getThreadGroup();
+            }
+
+            /* If the security doesn't have a strong opinion of the matter
+               use the parent thread group. *
+            if (g == null) {
+            */
+                g = parent.getThreadGroup();
+            // }
+        }
+
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        /* checkAccess regardless of whether or not threadgroup is
+           explicitly passed in. *
+        g.checkAccess();
+
+        /*
+         * Do we have the required permissions?
+         *
+        if (security != null) {
+            if (isCCLOverridden(getClass())) {
+                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
+            }
+        }
+        */
+
+        g.addUnstarted();
+
+        this.group = g;
+        this.daemon = parent.isDaemon();
+        this.priority = parent.getPriority();
+        // Android-changed: Moved into init2(Thread) helper method.
+        /*
+        if (security == null || isCCLOverridden(parent.getClass()))
+            this.contextClassLoader = parent.getContextClassLoader();
+        else
+            this.contextClassLoader = parent.contextClassLoader;
+        this.inheritedAccessControlContext =
+                acc != null ? acc : AccessController.getContext();
+        */
+        this.target = target;
+        // Android-removed: The priority parameter is unchecked on Android.
+        // It is unclear why this is not being done (b/80180276).
+        // setPriority(priority);
+        // Android-changed: Moved into init2(Thread) helper method.
+        // if (parent.inheritableThreadLocals != null)
+        //     this.inheritableThreadLocals =
+        //         ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
+        init2(parent);
+
+        /* Stash the specified stack size in case the VM cares */
+        this.stackSize = stackSize;
+
+        /* Set thread ID */
+        tid = nextThreadID();
+    }
+
+    /**
+     * Throws CloneNotSupportedException as a Thread can not be meaningfully
+     * cloned. Construct a new Thread instead.
+     *
+     * @throws  CloneNotSupportedException
+     *          always
+     */
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (null, null, gname)}, where {@code gname} is a newly generated
+     * name. Automatically generated names are of the form
+     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+     */
+    public Thread() {
+        init(null, null, "Thread-" + nextThreadNum(), 0);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (null, target, gname)}, where {@code gname} is a newly generated
+     * name. Automatically generated names are of the form
+     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this classes {@code run} method does
+     *         nothing.
+     */
+    public Thread(Runnable target) {
+        init(null, target, "Thread-" + nextThreadNum(), 0);
+    }
+
+    /**
+     * Creates a new Thread that inherits the given AccessControlContext.
+     * This is not a public constructor.
+     */
+    Thread(Runnable target, AccessControlContext acc) {
+        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (group, target, gname)} ,where {@code gname} is a newly generated
+     * name. Automatically generated names are of the form
+     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+     *
+     * @param  group
+     *         the thread group. If {@code null} and there is a security
+     *         manager, the group is determined by {@linkplain
+     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+     *         If there is not a security manager or {@code
+     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
+     *         is set to the current thread's thread group.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this thread's run method is invoked.
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot create a thread in the specified
+     *          thread group
+     */
+    public Thread(ThreadGroup group, Runnable target) {
+        init(group, target, "Thread-" + nextThreadNum(), 0);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (null, null, name)}.
+     *
+     * @param   name
+     *          the name of the new thread
+     */
+    public Thread(String name) {
+        init(null, null, name, 0);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (group, null, name)}.
+     *
+     * @param  group
+     *         the thread group. If {@code null} and there is a security
+     *         manager, the group is determined by {@linkplain
+     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+     *         If there is not a security manager or {@code
+     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
+     *         is set to the current thread's thread group.
+     *
+     * @param  name
+     *         the name of the new thread
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot create a thread in the specified
+     *          thread group
+     */
+    public Thread(ThreadGroup group, String name) {
+        init(group, null, name, 0);
+    }
+
+    // BEGIN Android-added: Private constructor - used by the runtime.
+    /** @hide */
+    Thread(ThreadGroup group, String name, int priority, boolean daemon) {
+        this.group = group;
+        this.group.addUnstarted();
+        // Must be tolerant of threads without a name.
+        if (name == null) {
+            name = "Thread-" + nextThreadNum();
+        }
+
+        // NOTE: Resist the temptation to call setName() here. This constructor is only called
+        // by the runtime to construct peers for threads that have attached via JNI and it's
+        // undesirable to clobber their natively set name.
+        this.name = name;
+
+        this.priority = priority;
+        this.daemon = daemon;
+        init2(currentThread());
+        tid = nextThreadID();
+    }
+
+    // Android-added: Helper method for previous constructor and init(...) method.
+    private void init2(Thread parent) {
+        this.contextClassLoader = parent.getContextClassLoader();
+        this.inheritedAccessControlContext = AccessController.getContext();
+        if (parent.inheritableThreadLocals != null) {
+            this.inheritableThreadLocals = ThreadLocal.createInheritedMap(
+                    parent.inheritableThreadLocals);
+        }
+    }
+    // END Android-added: Private constructor - used by the runtime.
+
+
+    /**
+     * Allocates a new {@code Thread} object. This constructor has the same
+     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+     * {@code (null, target, name)}.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this thread's run method is invoked.
+     *
+     * @param  name
+     *         the name of the new thread
+     */
+    public Thread(Runnable target, String name) {
+        init(null, target, name, 0);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object so that it has {@code target}
+     * as its run object, has the specified {@code name} as its name,
+     * and belongs to the thread group referred to by {@code group}.
+     *
+     * <p>If there is a security manager, its
+     * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
+     * method is invoked with the ThreadGroup as its argument.
+     *
+     * <p>In addition, its {@code checkPermission} method is invoked with
+     * the {@code RuntimePermission("enableContextClassLoaderOverride")}
+     * permission when invoked directly or indirectly by the constructor
+     * of a subclass which overrides the {@code getContextClassLoader}
+     * or {@code setContextClassLoader} methods.
+     *
+     * <p>The priority of the newly created thread is set equal to the
+     * priority of the thread creating it, that is, the currently running
+     * thread. The method {@linkplain #setPriority setPriority} may be
+     * used to change the priority to a new value.
+     *
+     * <p>The newly created thread is initially marked as being a daemon
+     * thread if and only if the thread creating it is currently marked
+     * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
+     * may be used to change whether or not a thread is a daemon.
+     *
+     * @param  group
+     *         the thread group. If {@code null} and there is a security
+     *         manager, the group is determined by {@linkplain
+     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+     *         If there is not a security manager or {@code
+     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
+     *         is set to the current thread's thread group.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this thread's run method is invoked.
+     *
+     * @param  name
+     *         the name of the new thread
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot create a thread in the specified
+     *          thread group or cannot override the context class loader methods.
+     */
+    public Thread(ThreadGroup group, Runnable target, String name) {
+        init(group, target, name, 0);
+    }
+
+    /**
+     * Allocates a new {@code Thread} object so that it has {@code target}
+     * as its run object, has the specified {@code name} as its name,
+     * and belongs to the thread group referred to by {@code group}, and has
+     * the specified <i>stack size</i>.
+     *
+     * <p>This constructor is identical to {@link
+     * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
+     * that it allows the thread stack size to be specified.  The stack size
+     * is the approximate number of bytes of address space that the virtual
+     * machine is to allocate for this thread's stack.  <b>The effect of the
+     * {@code stackSize} parameter, if any, is highly platform dependent.</b>
+     *
+     * <p>On some platforms, specifying a higher value for the
+     * {@code stackSize} parameter may allow a thread to achieve greater
+     * recursion depth before throwing a {@link StackOverflowError}.
+     * Similarly, specifying a lower value may allow a greater number of
+     * threads to exist concurrently without throwing an {@link
+     * OutOfMemoryError} (or other internal error).  The details of
+     * the relationship between the value of the <tt>stackSize</tt> parameter
+     * and the maximum recursion depth and concurrency level are
+     * platform-dependent.  <b>On some platforms, the value of the
+     * {@code stackSize} parameter may have no effect whatsoever.</b>
+     *
+     * <p>The virtual machine is free to treat the {@code stackSize}
+     * parameter as a suggestion.  If the specified value is unreasonably low
+     * for the platform, the virtual machine may instead use some
+     * platform-specific minimum value; if the specified value is unreasonably
+     * high, the virtual machine may instead use some platform-specific
+     * maximum.  Likewise, the virtual machine is free to round the specified
+     * value up or down as it sees fit (or to ignore it completely).
+     *
+     * <p>Specifying a value of zero for the {@code stackSize} parameter will
+     * cause this constructor to behave exactly like the
+     * {@code Thread(ThreadGroup, Runnable, String)} constructor.
+     *
+     * <p><i>Due to the platform-dependent nature of the behavior of this
+     * constructor, extreme care should be exercised in its use.
+     * The thread stack size necessary to perform a given computation will
+     * likely vary from one JRE implementation to another.  In light of this
+     * variation, careful tuning of the stack size parameter may be required,
+     * and the tuning may need to be repeated for each JRE implementation on
+     * which an application is to run.</i>
+     *
+     * <p>Implementation note: Java platform implementers are encouraged to
+     * document their implementation's behavior with respect to the
+     * {@code stackSize} parameter.
+     *
+     *
+     * @param  group
+     *         the thread group. If {@code null} and there is a security
+     *         manager, the group is determined by {@linkplain
+     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+     *         If there is not a security manager or {@code
+     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
+     *         is set to the current thread's thread group.
+     *
+     * @param  target
+     *         the object whose {@code run} method is invoked when this thread
+     *         is started. If {@code null}, this thread's run method is invoked.
+     *
+     * @param  name
+     *         the name of the new thread
+     *
+     * @param  stackSize
+     *         the desired stack size for the new thread, or zero to indicate
+     *         that this parameter is to be ignored.
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot create a thread in the specified
+     *          thread group
+     *
+     * @since 1.4
+     */
+    public Thread(ThreadGroup group, Runnable target, String name,
+                  long stackSize) {
+        init(group, target, name, stackSize);
+    }
+
+    /**
+     * Causes this thread to begin execution; the Java Virtual Machine
+     * calls the <code>run</code> method of this thread.
+     * <p>
+     * The result is that two threads are running concurrently: the
+     * current thread (which returns from the call to the
+     * <code>start</code> method) and the other thread (which executes its
+     * <code>run</code> method).
+     * <p>
+     * It is never legal to start a thread more than once.
+     * In particular, a thread may not be restarted once it has completed
+     * execution.
+     *
+     * @exception  IllegalThreadStateException  if the thread was already
+     *               started.
+     * @see        #run()
+     * @see        #stop()
+     */
+    public synchronized void start() {
+        /**
+         * This method is not invoked for the main method thread or "system"
+         * group threads created/set up by the VM. Any new functionality added
+         * to this method in the future may have to also be added to the VM.
+         *
+         * A zero status value corresponds to state "NEW".
+         */
+        // Android-changed: Replace unused threadStatus field with started field.
+        // The threadStatus field is unused on Android.
+        if (started)
+            throw new IllegalThreadStateException();
+
+        /* Notify the group that this thread is about to be started
+         * so that it can be added to the group's list of threads
+         * and the group's unstarted count can be decremented. */
+        group.add(this);
+
+        // Android-changed: Use field instead of local variable.
+        // It is necessary to remember the state of this across calls to this method so that it
+        // can throw an IllegalThreadStateException if this method is called on an already
+        // started thread.
+        started = false;
+        try {
+            // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+            // start0();
+            nativeCreate(this, stackSize, daemon);
+            started = true;
+        } finally {
+            try {
+                if (!started) {
+                    group.threadStartFailed(this);
+                }
+            } catch (Throwable ignore) {
+                /* do nothing. If start0 threw a Throwable then
+                  it will be passed up the call stack */
+            }
+        }
+    }
+
+    // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+    // The upstream native method start0() only takes a reference to this object and so must obtain
+    // the stack size and daemon status directly from the field whereas Android supplies the values
+    // explicitly on the method call.
+    // private native void start0();
+    private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
+
+    /**
+     * If this thread was constructed using a separate
+     * <code>Runnable</code> run object, then that
+     * <code>Runnable</code> object's <code>run</code> method is called;
+     * otherwise, this method does nothing and returns.
+     * <p>
+     * Subclasses of <code>Thread</code> should override this method.
+     *
+     * @see     #start()
+     * @see     #stop()
+     * @see     #Thread(ThreadGroup, Runnable, String)
+     */
+    @Override
+    public void run() {
+        if (target != null) {
+            target.run();
+        }
+    }
+
+    /**
+     * This method is called by the system to give a Thread
+     * a chance to clean up before it actually exits.
+     */
+    private void exit() {
+        if (group != null) {
+            group.threadTerminated(this);
+            group = null;
+        }
+        /* Aggressively null out all reference fields: see bug 4006245 */
+        target = null;
+        /* Speed the release of some of these resources */
+        threadLocals = null;
+        inheritableThreadLocals = null;
+        inheritedAccessControlContext = null;
+        blocker = null;
+        uncaughtExceptionHandler = null;
+    }
+
+    // Android-changed: Throws UnsupportedOperationException.
+    /**
+     * Throws {@code UnsupportedOperationException}.
+     *
+     * @deprecated This method was originally designed to force a thread to stop
+     *       and throw a {@code ThreadDeath} as an exception. It was inherently unsafe.
+     *       Stopping a thread with
+     *       Thread.stop causes it to unlock all of the monitors that it
+     *       has locked (as a natural consequence of the unchecked
+     *       <code>ThreadDeath</code> exception propagating up the stack).  If
+     *       any of the objects previously protected by these monitors were in
+     *       an inconsistent state, the damaged objects become visible to
+     *       other threads, potentially resulting in arbitrary behavior.  Many
+     *       uses of <code>stop</code> should be replaced by code that simply
+     *       modifies some variable to indicate that the target thread should
+     *       stop running.  The target thread should check this variable
+     *       regularly, and return from its run method in an orderly fashion
+     *       if the variable indicates that it is to stop running.  If the
+     *       target thread waits for long periods (on a condition variable,
+     *       for example), the <code>interrupt</code> method should be used to
+     *       interrupt the wait.
+     *       For more information, see
+     *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     */
+    @Deprecated
+    public final void stop() {
+        /*
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            checkAccess();
+            if (this != Thread.currentThread()) {
+                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
+            }
+        }
+        // A zero status value corresponds to "NEW", it can't change to
+        // not-NEW because we hold the lock.
+        if (threadStatus != 0) {
+            resume(); // Wake up thread if it was suspended; no-op otherwise
+        }
+
+        // The VM can handle all thread states
+        stop0(new ThreadDeath());
+        */
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Throws {@code UnsupportedOperationException}.
+     *
+     * @param obj ignored
+     *
+     * @deprecated This method was originally designed to force a thread to stop
+     *        and throw a given {@code Throwable} as an exception. It was
+     *        inherently unsafe (see {@link #stop()} for details), and furthermore
+     *        could be used to generate exceptions that the target thread was
+     *        not prepared to handle.
+     *        For more information, see
+     *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     */
+    @Deprecated
+    public final synchronized void stop(Throwable obj) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Interrupts this thread.
+     *
+     * <p> Unless the current thread is interrupting itself, which is
+     * always permitted, the {@link #checkAccess() checkAccess} method
+     * of this thread is invoked, which may cause a {@link
+     * SecurityException} to be thrown.
+     *
+     * <p> If this thread is blocked in an invocation of the {@link
+     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
+     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
+     * class, or of the {@link #join()}, {@link #join(long)}, {@link
+     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
+     * methods of this class, then its interrupt status will be cleared and it
+     * will receive an {@link InterruptedException}.
+     *
+     * <p> If this thread is blocked in an I/O operation upon an {@link
+     * java.nio.channels.InterruptibleChannel InterruptibleChannel}
+     * then the channel will be closed, the thread's interrupt
+     * status will be set, and the thread will receive a {@link
+     * java.nio.channels.ClosedByInterruptException}.
+     *
+     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
+     * then the thread's interrupt status will be set and it will return
+     * immediately from the selection operation, possibly with a non-zero
+     * value, just as if the selector's {@link
+     * java.nio.channels.Selector#wakeup wakeup} method were invoked.
+     *
+     * <p> If none of the previous conditions hold then this thread's interrupt
+     * status will be set. </p>
+     *
+     * <p> Interrupting a thread that is not alive need not have any effect.
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot modify this thread
+     *
+     * @revised 6.0
+     * @spec JSR-51
+     */
+    public void interrupt() {
+        if (this != Thread.currentThread())
+            checkAccess();
+
+        synchronized (blockerLock) {
+            Interruptible b = blocker;
+            if (b != null) {
+                interrupt0();           // Just to set the interrupt flag
+                b.interrupt(this);
+                return;
+            }
+        }
+        interrupt0();
+    }
+
+    /**
+     * Tests whether the current thread has been interrupted.  The
+     * <i>interrupted status</i> of the thread is cleared by this method.  In
+     * other words, if this method were to be called twice in succession, the
+     * second call would return false (unless the current thread were
+     * interrupted again, after the first call had cleared its interrupted
+     * status and before the second call had examined it).
+     *
+     * <p>A thread interruption ignored because a thread was not alive
+     * at the time of the interrupt will be reflected by this method
+     * returning false.
+     *
+     * @return  <code>true</code> if the current thread has been interrupted;
+     *          <code>false</code> otherwise.
+     * @see #isInterrupted()
+     * @revised 6.0
+     */
+    // Android-changed: Use native interrupted()/isInterrupted() methods.
+    // Upstream has one native method for both these methods that takes a boolean parameter that
+    // determines whether the interrupted status of the thread should be cleared after reading
+    // it. While that approach does allow code reuse it is less efficient/more complex than having
+    // a native implementation of each method because:
+    // * The pure Java interrupted() method requires two native calls, one to get the current
+    //   thread and one to get its interrupted status.
+    // * Updating the interrupted flag is more complex than simply reading it. Knowing that only
+    //   the current thread can clear the interrupted status makes the code simpler as it does not
+    //   need to be concerned about multiple threads trying to clear the status simultaneously.
+    // public static boolean interrupted() {
+    //     return currentThread().isInterrupted(true);
+    // }
+    @FastNative
+    public static native boolean interrupted();
+
+    /**
+     * Tests whether this thread has been interrupted.  The <i>interrupted
+     * status</i> of the thread is unaffected by this method.
+     *
+     * <p>A thread interruption ignored because a thread was not alive
+     * at the time of the interrupt will be reflected by this method
+     * returning false.
+     *
+     * @return  <code>true</code> if this thread has been interrupted;
+     *          <code>false</code> otherwise.
+     * @see     #interrupted()
+     * @revised 6.0
+     */
+    // Android-changed: Use native interrupted()/isInterrupted() methods.
+    // public boolean isInterrupted() {
+    //     return isInterrupted(false);
+    // }
+    @FastNative
+    public native boolean isInterrupted();
+
+    // Android-removed: Use native interrupted()/isInterrupted() methods.
+    /*
+    /**
+     * Tests if some Thread has been interrupted.  The interrupted state
+     * is reset or not based on the value of ClearInterrupted that is
+     * passed.
+     *
+    private native boolean isInterrupted(boolean ClearInterrupted);
+    */
+
+    // BEGIN Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
+    /**
+     * Throws {@link UnsupportedOperationException}.
+     *
+     * @deprecated This method was originally designed to destroy this
+     *     thread without any cleanup. Any monitors it held would have
+     *     remained locked. However, the method was never implemented.
+     *     If if were to be implemented, it would be deadlock-prone in
+     *     much the manner of {@link #suspend}. If the target thread held
+     *     a lock protecting a critical system resource when it was
+     *     destroyed, no thread could ever access this resource again.
+     *     If another thread ever attempted to lock this resource, deadlock
+     *     would result. Such deadlocks typically manifest themselves as
+     *     "frozen" processes. For more information, see
+     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
+     *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     * @throws UnsupportedOperationException always
+     */
+    @Deprecated
+    public void destroy() {
+        throw new UnsupportedOperationException();
+    }
+    // END Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
+
+    /**
+     * Tests if this thread is alive. A thread is alive if it has
+     * been started and has not yet died.
+     *
+     * @return  <code>true</code> if this thread is alive;
+     *          <code>false</code> otherwise.
+     */
+    // Android-changed: Provide pure Java implementation of isAlive().
+    public final boolean isAlive() {
+        return nativePeer != 0;
+    }
+
+    // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
+    /**
+     * Throws {@link UnsupportedOperationException}.
+     *
+     * @deprecated   This method was designed to suspend the Thread but it was
+     *   inherently deadlock-prone.  If the target thread holds a lock on the
+     *   monitor protecting a critical system resource when it is suspended, no
+     *   thread can access this resource until the target thread is resumed. If
+     *   the thread that would resume the target thread attempts to lock this
+     *   monitor prior to calling <code>resume</code>, deadlock results.  Such
+     *   deadlocks typically manifest themselves as "frozen" processes.
+     *   For more information, see
+     *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     * @throws UnsupportedOperationException always
+     */
+    @Deprecated
+    public final void suspend() {
+        // Android-changed: Unsupported on Android.
+        // checkAccess();
+        // suspend0();
+
+        throw new UnsupportedOperationException();
+    }
+
+    // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
+    /**
+     * Throws {@link UnsupportedOperationException}.
+     *
+     * @deprecated This method exists solely for use with {@link #suspend},
+     *     which has been deprecated because it is deadlock-prone.
+     *     For more information, see
+     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+     *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     * @throws UnsupportedOperationException always
+     */
+    @Deprecated
+    public final void resume() {
+        // Android-changed: Unsupported on Android.
+        // checkAccess();
+        // resume0();
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Changes the priority of this thread.
+     * <p>
+     * First the <code>checkAccess</code> method of this thread is called
+     * with no arguments. This may result in throwing a
+     * <code>SecurityException</code>.
+     * <p>
+     * Otherwise, the priority of this thread is set to the smaller of
+     * the specified <code>newPriority</code> and the maximum permitted
+     * priority of the thread's thread group.
+     *
+     * @param newPriority priority to set this thread to
+     * @exception  IllegalArgumentException  If the priority is not in the
+     *               range <code>MIN_PRIORITY</code> to
+     *               <code>MAX_PRIORITY</code>.
+     * @exception  SecurityException  if the current thread cannot modify
+     *               this thread.
+     * @see        #getPriority
+     * @see        #checkAccess()
+     * @see        #getThreadGroup()
+     * @see        #MAX_PRIORITY
+     * @see        #MIN_PRIORITY
+     * @see        ThreadGroup#getMaxPriority()
+     */
+    public final void setPriority(int newPriority) {
+        ThreadGroup g;
+        checkAccess();
+        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
+            // Android-changed: Improve exception message when the new priority is out of bounds.
+            throw new IllegalArgumentException("Priority out of range: " + newPriority);
+        }
+        if((g = getThreadGroup()) != null) {
+            if (newPriority > g.getMaxPriority()) {
+                newPriority = g.getMaxPriority();
+            }
+            // Android-changed: Avoid native call if Thread is not yet started.
+            // setPriority0(priority = newPriority);
+            synchronized(this) {
+                this.priority = newPriority;
+                if (isAlive()) {
+                    // BEGIN Android-added: Customize behavior of Thread.setPriority().
+                    // http://b/139521784
+                    // setPriority0(newPriority);
+                    ThreadPrioritySetter threadPrioritySetter =
+                        RuntimeHooks.getThreadPrioritySetter();
+                    int nativeTid = this.getNativeTid();
+                    if (threadPrioritySetter != null && nativeTid != 0) {
+                        threadPrioritySetter.setPriority(nativeTid, newPriority);
+                    } else {
+                        setPriority0(newPriority);
+                    }
+                    // END Android-added: Customize behavior of Thread.setPriority().
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns this thread's priority.
+     *
+     * @return  this thread's priority.
+     * @see     #setPriority
+     */
+    public final int getPriority() {
+        return priority;
+    }
+
+    /**
+     * Changes the name of this thread to be equal to the argument
+     * <code>name</code>.
+     * <p>
+     * First the <code>checkAccess</code> method of this thread is called
+     * with no arguments. This may result in throwing a
+     * <code>SecurityException</code>.
+     *
+     * @param      name   the new name for this thread.
+     * @exception  SecurityException  if the current thread cannot modify this
+     *               thread.
+     * @see        #getName
+     * @see        #checkAccess()
+     */
+    public final synchronized void setName(String name) {
+        checkAccess();
+        if (name == null) {
+            throw new NullPointerException("name cannot be null");
+        }
+
+        this.name = name;
+        // Android-changed: Use isAlive() not threadStatus to check whether Thread has started.
+        // The threadStatus field is not used in Android.
+        // if (threadStatus != 0) {
+        if (isAlive()) {
+            setNativeName(name);
+        }
+    }
+
+    /**
+     * Returns this thread's name.
+     *
+     * @return  this thread's name.
+     * @see     #setName(String)
+     */
+    public final String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the thread group to which this thread belongs.
+     * This method returns null if this thread has died
+     * (been stopped).
+     *
+     * @return  this thread's thread group.
+     */
+    public final ThreadGroup getThreadGroup() {
+        // BEGIN Android-added: Work around exit() not being called.
+        // Android runtime does not call exit() when a Thread exits so the group field is not
+        // set to null so it needs to pretend as if it did. If we are not going to call exit()
+        // then this should probably just check isAlive() here rather than getState() as the
+        // latter requires a native call.
+        if (getState() == Thread.State.TERMINATED) {
+            return null;
+        }
+        // END Android-added: Work around exit() not being called.
+        return group;
+    }
+
+    /**
+     * Returns an estimate of the number of active threads in the current
+     * thread's {@linkplain java.lang.ThreadGroup thread group} and its
+     * subgroups. Recursively iterates over all subgroups in the current
+     * thread's thread group.
+     *
+     * <p> The value returned is only an estimate because the number of
+     * threads may change dynamically while this method traverses internal
+     * data structures, and might be affected by the presence of certain
+     * system threads. This method is intended primarily for debugging
+     * and monitoring purposes.
+     *
+     * @return  an estimate of the number of active threads in the current
+     *          thread's thread group and in any other thread group that
+     *          has the current thread's thread group as an ancestor
+     */
+    public static int activeCount() {
+        return currentThread().getThreadGroup().activeCount();
+    }
+
+    /**
+     * Copies into the specified array every active thread in the current
+     * thread's thread group and its subgroups. This method simply
+     * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
+     * method of the current thread's thread group.
+     *
+     * <p> An application might use the {@linkplain #activeCount activeCount}
+     * method to get an estimate of how big the array should be, however
+     * <i>if the array is too short to hold all the threads, the extra threads
+     * are silently ignored.</i>  If it is critical to obtain every active
+     * thread in the current thread's thread group and its subgroups, the
+     * invoker should verify that the returned int value is strictly less
+     * than the length of {@code tarray}.
+     *
+     * <p> Due to the inherent race condition in this method, it is recommended
+     * that the method only be used for debugging and monitoring purposes.
+     *
+     * @param  tarray
+     *         an array into which to put the list of threads
+     *
+     * @return  the number of threads put into the array
+     *
+     * @throws  SecurityException
+     *          if {@link java.lang.ThreadGroup#checkAccess} determines that
+     *          the current thread cannot access its thread group
+     */
+    public static int enumerate(Thread tarray[]) {
+        return currentThread().getThreadGroup().enumerate(tarray);
+    }
+
+    /**
+     * Counts the number of stack frames in this thread. The thread must
+     * be suspended.
+     *
+     * @return     the number of stack frames in this thread.
+     * @exception  IllegalThreadStateException  if this thread is not
+     *             suspended.
+     * @deprecated The definition of this call depends on {@link #suspend},
+     *             which is deprecated.  Further, the results of this call
+     *             were never well-defined.
+     */
+    @Deprecated
+    // Android-changed: Provide non-native implementation of countStackFrames().
+    // public native int countStackFrames();
+    public int countStackFrames() {
+        return getStackTrace().length;
+    }
+
+    /**
+     * Waits at most {@code millis} milliseconds for this thread to
+     * die. A timeout of {@code 0} means to wait forever.
+     *
+     * <p> This implementation uses a loop of {@code this.wait} calls
+     * conditioned on {@code this.isAlive}. As a thread terminates the
+     * {@code this.notifyAll} method is invoked. It is recommended that
+     * applications not use {@code wait}, {@code notify}, or
+     * {@code notifyAll} on {@code Thread} instances.
+     *
+     * @param  millis
+     *         the time to wait in milliseconds
+     *
+     * @throws  IllegalArgumentException
+     *          if the value of {@code millis} is negative
+     *
+     * @throws  InterruptedException
+     *          if any thread has interrupted the current thread. The
+     *          <i>interrupted status</i> of the current thread is
+     *          cleared when this exception is thrown.
+     */
+    // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+    // public final synchronized void join(long millis)
+    public final void join(long millis)
+    throws InterruptedException {
+        synchronized(lock) {
+        long base = System.currentTimeMillis();
+        long now = 0;
+
+        if (millis < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (millis == 0) {
+            while (isAlive()) {
+                lock.wait(0);
+            }
+        } else {
+            while (isAlive()) {
+                long delay = millis - now;
+                if (delay <= 0) {
+                    break;
+                }
+                lock.wait(delay);
+                now = System.currentTimeMillis() - base;
+            }
+        }
+        }
+    }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
+
+    /**
+     * Waits at most {@code millis} milliseconds plus
+     * {@code nanos} nanoseconds for this thread to die.
+     *
+     * <p> This implementation uses a loop of {@code this.wait} calls
+     * conditioned on {@code this.isAlive}. As a thread terminates the
+     * {@code this.notifyAll} method is invoked. It is recommended that
+     * applications not use {@code wait}, {@code notify}, or
+     * {@code notifyAll} on {@code Thread} instances.
+     *
+     * @param  millis
+     *         the time to wait in milliseconds
+     *
+     * @param  nanos
+     *         {@code 0-999999} additional nanoseconds to wait
+     *
+     * @throws  IllegalArgumentException
+     *          if the value of {@code millis} is negative, or the value
+     *          of {@code nanos} is not in the range {@code 0-999999}
+     *
+     * @throws  InterruptedException
+     *          if any thread has interrupted the current thread. The
+     *          <i>interrupted status</i> of the current thread is
+     *          cleared when this exception is thrown.
+     */
+    // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+    // public final synchronized void join(long millis, int nanos)
+    public final void join(long millis, int nanos)
+    throws InterruptedException {
+
+        synchronized(lock) {
+        if (millis < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+
+        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+            millis++;
+        }
+
+        join(millis);
+        }
+    }
+    // END Android-changed: Synchronize on separate lock object not this Thread.
+
+    /**
+     * Waits for this thread to die.
+     *
+     * <p> An invocation of this method behaves in exactly the same
+     * way as the invocation
+     *
+     * <blockquote>
+     * {@linkplain #join(long) join}{@code (0)}
+     * </blockquote>
+     *
+     * @throws  InterruptedException
+     *          if any thread has interrupted the current thread. The
+     *          <i>interrupted status</i> of the current thread is
+     *          cleared when this exception is thrown.
+     */
+    public final void join() throws InterruptedException {
+        join(0);
+    }
+
+    /**
+     * Prints a stack trace of the current thread to the standard error stream.
+     * This method is used only for debugging.
+     *
+     * @see     Throwable#printStackTrace()
+     */
+    public static void dumpStack() {
+        new Exception("Stack trace").printStackTrace();
+    }
+
+    /**
+     * Marks this thread as either a {@linkplain #isDaemon daemon} thread
+     * or a user thread. The Java Virtual Machine exits when the only
+     * threads running are all daemon threads.
+     *
+     * <p> This method must be invoked before the thread is started.
+     *
+     * @param  on
+     *         if {@code true}, marks this thread as a daemon thread
+     *
+     * @throws  IllegalThreadStateException
+     *          if this thread is {@linkplain #isAlive alive}
+     *
+     * @throws  SecurityException
+     *          if {@link #checkAccess} determines that the current
+     *          thread cannot modify this thread
+     */
+    public final void setDaemon(boolean on) {
+        checkAccess();
+        if (isAlive()) {
+            throw new IllegalThreadStateException();
+        }
+        daemon = on;
+    }
+
+    /**
+     * Tests if this thread is a daemon thread.
+     *
+     * @return  <code>true</code> if this thread is a daemon thread;
+     *          <code>false</code> otherwise.
+     * @see     #setDaemon(boolean)
+     */
+    public final boolean isDaemon() {
+        return daemon;
+    }
+
+    /**
+     * Determines if the currently running thread has permission to
+     * modify this thread.
+     * <p>
+     * If there is a security manager, its <code>checkAccess</code> method
+     * is called with this thread as its argument. This may result in
+     * throwing a <code>SecurityException</code>.
+     *
+     * @exception  SecurityException  if the current thread is not allowed to
+     *               access this thread.
+     * @see        SecurityManager#checkAccess(Thread)
+     */
+    public final void checkAccess() {
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager security = System.getSecurityManager();
+        // if (security != null) {
+        //     security.checkAccess(this);
+        // }
+    }
+
+    /**
+     * Returns a string representation of this thread, including the
+     * thread's name, priority, and thread group.
+     *
+     * @return  a string representation of this thread.
+     */
+    public String toString() {
+        ThreadGroup group = getThreadGroup();
+        if (group != null) {
+            return "Thread[" + getName() + "," + getPriority() + "," +
+                           group.getName() + "]";
+        } else {
+            return "Thread[" + getName() + "," + getPriority() + "," +
+                            "" + "]";
+        }
+    }
+
+    /**
+     * Returns the context ClassLoader for this Thread. The context
+     * ClassLoader is provided by the creator of the thread for use
+     * by code running in this thread when loading classes and resources.
+     * If not {@linkplain #setContextClassLoader set}, the default is the
+     * ClassLoader context of the parent Thread. The context ClassLoader of the
+     * primordial thread is typically set to the class loader used to load the
+     * application.
+     *
+     * <p>If a security manager is present, and the invoker's class loader is not
+     * {@code null} and is not the same as or an ancestor of the context class
+     * loader, then this method invokes the security manager's {@link
+     * SecurityManager#checkPermission(java.security.Permission) checkPermission}
+     * method with a {@link RuntimePermission RuntimePermission}{@code
+     * ("getClassLoader")} permission to verify that retrieval of the context
+     * class loader is permitted.
+     *
+     * @return  the context ClassLoader for this Thread, or {@code null}
+     *          indicating the system class loader (or, failing that, the
+     *          bootstrap class loader)
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot get the context ClassLoader
+     *
+     * @since 1.2
+     */
+    @CallerSensitive
+    public ClassLoader getContextClassLoader() {
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        if (contextClassLoader == null)
+            return null;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            ClassLoader.checkClassLoaderPermission(contextClassLoader,
+                                                   Reflection.getCallerClass());
+        }
+        */
+        return contextClassLoader;
+    }
+
+    /**
+     * Sets the context ClassLoader for this Thread. The context
+     * ClassLoader can be set when a thread is created, and allows
+     * the creator of the thread to provide the appropriate class loader,
+     * through {@code getContextClassLoader}, to code running in the thread
+     * when loading classes and resources.
+     *
+     * <p>If a security manager is present, its {@link
+     * SecurityManager#checkPermission(java.security.Permission) checkPermission}
+     * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
+     * ("setContextClassLoader")} permission to see if setting the context
+     * ClassLoader is permitted.
+     *
+     * @param  cl
+     *         the context ClassLoader for this Thread, or null  indicating the
+     *         system class loader (or, failing that, the bootstrap class loader)
+     *
+     * @throws  SecurityException
+     *          if the current thread cannot set the context ClassLoader
+     *
+     * @since 1.2
+     */
+    public void setContextClassLoader(ClassLoader cl) {
+        // Android-removed: SecurityManager stubbed out on Android
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm != null) {
+        //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+        // }
+        contextClassLoader = cl;
+    }
+
+    /**
+     * Returns <tt>true</tt> if and only if the current thread holds the
+     * monitor lock on the specified object.
+     *
+     * <p>This method is designed to allow a program to assert that
+     * the current thread already holds a specified lock:
+     * <pre>
+     *     assert Thread.holdsLock(obj);
+     * </pre>
+     *
+     * @param  obj the object on which to test lock ownership
+     * @throws NullPointerException if obj is <tt>null</tt>
+     * @return <tt>true</tt> if the current thread holds the monitor lock on
+     *         the specified object.
+     * @since 1.4
+     */
+    public static native boolean holdsLock(Object obj);
+
+    private static final StackTraceElement[] EMPTY_STACK_TRACE
+        = new StackTraceElement[0];
+
+    /**
+     * Returns an array of stack trace elements representing the stack dump
+     * of this thread.  This method will return a zero-length array if
+     * this thread has not started, has started but has not yet been
+     * scheduled to run by the system, or has terminated.
+     * If the returned array is of non-zero length then the first element of
+     * the array represents the top of the stack, which is the most recent
+     * method invocation in the sequence.  The last element of the array
+     * represents the bottom of the stack, which is the least recent method
+     * invocation in the sequence.
+     *
+     * <p>If there is a security manager, and this thread is not
+     * the current thread, then the security manager's
+     * <tt>checkPermission</tt> method is called with a
+     * <tt>RuntimePermission("getStackTrace")</tt> permission
+     * to see if it's ok to get the stack trace.
+     *
+     * <p>Some virtual machines may, under some circumstances, omit one
+     * or more stack frames from the stack trace.  In the extreme case,
+     * a virtual machine that has no stack trace information concerning
+     * this thread is permitted to return a zero-length array from this
+     * method.
+     *
+     * @return an array of <tt>StackTraceElement</tt>,
+     * each represents one stack frame.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        <tt>checkPermission</tt> method doesn't allow
+     *        getting the stack trace of thread.
+     * @see SecurityManager#checkPermission
+     * @see RuntimePermission
+     * @see Throwable#getStackTrace
+     *
+     * @since 1.5
+     */
+    public StackTraceElement[] getStackTrace() {
+        // Android-changed: Use native VMStack to get stack trace.
+        StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
+        return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
+    }
+
+    /**
+     * Returns a map of stack traces for all live threads.
+     * The map keys are threads and each map value is an array of
+     * <tt>StackTraceElement</tt> that represents the stack dump
+     * of the corresponding <tt>Thread</tt>.
+     * The returned stack traces are in the format specified for
+     * the {@link #getStackTrace getStackTrace} method.
+     *
+     * <p>The threads may be executing while this method is called.
+     * The stack trace of each thread only represents a snapshot and
+     * each stack trace may be obtained at different time.  A zero-length
+     * array will be returned in the map value if the virtual machine has
+     * no stack trace information about a thread.
+     *
+     * <p>If there is a security manager, then the security manager's
+     * <tt>checkPermission</tt> method is called with a
+     * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
+     * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
+     * to see if it is ok to get the stack trace of all threads.
+     *
+     * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
+     * <tt>StackTraceElement</tt> that represents the stack trace of
+     * the corresponding thread.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        <tt>checkPermission</tt> method doesn't allow
+     *        getting the stack trace of thread.
+     * @see #getStackTrace
+     * @see SecurityManager#checkPermission
+     * @see RuntimePermission
+     * @see Throwable#getStackTrace
+     *
+     * @since 1.5
+     */
+    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        // check for getStackTrace permission
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(
+                SecurityConstants.GET_STACK_TRACE_PERMISSION);
+            security.checkPermission(
+                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+        }
+        */
+
+        // Get a snapshot of the list of all threads
+        // BEGIN Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+        // Allocate a bit more space than needed, in case new ones are just being created.
+        /*
+        Thread[] threads = getThreads();
+        StackTraceElement[][] traces = dumpThreads(threads);
+        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
+        for (int i = 0; i < threads.length; i++) {
+            StackTraceElement[] stackTrace = traces[i];
+            if (stackTrace != null) {
+                m.put(threads[i], stackTrace);
+            }
+            // else terminated so we don't put it in the map
+        }
+        */
+        int count = ThreadGroup.systemThreadGroup.activeCount();
+        Thread[] threads = new Thread[count + count / 2];
+
+        // Enumerate the threads.
+        count = ThreadGroup.systemThreadGroup.enumerate(threads);
+
+        // Collect the stacktraces
+        Map<Thread, StackTraceElement[]> m = new HashMap<Thread, StackTraceElement[]>();
+        for (int i = 0; i < count; i++) {
+            StackTraceElement[] stackTrace = threads[i].getStackTrace();
+            m.put(threads[i], stackTrace);
+        }
+        // END Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+        return m;
+    }
+
+
+    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
+                    new RuntimePermission("enableContextClassLoaderOverride");
+
+    /** cache of subclass security audit results */
+    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
+     * release */
+    private static class Caches {
+        /** cache of subclass security audit results */
+        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
+            new ConcurrentHashMap<>();
+
+        /** queue for WeakReferences to audited subclasses */
+        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
+            new ReferenceQueue<>();
+    }
+
+    /**
+     * Verifies that this (possibly subclass) instance can be constructed
+     * without violating security constraints: the subclass must not override
+     * security-sensitive non-final methods, or else the
+     * "enableContextClassLoaderOverride" RuntimePermission is checked.
+     */
+    private static boolean isCCLOverridden(Class<?> cl) {
+        if (cl == Thread.class)
+            return false;
+
+        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
+        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
+        Boolean result = Caches.subclassAudits.get(key);
+        if (result == null) {
+            result = Boolean.valueOf(auditSubclass(cl));
+            Caches.subclassAudits.putIfAbsent(key, result);
+        }
+
+        return result.booleanValue();
+    }
+
+    /**
+     * Performs reflective checks on given subclass to verify that it doesn't
+     * override security-sensitive non-final methods.  Returns true if the
+     * subclass overrides any of the methods, false otherwise.
+     */
+    private static boolean auditSubclass(final Class<?> subcl) {
+        Boolean result = AccessController.doPrivileged(
+            new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    for (Class<?> cl = subcl;
+                         cl != Thread.class;
+                         cl = cl.getSuperclass())
+                    {
+                        try {
+                            cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
+                            return Boolean.TRUE;
+                        } catch (NoSuchMethodException ex) {
+                        }
+                        try {
+                            Class<?>[] params = {ClassLoader.class};
+                            cl.getDeclaredMethod("setContextClassLoader", params);
+                            return Boolean.TRUE;
+                        } catch (NoSuchMethodException ex) {
+                        }
+                    }
+                    return Boolean.FALSE;
+                }
+            }
+        );
+        return result.booleanValue();
+    }
+
+    // Android-removed: Native methods that are unused on Android.
+    // private native static StackTraceElement[][] dumpThreads(Thread[] threads);
+    // private native static Thread[] getThreads();
+
+    /**
+     * Returns the identifier of this Thread.  The thread ID is a positive
+     * <tt>long</tt> number generated when this thread was created.
+     * The thread ID is unique and remains unchanged during its lifetime.
+     * When a thread is terminated, this thread ID may be reused.
+     *
+     * @return this thread's ID.
+     * @since 1.5
+     */
+    public long getId() {
+        return tid;
+    }
+
+    /**
+     * A thread state.  A thread can be in one of the following states:
+     * <ul>
+     * <li>{@link #NEW}<br>
+     *     A thread that has not yet started is in this state.
+     *     </li>
+     * <li>{@link #RUNNABLE}<br>
+     *     A thread executing in the Java virtual machine is in this state.
+     *     </li>
+     * <li>{@link #BLOCKED}<br>
+     *     A thread that is blocked waiting for a monitor lock
+     *     is in this state.
+     *     </li>
+     * <li>{@link #WAITING}<br>
+     *     A thread that is waiting indefinitely for another thread to
+     *     perform a particular action is in this state.
+     *     </li>
+     * <li>{@link #TIMED_WAITING}<br>
+     *     A thread that is waiting for another thread to perform an action
+     *     for up to a specified waiting time is in this state.
+     *     </li>
+     * <li>{@link #TERMINATED}<br>
+     *     A thread that has exited is in this state.
+     *     </li>
+     * </ul>
+     *
+     * <p>
+     * A thread can be in only one state at a given point in time.
+     * These states are virtual machine states which do not reflect
+     * any operating system thread states.
+     *
+     * @since   1.5
+     * @see #getState
+     */
+    public enum State {
+        /**
+         * Thread state for a thread which has not yet started.
+         */
+        NEW,
+
+        /**
+         * Thread state for a runnable thread.  A thread in the runnable
+         * state is executing in the Java virtual machine but it may
+         * be waiting for other resources from the operating system
+         * such as processor.
+         */
+        RUNNABLE,
+
+        /**
+         * Thread state for a thread blocked waiting for a monitor lock.
+         * A thread in the blocked state is waiting for a monitor lock
+         * to enter a synchronized block/method or
+         * reenter a synchronized block/method after calling
+         * {@link Object#wait() Object.wait}.
+         */
+        BLOCKED,
+
+        /**
+         * Thread state for a waiting thread.
+         * A thread is in the waiting state due to calling one of the
+         * following methods:
+         * <ul>
+         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
+         *   <li>{@link #join() Thread.join} with no timeout</li>
+         *   <li>{@link LockSupport#park() LockSupport.park}</li>
+         * </ul>
+         *
+         * <p>A thread in the waiting state is waiting for another thread to
+         * perform a particular action.
+         *
+         * For example, a thread that has called <tt>Object.wait()</tt>
+         * on an object is waiting for another thread to call
+         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
+         * that object. A thread that has called <tt>Thread.join()</tt>
+         * is waiting for a specified thread to terminate.
+         */
+        WAITING,
+
+        /**
+         * Thread state for a waiting thread with a specified waiting time.
+         * A thread is in the timed waiting state due to calling one of
+         * the following methods with a specified positive waiting time:
+         * <ul>
+         *   <li>{@link #sleep Thread.sleep}</li>
+         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
+         *   <li>{@link #join(long) Thread.join} with timeout</li>
+         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
+         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
+         * </ul>
+         */
+        TIMED_WAITING,
+
+        /**
+         * Thread state for a terminated thread.
+         * The thread has completed execution.
+         */
+        TERMINATED;
+    }
+
+    /**
+     * Returns the state of this thread.
+     * This method is designed for use in monitoring of the system state,
+     * not for synchronization control.
+     *
+     * @return this thread's state.
+     * @since 1.5
+     */
+    public State getState() {
+        // get current thread state
+        // Android-changed: Replace unused threadStatus field with started field.
+        // Use Android specific nativeGetStatus() method. See comment on started field for more
+        // information.
+        // return sun.misc.VM.toThreadState(threadStatus);
+        return State.values()[nativeGetStatus(started)];
+    }
+
+    // Added in JSR-166
+
+    /**
+     * Interface for handlers invoked when a <tt>Thread</tt> abruptly
+     * terminates due to an uncaught exception.
+     * <p>When a thread is about to terminate due to an uncaught exception
+     * the Java Virtual Machine will query the thread for its
+     * <tt>UncaughtExceptionHandler</tt> using
+     * {@link #getUncaughtExceptionHandler} and will invoke the handler's
+     * <tt>uncaughtException</tt> method, passing the thread and the
+     * exception as arguments.
+     * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
+     * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
+     * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
+     * has no
+     * special requirements for dealing with the exception, it can forward
+     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
+     * default uncaught exception handler}.
+     *
+     * @see #setDefaultUncaughtExceptionHandler
+     * @see #setUncaughtExceptionHandler
+     * @see ThreadGroup#uncaughtException
+     * @since 1.5
+     */
+    @FunctionalInterface
+    public interface UncaughtExceptionHandler {
+        /**
+         * Method invoked when the given thread terminates due to the
+         * given uncaught exception.
+         * <p>Any exception thrown by this method will be ignored by the
+         * Java Virtual Machine.
+         * @param t the thread
+         * @param e the exception
+         */
+        void uncaughtException(Thread t, Throwable e);
+    }
+
+    // null unless explicitly set
+    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
+
+    // null unless explicitly set
+    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
+
+    /**
+     * Set the default handler invoked when a thread abruptly terminates
+     * due to an uncaught exception, and no other handler has been defined
+     * for that thread.
+     *
+     * <p>Uncaught exception handling is controlled first by the thread, then
+     * by the thread's {@link ThreadGroup} object and finally by the default
+     * uncaught exception handler. If the thread does not have an explicit
+     * uncaught exception handler set, and the thread's thread group
+     * (including parent thread groups)  does not specialize its
+     * <tt>uncaughtException</tt> method, then the default handler's
+     * <tt>uncaughtException</tt> method will be invoked.
+     * <p>By setting the default uncaught exception handler, an application
+     * can change the way in which uncaught exceptions are handled (such as
+     * logging to a specific device, or file) for those threads that would
+     * already accept whatever &quot;default&quot; behavior the system
+     * provided.
+     *
+     * <p>Note that the default uncaught exception handler should not usually
+     * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
+     * infinite recursion.
+     *
+     * @param eh the object to use as the default uncaught exception handler.
+     * If <tt>null</tt> then there is no default handler.
+     *
+     * @throws SecurityException if a security manager is present and it
+     *         denies <tt>{@link RuntimePermission}
+     *         (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
+     *
+     * @see #setUncaughtExceptionHandler
+     * @see #getUncaughtExceptionHandler
+     * @see ThreadGroup#uncaughtException
+     * @since 1.5
+     */
+    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+        // Android-removed: SecurityManager stubbed out on Android
+        /*
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(
+                new RuntimePermission("setDefaultUncaughtExceptionHandler")
+                    );
+        }
+        */
+
+         defaultUncaughtExceptionHandler = eh;
+     }
+
+    /**
+     * Returns the default handler invoked when a thread abruptly terminates
+     * due to an uncaught exception. If the returned value is <tt>null</tt>,
+     * there is no default.
+     * @since 1.5
+     * @see #setDefaultUncaughtExceptionHandler
+     * @return the default uncaught exception handler for all threads
+     */
+    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
+        return defaultUncaughtExceptionHandler;
+    }
+
+    // BEGIN Android-added: The concept of an uncaughtExceptionPreHandler for use by platform.
+    // See http://b/29624607 for background information.
+    // null unless explicitly set
+    private static volatile UncaughtExceptionHandler uncaughtExceptionPreHandler;
+
+    /**
+     * Sets an {@link UncaughtExceptionHandler} that will be called before any
+     * returned by {@link #getUncaughtExceptionHandler()}. To allow the standard
+     * handlers to run, this handler should never terminate this process. Any
+     * throwables thrown by the handler will be ignored by
+     * {@link #dispatchUncaughtException(Throwable)}.
+     *
+     * @hide used when configuring the runtime for exception logging; see
+     *     {@link dalvik.system.RuntimeHooks} b/29624607
+     */
+    public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) {
+        uncaughtExceptionPreHandler = eh;
+    }
+
+    /** @hide */
+    public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
+        return uncaughtExceptionPreHandler;
+    }
+    // END Android-added: The concept of an uncaughtExceptionPreHandler for use by platform.
+
+    /**
+     * Returns the handler invoked when this thread abruptly terminates
+     * due to an uncaught exception. If this thread has not had an
+     * uncaught exception handler explicitly set then this thread's
+     * <tt>ThreadGroup</tt> object is returned, unless this thread
+     * has terminated, in which case <tt>null</tt> is returned.
+     * @since 1.5
+     * @return the uncaught exception handler for this thread
+     */
+    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
+        return uncaughtExceptionHandler != null ?
+            uncaughtExceptionHandler : group;
+    }
+
+    /**
+     * Set the handler invoked when this thread abruptly terminates
+     * due to an uncaught exception.
+     * <p>A thread can take full control of how it responds to uncaught
+     * exceptions by having its uncaught exception handler explicitly set.
+     * If no such handler is set then the thread's <tt>ThreadGroup</tt>
+     * object acts as its handler.
+     * @param eh the object to use as this thread's uncaught exception
+     * handler. If <tt>null</tt> then this thread has no explicit handler.
+     * @throws  SecurityException  if the current thread is not allowed to
+     *          modify this thread.
+     * @see #setDefaultUncaughtExceptionHandler
+     * @see ThreadGroup#uncaughtException
+     * @since 1.5
+     */
+    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+        checkAccess();
+        uncaughtExceptionHandler = eh;
+    }
+
+    /**
+     * Dispatch an uncaught exception to the handler. This method is
+     * intended to be called only by the runtime and by tests.
+     *
+     * @hide
+     */
+    // Android-changed: Make dispatchUncaughtException() public, for use by tests.
+    public final void dispatchUncaughtException(Throwable e) {
+        // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
+        Thread.UncaughtExceptionHandler initialUeh =
+                Thread.getUncaughtExceptionPreHandler();
+        if (initialUeh != null) {
+            try {
+                initialUeh.uncaughtException(this, e);
+            } catch (RuntimeException | Error ignored) {
+                // Throwables thrown by the initial handler are ignored
+            }
+        }
+        // END Android-added: uncaughtExceptionPreHandler for use by platform.
+        getUncaughtExceptionHandler().uncaughtException(this, e);
+    }
+
+    // BEGIN Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /**
+     * Marks this thread as either a special runtime-managed ("system daemon")
+     * thread or a normal (i.e. app code created) daemon thread.)
+     *
+     * <p>System daemon threads get special handling when starting up in some
+     * cases.
+     *
+     * <p>This method must be invoked before the thread is started.
+     *
+     * <p>This method must only be invoked on Thread instances that have already
+     * had {@code setDaemon(true)} called on them.
+     *
+     * <p>Package-private since only {@link java.lang.Daemons} needs to call
+     * this.
+     *
+     * @param  on if {@code true}, marks this thread as a system daemon thread
+     *
+     * @throws  IllegalThreadStateException
+     *          if this thread is {@linkplain #isAlive alive} or not a
+     *          {@linkplain #isDaemon daemon}
+     *
+     * @throws  SecurityException
+     *          if {@link #checkAccess} determines that the current
+     *          thread cannot modify this thread
+     *
+     * @hide For use by Daemons.java only.
+     */
+    final void setSystemDaemon(boolean on) {
+        checkAccess();
+        if (isAlive() || !isDaemon()) {
+            throw new IllegalThreadStateException();
+        }
+        systemDaemon = on;
+    }
+    // END Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+
+    /**
+     * Removes from the specified map any keys that have been enqueued
+     * on the specified reference queue.
+     */
+    static void processQueue(ReferenceQueue<Class<?>> queue,
+                             ConcurrentMap<? extends
+                             WeakReference<Class<?>>, ?> map)
+    {
+        Reference<? extends Class<?>> ref;
+        while((ref = queue.poll()) != null) {
+            map.remove(ref);
+        }
+    }
+
+    /**
+     *  Weak key for Class objects.
+     **/
+    static class WeakClassKey extends WeakReference<Class<?>> {
+        /**
+         * saved value of the referent's identity hash code, to maintain
+         * a consistent hash code after the referent has been cleared
+         */
+        private final int hash;
+
+        /**
+         * Create a new WeakClassKey to the given object, registered
+         * with a queue.
+         */
+        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
+            super(cl, refQueue);
+            hash = System.identityHashCode(cl);
+        }
+
+        /**
+         * Returns the identity hash code of the original referent.
+         */
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        /**
+         * Returns true if the given object is this identical
+         * WeakClassKey instance, or, if this object's referent has not
+         * been cleared, if the given object is another WeakClassKey
+         * instance with the identical non-null referent as this one.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+
+            if (obj instanceof WeakClassKey) {
+                Object referent = get();
+                return (referent != null) &&
+                       (referent == ((WeakClassKey) obj).get());
+            } else {
+                return false;
+            }
+        }
+    }
+
+
+    // The following three initially uninitialized fields are exclusively
+    // managed by class java.util.concurrent.ThreadLocalRandom. These
+    // fields are used to build the high-performance PRNGs in the
+    // concurrent code, and we can not risk accidental false sharing.
+    // Hence, the fields are isolated with @Contended.
+
+    // BEGIN Android-changed: @sun.misc.Contended is not supported on Android.
+    /** The current seed for a ThreadLocalRandom */
+    // @sun.misc.Contended("tlr")
+    long threadLocalRandomSeed;
+
+    /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
+    // @sun.misc.Contended("tlr")
+    int threadLocalRandomProbe;
+
+    /** Secondary seed isolated from public ThreadLocalRandom sequence */
+    //  @sun.misc.Contended("tlr")
+    int threadLocalRandomSecondarySeed;
+    // END Android-changed: @sun.misc.Contended is not supported on Android.
+
+    /* Some private helper methods */
+    private native void setPriority0(int newPriority);
+
+    // BEGIN Android-removed: Native methods that are unused on Android.
+    /*
+    private native void stop0(Object o);
+    private native void suspend0();
+    private native void resume0();
+    */
+    // END Android-removed: Native methods that are unused on Android.
+
+    @FastNative
+    private native void interrupt0();
+    private native void setNativeName(String name);
+
+    // Android-added: Android specific nativeGetStatus() method.
+    private native int nativeGetStatus(boolean hasBeenStarted);
+
+    // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
+    /**
+     * Returns the thread ID of the underlying native thread -- which is different from
+     * the {@link #getId() managed thread ID} -- or 0 if the native thread is not
+     * started or has stopped.
+     */
+    @FastNative
+    private native int getNativeTid();
+    // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
+}
diff --git a/java/lang/ThreadDeath.java b/java/lang/ThreadDeath.java
new file mode 100644
index 0000000..79e8bb5
--- /dev/null
+++ b/java/lang/ThreadDeath.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * An instance of {@code ThreadDeath} is thrown in the victim thread
+ * when the (deprecated) {@link Thread#stop()} method is invoked.
+ *
+ * <p>An application should catch instances of this class only if it
+ * must clean up after being terminated asynchronously.  If
+ * {@code ThreadDeath} is caught by a method, it is important that it
+ * be rethrown so that the thread actually dies.
+ *
+ * <p>The {@linkplain ThreadGroup#uncaughtException top-level error
+ * handler} does not print out a message if {@code ThreadDeath} is
+ * never caught.
+ *
+ * <p>The class {@code ThreadDeath} is specifically a subclass of
+ * {@code Error} rather than {@code Exception}, even though it is a
+ * "normal occurrence", because many applications catch all
+ * occurrences of {@code Exception} and then discard the exception.
+ *
+ * @since   JDK1.0
+ */
+
+public class ThreadDeath extends Error {
+    private static final long serialVersionUID = -4417128565033088268L;
+}
diff --git a/java/lang/ThreadGroup.java b/java/lang/ThreadGroup.java
new file mode 100644
index 0000000..292b536
--- /dev/null
+++ b/java/lang/ThreadGroup.java
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 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;
+
+import java.io.PrintStream;
+import java.util.Arrays;
+import sun.misc.VM;
+
+/**
+ * A thread group represents a set of threads. In addition, a thread
+ * group can also include other thread groups. The thread groups form
+ * a tree in which every thread group except the initial thread group
+ * has a parent.
+ * <p>
+ * A thread is allowed to access information about its own thread
+ * group, but not to access information about its thread group's
+ * parent thread group or any other thread groups.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+/* The locking strategy for this code is to try to lock only one level of the
+ * tree wherever possible, but otherwise to lock from the bottom up.
+ * That is, from child thread groups to parents.
+ * This has the advantage of limiting the number of locks that need to be held
+ * and in particular avoids having to grab the lock for the root thread group,
+ * (or a global lock) which would be a source of contention on a
+ * multi-processor system with many thread groups.
+ * This policy often leads to taking a snapshot of the state of a thread group
+ * and working off of that snapshot, rather than holding the thread group locked
+ * while we work on the children.
+ */
+public
+class ThreadGroup implements Thread.UncaughtExceptionHandler {
+    /* the runtime uses these directly; do not rename */
+    static final ThreadGroup systemThreadGroup = new ThreadGroup();
+
+    static final ThreadGroup mainThreadGroup = new ThreadGroup(systemThreadGroup, "main");
+
+    private final ThreadGroup parent;
+    String name;
+    int maxPriority;
+    boolean destroyed;
+    boolean daemon;
+    boolean vmAllowSuspension;
+
+    int nUnstartedThreads = 0;
+    int nthreads;
+    Thread threads[];
+
+    int ngroups;
+    ThreadGroup groups[];
+
+    /**
+     * Creates an empty Thread group that is not in any Thread group.
+     * This method is used to create the system Thread group.
+     */
+    private ThreadGroup() {     // called from C code
+        this.name = "system";
+        this.maxPriority = Thread.MAX_PRIORITY;
+        this.parent = null;
+    }
+
+    /**
+     * Constructs a new thread group. The parent of this new group is
+     * the thread group of the currently running thread.
+     * <p>
+     * The <code>checkAccess</code> method of the parent thread group is
+     * called with no arguments; this may result in a security exception.
+     *
+     * @param   name   the name of the new thread group.
+     * @exception  SecurityException  if the current thread cannot create a
+     *               thread in the specified thread group.
+     * @see     java.lang.ThreadGroup#checkAccess()
+     * @since   JDK1.0
+     */
+    public ThreadGroup(String name) {
+        this(Thread.currentThread().getThreadGroup(), name);
+    }
+
+    /**
+     * Creates a new thread group. The parent of this new group is the
+     * specified thread group.
+     * <p>
+     * The <code>checkAccess</code> method of the parent thread group is
+     * called with no arguments; this may result in a security exception.
+     *
+     * @param     parent   the parent thread group.
+     * @param     name     the name of the new thread group.
+     * @exception  NullPointerException  if the thread group argument is
+     *               <code>null</code>.
+     * @exception  SecurityException  if the current thread cannot create a
+     *               thread in the specified thread group.
+     * @see     java.lang.SecurityException
+     * @see     java.lang.ThreadGroup#checkAccess()
+     * @since   JDK1.0
+     */
+    public ThreadGroup(ThreadGroup parent, String name) {
+        this(checkParentAccess(parent), parent, name);
+    }
+
+    private ThreadGroup(Void unused, ThreadGroup parent, String name) {
+        this.name = name;
+        this.maxPriority = parent.maxPriority;
+        this.daemon = parent.daemon;
+        this.vmAllowSuspension = parent.vmAllowSuspension;
+        this.parent = parent;
+        parent.add(this);
+    }
+
+    /*
+     * @throws  NullPointerException  if the parent argument is {@code null}
+     * @throws  SecurityException     if the current thread cannot create a
+     *                                thread in the specified thread group.
+     */
+    private static Void checkParentAccess(ThreadGroup parent) {
+        parent.checkAccess();
+        return null;
+    }
+
+    /**
+     * Returns the name of this thread group.
+     *
+     * @return  the name of this thread group.
+     * @since   JDK1.0
+     */
+    public final String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the parent of this thread group.
+     * <p>
+     * First, if the parent is not <code>null</code>, the
+     * <code>checkAccess</code> method of the parent thread group is
+     * called with no arguments; this may result in a security exception.
+     *
+     * @return  the parent of this thread group. The top-level thread group
+     *          is the only thread group whose parent is <code>null</code>.
+     * @exception  SecurityException  if the current thread cannot modify
+     *               this thread group.
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @see        java.lang.SecurityException
+     * @see        java.lang.RuntimePermission
+     * @since   JDK1.0
+     */
+    public final ThreadGroup getParent() {
+        if (parent != null)
+            parent.checkAccess();
+        return parent;
+    }
+
+    /**
+     * Returns the maximum priority of this thread group. Threads that are
+     * part of this group cannot have a higher priority than the maximum
+     * priority.
+     *
+     * @return  the maximum priority that a thread in this thread group
+     *          can have.
+     * @see     #setMaxPriority
+     * @since   JDK1.0
+     */
+    public final int getMaxPriority() {
+        return maxPriority;
+    }
+
+    /**
+     * Tests if this thread group is a daemon thread group. A
+     * daemon thread group is automatically destroyed when its last
+     * thread is stopped or its last thread group is destroyed.
+     *
+     * @return  <code>true</code> if this thread group is a daemon thread group;
+     *          <code>false</code> otherwise.
+     * @since   JDK1.0
+     */
+    public final boolean isDaemon() {
+        return daemon;
+    }
+
+    /**
+     * Tests if this thread group has been destroyed.
+     *
+     * @return  true if this object is destroyed
+     * @since   JDK1.1
+     */
+    public synchronized boolean isDestroyed() {
+        return destroyed;
+    }
+
+    /**
+     * Changes the daemon status of this thread group.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * A daemon thread group is automatically destroyed when its last
+     * thread is stopped or its last thread group is destroyed.
+     *
+     * @param      daemon   if <code>true</code>, marks this thread group as
+     *                      a daemon thread group; otherwise, marks this
+     *                      thread group as normal.
+     * @exception  SecurityException  if the current thread cannot modify
+     *               this thread group.
+     * @see        java.lang.SecurityException
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     */
+    public final void setDaemon(boolean daemon) {
+        checkAccess();
+        this.daemon = daemon;
+    }
+
+    /**
+     * Sets the maximum priority of the group. Threads in the thread
+     * group that already have a higher priority are not affected.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * If the <code>pri</code> argument is less than
+     * {@link Thread#MIN_PRIORITY} or greater than
+     * {@link Thread#MAX_PRIORITY}, it is clamped to those values.
+     * <p>
+     * Otherwise, the priority of this ThreadGroup object is set to the
+     * smaller of the specified <code>pri</code> and the maximum permitted
+     * priority of the parent of this thread group. (If this thread group
+     * is the system thread group, which has no parent, then its maximum
+     * priority is simply set to <code>pri</code>.) Then this method is
+     * called recursively, with <code>pri</code> as its argument, for
+     * every thread group that belongs to this thread group.
+     *
+     * @param      pri   the new priority of the thread group.
+     * @exception  SecurityException  if the current thread cannot modify
+     *               this thread group.
+     * @see        #getMaxPriority
+     * @see        java.lang.SecurityException
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     */
+    public final void setMaxPriority(int pri) {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            checkAccess();
+            // BEGIN Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+            // This preserves backward compatibility with previous versions of Android.
+            // if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
+            //     return;
+            // }
+            if (pri < Thread.MIN_PRIORITY) {
+                pri = Thread.MIN_PRIORITY;
+            }
+            if (pri > Thread.MAX_PRIORITY) {
+                pri = Thread.MAX_PRIORITY;
+            }
+            // END Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+
+            maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri;
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            groupsSnapshot[i].setMaxPriority(pri);
+        }
+    }
+
+    /**
+     * Tests if this thread group is either the thread group
+     * argument or one of its ancestor thread groups.
+     *
+     * @param   g   a thread group.
+     * @return  <code>true</code> if this thread group is the thread group
+     *          argument or one of its ancestor thread groups;
+     *          <code>false</code> otherwise.
+     * @since   JDK1.0
+     */
+    public final boolean parentOf(ThreadGroup g) {
+        for (; g != null ; g = g.parent) {
+            if (g == this) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determines if the currently running thread has permission to
+     * modify this thread group.
+     * <p>
+     * If there is a security manager, its <code>checkAccess</code> method
+     * is called with this thread group as its argument. This may result
+     * in throwing a <code>SecurityException</code>.
+     *
+     * @exception  SecurityException  if the current thread is not allowed to
+     *               access this thread group.
+     * @see        java.lang.SecurityManager#checkAccess(java.lang.ThreadGroup)
+     * @since      JDK1.0
+     */
+    public final void checkAccess() {
+        // Android-removed: SecurityManager stubbed out on Android.
+        // SecurityManager security = System.getSecurityManager();
+        // if (security != null) {
+        //     security.checkAccess(this);
+        // }
+    }
+
+    /**
+     * Returns an estimate of the number of active threads in this thread
+     * group and its subgroups. Recursively iterates over all subgroups in
+     * this thread group.
+     *
+     * <p> The value returned is only an estimate because the number of
+     * threads may change dynamically while this method traverses internal
+     * data structures, and might be affected by the presence of certain
+     * system threads. This method is intended primarily for debugging
+     * and monitoring purposes.
+     *
+     * @return  an estimate of the number of active threads in this thread
+     *          group and in any other thread group that has this thread
+     *          group as an ancestor
+     *
+     * @since   JDK1.0
+     */
+    public int activeCount() {
+        int result;
+        // Snapshot sub-group data so we don't hold this lock
+        // while our children are computing.
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            if (destroyed) {
+                return 0;
+            }
+            result = nthreads;
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            result += groupsSnapshot[i].activeCount();
+        }
+        return result;
+    }
+
+    /**
+     * Copies into the specified array every active thread in this
+     * thread group and its subgroups.
+     *
+     * <p> An invocation of this method behaves in exactly the same
+     * way as the invocation
+     *
+     * <blockquote>
+     * {@linkplain #enumerate(Thread[], boolean) enumerate}{@code (list, true)}
+     * </blockquote>
+     *
+     * @param  list
+     *         an array into which to put the list of threads
+     *
+     * @return  the number of threads put into the array
+     *
+     * @throws  SecurityException
+     *          if {@linkplain #checkAccess checkAccess} determines that
+     *          the current thread cannot access this thread group
+     *
+     * @since   JDK1.0
+     */
+    public int enumerate(Thread list[]) {
+        checkAccess();
+        return enumerate(list, 0, true);
+    }
+
+    /**
+     * Copies into the specified array every active thread in this
+     * thread group. If {@code recurse} is {@code true},
+     * this method recursively enumerates all subgroups of this
+     * thread group and references to every active thread in these
+     * subgroups are also included. If the array is too short to
+     * hold all the threads, the extra threads are silently ignored.
+     *
+     * <p> An application might use the {@linkplain #activeCount activeCount}
+     * method to get an estimate of how big the array should be, however
+     * <i>if the array is too short to hold all the threads, the extra threads
+     * are silently ignored.</i>  If it is critical to obtain every active
+     * thread in this thread group, the caller should verify that the returned
+     * int value is strictly less than the length of {@code list}.
+     *
+     * <p> Due to the inherent race condition in this method, it is recommended
+     * that the method only be used for debugging and monitoring purposes.
+     *
+     * @param  list
+     *         an array into which to put the list of threads
+     *
+     * @param  recurse
+     *         if {@code true}, recursively enumerate all subgroups of this
+     *         thread group
+     *
+     * @return  the number of threads put into the array
+     *
+     * @throws  SecurityException
+     *          if {@linkplain #checkAccess checkAccess} determines that
+     *          the current thread cannot access this thread group
+     *
+     * @since   JDK1.0
+     */
+    public int enumerate(Thread list[], boolean recurse) {
+        checkAccess();
+        return enumerate(list, 0, recurse);
+    }
+
+    private int enumerate(Thread list[], int n, boolean recurse) {
+        int ngroupsSnapshot = 0;
+        ThreadGroup[] groupsSnapshot = null;
+        synchronized (this) {
+            if (destroyed) {
+                return 0;
+            }
+            int nt = nthreads;
+            if (nt > list.length - n) {
+                nt = list.length - n;
+            }
+            for (int i = 0; i < nt; i++) {
+                if (threads[i].isAlive()) {
+                    list[n++] = threads[i];
+                }
+            }
+            if (recurse) {
+                ngroupsSnapshot = ngroups;
+                if (groups != null) {
+                    groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+                } else {
+                    groupsSnapshot = null;
+                }
+            }
+        }
+        if (recurse) {
+            for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+                n = groupsSnapshot[i].enumerate(list, n, true);
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Returns an estimate of the number of active groups in this
+     * thread group and its subgroups. Recursively iterates over
+     * all subgroups in this thread group.
+     *
+     * <p> The value returned is only an estimate because the number of
+     * thread groups may change dynamically while this method traverses
+     * internal data structures. This method is intended primarily for
+     * debugging and monitoring purposes.
+     *
+     * @return  the number of active thread groups with this thread group as
+     *          an ancestor
+     *
+     * @since   JDK1.0
+     */
+    public int activeGroupCount() {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            if (destroyed) {
+                return 0;
+            }
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        int n = ngroupsSnapshot;
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            n += groupsSnapshot[i].activeGroupCount();
+        }
+        return n;
+    }
+
+    /**
+     * Copies into the specified array references to every active
+     * subgroup in this thread group and its subgroups.
+     *
+     * <p> An invocation of this method behaves in exactly the same
+     * way as the invocation
+     *
+     * <blockquote>
+     * {@linkplain #enumerate(ThreadGroup[], boolean) enumerate}{@code (list, true)}
+     * </blockquote>
+     *
+     * @param  list
+     *         an array into which to put the list of thread groups
+     *
+     * @return  the number of thread groups put into the array
+     *
+     * @throws  SecurityException
+     *          if {@linkplain #checkAccess checkAccess} determines that
+     *          the current thread cannot access this thread group
+     *
+     * @since   JDK1.0
+     */
+    public int enumerate(ThreadGroup list[]) {
+        checkAccess();
+        return enumerate(list, 0, true);
+    }
+
+    /**
+     * Copies into the specified array references to every active
+     * subgroup in this thread group. If {@code recurse} is
+     * {@code true}, this method recursively enumerates all subgroups of this
+     * thread group and references to every active thread group in these
+     * subgroups are also included.
+     *
+     * <p> An application might use the
+     * {@linkplain #activeGroupCount activeGroupCount} method to
+     * get an estimate of how big the array should be, however <i>if the
+     * array is too short to hold all the thread groups, the extra thread
+     * groups are silently ignored.</i>  If it is critical to obtain every
+     * active subgroup in this thread group, the caller should verify that
+     * the returned int value is strictly less than the length of
+     * {@code list}.
+     *
+     * <p> Due to the inherent race condition in this method, it is recommended
+     * that the method only be used for debugging and monitoring purposes.
+     *
+     * @param  list
+     *         an array into which to put the list of thread groups
+     *
+     * @param  recurse
+     *         if {@code true}, recursively enumerate all subgroups
+     *
+     * @return  the number of thread groups put into the array
+     *
+     * @throws  SecurityException
+     *          if {@linkplain #checkAccess checkAccess} determines that
+     *          the current thread cannot access this thread group
+     *
+     * @since   JDK1.0
+     */
+    public int enumerate(ThreadGroup list[], boolean recurse) {
+        checkAccess();
+        return enumerate(list, 0, recurse);
+    }
+
+    private int enumerate(ThreadGroup list[], int n, boolean recurse) {
+        int ngroupsSnapshot = 0;
+        ThreadGroup[] groupsSnapshot = null;
+        synchronized (this) {
+            if (destroyed) {
+                return 0;
+            }
+            int ng = ngroups;
+            if (ng > list.length - n) {
+                ng = list.length - n;
+            }
+            if (ng > 0) {
+                System.arraycopy(groups, 0, list, n, ng);
+                n += ng;
+            }
+            if (recurse) {
+                ngroupsSnapshot = ngroups;
+                if (groups != null) {
+                    groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+                } else {
+                    groupsSnapshot = null;
+                }
+            }
+        }
+        if (recurse) {
+            for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+                n = groupsSnapshot[i].enumerate(list, n, true);
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Stops all threads in this thread group.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * This method then calls the <code>stop</code> method on all the
+     * threads in this thread group and in all of its subgroups.
+     *
+     * @exception  SecurityException  if the current thread is not allowed
+     *               to access this thread group or any of the threads in
+     *               the thread group.
+     * @see        java.lang.SecurityException
+     * @see        java.lang.Thread#stop()
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     * @deprecated    This method is inherently unsafe.  See
+     *     {@link Thread#stop} for details.
+     */
+    @Deprecated
+    public final void stop() {
+        if (stopOrSuspend(false))
+            Thread.currentThread().stop();
+    }
+
+    /**
+     * Interrupts all threads in this thread group.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * This method then calls the <code>interrupt</code> method on all the
+     * threads in this thread group and in all of its subgroups.
+     *
+     * @exception  SecurityException  if the current thread is not allowed
+     *               to access this thread group or any of the threads in
+     *               the thread group.
+     * @see        java.lang.Thread#interrupt()
+     * @see        java.lang.SecurityException
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      1.2
+     */
+    public final void interrupt() {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            checkAccess();
+            for (int i = 0 ; i < nthreads ; i++) {
+                threads[i].interrupt();
+            }
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            groupsSnapshot[i].interrupt();
+        }
+    }
+
+    /**
+     * Suspends all threads in this thread group.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * This method then calls the <code>suspend</code> method on all the
+     * threads in this thread group and in all of its subgroups.
+     *
+     * @exception  SecurityException  if the current thread is not allowed
+     *               to access this thread group or any of the threads in
+     *               the thread group.
+     * @see        java.lang.Thread#suspend()
+     * @see        java.lang.SecurityException
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     * @deprecated    This method is inherently deadlock-prone.  See
+     *     {@link Thread#suspend} for details.
+     */
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public final void suspend() {
+        if (stopOrSuspend(true))
+            Thread.currentThread().suspend();
+    }
+
+    /**
+     * Helper method: recursively stops or suspends (as directed by the
+     * boolean argument) all of the threads in this thread group and its
+     * subgroups, except the current thread.  This method returns true
+     * if (and only if) the current thread is found to be in this thread
+     * group or one of its subgroups.
+     */
+    @SuppressWarnings("deprecation")
+    private boolean stopOrSuspend(boolean suspend) {
+        boolean suicide = false;
+        Thread us = Thread.currentThread();
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot = null;
+        synchronized (this) {
+            checkAccess();
+            for (int i = 0 ; i < nthreads ; i++) {
+                if (threads[i]==us)
+                    suicide = true;
+                else if (suspend)
+                    threads[i].suspend();
+                else
+                    threads[i].stop();
+            }
+
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++)
+            suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
+
+        return suicide;
+    }
+
+    /**
+     * Resumes all threads in this thread group.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     * <p>
+     * This method then calls the <code>resume</code> method on all the
+     * threads in this thread group and in all of its sub groups.
+     *
+     * @exception  SecurityException  if the current thread is not allowed to
+     *               access this thread group or any of the threads in the
+     *               thread group.
+     * @see        java.lang.SecurityException
+     * @see        java.lang.Thread#resume()
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     * @deprecated    This method is used solely in conjunction with
+     *      <tt>Thread.suspend</tt> and <tt>ThreadGroup.suspend</tt>,
+     *       both of which have been deprecated, as they are inherently
+     *       deadlock-prone.  See {@link Thread#suspend} for details.
+     */
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public final void resume() {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            checkAccess();
+            for (int i = 0 ; i < nthreads ; i++) {
+                threads[i].resume();
+            }
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            groupsSnapshot[i].resume();
+        }
+    }
+
+    /**
+     * Destroys this thread group and all of its subgroups. This thread
+     * group must be empty, indicating that all threads that had been in
+     * this thread group have since stopped.
+     * <p>
+     * First, the <code>checkAccess</code> method of this thread group is
+     * called with no arguments; this may result in a security exception.
+     *
+     * @exception  IllegalThreadStateException  if the thread group is not
+     *               empty or if the thread group has already been destroyed.
+     * @exception  SecurityException  if the current thread cannot modify this
+     *               thread group.
+     * @see        java.lang.ThreadGroup#checkAccess()
+     * @since      JDK1.0
+     */
+    public final void destroy() {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            checkAccess();
+            if (destroyed || (nthreads > 0)) {
+                throw new IllegalThreadStateException();
+            }
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+            if (parent != null) {
+                destroyed = true;
+                ngroups = 0;
+                groups = null;
+                nthreads = 0;
+                threads = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
+            groupsSnapshot[i].destroy();
+        }
+        if (parent != null) {
+            parent.remove(this);
+        }
+    }
+
+    /**
+     * Adds the specified Thread group to this group.
+     * @param g the specified Thread group to be added
+     * @exception IllegalThreadStateException If the Thread group has been destroyed.
+     */
+    private final void add(ThreadGroup g){
+        synchronized (this) {
+            if (destroyed) {
+                throw new IllegalThreadStateException();
+            }
+            if (groups == null) {
+                groups = new ThreadGroup[4];
+            } else if (ngroups == groups.length) {
+                groups = Arrays.copyOf(groups, ngroups * 2);
+            }
+            groups[ngroups] = g;
+
+            // This is done last so it doesn't matter in case the
+            // thread is killed
+            ngroups++;
+        }
+    }
+
+    /**
+     * Removes the specified Thread group from this group.
+     * @param g the Thread group to be removed
+     * @return if this Thread has already been destroyed.
+     */
+    private void remove(ThreadGroup g) {
+        synchronized (this) {
+            if (destroyed) {
+                return;
+            }
+            for (int i = 0 ; i < ngroups ; i++) {
+                if (groups[i] == g) {
+                    ngroups -= 1;
+                    System.arraycopy(groups, i + 1, groups, i, ngroups - i);
+                    // Zap dangling reference to the dead group so that
+                    // the garbage collector will collect it.
+                    groups[ngroups] = null;
+                    break;
+                }
+            }
+            if (nthreads == 0) {
+                notifyAll();
+            }
+            if (daemon && (nthreads == 0) &&
+                (nUnstartedThreads == 0) && (ngroups == 0))
+            {
+                destroy();
+            }
+        }
+    }
+
+
+    /**
+     * Increments the count of unstarted threads in the thread group.
+     * Unstarted threads are not added to the thread group so that they
+     * can be collected if they are never started, but they must be
+     * counted so that daemon thread groups with unstarted threads in
+     * them are not destroyed.
+     */
+    void addUnstarted() {
+        synchronized(this) {
+            if (destroyed) {
+                throw new IllegalThreadStateException();
+            }
+            nUnstartedThreads++;
+        }
+    }
+
+    /**
+     * Adds the specified thread to this thread group.
+     *
+     * <p> Note: This method is called from both library code
+     * and the Virtual Machine. It is called from VM to add
+     * certain system threads to the system thread group.
+     *
+     * @param  t
+     *         the Thread to be added
+     *
+     * @throws  IllegalThreadStateException
+     *          if the Thread group has been destroyed
+     */
+    void add(Thread t) {
+        synchronized (this) {
+            if (destroyed) {
+                throw new IllegalThreadStateException();
+            }
+            if (threads == null) {
+                threads = new Thread[4];
+            } else if (nthreads == threads.length) {
+                threads = Arrays.copyOf(threads, nthreads * 2);
+            }
+            threads[nthreads] = t;
+
+            // This is done last so it doesn't matter in case the
+            // thread is killed
+            nthreads++;
+
+            // The thread is now a fully fledged member of the group, even
+            // though it may, or may not, have been started yet. It will prevent
+            // the group from being destroyed so the unstarted Threads count is
+            // decremented.
+            nUnstartedThreads--;
+        }
+    }
+
+    /**
+     * Notifies the group that the thread {@code t} has failed
+     * an attempt to start.
+     *
+     * <p> The state of this thread group is rolled back as if the
+     * attempt to start the thread has never occurred. The thread is again
+     * considered an unstarted member of the thread group, and a subsequent
+     * attempt to start the thread is permitted.
+     *
+     * @param  t
+     *         the Thread whose start method was invoked
+     */
+    void threadStartFailed(Thread t) {
+        synchronized(this) {
+            remove(t);
+            nUnstartedThreads++;
+        }
+    }
+
+    /**
+     * Notifies the group that the thread {@code t} has terminated.
+     *
+     * <p> Destroy the group if all of the following conditions are
+     * true: this is a daemon thread group; there are no more alive
+     * or unstarted threads in the group; there are no subgroups in
+     * this thread group.
+     *
+     * @param  t
+     *         the Thread that has terminated
+     */
+    void threadTerminated(Thread t) {
+        synchronized (this) {
+            remove(t);
+
+            if (nthreads == 0) {
+                notifyAll();
+            }
+            if (daemon && (nthreads == 0) &&
+                (nUnstartedThreads == 0) && (ngroups == 0))
+            {
+                destroy();
+            }
+        }
+    }
+
+    /**
+     * Removes the specified Thread from this group. Invoking this method
+     * on a thread group that has been destroyed has no effect.
+     *
+     * @param  t
+     *         the Thread to be removed
+     */
+    private void remove(Thread t) {
+        synchronized (this) {
+            if (destroyed) {
+                return;
+            }
+            for (int i = 0 ; i < nthreads ; i++) {
+                if (threads[i] == t) {
+                    System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
+                    // Zap dangling reference to the dead thread so that
+                    // the garbage collector will collect it.
+                    threads[nthreads] = null;
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Prints information about this thread group to the standard
+     * output. This method is useful only for debugging.
+     *
+     * @since   JDK1.0
+     */
+    public void list() {
+        list(System.out, 0);
+    }
+    void list(PrintStream out, int indent) {
+        int ngroupsSnapshot;
+        ThreadGroup[] groupsSnapshot;
+        synchronized (this) {
+            for (int j = 0 ; j < indent ; j++) {
+                out.print(" ");
+            }
+            out.println(this);
+            indent += 4;
+            for (int i = 0 ; i < nthreads ; i++) {
+                for (int j = 0 ; j < indent ; j++) {
+                    out.print(" ");
+                }
+                out.println(threads[i]);
+            }
+            ngroupsSnapshot = ngroups;
+            if (groups != null) {
+                groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+            } else {
+                groupsSnapshot = null;
+            }
+        }
+        for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+            groupsSnapshot[i].list(out, indent);
+        }
+    }
+
+    /**
+     * Called by the Java Virtual Machine when a thread in this
+     * thread group stops because of an uncaught exception, and the thread
+     * does not have a specific {@link Thread.UncaughtExceptionHandler}
+     * installed.
+     * <p>
+     * The <code>uncaughtException</code> method of
+     * <code>ThreadGroup</code> does the following:
+     * <ul>
+     * <li>If this thread group has a parent thread group, the
+     *     <code>uncaughtException</code> method of that parent is called
+     *     with the same two arguments.
+     * <li>Otherwise, this method checks to see if there is a
+     *     {@linkplain Thread#getDefaultUncaughtExceptionHandler default
+     *     uncaught exception handler} installed, and if so, its
+     *     <code>uncaughtException</code> method is called with the same
+     *     two arguments.
+     * <li>Otherwise, this method determines if the <code>Throwable</code>
+     *     argument is an instance of {@link ThreadDeath}. If so, nothing
+     *     special is done. Otherwise, a message containing the
+     *     thread's name, as returned from the thread's {@link
+     *     Thread#getName getName} method, and a stack backtrace,
+     *     using the <code>Throwable</code>'s {@link
+     *     Throwable#printStackTrace printStackTrace} method, is
+     *     printed to the {@linkplain System#err standard error stream}.
+     * </ul>
+     * <p>
+     * Applications can override this method in subclasses of
+     * <code>ThreadGroup</code> to provide alternative handling of
+     * uncaught exceptions.
+     *
+     * @param   t   the thread that is about to exit.
+     * @param   e   the uncaught exception.
+     * @since   JDK1.0
+     */
+    public void uncaughtException(Thread t, Throwable e) {
+        if (parent != null) {
+            parent.uncaughtException(t, e);
+        } else {
+            Thread.UncaughtExceptionHandler ueh =
+                Thread.getDefaultUncaughtExceptionHandler();
+            if (ueh != null) {
+                ueh.uncaughtException(t, e);
+            } else if (!(e instanceof ThreadDeath)) {
+                System.err.print("Exception in thread \""
+                                 + t.getName() + "\" ");
+                e.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /**
+     * Used by VM to control lowmem implicit suspension.
+     *
+     * @param b boolean to allow or disallow suspension
+     * @return true on success
+     * @since   JDK1.1
+     * @deprecated The definition of this call depends on {@link #suspend},
+     *             which is deprecated.  Further, the behavior of this call
+     *             was never specified.
+     */
+    @Deprecated
+    public boolean allowThreadSuspension(boolean b) {
+        this.vmAllowSuspension = b;
+        if (!b) {
+            VM.unsuspendSomeThreads();
+        }
+        return true;
+    }
+
+    /**
+     * Returns a string representation of this Thread group.
+     *
+     * @return  a string representation of this thread group.
+     * @since   JDK1.0
+     */
+    public String toString() {
+        return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
+    }
+}
diff --git a/java/lang/ThreadLocal.annotated.java b/java/lang/ThreadLocal.annotated.java
new file mode 100644
index 0000000..b8cf527
--- /dev/null
+++ b/java/lang/ThreadLocal.annotated.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 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;
+
+import java.lang.ref.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocal<T> {
+
+public ThreadLocal() { throw new RuntimeException("Stub!"); }
+
[email protected] protected T initialValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public static <S> java.lang.ThreadLocal<S> withInitial(@libcore.util.NonNull java.util.function.Supplier<? extends S> supplier) { throw new RuntimeException("Stub!"); }
+
[email protected] public T get() { throw new RuntimeException("Stub!"); }
+
+public void set(@libcore.util.NullFromTypeParam T value) { throw new RuntimeException("Stub!"); }
+
+public void remove() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/ThreadLocal.java b/java/lang/ThreadLocal.java
new file mode 100644
index 0000000..c29ce7e
--- /dev/null
+++ b/java/lang/ThreadLocal.java
@@ -0,0 +1,722 @@
+/*
+ * Copyright (c) 1997, 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;
+import java.lang.ref.*;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+/**
+ * This class provides thread-local variables.  These variables differ from
+ * their normal counterparts in that each thread that accesses one (via its
+ * {@code get} or {@code set} method) has its own, independently initialized
+ * copy of the variable.  {@code ThreadLocal} instances are typically private
+ * static fields in classes that wish to associate state with a thread (e.g.,
+ * a user ID or Transaction ID).
+ *
+ * <p>For example, the class below generates unique identifiers local to each
+ * thread.
+ * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
+ * and remains unchanged on subsequent calls.
+ * <pre>
+ * import java.util.concurrent.atomic.AtomicInteger;
+ *
+ * public class ThreadId {
+ *     // Atomic integer containing the next thread ID to be assigned
+ *     private static final AtomicInteger nextId = new AtomicInteger(0);
+ *
+ *     // Thread local variable containing each thread's ID
+ *     private static final ThreadLocal&lt;Integer&gt; threadId =
+ *         new ThreadLocal&lt;Integer&gt;() {
+ *             &#64;Override protected Integer initialValue() {
+ *                 return nextId.getAndIncrement();
+ *         }
+ *     };
+ *
+ *     // Returns the current thread's unique ID, assigning it if necessary
+ *     public static int get() {
+ *         return threadId.get();
+ *     }
+ * }
+ * </pre>
+ * <p>Each thread holds an implicit reference to its copy of a thread-local
+ * variable as long as the thread is alive and the {@code ThreadLocal}
+ * instance is accessible; after a thread goes away, all of its copies of
+ * thread-local instances are subject to garbage collection (unless other
+ * references to these copies exist).
+ *
+ * @author  Josh Bloch and Doug Lea
+ * @since   1.2
+ */
+public class ThreadLocal<T> {
+    /**
+     * ThreadLocals rely on per-thread linear-probe hash maps attached
+     * to each thread (Thread.threadLocals and
+     * inheritableThreadLocals).  The ThreadLocal objects act as keys,
+     * searched via threadLocalHashCode.  This is a custom hash code
+     * (useful only within ThreadLocalMaps) that eliminates collisions
+     * in the common case where consecutively constructed ThreadLocals
+     * are used by the same threads, while remaining well-behaved in
+     * less common cases.
+     */
+    private final int threadLocalHashCode = nextHashCode();
+
+    /**
+     * The next hash code to be given out. Updated atomically. Starts at
+     * zero.
+     */
+    private static AtomicInteger nextHashCode =
+        new AtomicInteger();
+
+    /**
+     * The difference between successively generated hash codes - turns
+     * implicit sequential thread-local IDs into near-optimally spread
+     * multiplicative hash values for power-of-two-sized tables.
+     */
+    private static final int HASH_INCREMENT = 0x61c88647;
+
+    /**
+     * Returns the next hash code.
+     */
+    private static int nextHashCode() {
+        return nextHashCode.getAndAdd(HASH_INCREMENT);
+    }
+
+    /**
+     * Returns the current thread's "initial value" for this
+     * thread-local variable.  This method will be invoked the first
+     * time a thread accesses the variable with the {@link #get}
+     * method, unless the thread previously invoked the {@link #set}
+     * method, in which case the {@code initialValue} method will not
+     * be invoked for the thread.  Normally, this method is invoked at
+     * most once per thread, but it may be invoked again in case of
+     * subsequent invocations of {@link #remove} followed by {@link #get}.
+     *
+     * <p>This implementation simply returns {@code null}; if the
+     * programmer desires thread-local variables to have an initial
+     * value other than {@code null}, {@code ThreadLocal} must be
+     * subclassed, and this method overridden.  Typically, an
+     * anonymous inner class will be used.
+     *
+     * @return the initial value for this thread-local
+     */
+    protected T initialValue() {
+        return null;
+    }
+
+    /**
+     * Creates a thread local variable. The initial value of the variable is
+     * determined by invoking the {@code get} method on the {@code Supplier}.
+     *
+     * @param <S> the type of the thread local's value
+     * @param supplier the supplier to be used to determine the initial value
+     * @return a new thread local variable
+     * @throws NullPointerException if the specified supplier is null
+     * @since 1.8
+     */
+    public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
+        return new SuppliedThreadLocal<>(supplier);
+    }
+
+    /**
+     * Creates a thread local variable.
+     * @see #withInitial(java.util.function.Supplier)
+     */
+    public ThreadLocal() {
+    }
+
+    /**
+     * Returns the value in the current thread's copy of this
+     * thread-local variable.  If the variable has no value for the
+     * current thread, it is first initialized to the value returned
+     * by an invocation of the {@link #initialValue} method.
+     *
+     * @return the current thread's value of this thread-local
+     */
+    public T get() {
+        Thread t = Thread.currentThread();
+        ThreadLocalMap map = getMap(t);
+        if (map != null) {
+            ThreadLocalMap.Entry e = map.getEntry(this);
+            if (e != null) {
+                @SuppressWarnings("unchecked")
+                T result = (T)e.value;
+                return result;
+            }
+        }
+        return setInitialValue();
+    }
+
+    /**
+     * Variant of set() to establish initialValue. Used instead
+     * of set() in case user has overridden the set() method.
+     *
+     * @return the initial value
+     */
+    private T setInitialValue() {
+        T value = initialValue();
+        Thread t = Thread.currentThread();
+        ThreadLocalMap map = getMap(t);
+        if (map != null)
+            map.set(this, value);
+        else
+            createMap(t, value);
+        return value;
+    }
+
+    /**
+     * Sets the current thread's copy of this thread-local variable
+     * to the specified value.  Most subclasses will have no need to
+     * override this method, relying solely on the {@link #initialValue}
+     * method to set the values of thread-locals.
+     *
+     * @param value the value to be stored in the current thread's copy of
+     *        this thread-local.
+     */
+    public void set(T value) {
+        Thread t = Thread.currentThread();
+        ThreadLocalMap map = getMap(t);
+        if (map != null)
+            map.set(this, value);
+        else
+            createMap(t, value);
+    }
+
+    /**
+     * Removes the current thread's value for this thread-local
+     * variable.  If this thread-local variable is subsequently
+     * {@linkplain #get read} by the current thread, its value will be
+     * reinitialized by invoking its {@link #initialValue} method,
+     * unless its value is {@linkplain #set set} by the current thread
+     * in the interim.  This may result in multiple invocations of the
+     * {@code initialValue} method in the current thread.
+     *
+     * @since 1.5
+     */
+     public void remove() {
+         ThreadLocalMap m = getMap(Thread.currentThread());
+         if (m != null)
+             m.remove(this);
+     }
+
+    /**
+     * Get the map associated with a ThreadLocal. Overridden in
+     * InheritableThreadLocal.
+     *
+     * @param  t the current thread
+     * @return the map
+     */
+    ThreadLocalMap getMap(Thread t) {
+        return t.threadLocals;
+    }
+
+    /**
+     * Create the map associated with a ThreadLocal. Overridden in
+     * InheritableThreadLocal.
+     *
+     * @param t the current thread
+     * @param firstValue value for the initial entry of the map
+     */
+    void createMap(Thread t, T firstValue) {
+        t.threadLocals = new ThreadLocalMap(this, firstValue);
+    }
+
+    /**
+     * Factory method to create map of inherited thread locals.
+     * Designed to be called only from Thread constructor.
+     *
+     * @param  parentMap the map associated with parent thread
+     * @return a map containing the parent's inheritable bindings
+     */
+    static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
+        return new ThreadLocalMap(parentMap);
+    }
+
+    /**
+     * Method childValue is visibly defined in subclass
+     * InheritableThreadLocal, but is internally defined here for the
+     * sake of providing createInheritedMap factory method without
+     * needing to subclass the map class in InheritableThreadLocal.
+     * This technique is preferable to the alternative of embedding
+     * instanceof tests in methods.
+     */
+    T childValue(T parentValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * An extension of ThreadLocal that obtains its initial value from
+     * the specified {@code Supplier}.
+     */
+    static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
+
+        private final Supplier<? extends T> supplier;
+
+        SuppliedThreadLocal(Supplier<? extends T> supplier) {
+            this.supplier = Objects.requireNonNull(supplier);
+        }
+
+        @Override
+        protected T initialValue() {
+            return supplier.get();
+        }
+    }
+
+    /**
+     * ThreadLocalMap is a customized hash map suitable only for
+     * maintaining thread local values. No operations are exported
+     * outside of the ThreadLocal class. The class is package private to
+     * allow declaration of fields in class Thread.  To help deal with
+     * very large and long-lived usages, the hash table entries use
+     * WeakReferences for keys. However, since reference queues are not
+     * used, stale entries are guaranteed to be removed only when
+     * the table starts running out of space.
+     */
+    static class ThreadLocalMap {
+
+        /**
+         * The entries in this hash map extend WeakReference, using
+         * its main ref field as the key (which is always a
+         * ThreadLocal object).  Note that null keys (i.e. entry.get()
+         * == null) mean that the key is no longer referenced, so the
+         * entry can be expunged from table.  Such entries are referred to
+         * as "stale entries" in the code that follows.
+         */
+        static class Entry extends WeakReference<ThreadLocal<?>> {
+            /** The value associated with this ThreadLocal. */
+            Object value;
+
+            Entry(ThreadLocal<?> k, Object v) {
+                super(k);
+                value = v;
+            }
+        }
+
+        /**
+         * The initial capacity -- MUST be a power of two.
+         */
+        private static final int INITIAL_CAPACITY = 16;
+
+        /**
+         * The table, resized as necessary.
+         * table.length MUST always be a power of two.
+         */
+        private Entry[] table;
+
+        /**
+         * The number of entries in the table.
+         */
+        private int size = 0;
+
+        /**
+         * The next size value at which to resize.
+         */
+        private int threshold; // Default to 0
+
+        /**
+         * Set the resize threshold to maintain at worst a 2/3 load factor.
+         */
+        private void setThreshold(int len) {
+            threshold = len * 2 / 3;
+        }
+
+        /**
+         * Increment i modulo len.
+         */
+        private static int nextIndex(int i, int len) {
+            return ((i + 1 < len) ? i + 1 : 0);
+        }
+
+        /**
+         * Decrement i modulo len.
+         */
+        private static int prevIndex(int i, int len) {
+            return ((i - 1 >= 0) ? i - 1 : len - 1);
+        }
+
+        /**
+         * Construct a new map initially containing (firstKey, firstValue).
+         * ThreadLocalMaps are constructed lazily, so we only create
+         * one when we have at least one entry to put in it.
+         */
+        ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
+            table = new Entry[INITIAL_CAPACITY];
+            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
+            table[i] = new Entry(firstKey, firstValue);
+            size = 1;
+            setThreshold(INITIAL_CAPACITY);
+        }
+
+        /**
+         * Construct a new map including all Inheritable ThreadLocals
+         * from given parent map. Called only by createInheritedMap.
+         *
+         * @param parentMap the map associated with parent thread.
+         */
+        private ThreadLocalMap(ThreadLocalMap parentMap) {
+            Entry[] parentTable = parentMap.table;
+            int len = parentTable.length;
+            setThreshold(len);
+            table = new Entry[len];
+
+            for (int j = 0; j < len; j++) {
+                Entry e = parentTable[j];
+                if (e != null) {
+                    @SuppressWarnings("unchecked")
+                    ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
+                    if (key != null) {
+                        Object value = key.childValue(e.value);
+                        Entry c = new Entry(key, value);
+                        int h = key.threadLocalHashCode & (len - 1);
+                        while (table[h] != null)
+                            h = nextIndex(h, len);
+                        table[h] = c;
+                        size++;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Get the entry associated with key.  This method
+         * itself handles only the fast path: a direct hit of existing
+         * key. It otherwise relays to getEntryAfterMiss.  This is
+         * designed to maximize performance for direct hits, in part
+         * by making this method readily inlinable.
+         *
+         * @param  key the thread local object
+         * @return the entry associated with key, or null if no such
+         */
+        private Entry getEntry(ThreadLocal<?> key) {
+            int i = key.threadLocalHashCode & (table.length - 1);
+            Entry e = table[i];
+            if (e != null && e.get() == key)
+                return e;
+            else
+                return getEntryAfterMiss(key, i, e);
+        }
+
+        /**
+         * Version of getEntry method for use when key is not found in
+         * its direct hash slot.
+         *
+         * @param  key the thread local object
+         * @param  i the table index for key's hash code
+         * @param  e the entry at table[i]
+         * @return the entry associated with key, or null if no such
+         */
+        private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
+            Entry[] tab = table;
+            int len = tab.length;
+
+            while (e != null) {
+                ThreadLocal<?> k = e.get();
+                if (k == key)
+                    return e;
+                if (k == null)
+                    expungeStaleEntry(i);
+                else
+                    i = nextIndex(i, len);
+                e = tab[i];
+            }
+            return null;
+        }
+
+        /**
+         * Set the value associated with key.
+         *
+         * @param key the thread local object
+         * @param value the value to be set
+         */
+        private void set(ThreadLocal<?> key, Object value) {
+
+            // We don't use a fast path as with get() because it is at
+            // least as common to use set() to create new entries as
+            // it is to replace existing ones, in which case, a fast
+            // path would fail more often than not.
+
+            Entry[] tab = table;
+            int len = tab.length;
+            int i = key.threadLocalHashCode & (len-1);
+
+            for (Entry e = tab[i];
+                 e != null;
+                 e = tab[i = nextIndex(i, len)]) {
+                ThreadLocal<?> k = e.get();
+
+                if (k == key) {
+                    e.value = value;
+                    return;
+                }
+
+                if (k == null) {
+                    replaceStaleEntry(key, value, i);
+                    return;
+                }
+            }
+
+            tab[i] = new Entry(key, value);
+            int sz = ++size;
+            if (!cleanSomeSlots(i, sz) && sz >= threshold)
+                rehash();
+        }
+
+        /**
+         * Remove the entry for key.
+         */
+        private void remove(ThreadLocal<?> key) {
+            Entry[] tab = table;
+            int len = tab.length;
+            int i = key.threadLocalHashCode & (len-1);
+            for (Entry e = tab[i];
+                 e != null;
+                 e = tab[i = nextIndex(i, len)]) {
+                if (e.get() == key) {
+                    e.clear();
+                    expungeStaleEntry(i);
+                    return;
+                }
+            }
+        }
+
+        /**
+         * Replace a stale entry encountered during a set operation
+         * with an entry for the specified key.  The value passed in
+         * the value parameter is stored in the entry, whether or not
+         * an entry already exists for the specified key.
+         *
+         * As a side effect, this method expunges all stale entries in the
+         * "run" containing the stale entry.  (A run is a sequence of entries
+         * between two null slots.)
+         *
+         * @param  key the key
+         * @param  value the value to be associated with key
+         * @param  staleSlot index of the first stale entry encountered while
+         *         searching for key.
+         */
+        private void replaceStaleEntry(ThreadLocal<?> key, Object value,
+                                       int staleSlot) {
+            Entry[] tab = table;
+            int len = tab.length;
+            Entry e;
+
+            // Back up to check for prior stale entry in current run.
+            // We clean out whole runs at a time to avoid continual
+            // incremental rehashing due to garbage collector freeing
+            // up refs in bunches (i.e., whenever the collector runs).
+            int slotToExpunge = staleSlot;
+            for (int i = prevIndex(staleSlot, len);
+                 (e = tab[i]) != null;
+                 i = prevIndex(i, len))
+                if (e.get() == null)
+                    slotToExpunge = i;
+
+            // Find either the key or trailing null slot of run, whichever
+            // occurs first
+            for (int i = nextIndex(staleSlot, len);
+                 (e = tab[i]) != null;
+                 i = nextIndex(i, len)) {
+                ThreadLocal<?> k = e.get();
+
+                // If we find key, then we need to swap it
+                // with the stale entry to maintain hash table order.
+                // The newly stale slot, or any other stale slot
+                // encountered above it, can then be sent to expungeStaleEntry
+                // to remove or rehash all of the other entries in run.
+                if (k == key) {
+                    e.value = value;
+
+                    tab[i] = tab[staleSlot];
+                    tab[staleSlot] = e;
+
+                    // Start expunge at preceding stale entry if it exists
+                    if (slotToExpunge == staleSlot)
+                        slotToExpunge = i;
+                    cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
+                    return;
+                }
+
+                // If we didn't find stale entry on backward scan, the
+                // first stale entry seen while scanning for key is the
+                // first still present in the run.
+                if (k == null && slotToExpunge == staleSlot)
+                    slotToExpunge = i;
+            }
+
+            // If key not found, put new entry in stale slot
+            tab[staleSlot].value = null;
+            tab[staleSlot] = new Entry(key, value);
+
+            // If there are any other stale entries in run, expunge them
+            if (slotToExpunge != staleSlot)
+                cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
+        }
+
+        /**
+         * Expunge a stale entry by rehashing any possibly colliding entries
+         * lying between staleSlot and the next null slot.  This also expunges
+         * any other stale entries encountered before the trailing null.  See
+         * Knuth, Section 6.4
+         *
+         * @param staleSlot index of slot known to have null key
+         * @return the index of the next null slot after staleSlot
+         * (all between staleSlot and this slot will have been checked
+         * for expunging).
+         */
+        private int expungeStaleEntry(int staleSlot) {
+            Entry[] tab = table;
+            int len = tab.length;
+
+            // expunge entry at staleSlot
+            tab[staleSlot].value = null;
+            tab[staleSlot] = null;
+            size--;
+
+            // Rehash until we encounter null
+            Entry e;
+            int i;
+            for (i = nextIndex(staleSlot, len);
+                 (e = tab[i]) != null;
+                 i = nextIndex(i, len)) {
+                ThreadLocal<?> k = e.get();
+                if (k == null) {
+                    e.value = null;
+                    tab[i] = null;
+                    size--;
+                } else {
+                    int h = k.threadLocalHashCode & (len - 1);
+                    if (h != i) {
+                        tab[i] = null;
+
+                        // Unlike Knuth 6.4 Algorithm R, we must scan until
+                        // null because multiple entries could have been stale.
+                        while (tab[h] != null)
+                            h = nextIndex(h, len);
+                        tab[h] = e;
+                    }
+                }
+            }
+            return i;
+        }
+
+        /**
+         * Heuristically scan some cells looking for stale entries.
+         * This is invoked when either a new element is added, or
+         * another stale one has been expunged. It performs a
+         * logarithmic number of scans, as a balance between no
+         * scanning (fast but retains garbage) and a number of scans
+         * proportional to number of elements, that would find all
+         * garbage but would cause some insertions to take O(n) time.
+         *
+         * @param i a position known NOT to hold a stale entry. The
+         * scan starts at the element after i.
+         *
+         * @param n scan control: {@code log2(n)} cells are scanned,
+         * unless a stale entry is found, in which case
+         * {@code log2(table.length)-1} additional cells are scanned.
+         * When called from insertions, this parameter is the number
+         * of elements, but when from replaceStaleEntry, it is the
+         * table length. (Note: all this could be changed to be either
+         * more or less aggressive by weighting n instead of just
+         * using straight log n. But this version is simple, fast, and
+         * seems to work well.)
+         *
+         * @return true if any stale entries have been removed.
+         */
+        private boolean cleanSomeSlots(int i, int n) {
+            boolean removed = false;
+            Entry[] tab = table;
+            int len = tab.length;
+            do {
+                i = nextIndex(i, len);
+                Entry e = tab[i];
+                if (e != null && e.get() == null) {
+                    n = len;
+                    removed = true;
+                    i = expungeStaleEntry(i);
+                }
+            } while ( (n >>>= 1) != 0);
+            return removed;
+        }
+
+        /**
+         * Re-pack and/or re-size the table. First scan the entire
+         * table removing stale entries. If this doesn't sufficiently
+         * shrink the size of the table, double the table size.
+         */
+        private void rehash() {
+            expungeStaleEntries();
+
+            // Use lower threshold for doubling to avoid hysteresis
+            if (size >= threshold - threshold / 4)
+                resize();
+        }
+
+        /**
+         * Double the capacity of the table.
+         */
+        private void resize() {
+            Entry[] oldTab = table;
+            int oldLen = oldTab.length;
+            int newLen = oldLen * 2;
+            Entry[] newTab = new Entry[newLen];
+            int count = 0;
+
+            for (int j = 0; j < oldLen; ++j) {
+                Entry e = oldTab[j];
+                if (e != null) {
+                    ThreadLocal<?> k = e.get();
+                    if (k == null) {
+                        e.value = null; // Help the GC
+                    } else {
+                        int h = k.threadLocalHashCode & (newLen - 1);
+                        while (newTab[h] != null)
+                            h = nextIndex(h, newLen);
+                        newTab[h] = e;
+                        count++;
+                    }
+                }
+            }
+
+            setThreshold(newLen);
+            size = count;
+            table = newTab;
+        }
+
+        /**
+         * Expunge all stale entries in the table.
+         */
+        private void expungeStaleEntries() {
+            Entry[] tab = table;
+            int len = tab.length;
+            for (int j = 0; j < len; j++) {
+                Entry e = tab[j];
+                if (e != null && e.get() == null)
+                    expungeStaleEntry(j);
+            }
+        }
+    }
+}
diff --git a/java/lang/Throwable.annotated.java b/java/lang/Throwable.annotated.java
new file mode 100644
index 0000000..f6cef0c
--- /dev/null
+++ b/java/lang/Throwable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+
+import java.io.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Throwable implements java.io.Serializable {
+
+public Throwable() { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+protected Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause, boolean enableSuppression, boolean writableStackTrace) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getMessage() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getLocalizedMessage() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable getCause() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable initCause(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintStream s) { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintWriter s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable fillInStackTrace() { throw new RuntimeException("Stub!"); }
+
+public [email protected] StackTraceElement @libcore.util.NonNull [] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void setStackTrace([email protected] StackTraceElement @libcore.util.NonNull [] stackTrace) { throw new RuntimeException("Stub!"); }
+
+public final synchronized void addSuppressed(@libcore.util.NonNull java.lang.Throwable exception) { throw new RuntimeException("Stub!"); }
+
+public final synchronized [email protected] Throwable @libcore.util.NonNull [] getSuppressed() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Throwable.java b/java/lang/Throwable.java
new file mode 100644
index 0000000..5a3f8a8
--- /dev/null
+++ b/java/lang/Throwable.java
@@ -0,0 +1,1134 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 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;
+import dalvik.annotation.optimization.FastNative;
+import  java.io.*;
+import  java.util.*;
+
+/**
+ * The {@code Throwable} class is the superclass of all errors and
+ * exceptions in the Java language. Only objects that are instances of this
+ * class (or one of its subclasses) are thrown by the Java Virtual Machine or
+ * can be thrown by the Java {@code throw} statement. Similarly, only
+ * this class or one of its subclasses can be the argument type in a
+ * {@code catch} clause.
+ *
+ * For the purposes of compile-time checking of exceptions, {@code
+ * Throwable} and any subclass of {@code Throwable} that is not also a
+ * subclass of either {@link RuntimeException} or {@link Error} are
+ * regarded as checked exceptions.
+ *
+ * <p>Instances of two subclasses, {@link java.lang.Error} and
+ * {@link java.lang.Exception}, are conventionally used to indicate
+ * that exceptional situations have occurred. Typically, these instances
+ * are freshly created in the context of the exceptional situation so
+ * as to include relevant information (such as stack trace data).
+ *
+ * <p>A throwable contains a snapshot of the execution stack of its
+ * thread at the time it was created. It can also contain a message
+ * string that gives more information about the error. Over time, a
+ * throwable can {@linkplain Throwable#addSuppressed suppress} other
+ * throwables from being propagated.  Finally, the throwable can also
+ * contain a <i>cause</i>: another throwable that caused this
+ * throwable to be constructed.  The recording of this causal information
+ * is referred to as the <i>chained exception</i> facility, as the
+ * cause can, itself, have a cause, and so on, leading to a "chain" of
+ * exceptions, each caused by another.
+ *
+ * <p>One reason that a throwable may have a cause is that the class that
+ * throws it is built atop a lower layered abstraction, and an operation on
+ * the upper layer fails due to a failure in the lower layer.  It would be bad
+ * design to let the throwable thrown by the lower layer propagate outward, as
+ * it is generally unrelated to the abstraction provided by the upper layer.
+ * Further, doing so would tie the API of the upper layer to the details of
+ * its implementation, assuming the lower layer's exception was a checked
+ * exception.  Throwing a "wrapped exception" (i.e., an exception containing a
+ * cause) allows the upper layer to communicate the details of the failure to
+ * its caller without incurring either of these shortcomings.  It preserves
+ * the flexibility to change the implementation of the upper layer without
+ * changing its API (in particular, the set of exceptions thrown by its
+ * methods).
+ *
+ * <p>A second reason that a throwable may have a cause is that the method
+ * that throws it must conform to a general-purpose interface that does not
+ * permit the method to throw the cause directly.  For example, suppose
+ * a persistent collection conforms to the {@link java.util.Collection
+ * Collection} interface, and that its persistence is implemented atop
+ * {@code java.io}.  Suppose the internals of the {@code add} method
+ * can throw an {@link java.io.IOException IOException}.  The implementation
+ * can communicate the details of the {@code IOException} to its caller
+ * while conforming to the {@code Collection} interface by wrapping the
+ * {@code IOException} in an appropriate unchecked exception.  (The
+ * specification for the persistent collection should indicate that it is
+ * capable of throwing such exceptions.)
+ *
+ * <p>A cause can be associated with a throwable in two ways: via a
+ * constructor that takes the cause as an argument, or via the
+ * {@link #initCause(Throwable)} method.  New throwable classes that
+ * wish to allow causes to be associated with them should provide constructors
+ * that take a cause and delegate (perhaps indirectly) to one of the
+ * {@code Throwable} constructors that takes a cause.
+ *
+ * Because the {@code initCause} method is public, it allows a cause to be
+ * associated with any throwable, even a "legacy throwable" whose
+ * implementation predates the addition of the exception chaining mechanism to
+ * {@code Throwable}.
+ *
+ * <p>By convention, class {@code Throwable} and its subclasses have two
+ * constructors, one that takes no arguments and one that takes a
+ * {@code String} argument that can be used to produce a detail message.
+ * Further, those subclasses that might likely have a cause associated with
+ * them should have two more constructors, one that takes a
+ * {@code Throwable} (the cause), and one that takes a
+ * {@code String} (the detail message) and a {@code Throwable} (the
+ * cause).
+ *
+ * @author  unascribed
+ * @author  Josh Bloch (Added exception chaining and programmatic access to
+ *          stack trace in 1.4.)
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since JDK1.0
+ */
+public class Throwable implements Serializable {
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = -3042686055658047285L;
+
+    /**
+     * Native code saves some indication of the stack backtrace in this slot.
+     */
+    private transient Object backtrace;
+
+    /**
+     * Specific details about the Throwable.  For example, for
+     * {@code FileNotFoundException}, this contains the name of
+     * the file that could not be found.
+     *
+     * @serial
+     */
+    private String detailMessage;
+
+
+    /**
+     * Holder class to defer initializing sentinel objects only used
+     * for serialization.
+     */
+    private static class SentinelHolder {
+        /**
+         * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
+         * stack trace} to a one-element array containing this sentinel
+         * value indicates future attempts to set the stack trace will be
+         * ignored.  The sentinal is equal to the result of calling:<br>
+         * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
+         */
+        public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
+            new StackTraceElement("", "", null, Integer.MIN_VALUE);
+
+        /**
+         * Sentinel value used in the serial form to indicate an immutable
+         * stack trace.
+         */
+        public static final StackTraceElement[] STACK_TRACE_SENTINEL =
+            new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
+    }
+
+    // Android-removed: Use libcore.util.EmptyArray for the empty stack trace
+    // Adding the constant UNASSIGNED_STACK breaks serialization of some subclasses
+    // /**
+    //  * A shared value for an empty stack.
+    //  */
+    // private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
+
+    /*
+     * To allow Throwable objects to be made immutable and safely
+     * reused by the JVM, such as OutOfMemoryErrors, fields of
+     * Throwable that are writable in response to user actions, cause,
+     * stackTrace, and suppressedExceptions obey the following
+     * protocol:
+     *
+     * 1) The fields are initialized to a non-null sentinel value
+     * which indicates the value has logically not been set.
+     *
+     * 2) Writing a null to the field indicates further writes
+     * are forbidden
+     *
+     * 3) The sentinel value may be replaced with another non-null
+     * value.
+     *
+     * For example, implementations of the HotSpot JVM have
+     * preallocated OutOfMemoryError objects to provide for better
+     * diagnosability of that situation.  These objects are created
+     * without calling the constructor for that class and the fields
+     * in question are initialized to null.  To support this
+     * capability, any new fields added to Throwable that require
+     * being initialized to a non-null value require a coordinated JVM
+     * change.
+     */
+
+    /**
+     * The throwable that caused this throwable to get thrown, or null if this
+     * throwable was not caused by another throwable, or if the causative
+     * throwable is unknown.  If this field is equal to this throwable itself,
+     * it indicates that the cause of this throwable has not yet been
+     * initialized.
+     *
+     * @serial
+     * @since 1.4
+     */
+    private Throwable cause = this;
+
+    /**
+     * The stack trace, as returned by {@link #getStackTrace()}.
+     *
+     * The field is initialized to a zero-length array.  A {@code
+     * null} value of this field indicates subsequent calls to {@link
+     * #setStackTrace(StackTraceElement[])} and {@link
+     * #fillInStackTrace()} will be be no-ops.
+     *
+     * @serial
+     * @since 1.4
+     */
+    // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+    // private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
+    private StackTraceElement[] stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+
+    // Android-removed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // Adding this constant breaks serialization of some subclasses
+    /*
+    // Setting this static field introduces an acceptable
+    // initialization dependency on a few java.util classes.
+    private static final List<Throwable> SUPPRESSED_SENTINEL =
+        Collections.unmodifiableList(new ArrayList<Throwable>(0));
+    */
+
+    /**
+     * The list of suppressed exceptions, as returned by {@link
+     * #getSuppressed()}.  The list is initialized to a zero-element
+     * unmodifiable sentinel list.  When a serialized Throwable is
+     * read in, if the {@code suppressedExceptions} field points to a
+     * zero-element list, the field is reset to the sentinel value.
+     *
+     * @serial
+     * @since 1.7
+     */
+    // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
+    private List<Throwable> suppressedExceptions = Collections.emptyList();
+
+    /** Message for trying to suppress a null exception. */
+    private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
+
+    /** Message for trying to suppress oneself. */
+    private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
+
+    /** Caption  for labeling causative exception stack traces */
+    private static final String CAUSE_CAPTION = "Caused by: ";
+
+    /** Caption for labeling suppressed exception stack traces */
+    private static final String SUPPRESSED_CAPTION = "Suppressed: ";
+
+    /**
+     * Constructs a new throwable with {@code null} as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     *
+     * <p>The {@link #fillInStackTrace()} method is called to initialize
+     * the stack trace data in the newly created throwable.
+     */
+    public Throwable() {
+        fillInStackTrace();
+    }
+
+    /**
+     * Constructs a new throwable with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * <p>The {@link #fillInStackTrace()} method is called to initialize
+     * the stack trace data in the newly created throwable.
+     *
+     * @param   message   the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public Throwable(String message) {
+        fillInStackTrace();
+        detailMessage = message;
+    }
+
+    /**
+     * Constructs a new throwable with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this throwable's detail message.
+     *
+     * <p>The {@link #fillInStackTrace()} method is called to initialize
+     * the stack trace data in the newly created throwable.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Throwable(String message, Throwable cause) {
+        fillInStackTrace();
+        detailMessage = message;
+        this.cause = cause;
+    }
+
+    /**
+     * Constructs a new throwable with the specified cause and a detail
+     * message of {@code (cause==null ? null : cause.toString())} (which
+     * typically contains the class and detail message of {@code cause}).
+     * This constructor is useful for throwables that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * <p>The {@link #fillInStackTrace()} method is called to initialize
+     * the stack trace data in the newly created throwable.
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.4
+     */
+    public Throwable(Throwable cause) {
+        fillInStackTrace();
+        detailMessage = (cause==null ? null : cause.toString());
+        this.cause = cause;
+    }
+
+    /**
+     * Constructs a new throwable with the specified detail message,
+     * cause, {@linkplain #addSuppressed suppression} enabled or
+     * disabled, and writable stack trace enabled or disabled.  If
+     * suppression is disabled, {@link #getSuppressed} for this object
+     * will return a zero-length array and calls to {@link
+     * #addSuppressed} that would otherwise append an exception to the
+     * suppressed list will have no effect.  If the writable stack
+     * trace is false, this constructor will not call {@link
+     * #fillInStackTrace()}, a {@code null} will be written to the
+     * {@code stackTrace} field, and subsequent calls to {@code
+     * fillInStackTrace} and {@link
+     * #setStackTrace(StackTraceElement[])} will not set the stack
+     * trace.  If the writable stack trace is false, {@link
+     * #getStackTrace} will return a zero length array.
+     *
+     * <p>Note that the other constructors of {@code Throwable} treat
+     * suppression as being enabled and the stack trace as being
+     * writable.  Subclasses of {@code Throwable} should document any
+     * conditions under which suppression is disabled and document
+     * conditions under which the stack trace is not writable.
+     * Disabling of suppression should only occur in exceptional
+     * circumstances where special requirements exist, such as a
+     * virtual machine reusing exception objects under low-memory
+     * situations.  Circumstances where a given exception object is
+     * repeatedly caught and rethrown, such as to implement control
+     * flow between two sub-systems, is another situation where
+     * immutable throwable objects would be appropriate.
+     *
+     * @param  message the detail message.
+     * @param cause the cause.  (A {@code null} value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @param enableSuppression whether or not suppression is enabled or disabled
+     * @param writableStackTrace whether or not the stack trace should be
+     *                           writable
+     *
+     * @see OutOfMemoryError
+     * @see NullPointerException
+     * @see ArithmeticException
+     * @since 1.7
+     */
+    protected Throwable(String message, Throwable cause,
+                        boolean enableSuppression,
+                        boolean writableStackTrace) {
+        if (writableStackTrace) {
+            fillInStackTrace();
+        } else {
+            stackTrace = null;
+        }
+        detailMessage = message;
+        this.cause = cause;
+        if (!enableSuppression)
+            suppressedExceptions = null;
+    }
+
+    /**
+     * Returns the detail message string of this throwable.
+     *
+     * @return  the detail message string of this {@code Throwable} instance
+     *          (which may be {@code null}).
+     */
+    public String getMessage() {
+        return detailMessage;
+    }
+
+    /**
+     * Creates a localized description of this throwable.
+     * Subclasses may override this method in order to produce a
+     * locale-specific message.  For subclasses that do not override this
+     * method, the default implementation returns the same result as
+     * {@code getMessage()}.
+     *
+     * @return  The localized description of this throwable.
+     * @since   JDK1.1
+     */
+    public String getLocalizedMessage() {
+        return getMessage();
+    }
+
+    /**
+     * Returns the cause of this throwable or {@code null} if the
+     * cause is nonexistent or unknown.  (The cause is the throwable that
+     * caused this throwable to get thrown.)
+     *
+     * <p>This implementation returns the cause that was supplied via one of
+     * the constructors requiring a {@code Throwable}, or that was set after
+     * creation with the {@link #initCause(Throwable)} method.  While it is
+     * typically unnecessary to override this method, a subclass can override
+     * it to return a cause set by some other means.  This is appropriate for
+     * a "legacy chained throwable" that predates the addition of chained
+     * exceptions to {@code Throwable}.  Note that it is <i>not</i>
+     * necessary to override any of the {@code PrintStackTrace} methods,
+     * all of which invoke the {@code getCause} method to determine the
+     * cause of a throwable.
+     *
+     * @return  the cause of this throwable or {@code null} if the
+     *          cause is nonexistent or unknown.
+     * @since 1.4
+     */
+    public synchronized Throwable getCause() {
+        return (cause==this ? null : cause);
+    }
+
+    /**
+     * Initializes the <i>cause</i> of this throwable to the specified value.
+     * (The cause is the throwable that caused this throwable to get thrown.)
+     *
+     * <p>This method can be called at most once.  It is generally called from
+     * within the constructor, or immediately after creating the
+     * throwable.  If this throwable was created
+     * with {@link #Throwable(Throwable)} or
+     * {@link #Throwable(String,Throwable)}, this method cannot be called
+     * even once.
+     *
+     * <p>An example of using this method on a legacy throwable type
+     * without other support for setting the cause is:
+     *
+     * <pre>
+     * try {
+     *     lowLevelOp();
+     * } catch (LowLevelException le) {
+     *     throw (HighLevelException)
+     *           new HighLevelException().initCause(le); // Legacy constructor
+     * }
+     * </pre>
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @return  a reference to this {@code Throwable} instance.
+     * @throws IllegalArgumentException if {@code cause} is this
+     *         throwable.  (A throwable cannot be its own cause.)
+     * @throws IllegalStateException if this throwable was
+     *         created with {@link #Throwable(Throwable)} or
+     *         {@link #Throwable(String,Throwable)}, or this method has already
+     *         been called on this throwable.
+     * @since  1.4
+     */
+    public synchronized Throwable initCause(Throwable cause) {
+        if (this.cause != this)
+            throw new IllegalStateException("Can't overwrite cause with " +
+                                            Objects.toString(cause, "a null"), this);
+        if (cause == this)
+            throw new IllegalArgumentException("Self-causation not permitted", this);
+        this.cause = cause;
+        return this;
+    }
+
+    /**
+     * Returns a short description of this throwable.
+     * The result is the concatenation of:
+     * <ul>
+     * <li> the {@linkplain Class#getName() name} of the class of this object
+     * <li> ": " (a colon and a space)
+     * <li> the result of invoking this object's {@link #getLocalizedMessage}
+     *      method
+     * </ul>
+     * If {@code getLocalizedMessage} returns {@code null}, then just
+     * the class name is returned.
+     *
+     * @return a string representation of this throwable.
+     */
+    public String toString() {
+        String s = getClass().getName();
+        String message = getLocalizedMessage();
+        return (message != null) ? (s + ": " + message) : s;
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the
+     * standard error stream. This method prints a stack trace for this
+     * {@code Throwable} object on the error output stream that is
+     * the value of the field {@code System.err}. The first line of
+     * output contains the result of the {@link #toString()} method for
+     * this object.  Remaining lines represent data previously recorded by
+     * the method {@link #fillInStackTrace()}. The format of this
+     * information depends on the implementation, but the following
+     * example may be regarded as typical:
+     * <blockquote><pre>
+     * java.lang.NullPointerException
+     *         at MyClass.mash(MyClass.java:9)
+     *         at MyClass.crunch(MyClass.java:6)
+     *         at MyClass.main(MyClass.java:3)
+     * </pre></blockquote>
+     * This example was produced by running the program:
+     * <pre>
+     * class MyClass {
+     *     public static void main(String[] args) {
+     *         crunch(null);
+     *     }
+     *     static void crunch(int[] a) {
+     *         mash(a);
+     *     }
+     *     static void mash(int[] b) {
+     *         System.out.println(b[0]);
+     *     }
+     * }
+     * </pre>
+     * The backtrace for a throwable with an initialized, non-null cause
+     * should generally include the backtrace for the cause.  The format
+     * of this information depends on the implementation, but the following
+     * example may be regarded as typical:
+     * <pre>
+     * HighLevelException: MidLevelException: LowLevelException
+     *         at Junk.a(Junk.java:13)
+     *         at Junk.main(Junk.java:4)
+     * Caused by: MidLevelException: LowLevelException
+     *         at Junk.c(Junk.java:23)
+     *         at Junk.b(Junk.java:17)
+     *         at Junk.a(Junk.java:11)
+     *         ... 1 more
+     * Caused by: LowLevelException
+     *         at Junk.e(Junk.java:30)
+     *         at Junk.d(Junk.java:27)
+     *         at Junk.c(Junk.java:21)
+     *         ... 3 more
+     * </pre>
+     * Note the presence of lines containing the characters {@code "..."}.
+     * These lines indicate that the remainder of the stack trace for this
+     * exception matches the indicated number of frames from the bottom of the
+     * stack trace of the exception that was caused by this exception (the
+     * "enclosing" exception).  This shorthand can greatly reduce the length
+     * of the output in the common case where a wrapped exception is thrown
+     * from same method as the "causative exception" is caught.  The above
+     * example was produced by running the program:
+     * <pre>
+     * public class Junk {
+     *     public static void main(String args[]) {
+     *         try {
+     *             a();
+     *         } catch(HighLevelException e) {
+     *             e.printStackTrace();
+     *         }
+     *     }
+     *     static void a() throws HighLevelException {
+     *         try {
+     *             b();
+     *         } catch(MidLevelException e) {
+     *             throw new HighLevelException(e);
+     *         }
+     *     }
+     *     static void b() throws MidLevelException {
+     *         c();
+     *     }
+     *     static void c() throws MidLevelException {
+     *         try {
+     *             d();
+     *         } catch(LowLevelException e) {
+     *             throw new MidLevelException(e);
+     *         }
+     *     }
+     *     static void d() throws LowLevelException {
+     *        e();
+     *     }
+     *     static void e() throws LowLevelException {
+     *         throw new LowLevelException();
+     *     }
+     * }
+     *
+     * class HighLevelException extends Exception {
+     *     HighLevelException(Throwable cause) { super(cause); }
+     * }
+     *
+     * class MidLevelException extends Exception {
+     *     MidLevelException(Throwable cause)  { super(cause); }
+     * }
+     *
+     * class LowLevelException extends Exception {
+     * }
+     * </pre>
+     * As of release 7, the platform supports the notion of
+     * <i>suppressed exceptions</i> (in conjunction with the {@code
+     * try}-with-resources statement). Any exceptions that were
+     * suppressed in order to deliver an exception are printed out
+     * beneath the stack trace.  The format of this information
+     * depends on the implementation, but the following example may be
+     * regarded as typical:
+     *
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Something happened
+     *  at Foo.bar(Foo.java:10)
+     *  at Foo.main(Foo.java:5)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 0
+     *          at Resource.close(Resource.java:26)
+     *          at Foo.bar(Foo.java:9)
+     *          ... 1 more
+     * </pre>
+     * Note that the "... n more" notation is used on suppressed exceptions
+     * just at it is used on causes. Unlike causes, suppressed exceptions are
+     * indented beyond their "containing exceptions."
+     *
+     * <p>An exception can have both a cause and one or more suppressed
+     * exceptions:
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Main block
+     *  at Foo3.main(Foo3.java:7)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 2
+     *          at Resource.close(Resource.java:26)
+     *          at Foo3.main(Foo3.java:5)
+     *  Suppressed: Resource$CloseFailException: Resource ID = 1
+     *          at Resource.close(Resource.java:26)
+     *          at Foo3.main(Foo3.java:5)
+     * Caused by: java.lang.Exception: I did it
+     *  at Foo3.main(Foo3.java:8)
+     * </pre>
+     * Likewise, a suppressed exception can have a cause:
+     * <pre>
+     * Exception in thread "main" java.lang.Exception: Main block
+     *  at Foo4.main(Foo4.java:6)
+     *  Suppressed: Resource2$CloseFailException: Resource ID = 1
+     *          at Resource2.close(Resource2.java:20)
+     *          at Foo4.main(Foo4.java:5)
+     *  Caused by: java.lang.Exception: Rats, you caught me
+     *          at Resource2$CloseFailException.&lt;init&gt;(Resource2.java:45)
+     *          ... 2 more
+     * </pre>
+     */
+    public void printStackTrace() {
+        printStackTrace(System.err);
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s {@code PrintStream} to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+        printStackTrace(new WrappedPrintStream(s));
+    }
+
+    private void printStackTrace(PrintStreamOrWriter s) {
+        // Guard against malicious overrides of Throwable.equals by
+        // using a Set with identity equality semantics.
+        Set<Throwable> dejaVu =
+            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
+        dejaVu.add(this);
+
+        synchronized (s.lock()) {
+            // Print our stack trace
+            s.println(this);
+            StackTraceElement[] trace = getOurStackTrace();
+            for (StackTraceElement traceElement : trace)
+                s.println("\tat " + traceElement);
+
+            // Print suppressed exceptions, if any
+            for (Throwable se : getSuppressed())
+                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
+
+            // Print cause, if any
+            Throwable ourCause = getCause();
+            if (ourCause != null)
+                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
+        }
+    }
+
+    /**
+     * Print our stack trace as an enclosed exception for the specified
+     * stack trace.
+     */
+    private void printEnclosedStackTrace(PrintStreamOrWriter s,
+                                         StackTraceElement[] enclosingTrace,
+                                         String caption,
+                                         String prefix,
+                                         Set<Throwable> dejaVu) {
+        // Android-removed: Use of assert keyword which breaks serialization of some subclasses
+        // (Using assert adds a static field that determines whether assertions are enabled.)
+        // assert Thread.holdsLock(s.lock());
+        if (dejaVu.contains(this)) {
+            s.println("\t[CIRCULAR REFERENCE:" + this + "]");
+        } else {
+            dejaVu.add(this);
+            // Compute number of frames in common between this and enclosing trace
+            StackTraceElement[] trace = getOurStackTrace();
+            int m = trace.length - 1;
+            int n = enclosingTrace.length - 1;
+            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
+                m--; n--;
+            }
+            int framesInCommon = trace.length - 1 - m;
+
+            // Print our stack trace
+            s.println(prefix + caption + this);
+            for (int i = 0; i <= m; i++)
+                s.println(prefix + "\tat " + trace[i]);
+            if (framesInCommon != 0)
+                s.println(prefix + "\t... " + framesInCommon + " more");
+
+            // Print suppressed exceptions, if any
+            for (Throwable se : getSuppressed())
+                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
+                                           prefix +"\t", dejaVu);
+
+            // Print cause, if any
+            Throwable ourCause = getCause();
+            if (ourCause != null)
+                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
+        }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified
+     * print writer.
+     *
+     * @param s {@code PrintWriter} to use for output
+     * @since   JDK1.1
+     */
+    public void printStackTrace(PrintWriter s) {
+        printStackTrace(new WrappedPrintWriter(s));
+    }
+
+    /**
+     * Wrapper class for PrintStream and PrintWriter to enable a single
+     * implementation of printStackTrace.
+     */
+    private abstract static class PrintStreamOrWriter {
+        /** Returns the object to be locked when using this StreamOrWriter */
+        abstract Object lock();
+
+        /** Prints the specified string as a line on this StreamOrWriter */
+        abstract void println(Object o);
+    }
+
+    private static class WrappedPrintStream extends PrintStreamOrWriter {
+        private final PrintStream printStream;
+
+        WrappedPrintStream(PrintStream printStream) {
+            this.printStream = printStream;
+        }
+
+        Object lock() {
+            return printStream;
+        }
+
+        void println(Object o) {
+            printStream.println(o);
+        }
+    }
+
+    private static class WrappedPrintWriter extends PrintStreamOrWriter {
+        private final PrintWriter printWriter;
+
+        WrappedPrintWriter(PrintWriter printWriter) {
+            this.printWriter = printWriter;
+        }
+
+        Object lock() {
+            return printWriter;
+        }
+
+        void println(Object o) {
+            printWriter.println(o);
+        }
+    }
+
+    /**
+     * Fills in the execution stack trace. This method records within this
+     * {@code Throwable} object information about the current state of
+     * the stack frames for the current thread.
+     *
+     * <p>If the stack trace of this {@code Throwable} {@linkplain
+     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
+     * writable}, calling this method has no effect.
+     *
+     * @return  a reference to this {@code Throwable} instance.
+     * @see     java.lang.Throwable#printStackTrace()
+     */
+    public synchronized Throwable fillInStackTrace() {
+        if (stackTrace != null ||
+            backtrace != null /* Out of protocol state */ ) {
+            // Android-changed: Use Android-specific nativeFillInStackTrace
+            // fillInStackTrace(0);
+            backtrace = nativeFillInStackTrace();
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // stackTrace = UNASSIGNED_STACK;
+            stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+        }
+        return this;
+    }
+
+    // Android-changed: Use Android-specific nativeFillInStackTrace
+    // private native Throwable fillInStackTrace(int dummy);
+    @FastNative
+    private static native Object nativeFillInStackTrace();
+
+    /**
+     * Provides programmatic access to the stack trace information printed by
+     * {@link #printStackTrace()}.  Returns an array of stack trace elements,
+     * each representing one stack frame.  The zeroth element of the array
+     * (assuming the array's length is non-zero) represents the top of the
+     * stack, which is the last method invocation in the sequence.  Typically,
+     * this is the point at which this throwable was created and thrown.
+     * The last element of the array (assuming the array's length is non-zero)
+     * represents the bottom of the stack, which is the first method invocation
+     * in the sequence.
+     *
+     * <p>Some virtual machines may, under some circumstances, omit one
+     * or more stack frames from the stack trace.  In the extreme case,
+     * a virtual machine that has no stack trace information concerning
+     * this throwable is permitted to return a zero-length array from this
+     * method.  Generally speaking, the array returned by this method will
+     * contain one element for every frame that would be printed by
+     * {@code printStackTrace}.  Writes to the returned array do not
+     * affect future calls to this method.
+     *
+     * @return an array of stack trace elements representing the stack trace
+     *         pertaining to this throwable.
+     * @since  1.4
+     */
+    public StackTraceElement[] getStackTrace() {
+        return getOurStackTrace().clone();
+    }
+
+    private synchronized StackTraceElement[] getOurStackTrace() {
+        // Initialize stack trace field with information from
+        // backtrace if this is the first call to this method
+        // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+        // if (stackTrace == UNASSIGNED_STACK ||
+        if (stackTrace == libcore.util.EmptyArray.STACK_TRACE_ELEMENT ||
+            (stackTrace == null && backtrace != null) /* Out of protocol state */) {
+            // BEGIN Android-changed: Use Android-specific nativeGetStackTrace
+            // int depth = getStackTraceDepth();
+            // stackTrace = new StackTraceElement[depth];
+            // for (int i=0; i < depth; i++)
+            //     stackTrace[i] = getStackTraceElement(i);
+            stackTrace = nativeGetStackTrace(backtrace);
+            backtrace = null;
+            if (stackTrace == null) {
+                return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+            }
+            // END Android-changed: Use Android-specific nativeGetStackTrace
+        } else if (stackTrace == null) {
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // return UNASSIGNED_STACK;
+            return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+        }
+        return stackTrace;
+    }
+
+    /**
+     * Sets the stack trace elements that will be returned by
+     * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
+     * and related methods.
+     *
+     * This method, which is designed for use by RPC frameworks and other
+     * advanced systems, allows the client to override the default
+     * stack trace that is either generated by {@link #fillInStackTrace()}
+     * when a throwable is constructed or deserialized when a throwable is
+     * read from a serialization stream.
+     *
+     * <p>If the stack trace of this {@code Throwable} {@linkplain
+     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
+     * writable}, calling this method has no effect other than
+     * validating its argument.
+     *
+     * @param   stackTrace the stack trace elements to be associated with
+     * this {@code Throwable}.  The specified array is copied by this
+     * call; changes in the specified array after the method invocation
+     * returns will have no affect on this {@code Throwable}'s stack
+     * trace.
+     *
+     * @throws NullPointerException if {@code stackTrace} is
+     *         {@code null} or if any of the elements of
+     *         {@code stackTrace} are {@code null}
+     *
+     * @since  1.4
+     */
+    public void setStackTrace(StackTraceElement[] stackTrace) {
+        // Validate argument
+        StackTraceElement[] defensiveCopy = stackTrace.clone();
+        for (int i = 0; i < defensiveCopy.length; i++) {
+            if (defensiveCopy[i] == null)
+                throw new NullPointerException("stackTrace[" + i + "]");
+        }
+
+        synchronized (this) {
+            if (this.stackTrace == null && // Immutable stack
+                backtrace == null) // Test for out of protocol state
+                return;
+            this.stackTrace = defensiveCopy;
+        }
+    }
+
+    // Android-removed: Unused native method getStackTraceDepth()
+    // /**
+    //  * Returns the number of elements in the stack trace (or 0 if the stack
+    //  * trace is unavailable).
+    //  *
+    //  * package-protection for use by SharedSecrets.
+    //  */
+    // native int getStackTraceDepth();
+
+    /**
+     * Returns the specified element of the stack trace.
+     *
+     * package-protection for use by SharedSecrets.
+     *
+     * @param index index of the element to return.
+     * @throws IndexOutOfBoundsException if {@code index < 0 ||
+     *         index >= getStackTraceDepth() }
+     */
+    // Android-changed: Use Android-specific nativeGetStackTrace
+    // native StackTraceElement getStackTraceElement(int index);
+    @FastNative
+    private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
+
+
+    /**
+     * Reads a {@code Throwable} from a stream, enforcing
+     * well-formedness constraints on fields.  Null entries and
+     * self-pointers are not allowed in the list of {@code
+     * suppressedExceptions}.  Null entries are not allowed for stack
+     * trace elements.  A null stack trace in the serial form results
+     * in a zero-length stack element array. A single-element stack
+     * trace whose entry is equal to {@code new StackTraceElement("",
+     * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code
+     * stackTrace} field.
+     *
+     * Note that there are no constraints on the value the {@code
+     * cause} field can hold; both {@code null} and {@code this} are
+     * valid values for the field.
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        s.defaultReadObject();     // read in all fields
+        if (suppressedExceptions != null) {
+            List<Throwable> suppressed = null;
+            if (suppressedExceptions.isEmpty()) {
+                // Use the sentinel for a zero-length list
+                // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+                // suppressed = SUPPRESSED_SENTINEL;
+                suppressed = Collections.emptyList();
+            } else { // Copy Throwables to new list
+                suppressed = new ArrayList<>(1);
+                for (Throwable t : suppressedExceptions) {
+                    // Enforce constraints on suppressed exceptions in
+                    // case of corrupt or malicious stream.
+                    if (t == null)
+                        throw new NullPointerException(NULL_CAUSE_MESSAGE);
+                    if (t == this)
+                        throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
+                    suppressed.add(t);
+                }
+            }
+            suppressedExceptions = suppressed;
+        } // else a null suppressedExceptions field remains null
+
+        /*
+         * For zero-length stack traces, use a clone of
+         * UNASSIGNED_STACK rather than UNASSIGNED_STACK itself to
+         * allow identity comparison against UNASSIGNED_STACK in
+         * getOurStackTrace.  The identity of UNASSIGNED_STACK in
+         * stackTrace indicates to the getOurStackTrace method that
+         * the stackTrace needs to be constructed from the information
+         * in backtrace.
+         */
+        if (stackTrace != null) {
+            if (stackTrace.length == 0) {
+                // Android-removed: clone() call not needed because of libcore.util.EmptyArray usage
+                // stackTrace = UNASSIGNED_STACK.clone();
+            }  else if (stackTrace.length == 1 &&
+                        // Check for the marker of an immutable stack trace
+                        SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
+                stackTrace = null;
+            } else { // Verify stack trace elements are non-null.
+                for(StackTraceElement ste : stackTrace) {
+                    if (ste == null)
+                        throw new NullPointerException("null StackTraceElement in serial stream. ");
+                }
+            }
+        } else {
+            // A null stackTrace field in the serial form can result
+            // from an exception serialized without that field in
+            // older JDK releases; treat such exceptions as having
+            // empty stack traces.
+            // Android-changed: Directly create empty array instead of cloning UNASSIGNED_STACK
+            // stackTrace = UNASSIGNED_STACK.clone();
+            stackTrace = new StackTraceElement[0];
+        }
+    }
+
+    /**
+     * Write a {@code Throwable} object to a stream.
+     *
+     * A {@code null} stack trace field is represented in the serial
+     * form as a one-element array whose element is equal to {@code
+     * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
+     */
+    private synchronized void writeObject(ObjectOutputStream s)
+        throws IOException {
+        // Ensure that the stackTrace field is initialized to a
+        // non-null value, if appropriate.  As of JDK 7, a null stack
+        // trace field is a valid value indicating the stack trace
+        // should not be set.
+        getOurStackTrace();
+
+        StackTraceElement[] oldStackTrace = stackTrace;
+        try {
+            if (stackTrace == null)
+                stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
+            s.defaultWriteObject();
+        } finally {
+            stackTrace = oldStackTrace;
+        }
+    }
+
+    /**
+     * Appends the specified exception to the exceptions that were
+     * suppressed in order to deliver this exception. This method is
+     * thread-safe and typically called (automatically and implicitly)
+     * by the {@code try}-with-resources statement.
+     *
+     * <p>The suppression behavior is enabled <em>unless</em> disabled
+     * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
+     * a constructor}.  When suppression is disabled, this method does
+     * nothing other than to validate its argument.
+     *
+     * <p>Note that when one exception {@linkplain
+     * #initCause(Throwable) causes} another exception, the first
+     * exception is usually caught and then the second exception is
+     * thrown in response.  In other words, there is a causal
+     * connection between the two exceptions.
+     *
+     * In contrast, there are situations where two independent
+     * exceptions can be thrown in sibling code blocks, in particular
+     * in the {@code try} block of a {@code try}-with-resources
+     * statement and the compiler-generated {@code finally} block
+     * which closes the resource.
+     *
+     * In these situations, only one of the thrown exceptions can be
+     * propagated.  In the {@code try}-with-resources statement, when
+     * there are two such exceptions, the exception originating from
+     * the {@code try} block is propagated and the exception from the
+     * {@code finally} block is added to the list of exceptions
+     * suppressed by the exception from the {@code try} block.  As an
+     * exception unwinds the stack, it can accumulate multiple
+     * suppressed exceptions.
+     *
+     * <p>An exception may have suppressed exceptions while also being
+     * caused by another exception.  Whether or not an exception has a
+     * cause is semantically known at the time of its creation, unlike
+     * whether or not an exception will suppress other exceptions
+     * which is typically only determined after an exception is
+     * thrown.
+     *
+     * <p>Note that programmer written code is also able to take
+     * advantage of calling this method in situations where there are
+     * multiple sibling exceptions and only one can be propagated.
+     *
+     * @param exception the exception to be added to the list of
+     *        suppressed exceptions
+     * @throws IllegalArgumentException if {@code exception} is this
+     *         throwable; a throwable cannot suppress itself.
+     * @throws NullPointerException if {@code exception} is {@code null}
+     * @since 1.7
+     */
+    public final synchronized void addSuppressed(Throwable exception) {
+        if (exception == this)
+            throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE, exception);
+
+        if (exception == null)
+            throw new NullPointerException(NULL_CAUSE_MESSAGE);
+
+        if (suppressedExceptions == null) // Suppressed exceptions not recorded
+            return;
+
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL)
+        if (suppressedExceptions.isEmpty())
+            suppressedExceptions = new ArrayList<>(1);
+
+        suppressedExceptions.add(exception);
+    }
+
+    // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY
+    // private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
+    private static Throwable[] EMPTY_THROWABLE_ARRAY;
+
+    /**
+     * Returns an array containing all of the exceptions that were
+     * suppressed, typically by the {@code try}-with-resources
+     * statement, in order to deliver this exception.
+     *
+     * If no exceptions were suppressed or {@linkplain
+     * #Throwable(String, Throwable, boolean, boolean) suppression is
+     * disabled}, an empty array is returned.  This method is
+     * thread-safe.  Writes to the returned array do not affect future
+     * calls to this method.
+     *
+     * @return an array containing all of the exceptions that were
+     *         suppressed to deliver this exception.
+     * @since 1.7
+     */
+    public final synchronized Throwable[] getSuppressed() {
+        // Android-added: Lazily initialize EMPTY_THROWABLE_ARRAY
+        if (EMPTY_THROWABLE_ARRAY == null) {
+            EMPTY_THROWABLE_ARRAY = new Throwable[0];
+        }
+
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL ||
+        //    suppressedExceptions == null)
+        if (suppressedExceptions == null || suppressedExceptions.isEmpty())
+            return EMPTY_THROWABLE_ARRAY;
+        else
+            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
+    }
+}
diff --git a/java/lang/TypeNotPresentException.java b/java/lang/TypeNotPresentException.java
new file mode 100644
index 0000000..65a0207
--- /dev/null
+++ b/java/lang/TypeNotPresentException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2003, 2008, 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;
+
+/**
+ * Thrown when an application tries to access a type using a string
+ * representing the type's name, but no definition for the type with
+ * the specified name can be found.   This exception differs from
+ * {@link ClassNotFoundException} in that <tt>ClassNotFoundException</tt> is a
+ * checked exception, whereas this exception is unchecked.
+ *
+ * <p>Note that this exception may be used when undefined type variables
+ * are accessed as well as when types (e.g., classes, interfaces or
+ * annotation types) are loaded.
+ * In particular, this exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author  Josh Bloch
+ * @see     java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class TypeNotPresentException extends RuntimeException {
+    private static final long serialVersionUID = -5101214195716534496L;
+
+    private String typeName;
+
+    /**
+     * Constructs a <tt>TypeNotPresentException</tt> for the named type
+     * with the specified cause.
+     *
+     * @param typeName the fully qualified name of the unavailable type
+     * @param cause the exception that was thrown when the system attempted to
+     *    load the named type, or <tt>null</tt> if unavailable or inapplicable
+     */
+    public TypeNotPresentException(String typeName, Throwable cause) {
+        super("Type " + typeName + " not present", cause);
+        this.typeName = typeName;
+    }
+
+    /**
+     * Returns the fully qualified name of the unavailable type.
+     *
+     * @return the fully qualified name of the unavailable type
+     */
+    public String typeName() { return typeName;}
+}
diff --git a/java/lang/UNIXProcess.java b/java/lang/UNIXProcess.java
new file mode 100644
index 0000000..40fd8bb
--- /dev/null
+++ b/java/lang/UNIXProcess.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2010, 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;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadFactory;
+import java.security.AccessController;
+import static java.security.AccessController.doPrivileged;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * java.lang.Process subclass in the UNIX environment.
+ *
+ * @author Mario Wolczko and Ross Knippel.
+ * @author Konstantin Kladko (ported to Linux)
+ * @author Martin Buchholz
+ */
+final class UNIXProcess extends Process {
+    private final int pid;
+    private int exitcode;
+    private boolean hasExited;
+
+    private /* final */ OutputStream stdin;
+    private /* final */ InputStream  stdout;
+    private /* final */ InputStream  stderr;
+
+    /* this is for the reaping thread */
+    private native int waitForProcessExit(int pid);
+
+    /**
+     * Create a process using fork(2) and exec(2).
+     *
+     * @param fds an array of three file descriptors.
+     *        Indexes 0, 1, and 2 correspond to standard input,
+     *        standard output and standard error, respectively.  On
+     *        input, a value of -1 means to create a pipe to connect
+     *        child and parent processes.  On output, a value which
+     *        is not -1 is the parent pipe fd corresponding to the
+     *        pipe which has been created.  An element of this array
+     *        is -1 on input if and only if it is <em>not</em> -1 on
+     *        output.
+     * @return the pid of the subprocess
+     */
+    private native int forkAndExec(byte[] prog,
+                                   byte[] argBlock, int argc,
+                                   byte[] envBlock, int envc,
+                                   byte[] dir,
+                                   int[] fds,
+                                   boolean redirectErrorStream)
+        throws IOException;
+
+    /**
+     * The thread factory used to create "process reaper" daemon threads.
+     */
+    private static class ProcessReaperThreadFactory implements ThreadFactory {
+        private final static ThreadGroup group = getRootThreadGroup();
+
+        private static ThreadGroup getRootThreadGroup() {
+            return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+                public ThreadGroup run() {
+                    ThreadGroup root = Thread.currentThread().getThreadGroup();
+                    while (root.getParent() != null)
+                        root = root.getParent();
+                    return root;
+                }});
+        }
+
+        public Thread newThread(Runnable grimReaper) {
+            // Our thread stack requirement is quite modest.
+            Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+            t.setDaemon(true);
+            // A small attempt (probably futile) to avoid priority inversion
+            t.setPriority(Thread.MAX_PRIORITY);
+            return t;
+        }
+    }
+
+    /**
+     * The thread pool of "process reaper" daemon threads.
+     */
+    private static final Executor processReaperExecutor =
+        doPrivileged(new PrivilegedAction<Executor>() {
+            public Executor run() {
+                return Executors.newCachedThreadPool
+                    (new ProcessReaperThreadFactory());
+            }});
+
+    UNIXProcess(final byte[] prog,
+                final byte[] argBlock, final int argc,
+                final byte[] envBlock, final int envc,
+                final byte[] dir,
+                final int[] fds,
+                final boolean redirectErrorStream)
+            throws IOException {
+
+        pid = forkAndExec(prog,
+                          argBlock, argc,
+                          envBlock, envc,
+                          dir,
+                          fds,
+                          redirectErrorStream);
+
+        try {
+            doPrivileged(new PrivilegedExceptionAction<Void>() {
+                public Void run() throws IOException {
+                    initStreams(fds);
+                    return null;
+                }});
+        } catch (PrivilegedActionException ex) {
+            throw (IOException) ex.getException();
+        }
+    }
+
+    static FileDescriptor newFileDescriptor(int fd) {
+        FileDescriptor fileDescriptor = new FileDescriptor();
+        fileDescriptor.setInt$(fd);
+        return fileDescriptor;
+    }
+
+    void initStreams(int[] fds) throws IOException {
+        stdin = (fds[0] == -1) ?
+            ProcessBuilder.NullOutputStream.INSTANCE :
+            new ProcessPipeOutputStream(fds[0]);
+
+        stdout = (fds[1] == -1) ?
+            ProcessBuilder.NullInputStream.INSTANCE :
+            new ProcessPipeInputStream(fds[1]);
+
+        stderr = (fds[2] == -1) ?
+            ProcessBuilder.NullInputStream.INSTANCE :
+            new ProcessPipeInputStream(fds[2]);
+
+        processReaperExecutor.execute(new Runnable() {
+            public void run() {
+                int exitcode = waitForProcessExit(pid);
+                UNIXProcess.this.processExited(exitcode);
+            }});
+    }
+
+    void processExited(int exitcode) {
+        synchronized (this) {
+            this.exitcode = exitcode;
+            hasExited = true;
+            notifyAll();
+        }
+
+        if (stdout instanceof ProcessPipeInputStream)
+            ((ProcessPipeInputStream) stdout).processExited();
+
+        if (stderr instanceof ProcessPipeInputStream)
+            ((ProcessPipeInputStream) stderr).processExited();
+
+        if (stdin instanceof ProcessPipeOutputStream)
+            ((ProcessPipeOutputStream) stdin).processExited();
+    }
+
+    public OutputStream getOutputStream() {
+        return stdin;
+    }
+
+    public InputStream getInputStream() {
+        return stdout;
+    }
+
+    public InputStream getErrorStream() {
+        return stderr;
+    }
+
+    public synchronized int waitFor() throws InterruptedException {
+        while (!hasExited) {
+            wait();
+        }
+        return exitcode;
+    }
+
+    public synchronized int exitValue() {
+        if (!hasExited) {
+            throw new IllegalThreadStateException("process hasn't exited");
+        }
+        return exitcode;
+    }
+
+    private static native void destroyProcess(int pid);
+    public void destroy() {
+        // There is a risk that pid will be recycled, causing us to
+        // kill the wrong process!  So we only terminate processes
+        // that appear to still be running.  Even with this check,
+        // there is an unavoidable race condition here, but the window
+        // is very small, and OSes try hard to not recycle pids too
+        // soon, so this is quite safe.
+        synchronized (this) {
+            if (!hasExited)
+                destroyProcess(pid);
+        }
+        try { stdin.close();  } catch (IOException ignored) {}
+        try { stdout.close(); } catch (IOException ignored) {}
+        try { stderr.close(); } catch (IOException ignored) {}
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("Process[pid=");
+        sb.append(pid);
+        if (hasExited) {
+            sb.append(" ,hasExited=true, exitcode=");
+            sb.append(exitcode);
+            sb.append("]");
+        } else {
+            sb.append(", hasExited=false]");
+        }
+
+        return sb.toString();
+    }
+
+    /* This routine initializes JNI field offsets for the class */
+    private static native void initIDs();
+
+    static {
+        initIDs();
+    }
+
+    /**
+     * A buffered input stream for a subprocess pipe file descriptor
+     * that allows the underlying file descriptor to be reclaimed when
+     * the process exits, via the processExited hook.
+     *
+     * This is tricky because we do not want the user-level InputStream to be
+     * closed until the user invokes close(), and we need to continue to be
+     * able to read any buffered data lingering in the OS pipe buffer.
+     */
+    static class ProcessPipeInputStream extends BufferedInputStream {
+        ProcessPipeInputStream(int fd) {
+            super(new FileInputStream(newFileDescriptor(fd), true /* isFdOwner */));
+        }
+
+        private static byte[] drainInputStream(InputStream in)
+                throws IOException {
+            if (in == null) return null;
+            int n = 0;
+            int j;
+            byte[] a = null;
+            while ((j = in.available()) > 0) {
+                a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+                n += in.read(a, n, j);
+            }
+            return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
+        }
+
+        /** Called by the process reaper thread when the process exits. */
+        synchronized void processExited() {
+            // Most BufferedInputStream methods are synchronized, but close()
+            // is not, and so we have to handle concurrent racing close().
+            try {
+                InputStream in = this.in;
+                if (in != null) {
+                    byte[] stragglers = drainInputStream(in);
+                    in.close();
+                    this.in = (stragglers == null) ?
+                        ProcessBuilder.NullInputStream.INSTANCE :
+                        new ByteArrayInputStream(stragglers);
+                    if (buf == null) // asynchronous close()?
+                        this.in = null;
+                }
+            } catch (IOException ignored) {
+                // probably an asynchronous close().
+            }
+        }
+    }
+
+    /**
+     * A buffered output stream for a subprocess pipe file descriptor
+     * that allows the underlying file descriptor to be reclaimed when
+     * the process exits, via the processExited hook.
+     */
+    static class ProcessPipeOutputStream extends BufferedOutputStream {
+        ProcessPipeOutputStream(int fd) {
+            super(new FileOutputStream(newFileDescriptor(fd), true /* isFdOwner */));
+        }
+
+        /** Called by the process reaper thread when the process exits. */
+        synchronized void processExited() {
+            OutputStream out = this.out;
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ignored) {
+                    // We know of no reason to get an IOException, but if
+                    // we do, there's nothing else to do but carry on.
+                }
+                this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+            }
+        }
+    }
+}
diff --git a/java/lang/UnknownError.java b/java/lang/UnknownError.java
new file mode 100644
index 0000000..0706f81
--- /dev/null
+++ b/java/lang/UnknownError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an unknown but serious exception has occurred in the
+ * Java Virtual Machine.
+ *
+ * @author unascribed
+ * @since   JDK1.0
+ */
+public
+class UnknownError extends VirtualMachineError {
+    private static final long serialVersionUID = 2524784860676771849L;
+
+    /**
+     * Constructs an <code>UnknownError</code> with no detail message.
+     */
+    public UnknownError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>UnknownError</code> with the specified detail
+     * message.
+     *
+     * @param   s   the detail message.
+     */
+    public UnknownError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/UnsatisfiedLinkError.java b/java/lang/UnsatisfiedLinkError.java
new file mode 100644
index 0000000..32a8ba8
--- /dev/null
+++ b/java/lang/UnsatisfiedLinkError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if the Java Virtual Machine cannot find an appropriate
+ * native-language definition of a method declared <code>native</code>.
+ *
+ * @author unascribed
+ * @see     java.lang.Runtime
+ * @since   JDK1.0
+ */
+public
+class UnsatisfiedLinkError extends LinkageError {
+    private static final long serialVersionUID = -4019343241616879428L;
+
+    /**
+     * Constructs an <code>UnsatisfiedLinkError</code> with no detail message.
+     */
+    public UnsatisfiedLinkError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>UnsatisfiedLinkError</code> with the
+     * specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public UnsatisfiedLinkError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/UnsupportedClassVersionError.java b/java/lang/UnsupportedClassVersionError.java
new file mode 100644
index 0000000..aed4d04
--- /dev/null
+++ b/java/lang/UnsupportedClassVersionError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1998, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine attempts to read a class
+ * file and determines that the major and minor version numbers
+ * in the file are not supported.
+ *
+ * @since   1.2
+ */
+public
+class UnsupportedClassVersionError extends ClassFormatError {
+    private static final long serialVersionUID = -7123279212883497373L;
+
+    /**
+     * Constructs a <code>UnsupportedClassVersionError</code>
+     * with no detail message.
+     */
+    public UnsupportedClassVersionError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>UnsupportedClassVersionError</code> with
+     * the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public UnsupportedClassVersionError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/UnsupportedOperationException.java b/java/lang/UnsupportedOperationException.java
new file mode 100644
index 0000000..fcb355c
--- /dev/null
+++ b/java/lang/UnsupportedOperationException.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997, 2006, 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;
+
+/**
+ * Thrown to indicate that the requested operation is not supported.<p>
+ *
+ * This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @author  Josh Bloch
+ * @since   1.2
+ */
+public class UnsupportedOperationException extends RuntimeException {
+    /**
+     * Constructs an UnsupportedOperationException with no detail message.
+     */
+    public UnsupportedOperationException() {
+    }
+
+    /**
+     * Constructs an UnsupportedOperationException with the specified
+     * detail message.
+     *
+     * @param message the detail message
+     */
+    public UnsupportedOperationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.
+     *
+     * <p>Note that the detail message associated with <code>cause</code> is
+     * <i>not</i> automatically incorporated in this exception's detail
+     * message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link Throwable#getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value
+     *         is permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since 1.5
+     */
+    public UnsupportedOperationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * java.security.PrivilegedActionException}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link Throwable#getCause()} method).  (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.5
+     */
+    public UnsupportedOperationException(Throwable cause) {
+        super(cause);
+    }
+
+    static final long serialVersionUID = -1242599979055084673L;
+}
diff --git a/java/lang/VMClassLoader.java b/java/lang/VMClassLoader.java
new file mode 100644
index 0000000..d44f888
--- /dev/null
+++ b/java/lang/VMClassLoader.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.util.ArrayList;
+import java.util.List;
+import libcore.io.ClassPathURLStreamHandler;
+
+class VMClassLoader {
+
+    private static final ClassPathURLStreamHandler[] bootClassPathUrlHandlers;
+    static {
+        bootClassPathUrlHandlers = createBootClassPathUrlHandlers();
+    }
+
+    /**
+     * Creates an array of ClassPathURLStreamHandler objects for handling resource loading from
+     * the boot classpath.
+     */
+    private static ClassPathURLStreamHandler[] createBootClassPathUrlHandlers() {
+        String[] bootClassPathEntries = getBootClassPathEntries();
+        ArrayList<URLStreamHandler> urlStreamHandlers =
+                new ArrayList<URLStreamHandler>(bootClassPathEntries.length);
+        for (String bootClassPathEntry : bootClassPathEntries) {
+            try {
+                String entryUri = new File(bootClassPathEntry).toURI().toString();
+
+                // We assume all entries are zip or jar files.
+                URLStreamHandler urlStreamHandler =
+                        new ClassPathURLStreamHandler(bootClassPathEntry);
+                urlStreamHandlers.add(urlStreamHandler);
+            } catch (IOException e) {
+                // Skip it
+                System.logE("Unable to open boot classpath entry: " + bootClassPathEntry, e);
+            }
+        }
+        return urlStreamHandlers.toArray(new ClassPathURLStreamHandler[urlStreamHandlers.size()]);
+    }
+
+    /**
+     * Get a resource from a file in the bootstrap class path.
+     *
+     * We assume that the bootclasspath can't change once the VM has started.
+     * This assumption seems to be supported by the spec.
+     */
+    static URL getResource(String name) {
+        for (ClassPathURLStreamHandler urlHandler : bootClassPathUrlHandlers) {
+            URL url = urlHandler.getEntryUrlOrNull(name);
+            if (url != null) {
+                return url;
+            }
+        }
+        return null;
+    }
+
+    /*
+     * Get an enumeration with all matching resources.
+     */
+    static List<URL> getResources(String name) {
+        ArrayList<URL> list = new ArrayList<URL>();
+        for (ClassPathURLStreamHandler urlHandler : bootClassPathUrlHandlers) {
+            URL url = urlHandler.getEntryUrlOrNull(name);
+            if (url != null) {
+                list.add(url);
+            }
+        }
+        return list;
+    }
+
+    @FastNative
+    native static Class findLoadedClass(ClassLoader cl, String name);
+
+    /**
+     * Boot class path manipulation, for getResources().
+     */
+    native private static String[] getBootClassPathEntries();
+
+}
diff --git a/java/lang/VerifyError.java b/java/lang/VerifyError.java
new file mode 100644
index 0000000..9ca9f90
--- /dev/null
+++ b/java/lang/VerifyError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when the "verifier" detects that a class file,
+ * though well formed, contains some sort of internal inconsistency
+ * or security problem.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public
+class VerifyError extends LinkageError {
+    private static final long serialVersionUID = 7001962396098498785L;
+
+    /**
+     * Constructs an <code>VerifyError</code> with no detail message.
+     */
+    public VerifyError() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>VerifyError</code> with the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public VerifyError(String s) {
+        super(s);
+    }
+}
diff --git a/java/lang/VirtualMachineError.java b/java/lang/VirtualMachineError.java
new file mode 100644
index 0000000..c0a2a92
--- /dev/null
+++ b/java/lang/VirtualMachineError.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1995, 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 java.lang;
+
+/**
+ * Thrown to indicate that the Java Virtual Machine is broken or has
+ * run out of resources necessary for it to continue operating.
+ *
+ *
+ * @author  Frank Yellin
+ * @since   JDK1.0
+ */
+abstract public class VirtualMachineError extends Error {
+    private static final long serialVersionUID = 4161983926571568670L;
+
+    /**
+     * Constructs a <code>VirtualMachineError</code> with no detail message.
+     */
+    public VirtualMachineError() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>VirtualMachineError</code> with the specified
+     * detail message.
+     *
+     * @param   message   the detail message.
+     */
+    public VirtualMachineError(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a {@code VirtualMachineError} with the specified
+     * detail message and cause.  <p>Note that the detail message
+     * associated with {@code cause} is <i>not</i> automatically
+     * incorporated in this error's detail message.
+     *
+     * @param  message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.8
+     */
+    public VirtualMachineError(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs an a {@code VirtualMachineError} with the specified
+     * cause and a detail message of {@code (cause==null ? null :
+     * cause.toString())} (which typically contains the class and
+     * detail message of {@code cause}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method).  (A {@code null} value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     * @since  1.8
+     */
+    public VirtualMachineError(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/lang/Void.java b/java/lang/Void.java
new file mode 100644
index 0000000..96dbe6d
--- /dev/null
+++ b/java/lang/Void.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1996, 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 java.lang;
+
+/**
+ * The {@code Void} class is an uninstantiable placeholder class to hold a
+ * reference to the {@code Class} object representing the Java keyword
+ * void.
+ *
+ * @author  unascribed
+ * @since   JDK1.1
+ */
+public final
+class Void {
+
+    /**
+     * The {@code Class} object representing the pseudo-type corresponding to
+     * the keyword {@code void}.
+     */
+    @SuppressWarnings("unchecked")
+    public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");
+
+    /*
+     * The Void class cannot be instantiated.
+     */
+    private Void() {}
+}
diff --git a/java/lang/annotation/Annotation.java b/java/lang/annotation/Annotation.java
new file mode 100644
index 0000000..7de6746
--- /dev/null
+++ b/java/lang/annotation/Annotation.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * The common interface extended by all annotation types.  Note that an
+ * interface that manually extends this one does <i>not</i> define
+ * an annotation type.  Also note that this interface does not itself
+ * define an annotation type.
+ *
+ * More information about annotation types can be found in section 9.6 of
+ * <cite>The Java&trade; Language Specification</cite>.
+ *
+ * The {@link java.lang.reflect.AnnotatedElement} interface discusses
+ * compatibility concerns when evolving an annotation type from being
+ * non-repeatable to being repeatable.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+public interface Annotation {
+    /**
+     * Returns true if the specified object represents an annotation
+     * that is logically equivalent to this one.  In other words,
+     * returns true if the specified object is an instance of the same
+     * annotation type as this instance, all of whose members are equal
+     * to the corresponding member of this annotation, as defined below:
+     * <ul>
+     *    <li>Two corresponding primitive typed members whose values are
+     *    <tt>x</tt> and <tt>y</tt> are considered equal if <tt>x == y</tt>,
+     *    unless their type is <tt>float</tt> or <tt>double</tt>.
+     *
+     *    <li>Two corresponding <tt>float</tt> members whose values
+     *    are <tt>x</tt> and <tt>y</tt> are considered equal if
+     *    <tt>Float.valueOf(x).equals(Float.valueOf(y))</tt>.
+     *    (Unlike the <tt>==</tt> operator, NaN is considered equal
+     *    to itself, and <tt>0.0f</tt> unequal to <tt>-0.0f</tt>.)
+     *
+     *    <li>Two corresponding <tt>double</tt> members whose values
+     *    are <tt>x</tt> and <tt>y</tt> are considered equal if
+     *    <tt>Double.valueOf(x).equals(Double.valueOf(y))</tt>.
+     *    (Unlike the <tt>==</tt> operator, NaN is considered equal
+     *    to itself, and <tt>0.0</tt> unequal to <tt>-0.0</tt>.)
+     *
+     *    <li>Two corresponding <tt>String</tt>, <tt>Class</tt>, enum, or
+     *    annotation typed members whose values are <tt>x</tt> and <tt>y</tt>
+     *    are considered equal if <tt>x.equals(y)</tt>.  (Note that this
+     *    definition is recursive for annotation typed members.)
+     *
+     *    <li>Two corresponding array typed members <tt>x</tt> and <tt>y</tt>
+     *    are considered equal if <tt>Arrays.equals(x, y)</tt>, for the
+     *    appropriate overloading of {@link java.util.Arrays#equals}.
+     * </ul>
+     *
+     * @return true if the specified object represents an annotation
+     *     that is logically equivalent to this one, otherwise false
+     */
+    boolean equals(Object obj);
+
+    /**
+     * Returns the hash code of this annotation, as defined below:
+     *
+     * <p>The hash code of an annotation is the sum of the hash codes
+     * of its members (including those with default values), as defined
+     * below:
+     *
+     * The hash code of an annotation member is (127 times the hash code
+     * of the member-name as computed by {@link String#hashCode()}) XOR
+     * the hash code of the member-value, as defined below:
+     *
+     * <p>The hash code of a member-value depends on its type:
+     * <ul>
+     * <li>The hash code of a primitive value <tt><i>v</i></tt> is equal to
+     *     <tt><i>WrapperType</i>.valueOf(<i>v</i>).hashCode()</tt>, where
+     *     <tt><i>WrapperType</i></tt> is the wrapper type corresponding
+     *     to the primitive type of <tt><i>v</i></tt> ({@link Byte},
+     *     {@link Character}, {@link Double}, {@link Float}, {@link Integer},
+     *     {@link Long}, {@link Short}, or {@link Boolean}).
+     *
+     * <li>The hash code of a string, enum, class, or annotation member-value
+     I     <tt><i>v</i></tt> is computed as by calling
+     *     <tt><i>v</i>.hashCode()</tt>.  (In the case of annotation
+     *     member values, this is a recursive definition.)
+     *
+     * <li>The hash code of an array member-value is computed by calling
+     *     the appropriate overloading of
+     *     {@link java.util.Arrays#hashCode(long[]) Arrays.hashCode}
+     *     on the value.  (There is one overloading for each primitive
+     *     type, and one for object reference types.)
+     * </ul>
+     *
+     * @return the hash code of this annotation
+     */
+    int hashCode();
+
+    /**
+     * Returns a string representation of this annotation.  The details
+     * of the representation are implementation-dependent, but the following
+     * may be regarded as typical:
+     * <pre>
+     *   &#064;com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
+     * </pre>
+     *
+     * @return a string representation of this annotation
+     */
+    String toString();
+
+    /**
+     * Returns the annotation type of this annotation.
+     * @return the annotation type of this annotation
+     */
+    Class<? extends Annotation> annotationType();
+}
diff --git a/java/lang/annotation/AnnotationFormatError.java b/java/lang/annotation/AnnotationFormatError.java
new file mode 100644
index 0000000..f02104f
--- /dev/null
+++ b/java/lang/annotation/AnnotationFormatError.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2004, 2008, 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.annotation;
+
+/**
+ * Thrown when the annotation parser attempts to read an annotation
+ * from a class file and determines that the annotation is malformed.
+ * This error can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author  Josh Bloch
+ * @see     java.lang.reflect.AnnotatedElement
+ * @since   1.5
+ */
+public class AnnotationFormatError extends Error {
+    private static final long serialVersionUID = -4256701562333669892L;
+
+    /**
+     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * detail message.
+     *
+     * @param   message   the detail message.
+     */
+    public AnnotationFormatError(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * detail message and cause.  Note that the detail message associated
+     * with <code>cause</code> is <i>not</i> automatically incorporated in
+     * this error's detail message.
+     *
+     * @param  message the detail message
+     * @param  cause the cause (A <tt>null</tt> value is permitted, and
+     *     indicates that the cause is nonexistent or unknown.)
+     */
+    public AnnotationFormatError(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    /**
+     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * cause and a detail message of
+     * <tt>(cause == null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     *
+     * @param  cause the cause (A <tt>null</tt> value is permitted, and
+     *     indicates that the cause is nonexistent or unknown.)
+     */
+    public AnnotationFormatError(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/lang/annotation/AnnotationTypeMismatchException.java b/java/lang/annotation/AnnotationTypeMismatchException.java
new file mode 100644
index 0000000..88e2712
--- /dev/null
+++ b/java/lang/annotation/AnnotationTypeMismatchException.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003, 2008, 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.annotation;
+import java.lang.reflect.Method;
+
+/**
+ * Thrown to indicate that a program has attempted to access an element of
+ * an annotation whose type has changed after the annotation was compiled
+ * (or serialized).
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author  Josh Bloch
+ * @see     java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class AnnotationTypeMismatchException extends RuntimeException {
+    private static final long serialVersionUID = 8125925355765570191L;
+
+    /**
+     * The <tt>Method</tt> object for the annotation element.
+     */
+    private final Method element;
+
+    /**
+     * The (erroneous) type of data found in the annotation.  This string
+     * may, but is not required to, contain the value as well.  The exact
+     * format of the string is unspecified.
+     */
+    private final String foundType;
+
+    /**
+     * Constructs an AnnotationTypeMismatchException for the specified
+     * annotation type element and found data type.
+     *
+     * @param element the <tt>Method</tt> object for the annotation element
+     * @param foundType the (erroneous) type of data found in the annotation.
+     *        This string may, but is not required to, contain the value
+     *        as well.  The exact format of the string is unspecified.
+     */
+    public AnnotationTypeMismatchException(Method element, String foundType) {
+        super("Incorrectly typed data found for annotation element " + element
+              + " (Found data of type " + foundType + ")");
+        this.element = element;
+        this.foundType = foundType;
+    }
+
+    /**
+     * Returns the <tt>Method</tt> object for the incorrectly typed element.
+     *
+     * @return the <tt>Method</tt> object for the incorrectly typed element
+     */
+    public Method element() {
+        return this.element;
+    }
+
+    /**
+     * Returns the type of data found in the incorrectly typed element.
+     * The returned string may, but is not required to, contain the value
+     * as well.  The exact format of the string is unspecified.
+     *
+     * @return the type of data found in the incorrectly typed element
+     */
+    public String foundType() {
+        return this.foundType;
+    }
+}
diff --git a/java/lang/annotation/Documented.java b/java/lang/annotation/Documented.java
new file mode 100644
index 0000000..348a312
--- /dev/null
+++ b/java/lang/annotation/Documented.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003, 2004, 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.annotation;
+
+/**
+ * Indicates that annotations with a type are to be documented by javadoc
+ * and similar tools by default.  This type should be used to annotate the
+ * declarations of types whose annotations affect the use of annotated
+ * elements by their clients.  If a type declaration is annotated with
+ * Documented, its annotations become part of the public API
+ * of the annotated elements.
+ *
+ * @author  Joshua Bloch
+ * @since 1.5
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Documented {
+}
diff --git a/java/lang/annotation/ElementType.java b/java/lang/annotation/ElementType.java
new file mode 100644
index 0000000..4590f39
--- /dev/null
+++ b/java/lang/annotation/ElementType.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * The constants of this enumerated type provide a simple classification of the
+ * syntactic locations where annotations may appear in a Java program. These
+ * constants are used in {@link Target java.lang.annotation.Target}
+ * meta-annotations to specify where it is legal to write annotations of a
+ * given type.
+ *
+ * <p>The syntactic locations where annotations may appear are split into
+ * <em>declaration contexts</em> , where annotations apply to declarations, and
+ * <em>type contexts</em> , where annotations apply to types used in
+ * declarations and expressions.
+ *
+ * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
+ * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
+ * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
+ * to the declaration contexts in JLS 9.6.4.1.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
+ * field declaration.
+ *
+ * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
+ * 4.11, as well as to two declaration contexts: type declarations (including
+ * annotation type declarations) and type parameter declarations.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
+ * (or within the type of the field, if it is a nested, parameterized, or array
+ * type), and may also appear as a modifier for, say, a class declaration.
+ *
+ * <p>The {@code TYPE_USE} constant includes type declarations and type
+ * parameter declarations as a convenience for designers of type checkers which
+ * give semantics to annotation types. For example, if the annotation type
+ * {@code NonNull} is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
+ * {@code class C {...}} could be treated by a type checker as indicating that
+ * all variables of class {@code C} are non-null, while still allowing
+ * variables of other classes to be non-null or not non-null based on whether
+ * {@code @NonNull} appears at the variable's declaration.
+ *
+ * @author  Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 4.1 The Kinds of Types and Values
+ */
+public enum ElementType {
+    /** Class, interface (including annotation type), or enum declaration */
+    TYPE,
+
+    /** Field declaration (includes enum constants) */
+    FIELD,
+
+    /** Method declaration */
+    METHOD,
+
+    /** Formal parameter declaration */
+    PARAMETER,
+
+    /** Constructor declaration */
+    CONSTRUCTOR,
+
+    /** Local variable declaration */
+    LOCAL_VARIABLE,
+
+    /** Annotation type declaration */
+    ANNOTATION_TYPE,
+
+    /** Package declaration */
+    PACKAGE,
+
+    /**
+     * Type parameter declaration
+     *
+     * @since 1.8
+     */
+    TYPE_PARAMETER,
+
+    /**
+     * Use of a type
+     *
+     * @since 1.8
+     */
+    TYPE_USE
+}
diff --git a/java/lang/annotation/IncompleteAnnotationException.java b/java/lang/annotation/IncompleteAnnotationException.java
new file mode 100644
index 0000000..241b21a
--- /dev/null
+++ b/java/lang/annotation/IncompleteAnnotationException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * Thrown to indicate that a program has attempted to access an element of
+ * an annotation type that was added to the annotation type definition after
+ * the annotation was compiled (or serialized).  This exception will not be
+ * thrown if the new element has a default value.
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author  Josh Bloch
+ * @see     java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class IncompleteAnnotationException extends RuntimeException {
+    private static final long serialVersionUID = 8445097402741811912L;
+
+    private Class<? extends Annotation> annotationType;
+    private String elementName;
+
+    /**
+     * Constructs an IncompleteAnnotationException to indicate that
+     * the named element was missing from the specified annotation type.
+     *
+     * @param annotationType the Class object for the annotation type
+     * @param elementName the name of the missing element
+     * @throws NullPointerException if either parameter is {@code null}
+     */
+    public IncompleteAnnotationException(
+            Class<? extends Annotation> annotationType,
+            String elementName) {
+        super(annotationType.getName() + " missing element " +
+              elementName.toString());
+
+        this.annotationType = annotationType;
+        this.elementName = elementName;
+    }
+
+    /**
+     * Returns the Class object for the annotation type with the
+     * missing element.
+     *
+     * @return the Class object for the annotation type with the
+     *     missing element
+     */
+    public Class<? extends Annotation> annotationType() {
+        return annotationType;
+    }
+
+    /**
+     * Returns the name of the missing element.
+     *
+     * @return the name of the missing element
+     */
+    public String elementName() {
+        return elementName;
+    }
+}
diff --git a/java/lang/annotation/Inherited.java b/java/lang/annotation/Inherited.java
new file mode 100644
index 0000000..83391e2
--- /dev/null
+++ b/java/lang/annotation/Inherited.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * Indicates that an annotation type is automatically inherited.  If
+ * an Inherited meta-annotation is present on an annotation type
+ * declaration, and the user queries the annotation type on a class
+ * declaration, and the class declaration has no annotation for this type,
+ * then the class's superclass will automatically be queried for the
+ * annotation type.  This process will be repeated until an annotation for this
+ * type is found, or the top of the class hierarchy (Object)
+ * is reached.  If no superclass has an annotation for this type, then
+ * the query will indicate that the class in question has no such annotation.
+ *
+ * <p>Note that this meta-annotation type has no effect if the annotated
+ * type is used to annotate anything other than a class.  Note also
+ * that this meta-annotation only causes annotations to be inherited
+ * from superclasses; annotations on implemented interfaces have no
+ * effect.
+ *
+ * @author  Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.3.3 @Inherited
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Inherited {
+}
diff --git a/java/lang/annotation/Native.java b/java/lang/annotation/Native.java
new file mode 100644
index 0000000..861c1ff
--- /dev/null
+++ b/java/lang/annotation/Native.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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.annotation;
+
+
+/**
+ * Indicates that a field defining a constant value may be referenced
+ * from native code.
+ *
+ * The annotation may be used as a hint by tools that generate native
+ * header files to determine whether a header file is required, and
+ * if so, what declarations it should contain.
+ *
+ * @since 1.8
+ */
+@Documented
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Native {
+}
diff --git a/java/lang/annotation/Repeatable.java b/java/lang/annotation/Repeatable.java
new file mode 100644
index 0000000..7a2daa8
--- /dev/null
+++ b/java/lang/annotation/Repeatable.java
@@ -0,0 +1,49 @@
+/*
+ * 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.annotation;
+
+/**
+ * The annotation type {@code java.lang.annotation.Repeatable} is
+ * used to indicate that the annotation type whose declaration it
+ * (meta-)annotates is <em>repeatable</em>. The value of
+ * {@code @Repeatable} indicates the <em>containing annotation
+ * type</em> for the repeatable annotation type.
+ *
+ * @since 1.8
+ * @jls 9.6 Annotation Types
+ * @jls 9.7 Annotations
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Repeatable {
+    /**
+     * Indicates the <em>containing annotation type</em> for the
+     * repeatable annotation type.
+     * @return the containing annotation type
+     */
+    Class<? extends Annotation> value();
+}
diff --git a/java/lang/annotation/Retention.java b/java/lang/annotation/Retention.java
new file mode 100644
index 0000000..5efa43f
--- /dev/null
+++ b/java/lang/annotation/Retention.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * Indicates how long annotations with the annotated type are to
+ * be retained.  If no Retention annotation is present on
+ * an annotation type declaration, the retention policy defaults to
+ * {@code RetentionPolicy.CLASS}.
+ *
+ * <p>A Retention meta-annotation has effect only if the
+ * meta-annotated type is used directly for annotation.  It has no
+ * effect if the meta-annotated type is used as a member type in
+ * another annotation type.
+ *
+ * @author  Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.3.2 @Retention
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Retention {
+    /**
+     * Returns the retention policy.
+     * @return the retention policy
+     */
+    RetentionPolicy value();
+}
diff --git a/java/lang/annotation/RetentionPolicy.java b/java/lang/annotation/RetentionPolicy.java
new file mode 100644
index 0000000..82aa198
--- /dev/null
+++ b/java/lang/annotation/RetentionPolicy.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003, 2004, 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.annotation;
+
+/**
+ * Annotation retention policy.  The constants of this enumerated type
+ * describe the various policies for retaining annotations.  They are used
+ * in conjunction with the {@link Retention} meta-annotation type to specify
+ * how long annotations are to be retained.
+ *
+ * @author  Joshua Bloch
+ * @since 1.5
+ */
+public enum RetentionPolicy {
+    /**
+     * Annotations are to be discarded by the compiler.
+     */
+    SOURCE,
+
+    /**
+     * Annotations are to be recorded in the class file by the compiler
+     * but need not be retained by the VM at run time.  This is the default
+     * behavior.
+     */
+    CLASS,
+
+    /**
+     * Annotations are to be recorded in the class file by the compiler and
+     * retained by the VM at run time, so they may be read reflectively.
+     *
+     * @see java.lang.reflect.AnnotatedElement
+     */
+    RUNTIME
+}
diff --git a/java/lang/annotation/Target.java b/java/lang/annotation/Target.java
new file mode 100644
index 0000000..1ad4056
--- /dev/null
+++ b/java/lang/annotation/Target.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003, 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.annotation;
+
+/**
+ * Indicates the contexts in which an annotation type is applicable. The
+ * declaration contexts and type contexts in which an annotation type may be
+ * applicable are specified in JLS 9.6.4.1, and denoted in source code by enum
+ * constants of {@link ElementType java.lang.annotation.ElementType}.
+ *
+ * <p>If an {@code @Target} meta-annotation is not present on an annotation type
+ * {@code T} , then an annotation of type {@code T} may be written as a
+ * modifier for any declaration except a type parameter declaration.
+ *
+ * <p>If an {@code @Target} meta-annotation is present, the compiler will enforce
+ * the usage restrictions indicated by {@code ElementType}
+ * enum constants, in line with JLS 9.7.4.
+ *
+ * <p>For example, this {@code @Target} meta-annotation indicates that the
+ * declared type is itself a meta-annotation type.  It can only be used on
+ * annotation type declarations:
+ * <pre>
+ *    &#064;Target(ElementType.ANNOTATION_TYPE)
+ *    public &#064;interface MetaAnnotationType {
+ *        ...
+ *    }
+ * </pre>
+ *
+ * <p>This {@code @Target} meta-annotation indicates that the declared type is
+ * intended solely for use as a member type in complex annotation type
+ * declarations.  It cannot be used to annotate anything directly:
+ * <pre>
+ *    &#064;Target({})
+ *    public &#064;interface MemberType {
+ *        ...
+ *    }
+ * </pre>
+ *
+ * <p>It is a compile-time error for a single {@code ElementType} constant to
+ * appear more than once in an {@code @Target} annotation.  For example, the
+ * following {@code @Target} meta-annotation is illegal:
+ * <pre>
+ *    &#064;Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
+ *    public &#064;interface Bogus {
+ *        ...
+ *    }
+ * </pre>
+ *
+ * @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 9.7.4 Where Annotations May Appear
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Target {
+    /**
+     * Returns an array of the kinds of elements an annotation type
+     * can be applied to.
+     * @return an array of the kinds of elements an annotation type
+     * can be applied to
+     */
+    ElementType[] value();
+}
diff --git a/java/lang/annotation/package-info.java b/java/lang/annotation/package-info.java
new file mode 100644
index 0000000..b2b7ec6
--- /dev/null
+++ b/java/lang/annotation/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2004, 2006, 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.
+ */
+
+/**
+ * Provides library support for the Java programming language
+ * annotation facility.
+ *
+ * @author Josh Bloch
+ * @since 1.5
+ */
+package java.lang.annotation;
diff --git a/java/lang/invoke/ArrayElementVarHandle.java b/java/lang/invoke/ArrayElementVarHandle.java
new file mode 100644
index 0000000..e315ba7
--- /dev/null
+++ b/java/lang/invoke/ArrayElementVarHandle.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * A VarHandle to access array elements.
+ * @hide
+ */
+final class ArrayElementVarHandle extends VarHandle {
+    private ArrayElementVarHandle(Class<?> arrayClass) {
+        super(arrayClass.getComponentType(), arrayClass, false /* isFinal */,
+              arrayClass, int.class);
+    }
+
+    static ArrayElementVarHandle create(Class<?> arrayClass) {
+        return new ArrayElementVarHandle(arrayClass);
+    }
+}
diff --git a/java/lang/invoke/ByteArrayViewVarHandle.java b/java/lang/invoke/ByteArrayViewVarHandle.java
new file mode 100644
index 0000000..abdb1cb
--- /dev/null
+++ b/java/lang/invoke/ByteArrayViewVarHandle.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.nio.ByteOrder;
+
+/**
+ * A VarHandle to access byte array elements as an array of primitive types.
+ * @hide
+ */
+final class ByteArrayViewVarHandle extends VarHandle {
+    private boolean nativeByteOrder;
+
+    private ByteArrayViewVarHandle(Class<?> arrayClass, ByteOrder byteOrder) {
+        super(arrayClass.getComponentType(), byte[].class, false /* isFinal */,
+              byte[].class, int.class);
+        this.nativeByteOrder = byteOrder.equals(ByteOrder.nativeOrder());
+    }
+
+    static ByteArrayViewVarHandle create(Class<?> arrayClass, ByteOrder byteOrder) {
+        return new ByteArrayViewVarHandle(arrayClass, byteOrder);
+    }
+}
diff --git a/java/lang/invoke/ByteBufferViewVarHandle.java b/java/lang/invoke/ByteBufferViewVarHandle.java
new file mode 100644
index 0000000..75fcbab
--- /dev/null
+++ b/java/lang/invoke/ByteBufferViewVarHandle.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A VarHandle to access byte array elements as an array of primitive types.
+ * @hide
+ */
+final class ByteBufferViewVarHandle extends VarHandle {
+    private boolean nativeByteOrder;
+
+    private ByteBufferViewVarHandle(Class<?> arrayClass, ByteOrder byteOrder) {
+        super(arrayClass.getComponentType(), byte[].class, false /* isFinal */,
+              ByteBuffer.class, int.class);
+        this.nativeByteOrder = byteOrder.equals(ByteOrder.nativeOrder());
+    }
+
+    static ByteBufferViewVarHandle create(Class<?> arrayClass, ByteOrder byteOrder) {
+        return new ByteBufferViewVarHandle(arrayClass, byteOrder);
+    }
+}
diff --git a/java/lang/invoke/CallSite.java b/java/lang/invoke/CallSite.java
new file mode 100644
index 0000000..85b4bb9
--- /dev/null
+++ b/java/lang/invoke/CallSite.java
@@ -0,0 +1,387 @@
+/*
+ * 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;
+
+// Android-changed: Not using Empty
+//import sun.invoke.empty.Empty;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * A {@code CallSite} is a holder for a variable {@link MethodHandle},
+ * which is called its {@code target}.
+ * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
+ * all calls to the site's current target.
+ * A {@code CallSite} may be associated with several {@code invokedynamic}
+ * instructions, or it may be "free floating", associated with none.
+ * In any case, it may be invoked through an associated method handle
+ * called its {@linkplain #dynamicInvoker dynamic invoker}.
+ * <p>
+ * {@code CallSite} is an abstract class which does not allow
+ * direct subclassing by users.  It has three immediate,
+ * concrete subclasses that may be either instantiated or subclassed.
+ * <ul>
+ * <li>If a mutable target is not required, an {@code invokedynamic} instruction
+ * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
+ * <li>If a mutable target is required which has volatile variable semantics,
+ * because updates to the target must be immediately and reliably witnessed by other threads,
+ * a {@linkplain VolatileCallSite volatile call site} may be used.
+ * <li>Otherwise, if a mutable target is required,
+ * a {@linkplain MutableCallSite mutable call site} may be used.
+ * </ul>
+ * <p>
+ * A non-constant call site may be <em>relinked</em> by changing its target.
+ * The new target must have the same {@linkplain MethodHandle#type() type}
+ * as the previous target.
+ * Thus, though a call site can be relinked to a series of
+ * successive targets, it cannot change its type.
+ * <p>
+ * Here is a sample use of call sites and bootstrap methods which links every
+ * dynamic call site to print its arguments:
+<blockquote><pre>{@code
+static void test() throws Throwable {
+    // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
+    InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
+}
+private static void printArgs(Object... args) {
+  System.out.println(java.util.Arrays.deepToString(args));
+}
+private static final MethodHandle printArgs;
+static {
+  MethodHandles.Lookup lookup = MethodHandles.lookup();
+  Class thisClass = lookup.lookupClass();  // (who am I?)
+  printArgs = lookup.findStatic(thisClass,
+      "printArgs", MethodType.methodType(void.class, Object[].class));
+}
+private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
+  // ignore caller and name, but match the type:
+  return new ConstantCallSite(printArgs.asType(type));
+}
+}</pre></blockquote>
+ * @author John Rose, JSR 292 EG
+ */
+abstract
+public class CallSite {
+    // Android-changed: not used.
+    // static { MethodHandleImpl.initStatics(); }
+
+    // The actual payload of this call site:
+    /*package-private*/
+    MethodHandle target;    // Note: This field is known to the JVM.  Do not change.
+
+    /**
+     * Make a blank call site object with the given method type.
+     * An initial target method is supplied which will throw
+     * an {@link IllegalStateException} if called.
+     * <p>
+     * Before this {@code CallSite} object is returned from a bootstrap method,
+     * it is usually provided with a more useful target method,
+     * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+     * @throws NullPointerException if the proposed type is null
+     */
+    /*package-private*/
+    CallSite(MethodType type) {
+        // Android-changed: No cache for these so create uninitializedCallSite target here using
+        // method handle transformations to create a method handle that has the expected method
+        // type but throws an IllegalStateException.
+        // target = makeUninitializedCallSite(type);
+        this.target = MethodHandles.throwException(type.returnType(), IllegalStateException.class);
+        this.target = MethodHandles.insertArguments(
+            this.target, 0, new IllegalStateException("uninitialized call site"));
+        if (type.parameterCount() > 0) {
+            this.target = MethodHandles.dropArguments(this.target, 0, type.ptypes());
+        }
+
+        // Android-changed: Using initializer method for GET_TARGET
+        // rather than complex static initializer.
+        initializeGetTarget();
+    }
+
+    /**
+     * Make a call site object equipped with an initial target method handle.
+     * @param target the method handle which will be the initial target of the call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    /*package-private*/
+    CallSite(MethodHandle target) {
+        target.type();  // null check
+        this.target = target;
+
+        // Android-changed: Using initializer method for GET_TARGET
+        // rather than complex static initializer.
+        initializeGetTarget();
+    }
+
+    /**
+     * Make a call site object equipped with an initial target method handle.
+     * @param targetType the desired type of the call site
+     * @param createTargetHook a hook which will bind the call site to the target method handle
+     * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
+     *         or if the target returned by the hook is not of the given {@code targetType}
+     * @throws NullPointerException if the hook returns a null value
+     * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
+     * @throws Throwable anything else thrown by the hook function
+     */
+    /*package-private*/
+    CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
+        this(targetType);
+        ConstantCallSite selfCCS = (ConstantCallSite) this;
+        MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
+        checkTargetChange(this.target, boundTarget);
+        this.target = boundTarget;
+
+        // Android-changed: Using initializer method for GET_TARGET
+        // rather than complex static initializer.
+        initializeGetTarget();
+    }
+
+    /**
+     * Returns the type of this call site's target.
+     * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
+     * The {@code setTarget} method enforces this invariant by refusing any new target that does
+     * not have the previous target's type.
+     * @return the type of the current target, which is also the type of any future target
+     */
+    public MethodType type() {
+        // warning:  do not call getTarget here, because CCS.getTarget can throw IllegalStateException
+        return target.type();
+    }
+
+    /**
+     * Returns the target method of the call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
+     *
+     * @return the current linkage state of the call site, its target method handle
+     * @see ConstantCallSite
+     * @see VolatileCallSite
+     * @see #setTarget
+     * @see ConstantCallSite#getTarget
+     * @see MutableCallSite#getTarget
+     * @see VolatileCallSite#getTarget
+     */
+    public abstract MethodHandle getTarget();
+
+    /**
+     * Updates the target method of this call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
+     * <p>
+     * The type of the new target must be {@linkplain MethodType#equals equal to}
+     * the type of the old target.
+     *
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see CallSite#getTarget
+     * @see ConstantCallSite#setTarget
+     * @see MutableCallSite#setTarget
+     * @see VolatileCallSite#setTarget
+     */
+    public abstract void setTarget(MethodHandle newTarget);
+
+    void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
+        MethodType oldType = oldTarget.type();
+        MethodType newType = newTarget.type();  // null check!
+        if (!newType.equals(oldType))
+            throw wrongTargetType(newTarget, oldType);
+    }
+
+    private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
+        return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
+    }
+
+    /**
+     * Produces a method handle equivalent to an invokedynamic instruction
+     * which has been linked to this call site.
+     * <p>
+     * This method is equivalent to the following code:
+     * <blockquote><pre>{@code
+     * MethodHandle getTarget, invoker, result;
+     * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+     * invoker = MethodHandles.exactInvoker(this.type());
+     * result = MethodHandles.foldArguments(invoker, getTarget)
+     * }</pre></blockquote>
+     *
+     * @return a method handle which always invokes this call site's current target
+     */
+    public abstract MethodHandle dynamicInvoker();
+
+    /*non-public*/ MethodHandle makeDynamicInvoker() {
+        // Android-changed: Use bindTo() rather than bindArgumentL() (not implemented).
+        MethodHandle getTarget = GET_TARGET.bindTo(this);
+        MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+        return MethodHandles.foldArguments(invoker, getTarget);
+    }
+
+    // Android-changed: no longer final. GET_TARGET assigned in initializeGetTarget().
+    private static MethodHandle GET_TARGET = null;
+
+    private void initializeGetTarget() {
+        // Android-changed: moved from static initializer for
+        // GET_TARGET to avoid issues with running early. Called from
+        // constructors. CallSite creation is not performance critical.
+        synchronized (CallSite.class) {
+            if (GET_TARGET == null) {
+                try {
+                    GET_TARGET = IMPL_LOOKUP.
+                            findVirtual(CallSite.class, "getTarget",
+                                        MethodType.methodType(MethodHandle.class));
+                } catch (ReflectiveOperationException e) {
+                    throw new InternalError(e);
+                }
+            }
+        }
+    }
+
+    // Android-changed: not used.
+    // /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
+    // /*package-private*/
+    // static Empty uninitializedCallSite() {
+    //     throw new IllegalStateException("uninitialized call site");
+    // }
+
+    // unsafe stuff:
+    private static final long TARGET_OFFSET;
+    static {
+        try {
+            TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
+    /*package-private*/
+    void setTargetNormal(MethodHandle newTarget) {
+        // Android-changed: Set value directly.
+        // MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
+        target = newTarget;
+    }
+    /*package-private*/
+    MethodHandle getTargetVolatile() {
+        return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
+    }
+    /*package-private*/
+    void setTargetVolatile(MethodHandle newTarget) {
+        // Android-changed: Set value directly.
+        // MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
+        UNSAFE.putObjectVolatile(this, TARGET_OFFSET, newTarget);
+    }
+
+    // Android-changed: not used.
+    // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
+    // static CallSite makeSite(MethodHandle bootstrapMethod,
+    //                          // Callee information:
+    //                          String name, MethodType type,
+    //                          // Extra arguments for BSM, if any:
+    //                          Object info,
+    //                          // Caller information:
+    //                          Class<?> callerClass) {
+    //     MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
+    //     CallSite site;
+    //     try {
+    //         Object binding;
+    //         info = maybeReBox(info);
+    //         if (info == null) {
+    //             binding = bootstrapMethod.invoke(caller, name, type);
+    //         } else if (!info.getClass().isArray()) {
+    //             binding = bootstrapMethod.invoke(caller, name, type, info);
+    //         } else {
+    //             Object[] argv = (Object[]) info;
+    //             maybeReBoxElements(argv);
+    //             switch (argv.length) {
+    //             case 0:
+    //                 binding = bootstrapMethod.invoke(caller, name, type);
+    //                 break;
+    //             case 1:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0]);
+    //                 break;
+    //             case 2:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1]);
+    //                 break;
+    //             case 3:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2]);
+    //                 break;
+    //             case 4:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3]);
+    //                 break;
+    //             case 5:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3], argv[4]);
+    //                 break;
+    //             case 6:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+    //                 break;
+    //             default:
+    //                 final int NON_SPREAD_ARG_COUNT = 3;  // (caller, name, type)
+    //                 if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+    //                     throw new BootstrapMethodError("too many bootstrap method arguments");
+    //                 MethodType bsmType = bootstrapMethod.type();
+    //                 MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+    //                 MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+    //                 MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+    //                 binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+    //             }
+    //         }
+    //         //System.out.println("BSM for "+name+type+" => "+binding);
+    //         if (binding instanceof CallSite) {
+    //             site = (CallSite) binding;
+    //         }  else {
+    //             throw new ClassCastException("bootstrap method failed to produce a CallSite");
+    //         }
+    //         if (!site.getTarget().type().equals(type))
+    //             throw wrongTargetType(site.getTarget(), type);
+    //     } catch (Throwable ex) {
+    //         BootstrapMethodError bex;
+    //         if (ex instanceof BootstrapMethodError)
+    //             bex = (BootstrapMethodError) ex;
+    //         else
+    //             bex = new BootstrapMethodError("call site initialization exception", ex);
+    //         throw bex;
+    //     }
+    //     return site;
+    // }
+
+    // private static Object maybeReBox(Object x) {
+    //     if (x instanceof Integer) {
+    //         int xi = (int) x;
+    //         if (xi == (byte) xi)
+    //             x = xi;  // must rebox; see JLS 5.1.7
+    //     }
+    //     return x;
+    // }
+    // private static void maybeReBoxElements(Object[] xa) {
+    //     for (int i = 0; i < xa.length; i++) {
+    //         xa[i] = maybeReBox(xa[i]);
+    //     }
+    // }
+}
diff --git a/java/lang/invoke/ConstantCallSite.java b/java/lang/invoke/ConstantCallSite.java
new file mode 100644
index 0000000..f27d0e7
--- /dev/null
+++ b/java/lang/invoke/ConstantCallSite.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, 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;
+
+/**
+ * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
+ * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
+ * bound to the call site's target.
+ * @author John Rose, JSR 292 EG
+ */
+public class ConstantCallSite extends CallSite {
+    private final boolean isFrozen;
+
+    /**
+     * Creates a call site with a permanent target.
+     * @param target the target to be permanently associated with this call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    public ConstantCallSite(MethodHandle target) {
+        super(target);
+        isFrozen = true;
+    }
+
+    /**
+     * Creates a call site with a permanent target, possibly bound to the call site itself.
+     * <p>
+     * During construction of the call site, the {@code createTargetHook} is invoked to
+     * produce the actual target, as if by a call of the form
+     * {@code (MethodHandle) createTargetHook.invoke(this)}.
+     * <p>
+     * Note that user code cannot perform such an action directly in a subclass constructor,
+     * since the target must be fixed before the {@code ConstantCallSite} constructor returns.
+     * <p>
+     * The hook is said to bind the call site to a target method handle,
+     * and a typical action would be {@code someTarget.bindTo(this)}.
+     * However, the hook is free to take any action whatever,
+     * including ignoring the call site and returning a constant target.
+     * <p>
+     * The result returned by the hook must be a method handle of exactly
+     * the same type as the call site.
+     * <p>
+     * While the hook is being called, the new {@code ConstantCallSite}
+     * object is in a partially constructed state.
+     * In this state,
+     * a call to {@code getTarget}, or any other attempt to use the target,
+     * will result in an {@code IllegalStateException}.
+     * It is legal at all times to obtain the call site's type using the {@code type} method.
+     *
+     * @param targetType the type of the method handle to be permanently associated with this call site
+     * @param createTargetHook a method handle to invoke (on the call site) to produce the call site's target
+     * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
+     *         or if the target returned by the hook is not of the given {@code targetType}
+     * @throws NullPointerException if the hook returns a null value
+     * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
+     * @throws Throwable anything else thrown by the hook function
+     */
+    protected ConstantCallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
+        super(targetType, createTargetHook);
+        isFrozen = true;
+    }
+
+    /**
+     * Returns the target method of the call site, which behaves
+     * like a {@code final} field of the {@code ConstantCallSite}.
+     * That is, the target is always the original value passed
+     * to the constructor call which created this instance.
+     *
+     * @return the immutable linkage state of this call site, a constant method handle
+     * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
+     */
+    @Override public final MethodHandle getTarget() {
+        if (!isFrozen)  throw new IllegalStateException();
+        return target;
+    }
+
+    /**
+     * Always throws an {@link UnsupportedOperationException}.
+     * This kind of call site cannot change its target.
+     * @param ignore a new target proposed for the call site, which is ignored
+     * @throws UnsupportedOperationException because this kind of call site cannot change its target
+     */
+    @Override public final void setTarget(MethodHandle ignore) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns this call site's permanent target.
+     * Since that target will never change, this is a correct implementation
+     * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
+     * @return the immutable linkage state of this call site, a constant method handle
+     * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return getTarget();
+    }
+}
diff --git a/java/lang/invoke/FieldVarHandle.java b/java/lang/invoke/FieldVarHandle.java
new file mode 100644
index 0000000..0921040
--- /dev/null
+++ b/java/lang/invoke/FieldVarHandle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * A VarHandle that's associated with an ArtField.
+ * @hide
+ */
+final class FieldVarHandle extends VarHandle {
+    private final long artField;
+
+    private FieldVarHandle(Field field, Class<?> declaringClass) {
+        super(field.getType(), Modifier.isFinal(field.getModifiers()), declaringClass);
+        artField = field.getArtField();
+    }
+
+    private FieldVarHandle(Field field) {
+        super(field.getType(), Modifier.isFinal(field.getModifiers()));
+        artField = field.getArtField();
+    }
+
+    static FieldVarHandle create(Field field) {
+        if (Modifier.isStatic(field.getModifiers())) {
+            return new FieldVarHandle(field);
+        } else {
+            return new FieldVarHandle(field, field.getDeclaringClass());
+        }
+    }
+}
diff --git a/java/lang/invoke/LambdaConversionException.java b/java/lang/invoke/LambdaConversionException.java
new file mode 100644
index 0000000..e1123da
--- /dev/null
+++ b/java/lang/invoke/LambdaConversionException.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+/**
+ * LambdaConversionException
+ */
+public class LambdaConversionException extends Exception {
+    private static final long serialVersionUID = 292L + 8L;
+
+    /**
+     * Constructs a {@code LambdaConversionException}.
+     */
+    public LambdaConversionException() {
+    }
+
+    /**
+     * Constructs a {@code LambdaConversionException} with a message.
+     * @param message the detail message
+     */
+    public LambdaConversionException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a {@code LambdaConversionException} with a message and cause.
+     * @param message the detail message
+     * @param cause the cause
+     */
+    public LambdaConversionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a {@code LambdaConversionException} with a cause.
+     * @param cause the cause
+     */
+    public LambdaConversionException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a {@code LambdaConversionException} with a message,
+     * cause, and other settings.
+     * @param message the detail message
+     * @param cause the cause
+     * @param enableSuppression whether or not suppressed exceptions are enabled
+     * @param writableStackTrace whether or not the stack trace is writable
+     */
+    public LambdaConversionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/java/lang/invoke/LambdaMetafactory.java b/java/lang/invoke/LambdaMetafactory.java
new file mode 100644
index 0000000..e1ce46f
--- /dev/null
+++ b/java/lang/invoke/LambdaMetafactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+public class LambdaMetafactory {
+
+    public static final int FLAG_SERIALIZABLE = 1 << 0;
+
+    public static final int FLAG_MARKERS = 1 << 1;
+
+    public static final int FLAG_BRIDGES = 1 << 2;
+
+    public static CallSite metafactory(MethodHandles.Lookup caller,
+                                       String invokedName,
+                                       MethodType invokedType,
+                                       MethodType samMethodType,
+                                       MethodHandle implMethod,
+                                       MethodType instantiatedMethodType)
+            throws LambdaConversionException { return null; }
+
+    public static CallSite altMetafactory(MethodHandles.Lookup caller,
+                                          String invokedName,
+                                          MethodType invokedType,
+                                          Object... args)
+            throws LambdaConversionException { return null; }
+}
diff --git a/java/lang/invoke/MethodHandle.java b/java/lang/invoke/MethodHandle.java
new file mode 100644
index 0000000..87911c2
--- /dev/null
+++ b/java/lang/invoke/MethodHandle.java
@@ -0,0 +1,1646 @@
+/*
+ * 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 dalvik.system.EmulatedStackFrame;
+
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method handle is a typed, directly executable reference to an underlying method,
+ * constructor, field, or similar low-level operation, with optional
+ * transformations of arguments or return values.
+ * These transformations are quite general, and include such patterns as
+ * {@linkplain #asType conversion},
+ * {@linkplain #bindTo insertion},
+ * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
+ * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
+ *
+ * <h1>Method handle contents</h1>
+ * Method handles are dynamically and strongly typed according to their parameter and return types.
+ * They are not distinguished by the name or the defining class of their underlying methods.
+ * A method handle must be invoked using a symbolic type descriptor which matches
+ * the method handle's own {@linkplain #type type descriptor}.
+ * <p>
+ * Every method handle reports its type descriptor via the {@link #type type} accessor.
+ * This type descriptor is a {@link java.lang.invoke.MethodType MethodType} object,
+ * whose structure is a series of classes, one of which is
+ * the return type of the method (or {@code void.class} if none).
+ * <p>
+ * A method handle's type controls the types of invocations it accepts,
+ * and the kinds of transformations that apply to it.
+ * <p>
+ * A method handle contains a pair of special invoker methods
+ * called {@link #invokeExact invokeExact} and {@link #invoke invoke}.
+ * Both invoker methods provide direct access to the method handle's
+ * underlying method, constructor, field, or other operation,
+ * as modified by transformations of arguments and return values.
+ * Both invokers accept calls which exactly match the method handle's own type.
+ * The plain, inexact invoker also accepts a range of other call types.
+ * <p>
+ * Method handles are immutable and have no visible state.
+ * Of course, they can be bound to underlying methods or data which exhibit state.
+ * With respect to the Java Memory Model, any method handle will behave
+ * as if all of its (internal) fields are final variables.  This means that any method
+ * handle made visible to the application will always be fully formed.
+ * This is true even if the method handle is published through a shared
+ * variable in a data race.
+ * <p>
+ * Method handles cannot be subclassed by the user.
+ * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
+ * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
+ * operation.  The programmer should not draw conclusions about a method handle
+ * from its specific class, as the method handle class hierarchy (if any)
+ * may change from time to time or across implementations from different vendors.
+ *
+ * <h1>Method handle compilation</h1>
+ * A Java method call expression naming {@code invokeExact} or {@code invoke}
+ * can invoke a method handle from Java source code.
+ * From the viewpoint of source code, these methods can take any arguments
+ * and their result can be cast to any return type.
+ * Formally this is accomplished by giving the invoker methods
+ * {@code Object} return types and variable arity {@code Object} arguments,
+ * but they have an additional quality called <em>signature polymorphism</em>
+ * which connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to {@code invokeExact}
+ * and {@code invoke} compile to an {@code invokevirtual} instruction.
+ * More unusually, the compiler must record the actual argument types,
+ * and may not perform method invocation conversions on the arguments.
+ * Instead, it must push them on the stack according to their own unconverted types.
+ * The method handle object itself is pushed on the stack before the arguments.
+ * The compiler then calls the method handle with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also determine
+ * the return type.  This is based on a cast on the method invocation expression,
+ * if there is one, or else {@code Object} if the invocation is an expression
+ * or else {@code void} if the invocation is a statement.
+ * The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given
+ * a symbolic type descriptor of {@code java.lang.Void}.
+ * The ambiguity with the type {@code Void} is harmless, since there are no references of type
+ * {@code Void} except the null reference.
+ *
+ * <h1>Method handle invocation</h1>
+ * The first time a {@code invokevirtual} instruction is executed
+ * it is linked, by symbolically resolving the names in the instruction
+ * and verifying that the method call is statically legal.
+ * This is true of calls to {@code invokeExact} and {@code invoke}.
+ * In this case, the symbolic type descriptor emitted by the compiler is checked for
+ * correct syntax and names it contains are resolved.
+ * Thus, an {@code invokevirtual} instruction which invokes
+ * a method handle will always link, as long
+ * as the symbolic type descriptor is syntactically well-formed
+ * and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking,
+ * the receiving method handle's type is first checked by the JVM
+ * to ensure that it matches the symbolic type descriptor.
+ * If the type match fails, it means that the method which the
+ * caller is invoking is not present on the individual
+ * method handle being invoked.
+ * <p>
+ * In the case of {@code invokeExact}, the type descriptor of the invocation
+ * (after resolving symbolic type names) must exactly match the method type
+ * of the receiving method handle.
+ * In the case of plain, inexact {@code invoke}, the resolved type descriptor
+ * must be a valid argument to the receiver's {@link #asType asType} method.
+ * Thus, plain {@code invoke} is more permissive than {@code invokeExact}.
+ * <p>
+ * After type matching, a call to {@code invokeExact} directly
+ * and immediately invoke the method handle's underlying method
+ * (or other behavior, as the case may be).
+ * <p>
+ * A call to plain {@code invoke} works the same as a call to
+ * {@code invokeExact}, if the symbolic type descriptor specified by the caller
+ * exactly matches the method handle's own type.
+ * If there is a type mismatch, {@code invoke} attempts
+ * to adjust the type of the receiving method handle,
+ * as if by a call to {@link #asType asType},
+ * to obtain an exactly invokable method handle {@code M2}.
+ * This allows a more powerful negotiation of method type
+ * between caller and callee.
+ * <p>
+ * (<em>Note:</em> The adjusted method handle {@code M2} is not directly observable,
+ * and implementations are therefore not required to materialize it.)
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, method handle type matching will usually succeed.
+ * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
+ * either directly (in the case of {@code invokeExact}) or indirectly as if
+ * by a failed call to {@code asType} (in the case of {@code invoke}).
+ * <p>
+ * Thus, a method type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as
+ * a dynamic {@code WrongMethodTypeException}
+ * in a program which uses method handles.
+ * <p>
+ * Because method types contain "live" {@code Class} objects,
+ * method type matching takes into account both types names and class loaders.
+ * Thus, even if a method handle {@code M} is created in one
+ * class loader {@code L1} and used in another {@code L2},
+ * method handle calls are type-safe, because the caller's symbolic type
+ * descriptor, as resolved in {@code L2},
+ * is matched against the original callee method's symbolic type descriptor,
+ * as resolved in {@code L1}.
+ * The resolution in {@code L1} happens when {@code M} is created
+ * and its type is assigned, while the resolution in {@code L2} happens
+ * when the {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from the checking of type descriptors,
+ * a method handle's capability to call its underlying method is unrestricted.
+ * If a method handle is formed on a non-public method by a class
+ * that has access to that method, the resulting handle can be used
+ * in any place by any caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time
+ * a reflective method is invoked,
+ * method handle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the method handle is created</a>.
+ * In the case of {@code ldc} (see below), access checking is performed as part of linking
+ * the constant pool entry underlying the constant method handle.
+ * <p>
+ * Thus, handles to non-public methods, or to methods in non-public classes,
+ * should generally be kept secret.
+ * They should not be passed to untrusted code unless their use from
+ * the untrusted code would be harmless.
+ *
+ * <h1>Method handle creation</h1>
+ * Java code can create a method handle that directly accesses
+ * any method, constructor, or field that is accessible to that code.
+ * This is done via a reflective, capability-based API called
+ * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
+ * For example, a static method handle can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
+ * There are also conversion methods from Core Reflection API objects,
+ * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * <p>
+ * Like classes and strings, method handles that correspond to accessible
+ * fields, methods, and constructors can also be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
+ * refers directly to an associated {@code CONSTANT_Methodref},
+ * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
+ * constant pool entry.
+ * (For full details on method handle constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
+ * <p>
+ * Method handles produced by lookups or constant loads from methods or
+ * constructors with the variable arity modifier bit ({@code 0x0080})
+ * have a corresponding variable arity, as if they were defined with
+ * the help of {@link #asVarargsCollector asVarargsCollector}.
+ * <p>
+ * A method reference may refer either to a static or non-static method.
+ * In the non-static case, the method handle type includes an explicit
+ * receiver argument, prepended before any other arguments.
+ * In the method handle's type, the initial receiver argument is typed
+ * according to the class under which the method was initially requested.
+ * (E.g., if a non-static method handle is obtained via {@code ldc},
+ * the type of the receiver is the class named in the constant pool entry.)
+ * <p>
+ * Method handle constants are subject to the same link-time access checks
+ * their corresponding bytecode instructions, and the {@code ldc} instruction
+ * will throw corresponding linkage errors if the bytecode behaviors would
+ * throw such errors.
+ * <p>
+ * As a corollary of this, access to protected members is restricted
+ * to receivers only of the accessing class, or one of its subclasses,
+ * and the accessing class must in turn be a subclass (or package sibling)
+ * of the protected member's defining class.
+ * If a method reference refers to a protected non-static method or field
+ * of a class outside the current package, the receiver argument will
+ * be narrowed to the type of the accessing class.
+ * <p>
+ * When a method handle to a virtual method is invoked, the method is
+ * always looked up in the receiver (that is, the first argument).
+ * <p>
+ * A non-virtual method handle to a specific virtual method implementation
+ * can also be created.  These do not perform virtual lookup based on
+ * receiver type.  Such a method handle simulates the effect of
+ * an {@code invokespecial} instruction to the same method.
+ *
+ * <h1>Usage examples</h1>
+ * Here are some examples of usage:
+ * <blockquote><pre>{@code
+Object x, y; String s; int i;
+MethodType mt; MethodHandle mh;
+MethodHandles.Lookup lookup = MethodHandles.lookup();
+// mt is (char,char)String
+mt = MethodType.methodType(String.class, char.class, char.class);
+mh = lookup.findVirtual(String.class, "replace", mt);
+s = (String) mh.invokeExact("daddy",'d','n');
+// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
+assertEquals(s, "nanny");
+// weakly typed invocation (using MHs.invoke)
+s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
+assertEquals(s, "savvy");
+// mt is (Object[])List
+mt = MethodType.methodType(java.util.List.class, Object[].class);
+mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
+assert(mh.isVarargsCollector());
+x = mh.invoke("one", "two");
+// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+assertEquals(x, java.util.Arrays.asList("one","two"));
+// mt is (Object,Object,Object)Object
+mt = MethodType.genericMethodType(3);
+mh = mh.asType(mt);
+x = mh.invokeExact((Object)1, (Object)2, (Object)3);
+// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+assertEquals(x, java.util.Arrays.asList(1,2,3));
+// mt is ()int
+mt = MethodType.methodType(int.class);
+mh = lookup.findVirtual(java.util.List.class, "size", mt);
+i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
+// invokeExact(Ljava/util/List;)I
+assert(i == 3);
+mt = MethodType.methodType(void.class, String.class);
+mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
+mh.invokeExact(System.out, "Hello, world.");
+// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
+ * }</pre></blockquote>
+ * Each of the above calls to {@code invokeExact} or plain {@code invoke}
+ * generates a single invokevirtual instruction with
+ * the symbolic type descriptor indicated in the following comment.
+ * In these examples, the helper method {@code assertEquals} is assumed to
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals}
+ * on its arguments, and asserts that the result is true.
+ *
+ * <h1>Exceptions</h1>
+ * The methods {@code invokeExact} and {@code invoke} are declared
+ * to throw {@link java.lang.Throwable Throwable},
+ * which is to say that there is no static restriction on what a method handle
+ * can throw.  Since the JVM does not distinguish between checked
+ * and unchecked exceptions (other than by their class, of course),
+ * there is no particular effect on bytecode shape from ascribing
+ * checked exceptions to method handle invocations.  But in Java source
+ * code, methods which perform method handle calls must either explicitly
+ * throw {@code Throwable}, or else must catch all
+ * throwables locally, rethrowing only those which are legal in the context,
+ * and wrapping ones which are illegal.
+ *
+ * <h1><a name="sigpoly"></a>Signature polymorphism</h1>
+ * The unusual compilation and linkage behavior of
+ * {@code invokeExact} and plain {@code invoke}
+ * is referenced by the term <em>signature polymorphism</em>.
+ * As defined in the Java Language Specification,
+ * a signature polymorphic method is one which can operate with
+ * any of a wide range of call signatures and return types.
+ * <p>
+ * In source code, a call to a signature polymorphic method will
+ * compile, regardless of the requested symbolic type descriptor.
+ * As usual, the Java compiler emits an {@code invokevirtual}
+ * instruction with the given symbolic type descriptor against the named method.
+ * The unusual part is that the symbolic type descriptor is derived from
+ * the actual argument and return types, not from the method declaration.
+ * <p>
+ * When the JVM processes bytecode containing signature polymorphic calls,
+ * it will successfully link any such call, regardless of its symbolic type descriptor.
+ * (In order to retain type safety, the JVM will guard such calls with suitable
+ * dynamic type checks, as described elsewhere.)
+ * <p>
+ * Bytecode generators, including the compiler back end, are required to emit
+ * untransformed symbolic type descriptors for these methods.
+ * Tools which determine symbolic linkage are required to accept such
+ * untransformed descriptors, without reporting linkage errors.
+ *
+ * <h1>Interoperation between method handles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
+ * any class member represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent method handle.
+ * For example, a reflective {@link java.lang.reflect.Method Method} can
+ * be converted to a method handle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * The resulting method handles generally provide more direct and efficient
+ * access to the underlying class members.
+ * <p>
+ * As a special case,
+ * when the Core Reflection API is used to view the signature polymorphic
+ * methods {@code invokeExact} or plain {@code invoke} in this class,
+ * they appear as ordinary non-polymorphic methods.
+ * Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs} bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be
+ * invoked via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.
+ * However, such reflective calls do not result in method handle invocations.
+ * Such a call, if passed the required argument
+ * (a single one, of type {@code Object[]}), will ignore the argument and
+ * will throw an {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively
+ * invoke method handles under any symbolic type descriptor, this reflective view conflicts
+ * with the normal presentation of these methods via bytecodes.
+ * Thus, these two native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular type descriptor,
+ * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
+ * or {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}.
+ * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle
+ * to call {@code invokeExact} or plain {@code invoke},
+ * for any specified type descriptor .
+ *
+ * <h1>Interoperation between method handles and Java generics</h1>
+ * A method handle can be obtained on a method, constructor, or field
+ * which is declared with Java generic types.
+ * As with the Core Reflection API, the type of the method handle
+ * will constructed from the erasure of the source-level type.
+ * When a method handle is invoked, the types of its arguments
+ * or the return value cast type may be generic types or type instances.
+ * If this occurs, the compiler will replace those
+ * types by their erasures when it constructs the symbolic type descriptor
+ * for the {@code invokevirtual} instruction.
+ * <p>
+ * Method handles do not represent
+ * their function-like types in terms of Java parameterized (generic) types,
+ * because there are three mismatches between function-like types and parameterized
+ * Java types.
+ * <ul>
+ * <li>Method types range over all possible arities,
+ * from no arguments to up to the  <a href="MethodHandle.html#maxarity">maximum number</a> of allowed arguments.
+ * Generics are not variadic, and so cannot represent this.</li>
+ * <li>Method types can specify arguments of primitive types,
+ * which Java generic types cannot range over.</li>
+ * <li>Higher order functions over method handles (combinators) are
+ * often generic across a wide range of function types, including
+ * those of multiple arities.  It is impossible to represent such
+ * genericity with a Java type parameter.</li>
+ * </ul>
+ *
+ * <h1><a name="maxarity"></a>Arity limits</h1>
+ * The JVM imposes on all methods and constructors of any kind an absolute
+ * limit of 255 stacked arguments.  This limit can appear more restrictive
+ * in certain cases:
+ * <ul>
+ * <li>A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots.
+ * <li>A non-static method consumes an extra argument for the object on which the method is called.
+ * <li>A constructor consumes an extra argument for the object which is being constructed.
+ * <li>Since a method handle&rsquo;s {@code invoke} method (or other signature-polymorphic method) is non-virtual,
+ *     it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object.
+ * </ul>
+ * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments.
+ * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it.
+ * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}.
+ * In particular, a method handle&rsquo;s type must not have an arity of the exact maximum 255.
+ *
+ * @see MethodType
+ * @see MethodHandles
+ * @author John Rose, JSR 292 EG
+ */
+public abstract class MethodHandle {
+    // Android-removed: MethodHandleImpl.initStatics() unused on Android.
+    // static { MethodHandleImpl.initStatics(); }
+
+    /**
+     * Internal marker interface which distinguishes (to the Java compiler)
+     * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
+     *
+     * @hide
+     */
+    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+    // Android-changed: Made public @hide as otherwise it breaks the stubs generation.
+    // @interface PolymorphicSignature { }
+    public @interface PolymorphicSignature { }
+
+    // Android-added: Comment to differentiate between type and nominalType.
+    /**
+     * The type of this method handle, this corresponds to the exact type of the method
+     * being invoked.
+     * 
+     * @see #nominalType
+     */
+    private final MethodType type;
+    // Android-removed: LambdaForm and customizationCount unused on Android.
+    // They will be substituted with appropriate implementation / delegate classes.
+    /*
+    /*private* final LambdaForm form;
+    // form is not private so that invokers can easily fetch it
+    /*private* MethodHandle asTypeCache;
+    // asTypeCache is not private so that invokers can easily fetch it
+    /*non-public* byte customizationCount;
+    // customizationCount should be accessible from invokers
+    */
+
+    // BEGIN Android-added: Android specific implementation.
+    // The MethodHandle functionality is tightly coupled with internal details of the runtime and
+    // so Android has a completely different implementation compared to the RI.
+    /**
+     * The nominal type of this method handle, will be non-null if a method handle declares
+     * a different type from its "real" type, which is either the type of the method being invoked
+     * or the type of the emulated stackframe expected by an underyling adapter.
+     */
+    private MethodType nominalType;
+
+    /**
+     * The spread invoker associated with this type with zero trailing arguments.
+     * This is used to speed up invokeWithArguments.
+     */
+    private MethodHandle cachedSpreadInvoker;
+
+    /**
+     * The INVOKE* constants and SGET/SPUT and IGET/IPUT constants specify the behaviour of this
+     * method handle with respect to the ArtField* or the ArtMethod* that it operates on. These
+     * behaviours are equivalent to the dex bytecode behaviour on the respective method_id or
+     * field_id in the equivalent instruction.
+     *
+     * INVOKE_TRANSFORM is a special type of handle which doesn't encode any dex bytecode behaviour,
+     * instead it transforms the list of input arguments or performs other higher order operations
+     * before (optionally) delegating to another method handle.
+     *
+     * INVOKE_CALLSITE_TRANSFORM is a variation on INVOKE_TRANSFORM where the method type of
+     * a MethodHandle dynamically varies based on the callsite. This is used by
+     * the VarargsCollector implementation which places any number of trailing arguments
+     * into an array before invoking an arity method. The "any number of trailing arguments" means
+     * it would otherwise generate WrongMethodTypeExceptions as the callsite method type and
+     * VarargsCollector method type appear incompatible.
+     */
+
+    /** @hide */ public static final int INVOKE_VIRTUAL = 0;
+    /** @hide */ public static final int INVOKE_SUPER = 1;
+    /** @hide */ public static final int INVOKE_DIRECT = 2;
+    /** @hide */ public static final int INVOKE_STATIC = 3;
+    /** @hide */ public static final int INVOKE_INTERFACE = 4;
+    /** @hide */ public static final int INVOKE_TRANSFORM = 5;
+    /** @hide */ public static final int INVOKE_CALLSITE_TRANSFORM = 6;
+    /** @hide */ public static final int INVOKE_VAR_HANDLE = 7;
+    /** @hide */ public static final int INVOKE_VAR_HANDLE_EXACT = 8;
+    /** @hide */ public static final int IGET = 9;
+    /** @hide */ public static final int IPUT = 10;
+    /** @hide */ public static final int SGET = 11;
+    /** @hide */ public static final int SPUT = 12;
+
+    // The kind of this method handle (used by the runtime). This is one of the INVOKE_*
+    // constants or SGET/SPUT, IGET/IPUT.
+    /** @hide */ protected final int handleKind;
+
+    // The ArtMethod* or ArtField* associated with this method handle (used by the runtime).
+    /** @hide */ protected final long artFieldOrMethod;
+
+    /** @hide */
+    protected MethodHandle(long artFieldOrMethod, int handleKind, MethodType type) {
+        this.artFieldOrMethod = artFieldOrMethod;
+        this.handleKind = handleKind;
+        this.type = type;
+    }
+    // END Android-added: Android specific implementation.
+
+    /**
+     * Reports the type of this method handle.
+     * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
+     * @return the method handle type
+     */
+    public MethodType type() {
+        // Android-added: Added nominalType field.
+        if (nominalType != null) {
+            return nominalType;
+        }
+
+        return type;
+    }
+
+    // BEGIN Android-removed: LambdaForm unsupported on Android.
+    /*
+    /**
+     * Package-private constructor for the method handle implementation hierarchy.
+     * Method handle inheritance will be contained completely within
+     * the {@code java.lang.invoke} package.
+     *
+    // @param type type (permanently assigned) of the new method handle
+    /*non-public* MethodHandle(MethodType type, LambdaForm form) {
+        type.getClass();  // explicit NPE
+        form.getClass();  // explicit NPE
+        this.type = type;
+        this.form = form.uncustomize();
+
+        this.form.prepare();  // TO DO:  Try to delay this step until just before invocation.
+    }
+    */
+    // END Android-removed: LambdaForm unsupported on Android.
+
+    /**
+     * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
+     * The symbolic type descriptor at the call site of {@code invokeExact} must
+     * exactly match this method handle's {@link #type type}.
+     * No conversions are allowed on arguments or return values.
+     * <p>
+     * When this method is observed via the Core Reflection API,
+     * it will appear as a single native method, taking an object array and returning an object.
+     * If this native method is invoked directly via
+     * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+     * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+     * it will throw an {@code UnsupportedOperationException}.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
+     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+     */
+    public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
+
+    /**
+     * Invokes the method handle, allowing any caller type descriptor,
+     * and optionally performing conversions on arguments and return values.
+     * <p>
+     * If the call site's symbolic type descriptor exactly matches this method handle's {@link #type type},
+     * the call proceeds as if by {@link #invokeExact invokeExact}.
+     * <p>
+     * Otherwise, the call proceeds as if this method handle were first
+     * adjusted by calling {@link #asType asType} to adjust this method handle
+     * to the required type, and then the call proceeds as if by
+     * {@link #invokeExact invokeExact} on the adjusted method handle.
+     * <p>
+     * There is no guarantee that the {@code asType} call is actually made.
+     * If the JVM can predict the results of making the call, it may perform
+     * adaptations directly on the caller's arguments,
+     * and call the target method handle according to its own exact type.
+     * <p>
+     * The resolved type descriptor at the call site of {@code invoke} must
+     * be a valid argument to the receivers {@code asType} method.
+     * In particular, the caller must specify the same argument arity
+     * as the callee's type,
+     * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
+     * <p>
+     * When this method is observed via the Core Reflection API,
+     * it will appear as a single native method, taking an object array and returning an object.
+     * If this native method is invoked directly via
+     * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+     * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+     * it will throw an {@code UnsupportedOperationException}.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's symbolic type descriptor
+     * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
+     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+     */
+    public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
+
+    // BEGIN Android-removed: RI implementation unused on Android.
+    /*
+    /**
+     * Private method for trusted invocation of a method handle respecting simplified signatures.
+     * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
+     * <p>
+     * The caller signature is restricted to the following basic types:
+     * Object, int, long, float, double, and void return.
+     * <p>
+     * The caller is responsible for maintaining type correctness by ensuring
+     * that the each outgoing argument value is a member of the range of the corresponding
+     * callee argument type.
+     * (The caller should therefore issue appropriate casts and integer narrowing
+     * operations on outgoing argument values.)
+     * The caller can assume that the incoming result value is part of the range
+     * of the callee's return type.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     * @param args the signature-polymorphic parameter list, statically represented using varargs
+     * @return the signature-polymorphic result, statically represented using {@code Object}
+     *
+    /*non-public* static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+    */
+    // END Android-removed: RI implementation unused on Android.
+
+    /**
+     * Performs a variable arity invocation, passing the arguments in the given list
+     * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
+     * which mentions only the type {@code Object}, and whose arity is the length
+     * of the argument list.
+     * <p>
+     * Specifically, execution proceeds as if by the following steps,
+     * although the methods are not guaranteed to be called if the JVM
+     * can predict their effects.
+     * <ul>
+     * <li>Determine the length of the argument array as {@code N}.
+     *     For a null reference, {@code N=0}. </li>
+     * <li>Determine the general type {@code TN} of {@code N} arguments as
+     *     as {@code TN=MethodType.genericMethodType(N)}.</li>
+     * <li>Force the original target method handle {@code MH0} to the
+     *     required type, as {@code MH1 = MH0.asType(TN)}. </li>
+     * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
+     * <li>Invoke the type-adjusted method handle on the unpacked arguments:
+     *     MH1.invokeExact(A0, ...). </li>
+     * <li>Take the return value as an {@code Object} reference. </li>
+     * </ul>
+     * <p>
+     * Because of the action of the {@code asType} step, the following argument
+     * conversions are applied as necessary:
+     * <ul>
+     * <li>reference casting
+     * <li>unboxing
+     * <li>widening primitive conversions
+     * </ul>
+     * <p>
+     * The result returned by the call is boxed if it is a primitive,
+     * or forced to null if the return type is void.
+     * <p>
+     * This call is equivalent to the following code:
+     * <blockquote><pre>{@code
+     * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
+     * Object result = invoker.invokeExact(this, arguments);
+     * }</pre></blockquote>
+     * <p>
+     * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
+     * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
+     * It can therefore be used as a bridge between native or reflective code and method handles.
+     *
+     * @param arguments the arguments to pass to the target
+     * @return the result returned by the target
+     * @throws ClassCastException if an argument cannot be converted by reference casting
+     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+     * @throws Throwable anything thrown by the target method invocation
+     * @see MethodHandles#spreadInvoker
+     */
+    public Object invokeWithArguments(Object... arguments) throws Throwable {
+        // BEGIN Android-changed: Android specific implementation.
+        // MethodType invocationType = MethodType.genericMethodType(arguments == null ? 0 : arguments.length);
+        // return invocationType.invokers().spreadInvoker(0).invokeExact(asType(invocationType), arguments);
+        MethodHandle invoker = null;
+        synchronized (this) {
+            if (cachedSpreadInvoker == null) {
+                cachedSpreadInvoker = MethodHandles.spreadInvoker(this.type(), 0);
+            }
+
+            invoker = cachedSpreadInvoker;
+        }
+
+        return invoker.invoke(this, arguments);
+        // END Android-changed: Android specific implementation.
+    }
+
+    /**
+     * Performs a variable arity invocation, passing the arguments in the given array
+     * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
+     * which mentions only the type {@code Object}, and whose arity is the length
+     * of the argument array.
+     * <p>
+     * This method is also equivalent to the following code:
+     * <blockquote><pre>{@code
+     *   invokeWithArguments(arguments.toArray()
+     * }</pre></blockquote>
+     *
+     * @param arguments the arguments to pass to the target
+     * @return the result returned by the target
+     * @throws NullPointerException if {@code arguments} is a null reference
+     * @throws ClassCastException if an argument cannot be converted by reference casting
+     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+     * @throws Throwable anything thrown by the target method invocation
+     */
+    public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
+        return invokeWithArguments(arguments.toArray());
+    }
+
+    /**
+     * Produces an adapter method handle which adapts the type of the
+     * current method handle to a new type.
+     * The resulting method handle is guaranteed to report a type
+     * which is equal to the desired new type.
+     * <p>
+     * If the original type and new type are equal, returns {@code this}.
+     * <p>
+     * The new method handle, when invoked, will perform the following
+     * steps:
+     * <ul>
+     * <li>Convert the incoming argument list to match the original
+     *     method handle's argument list.
+     * <li>Invoke the original method handle on the converted argument list.
+     * <li>Convert any result returned by the original method handle
+     *     to the return type of new method handle.
+     * </ul>
+     * <p>
+     * This method provides the crucial behavioral difference between
+     * {@link #invokeExact invokeExact} and plain, inexact {@link #invoke invoke}.
+     * The two methods
+     * perform the same steps when the caller's type descriptor exactly m atches
+     * the callee's, but when the types differ, plain {@link #invoke invoke}
+     * also calls {@code asType} (or some internal equivalent) in order
+     * to match up the caller's and callee's types.
+     * <p>
+     * If the current method is a variable arity method handle
+     * argument list conversion may involve the conversion and collection
+     * of several arguments into an array, as
+     * {@linkplain #asVarargsCollector described elsewhere}.
+     * In every other case, all conversions are applied <em>pairwise</em>,
+     * which means that each argument or return value is converted to
+     * exactly one argument or return value (or no return value).
+     * The applied conversions are defined by consulting the
+     * the corresponding component types of the old and new
+     * method handle types.
+     * <p>
+     * Let <em>T0</em> and <em>T1</em> be corresponding new and old parameter types,
+     * or old and new return types.  Specifically, for some valid index {@code i}, let
+     * <em>T0</em>{@code =newType.parameterType(i)} and <em>T1</em>{@code =this.type().parameterType(i)}.
+     * Or else, going the other way for return values, let
+     * <em>T0</em>{@code =this.type().returnType()} and <em>T1</em>{@code =newType.returnType()}.
+     * If the types are the same, the new method handle makes no change
+     * to the corresponding argument or return value (if any).
+     * Otherwise, one of the following conversions is applied
+     * if possible:
+     * <ul>
+     * <li>If <em>T0</em> and <em>T1</em> are references, then a cast to <em>T1</em> is applied.
+     *     (The types do not need to be related in any particular way.
+     *     This is because a dynamic value of null can convert to any reference type.)
+     * <li>If <em>T0</em> and <em>T1</em> are primitives, then a Java method invocation
+     *     conversion (JLS 5.3) is applied, if one exists.
+     *     (Specifically, <em>T0</em> must convert to <em>T1</em> by a widening primitive conversion.)
+     * <li>If <em>T0</em> is a primitive and <em>T1</em> a reference,
+     *     a Java casting conversion (JLS 5.5) is applied if one exists.
+     *     (Specifically, the value is boxed from <em>T0</em> to its wrapper class,
+     *     which is then widened as needed to <em>T1</em>.)
+     * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
+     *     conversion will be applied at runtime, possibly followed
+     *     by a Java method invocation conversion (JLS 5.3)
+     *     on the primitive value.  (These are the primitive widening conversions.)
+     *     <em>T0</em> must be a wrapper class or a supertype of one.
+     *     (In the case where <em>T0</em> is Object, these are the conversions
+     *     allowed by {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.)
+     *     The unboxing conversion must have a possibility of success, which means that
+     *     if <em>T0</em> is not itself a wrapper class, there must exist at least one
+     *     wrapper class <em>TW</em> which is a subtype of <em>T0</em> and whose unboxed
+     *     primitive value can be widened to <em>T1</em>.
+     * <li>If the return type <em>T1</em> is marked as void, any returned value is discarded
+     * <li>If the return type <em>T0</em> is void and <em>T1</em> a reference, a null value is introduced.
+     * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
+     *     a zero value is introduced.
+     * </ul>
+     * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
+     * because neither corresponds specifically to the <em>dynamic type</em> of any
+     * actual argument or return value.)
+     * <p>
+     * The method handle conversion cannot be made if any one of the required
+     * pairwise conversions cannot be made.
+     * <p>
+     * At runtime, the conversions applied to reference arguments
+     * or return values may require additional runtime checks which can fail.
+     * An unboxing operation may fail because the original reference is null,
+     * causing a {@link java.lang.NullPointerException NullPointerException}.
+     * An unboxing operation or a reference cast may also fail on a reference
+     * to an object of the wrong type,
+     * causing a {@link java.lang.ClassCastException ClassCastException}.
+     * Although an unboxing operation may accept several kinds of wrappers,
+     * if none are available, a {@code ClassCastException} will be thrown.
+     *
+     * @param newType the expected type of the new method handle
+     * @return a method handle which delegates to {@code this} after performing
+     *           any necessary argument conversions, and arranges for any
+     *           necessary return value conversions
+     * @throws NullPointerException if {@code newType} is a null reference
+     * @throws WrongMethodTypeException if the conversion cannot be made
+     * @see MethodHandles#explicitCastArguments
+     */
+    public MethodHandle asType(MethodType newType) {
+        // Fast path alternative to a heavyweight {@code asType} call.
+        // Return 'this' if the conversion will be a no-op.
+        if (newType == type) {
+            return this;
+        }
+        // Android-removed: Type conversion memoizing is unsupported on Android.
+        /*
+        // Return 'this.asTypeCache' if the conversion is already memoized.
+        MethodHandle atc = asTypeCached(newType);
+        if (atc != null) {
+            return atc;
+        }
+        */
+        return asTypeUncached(newType);
+    }
+
+    // Android-removed: Type conversion memoizing is unsupported on Android.
+    /*
+    private MethodHandle asTypeCached(MethodType newType) {
+        MethodHandle atc = asTypeCache;
+        if (atc != null && newType == atc.type) {
+            return atc;
+        }
+        return null;
+    }
+    */
+
+    /** Override this to change asType behavior. */
+    /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+        if (!type.isConvertibleTo(newType))
+            throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
+        // BEGIN Android-changed: Android specific implementation.
+        // return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
+        MethodHandle mh = duplicate();
+        mh.nominalType = newType;
+        return mh;
+        // END Android-changed: Android specific implementation.
+    }
+
+    /**
+     * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
+     * and spreads its elements as positional arguments.
+     * The new method handle adapts, as its <i>target</i>,
+     * the current method handle.  The type of the adapter will be
+     * the same as the type of the target, except that the final
+     * {@code arrayLength} parameters of the target's type are replaced
+     * by a single array parameter of type {@code arrayType}.
+     * <p>
+     * If the array element type differs from any of the corresponding
+     * argument types on the original target,
+     * the original target is adapted to take the array elements directly,
+     * as if by a call to {@link #asType asType}.
+     * <p>
+     * When called, the adapter replaces a trailing array argument
+     * by the array's elements, each as its own argument to the target.
+     * (The order of the arguments is preserved.)
+     * They are converted pairwise by casting and/or unboxing
+     * to the types of the trailing parameters of the target.
+     * Finally the target is called.
+     * What the target eventually returns is returned unchanged by the adapter.
+     * <p>
+     * Before calling the target, the adapter verifies that the array
+     * contains exactly enough elements to provide a correct argument count
+     * to the target method handle.
+     * (The array may also be null when zero elements are required.)
+     * <p>
+     * If, when the adapter is called, the supplied array argument does
+     * not have the correct number of elements, the adapter will throw
+     * an {@link IllegalArgumentException} instead of invoking the target.
+     * <p>
+     * Here are some simple examples of array-spreading method handles:
+     * <blockquote><pre>{@code
+MethodHandle equals = publicLookup()
+  .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
+assert( (boolean) equals.invokeExact("me", (Object)"me"));
+assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
+// spread both arguments from a 2-array:
+MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
+assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
+assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
+// try to spread from anything but a 2-array:
+for (int n = 0; n <= 10; n++) {
+  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
+  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
+  catch (IllegalArgumentException ex) { } // OK
+}
+// spread both arguments from a String array:
+MethodHandle eq2s = equals.asSpreader(String[].class, 2);
+assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
+assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));
+// spread second arguments from a 1-array:
+MethodHandle eq1 = equals.asSpreader(Object[].class, 1);
+assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));
+assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));
+// spread no arguments from a 0-array or null:
+MethodHandle eq0 = equals.asSpreader(Object[].class, 0);
+assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
+assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
+// asSpreader and asCollector are approximate inverses:
+for (int n = 0; n <= 2; n++) {
+    for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
+        MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
+        assert( (boolean) equals2.invokeWithArguments("me", "me"));
+        assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
+    }
+}
+MethodHandle caToString = publicLookup()
+  .findStatic(Arrays.class, "toString", methodType(String.class, char[].class));
+assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
+MethodHandle caString3 = caToString.asCollector(char[].class, 3);
+assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
+MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
+assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
+     * }</pre></blockquote>
+     * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
+     * @param arrayLength the number of arguments to spread from an incoming array argument
+     * @return a new method handle which spreads its final array argument,
+     *         before calling the original method handle
+     * @throws NullPointerException if {@code arrayType} is a null reference
+     * @throws IllegalArgumentException if {@code arrayType} is not an array type,
+     *         or if target does not have at least
+     *         {@code arrayLength} parameter types,
+     *         or if {@code arrayLength} is negative,
+     *         or if the resulting method handle's type would have
+     *         <a href="MethodHandle.html#maxarity">too many parameters</a>
+     * @throws WrongMethodTypeException if the implied {@code asType} call fails
+     * @see #asCollector
+     */
+    public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
+        MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
+        // BEGIN Android-changed: Android specific implementation.
+        /*
+        int arity = type().parameterCount();
+        int spreadArgPos = arity - arrayLength;
+        MethodHandle afterSpread = this.asType(postSpreadType);
+        BoundMethodHandle mh = afterSpread.rebind();
+        LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
+        MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
+        return mh.copyWith(preSpreadType, lform);
+        */
+        final int targetParamCount = postSpreadType.parameterCount();
+        MethodType dropArrayArgs = postSpreadType.dropParameterTypes(
+                (targetParamCount - arrayLength), targetParamCount);
+        MethodType adapterType = dropArrayArgs.appendParameterTypes(arrayType);
+
+        return new Transformers.Spreader(this, adapterType, arrayLength);
+        // END Android-changed: Android specific implementation.
+    }
+
+    /**
+     * See if {@code asSpreader} can be validly called with the given arguments.
+     * Return the type of the method handle call after spreading but before conversions.
+     */
+    private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
+        spreadArrayChecks(arrayType, arrayLength);
+        int nargs = type().parameterCount();
+        if (nargs < arrayLength || arrayLength < 0)
+            throw newIllegalArgumentException("bad spread array length");
+        Class<?> arrayElement = arrayType.getComponentType();
+        MethodType mtype = type();
+        boolean match = true, fail = false;
+        for (int i = nargs - arrayLength; i < nargs; i++) {
+            Class<?> ptype = mtype.parameterType(i);
+            if (ptype != arrayElement) {
+                match = false;
+                if (!MethodType.canConvert(arrayElement, ptype)) {
+                    fail = true;
+                    break;
+                }
+            }
+        }
+        if (match)  return mtype;
+        MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
+        if (!fail)  return needType;
+        // elicit an error:
+        this.asType(needType);
+        throw newInternalError("should not return", null);
+    }
+
+    private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
+        Class<?> arrayElement = arrayType.getComponentType();
+        if (arrayElement == null)
+            throw newIllegalArgumentException("not an array type", arrayType);
+        if ((arrayLength & 0x7F) != arrayLength) {
+            if ((arrayLength & 0xFF) != arrayLength)
+                throw newIllegalArgumentException("array length is not legal", arrayLength);
+            assert(arrayLength >= 128);
+            if (arrayElement == long.class ||
+                arrayElement == double.class)
+                throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
+        }
+    }
+
+    /**
+     * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
+     * positional arguments and collects them into an array argument.
+     * The new method handle adapts, as its <i>target</i>,
+     * the current method handle.  The type of the adapter will be
+     * the same as the type of the target, except that a single trailing
+     * parameter (usually of type {@code arrayType}) is replaced by
+     * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
+     * <p>
+     * If the array type differs from the final argument type on the original target,
+     * the original target is adapted to take the array type directly,
+     * as if by a call to {@link #asType asType}.
+     * <p>
+     * When called, the adapter replaces its trailing {@code arrayLength}
+     * arguments by a single new array of type {@code arrayType}, whose elements
+     * comprise (in order) the replaced arguments.
+     * Finally the target is called.
+     * What the target eventually returns is returned unchanged by the adapter.
+     * <p>
+     * (The array may also be a shared constant when {@code arrayLength} is zero.)
+     * <p>
+     * (<em>Note:</em> The {@code arrayType} is often identical to the last
+     * parameter type of the original target.
+     * It is an explicit argument for symmetry with {@code asSpreader}, and also
+     * to allow the target to use a simple {@code Object} as its last parameter type.)
+     * <p>
+     * In order to create a collecting adapter which is not restricted to a particular
+     * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
+     * <p>
+     * Here are some examples of array-collecting method handles:
+     * <blockquote><pre>{@code
+MethodHandle deepToString = publicLookup()
+  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+assertEquals("[won]",   (String) deepToString.invokeExact(new Object[]{"won"}));
+MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
+assertEquals(methodType(String.class, Object.class), ts1.type());
+//assertEquals("[won]", (String) ts1.invokeExact(         new Object[]{"won"})); //FAIL
+assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));
+// arrayType can be a subtype of Object[]
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals(methodType(String.class, String.class, String.class), ts2.type());
+assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));
+MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);
+assertEquals("[]", (String) ts0.invokeExact());
+// collectors can be nested, Lisp-style
+MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);
+assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));
+// arrayType can be any primitive array type
+MethodHandle bytesToString = publicLookup()
+  .findStatic(Arrays.class, "toString", methodType(String.class, byte[].class))
+  .asCollector(byte[].class, 3);
+assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));
+MethodHandle longsToString = publicLookup()
+  .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
+  .asCollector(long[].class, 1);
+assertEquals("[123]", (String) longsToString.invokeExact((long)123));
+     * }</pre></blockquote>
+     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+     * @param arrayLength the number of arguments to collect into a new array argument
+     * @return a new method handle which collects some trailing argument
+     *         into an array, before calling the original method handle
+     * @throws NullPointerException if {@code arrayType} is a null reference
+     * @throws IllegalArgumentException if {@code arrayType} is not an array type
+     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
+     *         or {@code arrayLength} is not a legal array size,
+     *         or the resulting method handle's type would have
+     *         <a href="MethodHandle.html#maxarity">too many parameters</a>
+     * @throws WrongMethodTypeException if the implied {@code asType} call fails
+     * @see #asSpreader
+     * @see #asVarargsCollector
+     */
+    public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
+        asCollectorChecks(arrayType, arrayLength);
+        // BEGIN Android-changed: Android specific implementation.
+        /*
+        int collectArgPos = type().parameterCount() - 1;
+        BoundMethodHandle mh = rebind();
+        MethodType resultType = type().asCollectorType(arrayType, arrayLength);
+        MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
+        LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
+        if (lform != null) {
+            return mh.copyWith(resultType, lform);
+        }
+        lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
+        return mh.copyWithExtendL(resultType, lform, newArray);
+        */
+        return new Transformers.Collector(this, arrayType, arrayLength);
+        // END Android-changed: Android specific implementation.
+    }
+
+    /**
+     * See if {@code asCollector} can be validly called with the given arguments.
+     * Return false if the last parameter is not an exact match to arrayType.
+     */
+    /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
+        spreadArrayChecks(arrayType, arrayLength);
+        int nargs = type().parameterCount();
+        if (nargs != 0) {
+            Class<?> lastParam = type().parameterType(nargs-1);
+            if (lastParam == arrayType)  return true;
+            if (lastParam.isAssignableFrom(arrayType))  return false;
+        }
+        throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
+    }
+
+    /**
+     * Makes a <em>variable arity</em> adapter which is able to accept
+     * any number of trailing positional arguments and collect them
+     * into an array argument.
+     * <p>
+     * The type and behavior of the adapter will be the same as
+     * the type and behavior of the target, except that certain
+     * {@code invoke} and {@code asType} requests can lead to
+     * trailing positional arguments being collected into target's
+     * trailing parameter.
+     * Also, the last parameter type of the adapter will be
+     * {@code arrayType}, even if the target has a different
+     * last parameter type.
+     * <p>
+     * This transformation may return {@code this} if the method handle is
+     * already of variable arity and its trailing parameter type
+     * is identical to {@code arrayType}.
+     * <p>
+     * When called with {@link #invokeExact invokeExact}, the adapter invokes
+     * the target with no argument changes.
+     * (<em>Note:</em> This behavior is different from a
+     * {@linkplain #asCollector fixed arity collector},
+     * since it accepts a whole array of indeterminate length,
+     * rather than a fixed number of arguments.)
+     * <p>
+     * When called with plain, inexact {@link #invoke invoke}, if the caller
+     * type is the same as the adapter, the adapter invokes the target as with
+     * {@code invokeExact}.
+     * (This is the normal behavior for {@code invoke} when types match.)
+     * <p>
+     * Otherwise, if the caller and adapter arity are the same, and the
+     * trailing parameter type of the caller is a reference type identical to
+     * or assignable to the trailing parameter type of the adapter,
+     * the arguments and return values are converted pairwise,
+     * as if by {@link #asType asType} on a fixed arity
+     * method handle.
+     * <p>
+     * Otherwise, the arities differ, or the adapter's trailing parameter
+     * type is not assignable from the corresponding caller type.
+     * In this case, the adapter replaces all trailing arguments from
+     * the original trailing argument position onward, by
+     * a new array of type {@code arrayType}, whose elements
+     * comprise (in order) the replaced arguments.
+     * <p>
+     * The caller type must provides as least enough arguments,
+     * and of the correct type, to satisfy the target's requirement for
+     * positional arguments before the trailing array argument.
+     * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
+     * where {@code N} is the arity of the target.
+     * Also, there must exist conversions from the incoming arguments
+     * to the target's arguments.
+     * As with other uses of plain {@code invoke}, if these basic
+     * requirements are not fulfilled, a {@code WrongMethodTypeException}
+     * may be thrown.
+     * <p>
+     * In all cases, what the target eventually returns is returned unchanged by the adapter.
+     * <p>
+     * In the final case, it is exactly as if the target method handle were
+     * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
+     * to the arity required by the caller type.
+     * (As with {@code asCollector}, if the array length is zero,
+     * a shared constant may be used instead of a new array.
+     * If the implied call to {@code asCollector} would throw
+     * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
+     * the call to the variable arity adapter must throw
+     * {@code WrongMethodTypeException}.)
+     * <p>
+     * The behavior of {@link #asType asType} is also specialized for
+     * variable arity adapters, to maintain the invariant that
+     * plain, inexact {@code invoke} is always equivalent to an {@code asType}
+     * call to adjust the target type, followed by {@code invokeExact}.
+     * Therefore, a variable arity adapter responds
+     * to an {@code asType} request by building a fixed arity collector,
+     * if and only if the adapter and requested type differ either
+     * in arity or trailing argument type.
+     * The resulting fixed arity collector has its type further adjusted
+     * (if necessary) to the requested type by pairwise conversion,
+     * as if by another application of {@code asType}.
+     * <p>
+     * When a method handle is obtained by executing an {@code ldc} instruction
+     * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
+     * as a variable arity method (with the modifier bit {@code 0x0080}),
+     * the method handle will accept multiple arities, as if the method handle
+     * constant were created by means of a call to {@code asVarargsCollector}.
+     * <p>
+     * In order to create a collecting adapter which collects a predetermined
+     * number of arguments, and whose type reflects this predetermined number,
+     * use {@link #asCollector asCollector} instead.
+     * <p>
+     * No method handle transformations produce new method handles with
+     * variable arity, unless they are documented as doing so.
+     * Therefore, besides {@code asVarargsCollector},
+     * all methods in {@code MethodHandle} and {@code MethodHandles}
+     * will return a method handle with fixed arity,
+     * except in the cases where they are specified to return their original
+     * operand (e.g., {@code asType} of the method handle's own type).
+     * <p>
+     * Calling {@code asVarargsCollector} on a method handle which is already
+     * of variable arity will produce a method handle with the same type and behavior.
+     * It may (or may not) return the original variable arity method handle.
+     * <p>
+     * Here is an example, of a list-making variable arity method handle:
+     * <blockquote><pre>{@code
+MethodHandle deepToString = publicLookup()
+  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
+assertEquals("[won]",   (String) ts1.invokeExact(    new Object[]{"won"}));
+assertEquals("[won]",   (String) ts1.invoke(         new Object[]{"won"}));
+assertEquals("[won]",   (String) ts1.invoke(                      "won" ));
+assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
+// findStatic of Arrays.asList(...) produces a variable arity method handle:
+MethodHandle asList = publicLookup()
+  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
+assertEquals(methodType(List.class, Object[].class), asList.type());
+assert(asList.isVarargsCollector());
+assertEquals("[]", asList.invoke().toString());
+assertEquals("[1]", asList.invoke(1).toString());
+assertEquals("[two, too]", asList.invoke("two", "too").toString());
+String[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
+assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
+List ls = (List) asList.invoke((Object)argv);
+assertEquals(1, ls.size());
+assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
+     * }</pre></blockquote>
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * These rules are designed as a dynamically-typed variation
+     * of the Java rules for variable arity methods.
+     * In both cases, callers to a variable arity method or method handle
+     * can either pass zero or more positional arguments, or else pass
+     * pre-collected arrays of any length.  Users should be aware of the
+     * special role of the final argument, and of the effect of a
+     * type match on that final argument, which determines whether
+     * or not a single trailing argument is interpreted as a whole
+     * array or a single element of an array to be collected.
+     * Note that the dynamic type of the trailing argument has no
+     * effect on this decision, only a comparison between the symbolic
+     * type descriptor of the call site and the type descriptor of the method handle.)
+     *
+     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+     * @return a new method handle which can collect any number of trailing arguments
+     *         into an array, before calling the original method handle
+     * @throws NullPointerException if {@code arrayType} is a null reference
+     * @throws IllegalArgumentException if {@code arrayType} is not an array type
+     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type
+     * @see #asCollector
+     * @see #isVarargsCollector
+     * @see #asFixedArity
+     */
+    public MethodHandle asVarargsCollector(Class<?> arrayType) {
+        arrayType.getClass(); // explicit NPE
+        boolean lastMatch = asCollectorChecks(arrayType, 0);
+        if (isVarargsCollector() && lastMatch)
+            return this;
+        // Android-changed: Android specific implementation.
+        // return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+        return new Transformers.VarargsCollector(this);
+    }
+
+    /**
+     * Determines if this method handle
+     * supports {@linkplain #asVarargsCollector variable arity} calls.
+     * Such method handles arise from the following sources:
+     * <ul>
+     * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
+     * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
+     *     which resolves to a variable arity Java method or constructor
+     * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
+     *     which resolves to a variable arity Java method or constructor
+     * </ul>
+     * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
+     * @see #asVarargsCollector
+     * @see #asFixedArity
+     */
+    public boolean isVarargsCollector() {
+        return false;
+    }
+
+    /**
+     * Makes a <em>fixed arity</em> method handle which is otherwise
+     * equivalent to the current method handle.
+     * <p>
+     * If the current method handle is not of
+     * {@linkplain #asVarargsCollector variable arity},
+     * the current method handle is returned.
+     * This is true even if the current method handle
+     * could not be a valid input to {@code asVarargsCollector}.
+     * <p>
+     * Otherwise, the resulting fixed-arity method handle has the same
+     * type and behavior of the current method handle,
+     * except that {@link #isVarargsCollector isVarargsCollector}
+     * will be false.
+     * The fixed-arity method handle may (or may not) be the
+     * a previous argument to {@code asVarargsCollector}.
+     * <p>
+     * Here is an example, of a list-making variable arity method handle:
+     * <blockquote><pre>{@code
+MethodHandle asListVar = publicLookup()
+  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+  .asVarargsCollector(Object[].class);
+MethodHandle asListFix = asListVar.asFixedArity();
+assertEquals("[1]", asListVar.invoke(1).toString());
+Exception caught = null;
+try { asListFix.invoke((Object)1); }
+catch (Exception ex) { caught = ex; }
+assert(caught instanceof ClassCastException);
+assertEquals("[two, too]", asListVar.invoke("two", "too").toString());
+try { asListFix.invoke("two", "too"); }
+catch (Exception ex) { caught = ex; }
+assert(caught instanceof WrongMethodTypeException);
+Object[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
+assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());
+assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());
+assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
+     * }</pre></blockquote>
+     *
+     * @return a new method handle which accepts only a fixed number of arguments
+     * @see #asVarargsCollector
+     * @see #isVarargsCollector
+     */
+    public MethodHandle asFixedArity() {
+        // BEGIN Android-changed: Android specific implementation.
+        // assert(!isVarargsCollector());
+        // return this;
+
+        MethodHandle mh = this;
+        if (mh.isVarargsCollector()) {
+            mh = ((Transformers.VarargsCollector) mh).asFixedArity();
+        }
+        assert(!mh.isVarargsCollector());
+        return mh;
+        // END Android-changed: Android specific implementation.
+    }
+
+    /**
+     * Binds a value {@code x} to the first argument of a method handle, without invoking it.
+     * The new method handle adapts, as its <i>target</i>,
+     * the current method handle by binding it to the given argument.
+     * The type of the bound handle will be
+     * the same as the type of the target, except that a single leading
+     * reference parameter will be omitted.
+     * <p>
+     * When called, the bound handle inserts the given value {@code x}
+     * as a new leading argument to the target.  The other arguments are
+     * also passed unchanged.
+     * What the target eventually returns is returned unchanged by the bound handle.
+     * <p>
+     * The reference {@code x} must be convertible to the first parameter
+     * type of the target.
+     * <p>
+     * (<em>Note:</em>  Because method handles are immutable, the target method handle
+     * retains its original type and behavior.)
+     * @param x  the value to bind to the first argument of the target
+     * @return a new method handle which prepends the given value to the incoming
+     *         argument list, before calling the original method handle
+     * @throws IllegalArgumentException if the target does not have a
+     *         leading parameter type that is a reference type
+     * @throws ClassCastException if {@code x} cannot be converted
+     *         to the leading parameter type of the target
+     * @see MethodHandles#insertArguments
+     */
+    public MethodHandle bindTo(Object x) {
+        x = type.leadingReferenceParameter().cast(x);  // throw CCE if needed
+        // Android-changed: Android specific implementation.
+        // return bindArgumentL(0, x);
+        return new Transformers.BindTo(this, x);
+    }
+
+    /**
+     * Returns a string representation of the method handle,
+     * starting with the string {@code "MethodHandle"} and
+     * ending with the string representation of the method handle's type.
+     * In other words, this method returns a string equal to the value of:
+     * <blockquote><pre>{@code
+     * "MethodHandle" + type().toString()
+     * }</pre></blockquote>
+     * <p>
+     * (<em>Note:</em>  Future releases of this API may add further information
+     * to the string representation.
+     * Therefore, the present syntax should not be parsed by applications.)
+     *
+     * @return a string representation of the method handle
+     */
+    @Override
+    public String toString() {
+        // Android-removed: Debugging support unused on Android.
+        // if (DEBUG_METHOD_HANDLE_NAMES)  return "MethodHandle"+debugString();
+        return standardString();
+    }
+    String standardString() {
+        return "MethodHandle"+type;
+    }
+
+    // BEGIN Android-removed: Debugging support unused on Android.
+    /*
+    /** Return a string with a several lines describing the method handle structure.
+     *  This string would be suitable for display in an IDE debugger.
+     *
+    String debugString() {
+        return type+" : "+internalForm()+internalProperties();
+    }
+    */
+    // END Android-removed: Debugging support unused on Android.
+
+    // BEGIN Android-added: Android specific implementation.
+    /** @hide */
+    public int getHandleKind() {
+        return handleKind;
+    }
+
+    /** @hide */
+    protected void transform(EmulatedStackFrame arguments) throws Throwable {
+        throw new AssertionError("MethodHandle.transform should never be called.");
+    }
+
+    /**
+     * Creates a copy of this method handle, copying all relevant data.
+     *
+     * @hide
+     */
+    protected MethodHandle duplicate() {
+        try {
+            return (MethodHandle) this.clone();
+        } catch (CloneNotSupportedException cnse) {
+            throw new AssertionError("Subclass of Transformer is not cloneable");
+        }
+    }
+
+    /**
+     * This is the entry point for all transform calls, and dispatches to the protected
+     * transform method. This layer of indirection exists purely for convenience, because
+     * we can invoke-direct on a fixed ArtMethod for all transform variants.
+     *
+     * NOTE: If this extra layer of indirection proves to be a problem, we can get rid
+     * of this layer of indirection at the cost of some additional ugliness.
+     */
+    private void transformInternal(EmulatedStackFrame arguments) throws Throwable {
+        transform(arguments);
+    }
+    // END Android-added: Android specific implementation.
+
+    // BEGIN Android-removed: RI implementation unused on Android.
+    /*
+    //// Implementation methods.
+    //// Sub-classes can override these default implementations.
+    //// All these methods assume arguments are already validated.
+
+    // Other transforms to do:  convert, explicitCast, permute, drop, filter, fold, GWT, catch
+
+    BoundMethodHandle bindArgumentL(int pos, Object value) {
+        return rebind().bindArgumentL(pos, value);
+    }
+
+    /*non-public*
+    MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+        if (!member.isVarargs())  return this;
+        Class<?> arrayType = type().lastParameterType();
+        if (arrayType.isArray()) {
+            return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+        }
+        throw member.makeAccessException("cannot make variable arity", null);
+    }
+
+    /*non-public*
+    MethodHandle viewAsType(MethodType newType, boolean strict) {
+        // No actual conversions, just a new view of the same method.
+        // Note that this operation must not produce a DirectMethodHandle,
+        // because retyped DMHs, like any transformed MHs,
+        // cannot be cracked into MethodHandleInfo.
+        assert viewAsTypeChecks(newType, strict);
+        BoundMethodHandle mh = rebind();
+        assert(!((MethodHandle)mh instanceof DirectMethodHandle));
+        return mh.copyWith(newType, mh.form);
+    }
+
+    /*non-public*
+    boolean viewAsTypeChecks(MethodType newType, boolean strict) {
+        if (strict) {
+            assert(type().isViewableAs(newType, true))
+                : Arrays.asList(this, newType);
+        } else {
+            assert(type().basicType().isViewableAs(newType.basicType(), true))
+                : Arrays.asList(this, newType);
+        }
+        return true;
+    }
+
+    // Decoding
+
+    /*non-public*
+    LambdaForm internalForm() {
+        return form;
+    }
+
+    /*non-public*
+    MemberName internalMemberName() {
+        return null;  // DMH returns DMH.member
+    }
+
+    /*non-public*
+    Class<?> internalCallerClass() {
+        return null;  // caller-bound MH for @CallerSensitive method returns caller
+    }
+
+    /*non-public*
+    MethodHandleImpl.Intrinsic intrinsicName() {
+        // no special intrinsic meaning to most MHs
+        return MethodHandleImpl.Intrinsic.NONE;
+    }
+
+    /*non-public*
+    MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
+        if (member != null) {
+            return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
+        } else if (internalMemberName() == null) {
+            // The required internaMemberName is null, and this MH (like most) doesn't have one.
+            return this;
+        } else {
+            // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
+            MethodHandle result = rebind();
+            assert (result.internalMemberName() == null);
+            return result;
+        }
+    }
+
+    /*non-public*
+    boolean isInvokeSpecial() {
+        return false;  // DMH.Special returns true
+    }
+
+    /*non-public*
+    Object internalValues() {
+        return null;
+    }
+
+    /*non-public*
+    Object internalProperties() {
+        // Override to something to follow this.form, like "\n& FOO=bar"
+        return "";
+    }
+
+    //// Method handle implementation methods.
+    //// Sub-classes can override these default implementations.
+    //// All these methods assume arguments are already validated.
+
+    /*non-public*
+    abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
+
+    /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
+     *  Many transforms are implemented only for BMHs.
+     *  @return a behaviorally equivalent BMH
+     *
+    abstract BoundMethodHandle rebind();
+
+    /**
+     * Replace the old lambda form of this method handle with a new one.
+     * The new one must be functionally equivalent to the old one.
+     * Threads may continue running the old form indefinitely,
+     * but it is likely that the new one will be preferred for new executions.
+     * Use with discretion.
+     *
+    /*non-public*
+    void updateForm(LambdaForm newForm) {
+        assert(newForm.customized == null || newForm.customized == this);
+        if (form == newForm)  return;
+        newForm.prepare();  // as in MethodHandle.<init>
+        UNSAFE.putObject(this, FORM_OFFSET, newForm);
+        UNSAFE.fullFence();
+    }
+
+    /** Craft a LambdaForm customized for this particular MethodHandle *
+    /*non-public*
+    void customize() {
+        if (form.customized == null) {
+            LambdaForm newForm = form.customize(this);
+            updateForm(newForm);
+        } else {
+            assert(form.customized == this);
+        }
+    }
+
+    private static final long FORM_OFFSET;
+    static {
+        try {
+            FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+    */
+    // END Android-removed: RI implementation unused on Android.
+}
diff --git a/java/lang/invoke/MethodHandleImpl.java b/java/lang/invoke/MethodHandleImpl.java
new file mode 100644
index 0000000..6514cb6
--- /dev/null
+++ b/java/lang/invoke/MethodHandleImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+// Android-changed: Android specific implementation.
+// The whole class was implemented from scratch for the Android runtime based
+// on the specification of the MethodHandle class.
+// The code does not originate from upstream OpenJDK.
+/**
+ * A method handle that's directly associated with an ArtField or an ArtMethod and
+ * specifies no additional transformations.
+ *
+ * @hide
+ */
+public class MethodHandleImpl extends MethodHandle implements Cloneable {
+    private HandleInfo info;
+
+    MethodHandleImpl(long artFieldOrMethod, int handleKind, MethodType type) {
+        super(artFieldOrMethod, handleKind, type);
+    }
+
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
+    MethodHandleInfo reveal() {
+        if (info == null) {
+            final Member member = getMemberInternal();
+            info = new HandleInfo(member, this);
+        }
+
+        return info;
+    }
+
+    /**
+     * Materialize a member from this method handle's ArtField or ArtMethod pointer.
+     */
+    public native Member getMemberInternal();
+
+    /**
+     * Implementation of {@code MethodHandleInfo} in terms of the handle being cracked
+     * and its corresponding {@code java.lang.reflect.Member}.
+     */
+    static class HandleInfo implements MethodHandleInfo {
+        private final Member member;
+        private final MethodHandle handle;
+
+        HandleInfo(Member member, MethodHandle handle) {
+            this.member = member;
+            this.handle = handle;
+        }
+
+        @Override
+        public int getReferenceKind() {
+            switch (handle.getHandleKind()) {
+                case INVOKE_VIRTUAL: {
+                    if (member.getDeclaringClass().isInterface()) {
+                        return REF_invokeInterface;
+                    } else {
+                        return REF_invokeVirtual;
+                    }
+                }
+
+                case INVOKE_DIRECT: {
+                    if (member instanceof Constructor) {
+                        return REF_newInvokeSpecial;
+                    } else {
+                        return REF_invokeSpecial;
+                    }
+                }
+
+                case INVOKE_SUPER:
+                    return MethodHandleInfo.REF_invokeSpecial;
+                case INVOKE_STATIC:
+                    return MethodHandleInfo.REF_invokeStatic;
+                case IGET:
+                    return MethodHandleInfo.REF_getField;
+                case IPUT:
+                    return MethodHandleInfo.REF_putField;
+                case SGET:
+                    return MethodHandleInfo.REF_getStatic;
+                case SPUT:
+                    return MethodHandleInfo.REF_putStatic;
+                default:
+                    throw new AssertionError("Unexpected handle kind: " + handle.getHandleKind());
+            }
+        }
+
+        @Override
+        public Class<?> getDeclaringClass() {
+            return member.getDeclaringClass();
+        }
+
+        @Override
+        public String getName() {
+            if (member instanceof Constructor) {
+                return "<init>";
+            }
+
+            return member.getName();
+        }
+
+        @Override
+        public MethodType getMethodType() {
+            // The "nominal" type of a cracked method handle is the same as the type
+            // of the handle itself, except in the cases enumerated below.
+            MethodType handleType = handle.type();
+
+            boolean omitLeadingParam = false;
+
+            // For constructs, the return type is always void.class, and not the type of
+            // the object returned. We also need to omit the leading reference, which is
+            // nominally the type of the object being constructed.
+            if (member instanceof Constructor) {
+                handleType = handleType.changeReturnType(void.class);
+                omitLeadingParam = true;
+            }
+
+            // For instance field gets/puts and instance method gets/puts, we omit the
+            // leading reference parameter to |this|.
+            switch (handle.getHandleKind()) {
+                case IGET:
+                case IPUT:
+                case INVOKE_INTERFACE:
+                case INVOKE_DIRECT:
+                case INVOKE_VIRTUAL:
+                case INVOKE_SUPER:
+                    omitLeadingParam = true;
+            }
+
+            return omitLeadingParam ? handleType.dropParameterTypes(0, 1) : handleType;
+        }
+
+        @Override
+        public <T extends Member> T reflectAs(Class<T> expected, MethodHandles.Lookup lookup) {
+            try {
+                lookup.checkAccess(member.getDeclaringClass(), member.getDeclaringClass(),
+                        member.getModifiers(), member.getName());
+            } catch (IllegalAccessException exception) {
+                throw new IllegalArgumentException("Unable to access member.", exception);
+            }
+
+            return (T) member;
+        }
+
+        @Override
+        public int getModifiers() {
+            return member.getModifiers();
+        }
+    }
+}
diff --git a/java/lang/invoke/MethodHandleInfo.java b/java/lang/invoke/MethodHandleInfo.java
new file mode 100644
index 0000000..356768d
--- /dev/null
+++ b/java/lang/invoke/MethodHandleInfo.java
@@ -0,0 +1,321 @@
+/*
+ * 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.reflect.*;
+import java.util.*;
+import java.lang.invoke.MethodHandleNatives.Constants;
+import java.lang.invoke.MethodHandles.Lookup;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A symbolic reference obtained by cracking a direct method handle
+ * into its consitutent symbolic parts.
+ * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
+ * <h1><a name="directmh"></a>Direct Method Handles</h1>
+ * A <em>direct method handle</em> represents a method, constructor, or field without
+ * any intervening argument bindings or other transformations.
+ * The method, constructor, or field referred to by a direct method handle is called
+ * its <em>underlying member</em>.
+ * Direct method handles may be obtained in any of these ways:
+ * <ul>
+ * <li>By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant.
+ *     (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.)
+ * <li>By calling one of the <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>,
+ *     such as {@link Lookup#findVirtual Lookup.findVirtual},
+ *     to resolve a symbolic reference into a method handle.
+ *     A symbolic reference consists of a class, name string, and type.
+ * <li>By calling the factory method {@link Lookup#unreflect Lookup.unreflect}
+ *     or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial}
+ *     to convert a {@link Method} into a method handle.
+ * <li>By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor}
+ *     to convert a {@link Constructor} into a method handle.
+ * <li>By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter}
+ *     or {@link Lookup#unreflectSetter Lookup.unreflectSetter}
+ *     to convert a {@link Field} into a method handle.
+ * </ul>
+ *
+ * <h1>Restrictions on Cracking</h1>
+ * Given a suitable {@code Lookup} object, it is possible to crack any direct method handle
+ * to recover a symbolic reference for the underlying method, constructor, or field.
+ * Cracking must be done via a {@code Lookup} object equivalent to that which created
+ * the target method handle, or which has enough access permissions to recreate
+ * an equivalent method handle.
+ * <p>
+ * If the underlying method is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>,
+ * the direct method handle will have been "bound" to a particular caller class, the
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}
+ * of the lookup object used to create it.
+ * Cracking this method handle with a different lookup class will fail
+ * even if the underlying method is public (like {@code Class.forName}).
+ * <p>
+ * The requirement of lookup object matching provides a "fast fail" behavior
+ * for programs which may otherwise trust erroneous revelation of a method
+ * handle with symbolic information (or caller binding) from an unexpected scope.
+ * Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation.
+ *
+ * <h1><a name="refkinds"></a>Reference kinds</h1>
+ * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
+ * correspond to all major use cases for methods, constructors, and fields.
+ * These use cases may be distinguished using small integers as follows:
+ * <table border=1 cellpadding=5 summary="reference kinds">
+ * <tr><th>reference kind</th><th>descriptive name</th><th>scope</th><th>member</th><th>behavior</th></tr>
+ * <tr>
+ *     <td>{@code 1}</td><td>{@code REF_getField}</td><td>{@code class}</td>
+ *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 2}</td><td>{@code REF_getStatic}</td><td>{@code class} or {@code interface}</td>
+ *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 3}</td><td>{@code REF_putField}</td><td>{@code class}</td>
+ *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 4}</td><td>{@code REF_putStatic}</td><td>{@code class}</td>
+ *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 5}</td><td>{@code REF_invokeVirtual}</td><td>{@code class}</td>
+ *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 6}</td><td>{@code REF_invokeStatic}</td><td>{@code class} or {@code interface}</td>
+ *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 7}</td><td>{@code REF_invokeSpecial}</td><td>{@code class} or {@code interface}</td>
+ *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 8}</td><td>{@code REF_newInvokeSpecial}</td><td>{@code class}</td>
+ *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
+ * </tr>
+ * <tr>
+ *     <td>{@code 9}</td><td>{@code REF_invokeInterface}</td><td>{@code interface}</td>
+ *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+ * </tr>
+ * </table>
+ * @since 1.8
+ */
+public
+interface MethodHandleInfo {
+    /**
+     * A direct method handle reference kind,
+     * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
+     */
+    public static final int
+        REF_getField                = Constants.REF_getField,
+        REF_getStatic               = Constants.REF_getStatic,
+        REF_putField                = Constants.REF_putField,
+        REF_putStatic               = Constants.REF_putStatic,
+        REF_invokeVirtual           = Constants.REF_invokeVirtual,
+        REF_invokeStatic            = Constants.REF_invokeStatic,
+        REF_invokeSpecial           = Constants.REF_invokeSpecial,
+        REF_newInvokeSpecial        = Constants.REF_newInvokeSpecial,
+        REF_invokeInterface         = Constants.REF_invokeInterface;
+
+    /**
+     * Returns the reference kind of the cracked method handle, which in turn
+     * determines whether the method handle's underlying member was a constructor, method, or field.
+     * See the <a href="MethodHandleInfo.html#refkinds">table above</a> for definitions.
+     * @return the integer code for the kind of reference used to access the underlying member
+     */
+    public int getReferenceKind();
+
+    /**
+     * Returns the class in which the cracked method handle's underlying member was defined.
+     * @return the declaring class of the underlying member
+     */
+    public Class<?> getDeclaringClass();
+
+    /**
+     * Returns the name of the cracked method handle's underlying member.
+     * This is {@code "<init>"} if the underlying member was a constructor,
+     * else it is a simple method name or field name.
+     * @return the simple name of the underlying member
+     */
+    public String getName();
+
+    /**
+     * Returns the nominal type of the cracked symbolic reference, expressed as a method type.
+     * If the reference is to a constructor, the return type will be {@code void}.
+     * If it is to a non-static method, the method type will not mention the {@code this} parameter.
+     * If it is to a field and the requested access is to read the field,
+     * the method type will have no parameters and return the field type.
+     * If it is to a field and the requested access is to write the field,
+     * the method type will have one parameter of the field type and return {@code void}.
+     * <p>
+     * Note that original direct method handle may include a leading {@code this} parameter,
+     * or (in the case of a constructor) will replace the {@code void} return type
+     * with the constructed class.
+     * The nominal type does not include any {@code this} parameter,
+     * and (in the case of a constructor) will return {@code void}.
+     * @return the type of the underlying member, expressed as a method type
+     */
+    public MethodType getMethodType();
+
+    // Utility methods.
+    // NOTE: class/name/type and reference kind constitute a symbolic reference
+    // member and modifiers are an add-on, derived from Core Reflection (or the equivalent)
+
+    /**
+     * Reflects the underlying member as a method, constructor, or field object.
+     * If the underlying member is public, it is reflected as if by
+     * {@code getMethod}, {@code getConstructor}, or {@code getField}.
+     * Otherwise, it is reflected as if by
+     * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}.
+     * The underlying member must be accessible to the given lookup object.
+     * @param <T> the desired type of the result, either {@link Member} or a subtype
+     * @param expected a class object representing the desired result type {@code T}
+     * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges
+     * @return a reference to the method, constructor, or field object
+     * @exception ClassCastException if the member is not of the expected type
+     * @exception NullPointerException if either argument is {@code null}
+     * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object
+     */
+    public <T extends Member> T reflectAs(Class<T> expected, Lookup lookup);
+
+    /**
+     * Returns the access modifiers of the underlying member.
+     * @return the Java language modifiers for underlying member,
+     *         or -1 if the member cannot be accessed
+     * @see Modifier
+     * @see #reflectAs
+     */
+    public int getModifiers();
+
+    /**
+     * Determines if the underlying member was a variable arity method or constructor.
+     * Such members are represented by method handles that are varargs collectors.
+     * @implSpec
+     * This produces a result equivalent to:
+     * <pre>{@code
+     *     getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
+     * }</pre>
+     *
+     *
+     * @return {@code true} if and only if the underlying member was declared with variable arity.
+     */
+    // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
+    public default boolean isVarArgs()  {
+        // fields are never varargs:
+        if (MethodHandleNatives.refKindIsField((byte) getReferenceKind()))
+            return false;
+        // not in the public API: Modifier.VARARGS
+        final int ACC_VARARGS = 0x00000080;  // from JVMS 4.6 (Table 4.20)
+        assert(ACC_VARARGS == Modifier.TRANSIENT);
+        return Modifier.isTransient(getModifiers());
+    }
+
+    /**
+     * Returns the descriptive name of the given reference kind,
+     * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
+     * The conventional prefix "REF_" is omitted.
+     * @param referenceKind an integer code for a kind of reference used to access a class member
+     * @return a mixed-case string such as {@code "getField"}
+     * @exception IllegalArgumentException if the argument is not a valid
+     *            <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
+     */
+    public static String referenceKindToString(int referenceKind) {
+        if (!MethodHandleNatives.refKindIsValid(referenceKind))
+            throw newIllegalArgumentException("invalid reference kind", referenceKind);
+        return MethodHandleNatives.refKindName((byte)referenceKind);
+    }
+
+    /**
+     * Returns a string representation for a {@code MethodHandleInfo},
+     * given the four parts of its symbolic reference.
+     * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the
+     * {@linkplain #referenceKindToString reference kind string} for {@code kind},
+     * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc}
+     * {@code N} is the {@code name}, and
+     * {@code MT} is the {@code type}.
+     * These four values may be obtained from the
+     * {@linkplain #getReferenceKind reference kind},
+     * {@linkplain #getDeclaringClass declaring class},
+     * {@linkplain #getName member name},
+     * and {@linkplain #getMethodType method type}
+     * of a {@code MethodHandleInfo} object.
+     *
+     * @implSpec
+     * This produces a result equivalent to:
+     * <pre>{@code
+     *     String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
+     * }</pre>
+     *
+     * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference
+     * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference
+     * @param name the {@linkplain #getName member name} part of the symbolic reference
+     * @param type the {@linkplain #getMethodType method type} part of the symbolic reference
+     * @return a string of the form {@code "RK C.N:MT"}
+     * @exception IllegalArgumentException if the first argument is not a valid
+     *            <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
+     * @exception NullPointerException if any reference argument is {@code null}
+     */
+    public static String toString(int kind, Class<?> defc, String name, MethodType type) {
+        Objects.requireNonNull(name); Objects.requireNonNull(type);
+        return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type);
+    }
+
+    // BEGIN Android-added: refKind...() methods needed for API compatibility with 26.
+    // These methods were accidentally added into the public API in API level. They are now
+    // deprecated as a prelude to being removed from the public API.
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+     *             replacement is available but it is possible to replicate using information from
+     *             the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+     *             {@code refKind >= 1 && refKind <= 9}. There are no guarantees that this logic
+     *             will work if future versions extend the table.
+     */
+    @Deprecated
+    static boolean refKindIsValid(int refKind) {
+        return MethodHandleNatives.refKindIsValid(refKind);
+    }
+
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+     *             replacement is available but it is possible to replicate using information from
+     *             the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+     *             {@code refKind >= 1 && refKind <= 4}.  There are no guarantees that this logic
+     *             will work if future versions extend the table.
+     */
+    @Deprecated
+    static boolean refKindIsField(int refKind) {
+        return MethodHandleNatives.refKindIsField((byte) refKind);
+    }
+
+    /**
+     * @deprecated This internal method was accidentally added to API 26 and must not be used. Use
+     *             {@link MethodHandleInfo#referenceKindToString(int)} instead.
+     */
+    @Deprecated
+    static String refKindName(int refKind) {
+        return MethodHandleNatives.refKindName((byte) refKind);
+    }
+    // END Android-added: refKind...() methods needed for API compatibility with 26.
+}
diff --git a/java/lang/invoke/MethodHandleNatives.java b/java/lang/invoke/MethodHandleNatives.java
new file mode 100644
index 0000000..87f95ff
--- /dev/null
+++ b/java/lang/invoke/MethodHandleNatives.java
@@ -0,0 +1,551 @@
+/*
+ * 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 static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The JVM interface for the method handles package is all here.
+ * This is an interface internal and private to an implementation of JSR 292.
+ * <em>This class is not part of the JSR 292 standard.</em>
+ * @author jrose
+ */
+class MethodHandleNatives {
+
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    private MethodHandleNatives() { } // static only
+
+    /// MemberName support
+
+    static native void init(MemberName self, Object ref);
+    static native void expand(MemberName self);
+    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
+    static native int getMembers(Class<?> defc, String matchName, String matchSig,
+            int matchFlags, Class<?> caller, int skip, MemberName[] results);
+
+    /// Field layout queries parallel to sun.misc.Unsafe:
+    static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
+    static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
+
+    /// MethodHandle support
+
+    /** Fetch MH-related JVM parameter.
+     *  which=0 retrieves MethodHandlePushLimit
+     *  which=1 retrieves stack slot push size (in address units)
+     *
+    static native int getConstant(int which);
+
+    static final boolean COUNT_GWT;
+
+    /// CallSite support
+
+    /** Tell the JVM that we need to change the target of a CallSite. *
+    static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
+    static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+
+    private static native void registerNatives();
+    static {
+        registerNatives();
+        COUNT_GWT                   = getConstant(Constants.GC_COUNT_GWT) != 0;
+
+        // The JVM calls MethodHandleNatives.<clinit>.  Cascade the <clinit> calls as needed:
+        MethodHandleImpl.initStatics();
+    }
+    */
+    // END Android-removed: Unused implementation code.
+
+    // All compile-time constants go here.
+    // There is an opportunity to check them against the JVM's idea of them.
+    static class Constants {
+        Constants() { } // static only
+        // BEGIN Android-removed: Unused implementation code.
+        /*
+        // MethodHandleImpl
+        static final int // for getConstant
+                GC_COUNT_GWT = 4,
+                GC_LAMBDA_SUPPORT = 5;
+
+        // MemberName
+        // The JVM uses values of -2 and above for vtable indexes.
+        // Field values are simple positive offsets.
+        // Ref: src/share/vm/oops/methodOop.hpp
+        // This value is negative enough to avoid such numbers,
+        // but not too negative.
+        static final int
+                MN_IS_METHOD           = 0x00010000, // method (not constructor)
+                MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
+                MN_IS_FIELD            = 0x00040000, // field
+                MN_IS_TYPE             = 0x00080000, // nested type
+                MN_CALLER_SENSITIVE    = 0x00100000, // @CallerSensitive annotation detected
+                MN_REFERENCE_KIND_SHIFT = 24, // refKind
+                MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+                // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+                MN_SEARCH_SUPERCLASSES = 0x00100000,
+                MN_SEARCH_INTERFACES   = 0x00200000;
+
+        /**
+         * Basic types as encoded in the JVM.  These code values are not
+         * intended for use outside this class.  They are used as part of
+         * a private interface between the JVM and this class.
+         *
+        static final int
+            T_BOOLEAN  =  4,
+            T_CHAR     =  5,
+            T_FLOAT    =  6,
+            T_DOUBLE   =  7,
+            T_BYTE     =  8,
+            T_SHORT    =  9,
+            T_INT      = 10,
+            T_LONG     = 11,
+            T_OBJECT   = 12,
+            //T_ARRAY    = 13
+            T_VOID     = 14,
+            //T_ADDRESS  = 15
+            T_ILLEGAL  = 99;
+
+        /**
+         * Constant pool entry types.
+         *
+        static final byte
+            CONSTANT_Utf8                = 1,
+            CONSTANT_Integer             = 3,
+            CONSTANT_Float               = 4,
+            CONSTANT_Long                = 5,
+            CONSTANT_Double              = 6,
+            CONSTANT_Class               = 7,
+            CONSTANT_String              = 8,
+            CONSTANT_Fieldref            = 9,
+            CONSTANT_Methodref           = 10,
+            CONSTANT_InterfaceMethodref  = 11,
+            CONSTANT_NameAndType         = 12,
+            CONSTANT_MethodHandle        = 15,  // JSR 292
+            CONSTANT_MethodType          = 16,  // JSR 292
+            CONSTANT_InvokeDynamic       = 18,
+            CONSTANT_LIMIT               = 19;   // Limit to tags found in classfiles
+
+        /**
+         * Access modifier flags.
+         *
+        static final char
+            ACC_PUBLIC                 = 0x0001,
+            ACC_PRIVATE                = 0x0002,
+            ACC_PROTECTED              = 0x0004,
+            ACC_STATIC                 = 0x0008,
+            ACC_FINAL                  = 0x0010,
+            ACC_SYNCHRONIZED           = 0x0020,
+            ACC_VOLATILE               = 0x0040,
+            ACC_TRANSIENT              = 0x0080,
+            ACC_NATIVE                 = 0x0100,
+            ACC_INTERFACE              = 0x0200,
+            ACC_ABSTRACT               = 0x0400,
+            ACC_STRICT                 = 0x0800,
+            ACC_SYNTHETIC              = 0x1000,
+            ACC_ANNOTATION             = 0x2000,
+            ACC_ENUM                   = 0x4000,
+            // aliases:
+            ACC_SUPER                  = ACC_SYNCHRONIZED,
+            ACC_BRIDGE                 = ACC_VOLATILE,
+            ACC_VARARGS                = ACC_TRANSIENT;
+        */
+        // END Android-removed: Unused implementation code.
+
+        /**
+         * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
+         */
+        static final byte
+            REF_NONE                    = 0,  // null value
+            REF_getField                = 1,
+            REF_getStatic               = 2,
+            REF_putField                = 3,
+            REF_putStatic               = 4,
+            REF_invokeVirtual           = 5,
+            REF_invokeStatic            = 6,
+            REF_invokeSpecial           = 7,
+            REF_newInvokeSpecial        = 8,
+            REF_invokeInterface         = 9,
+            REF_LIMIT                  = 10;
+    }
+
+    static boolean refKindIsValid(int refKind) {
+        return (refKind > REF_NONE && refKind < REF_LIMIT);
+    }
+    static boolean refKindIsField(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_putStatic);
+    }
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    static boolean refKindIsGetter(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_getStatic);
+    }
+    static boolean refKindIsSetter(byte refKind) {
+        return refKindIsField(refKind) && !refKindIsGetter(refKind);
+    }
+    static boolean refKindIsMethod(byte refKind) {
+        return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindIsConstructor(byte refKind) {
+        return (refKind == REF_newInvokeSpecial);
+    }
+    static boolean refKindHasReceiver(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind & 1) != 0;
+    }
+    static boolean refKindIsStatic(byte refKind) {
+        return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindDoesDispatch(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind == REF_invokeVirtual ||
+                refKind == REF_invokeInterface);
+    }
+    static {
+        final int HR_MASK = ((1 << REF_getField) |
+                             (1 << REF_putField) |
+                             (1 << REF_invokeVirtual) |
+                             (1 << REF_invokeSpecial) |
+                             (1 << REF_invokeInterface)
+                            );
+        for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
+            assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
+        }
+    }
+    */
+    // END Android-removed: Unused implementation code.
+    static String refKindName(byte refKind) {
+        assert(refKindIsValid(refKind));
+        switch (refKind) {
+        case REF_getField:          return "getField";
+        case REF_getStatic:         return "getStatic";
+        case REF_putField:          return "putField";
+        case REF_putStatic:         return "putStatic";
+        case REF_invokeVirtual:     return "invokeVirtual";
+        case REF_invokeStatic:      return "invokeStatic";
+        case REF_invokeSpecial:     return "invokeSpecial";
+        case REF_newInvokeSpecial:  return "newInvokeSpecial";
+        case REF_invokeInterface:   return "invokeInterface";
+        default:                    return "REF_???";
+        }
+    }
+    // BEGIN Android-removed: Unused implementation code.
+    /*
+    private static native int getNamedCon(int which, Object[] name);
+    static boolean verifyConstants() {
+        Object[] box = { null };
+        for (int i = 0; ; i++) {
+            box[0] = null;
+            int vmval = getNamedCon(i, box);
+            if (box[0] == null)  break;
+            String name = (String) box[0];
+            try {
+                Field con = Constants.class.getDeclaredField(name);
+                int jval = con.getInt(null);
+                if (jval == vmval)  continue;
+                String err = (name+": JVM has "+vmval+" while Java has "+jval);
+                if (name.equals("CONV_OP_LIMIT")) {
+                    System.err.println("warning: "+err);
+                    continue;
+                }
+                throw new InternalError(err);
+            } catch (NoSuchFieldException | IllegalAccessException ex) {
+                String err = (name+": JVM has "+vmval+" which Java does not define");
+                // ignore exotic ops the JVM cares about; we just wont issue them
+                //System.err.println("warning: "+err);
+                continue;
+            }
+        }
+        return true;
+    }
+    static {
+        assert(verifyConstants());
+    }
+
+    // Up-calls from the JVM.
+    // These must NOT be public.
+
+    /**
+     * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
+     *
+    static MemberName linkCallSite(Object callerObj,
+                                   Object bootstrapMethodObj,
+                                   Object nameObj, Object typeObj,
+                                   Object staticArguments,
+                                   Object[] appendixResult) {
+        MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
+        Class<?> caller = (Class<?>)callerObj;
+        String name = nameObj.toString().intern();
+        MethodType type = (MethodType)typeObj;
+        if (!TRACE_METHOD_LINKAGE)
+            return linkCallSiteImpl(caller, bootstrapMethod, name, type,
+                                    staticArguments, appendixResult);
+        return linkCallSiteTracing(caller, bootstrapMethod, name, type,
+                                   staticArguments, appendixResult);
+    }
+    static MemberName linkCallSiteImpl(Class<?> caller,
+                                       MethodHandle bootstrapMethod,
+                                       String name, MethodType type,
+                                       Object staticArguments,
+                                       Object[] appendixResult) {
+        CallSite callSite = CallSite.makeSite(bootstrapMethod,
+                                              name,
+                                              type,
+                                              staticArguments,
+                                              caller);
+        if (callSite instanceof ConstantCallSite) {
+            appendixResult[0] = callSite.dynamicInvoker();
+            return Invokers.linkToTargetMethod(type);
+        } else {
+            appendixResult[0] = callSite;
+            return Invokers.linkToCallSiteMethod(type);
+        }
+    }
+    // Tracing logic:
+    static MemberName linkCallSiteTracing(Class<?> caller,
+                                          MethodHandle bootstrapMethod,
+                                          String name, MethodType type,
+                                          Object staticArguments,
+                                          Object[] appendixResult) {
+        Object bsmReference = bootstrapMethod.internalMemberName();
+        if (bsmReference == null)  bsmReference = bootstrapMethod;
+        Object staticArglist = (staticArguments instanceof Object[] ?
+                                java.util.Arrays.asList((Object[]) staticArguments) :
+                                staticArguments);
+        System.out.println("linkCallSite "+caller.getName()+" "+
+                           bsmReference+" "+
+                           name+type+"/"+staticArglist);
+        try {
+            MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
+                                              staticArguments, appendixResult);
+            System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
+            return res;
+        } catch (Throwable ex) {
+            System.out.println("linkCallSite => throw "+ex);
+            throw ex;
+        }
+    }
+
+    /**
+     * The JVM wants a pointer to a MethodType.  Oblige it by finding or creating one.
+     *
+    static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
+        return MethodType.makeImpl(rtype, ptypes, true);
+    }
+
+    /**
+     * The JVM wants to link a call site that requires a dynamic type check.
+     * Name is a type-checking invoker, invokeExact or invoke.
+     * Return a JVM method (MemberName) to handle the invoking.
+     * The method assumes the following arguments on the stack:
+     * 0: the method handle being invoked
+     * 1-N: the arguments to the method handle invocation
+     * N+1: an optional, implicitly added argument (typically the given MethodType)
+     * <p>
+     * The nominal method at such a call site is an instance of
+     * a signature-polymorphic method (see @PolymorphicSignature).
+     * Such method instances are user-visible entities which are
+     * "split" from the generic placeholder method in {@code MethodHandle}.
+     * (Note that the placeholder method is not identical with any of
+     * its instances.  If invoked reflectively, is guaranteed to throw an
+     * {@code UnsupportedOperationException}.)
+     * If the signature-polymorphic method instance is ever reified,
+     * it appears as a "copy" of the original placeholder
+     * (a native final member of {@code MethodHandle}) except
+     * that its type descriptor has shape required by the instance,
+     * and the method instance is <em>not</em> varargs.
+     * The method instance is also marked synthetic, since the
+     * method (by definition) does not appear in Java source code.
+     * <p>
+     * The JVM is allowed to reify this method as instance metadata.
+     * For example, {@code invokeBasic} is always reified.
+     * But the JVM may instead call {@code linkMethod}.
+     * If the result is an * ordered pair of a {@code (method, appendix)},
+     * the method gets all the arguments (0..N inclusive)
+     * plus the appendix (N+1), and uses the appendix to complete the call.
+     * In this way, one reusable method (called a "linker method")
+     * can perform the function of any number of polymorphic instance
+     * methods.
+     * <p>
+     * Linker methods are allowed to be weakly typed, with any or
+     * all references rewritten to {@code Object} and any primitives
+     * (except {@code long}/{@code float}/{@code double})
+     * rewritten to {@code int}.
+     * A linker method is trusted to return a strongly typed result,
+     * according to the specific method type descriptor of the
+     * signature-polymorphic instance it is emulating.
+     * This can involve (as necessary) a dynamic check using
+     * data extracted from the appendix argument.
+     * <p>
+     * The JVM does not inspect the appendix, other than to pass
+     * it verbatim to the linker method at every call.
+     * This means that the JDK runtime has wide latitude
+     * for choosing the shape of each linker method and its
+     * corresponding appendix.
+     * Linker methods should be generated from {@code LambdaForm}s
+     * so that they do not become visible on stack traces.
+     * <p>
+     * The {@code linkMethod} call is free to omit the appendix
+     * (returning null) and instead emulate the required function
+     * completely in the linker method.
+     * As a corner case, if N==255, no appendix is possible.
+     * In this case, the method returned must be custom-generated to
+     * to perform any needed type checking.
+     * <p>
+     * If the JVM does not reify a method at a call site, but instead
+     * calls {@code linkMethod}, the corresponding call represented
+     * in the bytecodes may mention a valid method which is not
+     * representable with a {@code MemberName}.
+     * Therefore, use cases for {@code linkMethod} tend to correspond to
+     * special cases in reflective code such as {@code findVirtual}
+     * or {@code revealDirect}.
+     *
+    static MemberName linkMethod(Class<?> callerClass, int refKind,
+                                 Class<?> defc, String name, Object type,
+                                 Object[] appendixResult) {
+        if (!TRACE_METHOD_LINKAGE)
+            return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+        return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
+    }
+    static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
+                                     Class<?> defc, String name, Object type,
+                                     Object[] appendixResult) {
+        try {
+            if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+                return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+            }
+        } catch (Throwable ex) {
+            if (ex instanceof LinkageError)
+                throw (LinkageError) ex;
+            else
+                throw new LinkageError(ex.getMessage(), ex);
+        }
+        throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+    }
+    private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+        if (type instanceof MethodType)
+            return (MethodType) type;
+        else
+            return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+    }
+    // Tracing logic:
+    static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
+                                        Class<?> defc, String name, Object type,
+                                        Object[] appendixResult) {
+        System.out.println("linkMethod "+defc.getName()+"."+
+                           name+type+"/"+Integer.toHexString(refKind));
+        try {
+            MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+            System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
+            return res;
+        } catch (Throwable ex) {
+            System.out.println("linkMethod => throw "+ex);
+            throw ex;
+        }
+    }
+
+
+    /**
+     * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
+     * It will make an up-call to this method.  (Do not change the name or signature.)
+     * The type argument is a Class for field requests and a MethodType for non-fields.
+     * <p>
+     * Recent versions of the JVM may also pass a resolved MemberName for the type.
+     * In that case, the name is ignored and may be null.
+     *
+    static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
+                                                 Class<?> defc, String name, Object type) {
+        try {
+            Lookup lookup = IMPL_LOOKUP.in(callerClass);
+            assert(refKindIsValid(refKind));
+            return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
+        } catch (IllegalAccessException ex) {
+            Throwable cause = ex.getCause();
+            if (cause instanceof AbstractMethodError) {
+                throw (AbstractMethodError) cause;
+            } else {
+                Error err = new IllegalAccessError(ex.getMessage());
+                throw initCauseFrom(err, ex);
+            }
+        } catch (NoSuchMethodException ex) {
+            Error err = new NoSuchMethodError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (NoSuchFieldException ex) {
+            Error err = new NoSuchFieldError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (ReflectiveOperationException ex) {
+            Error err = new IncompatibleClassChangeError();
+            throw initCauseFrom(err, ex);
+        }
+    }
+
+    /**
+     * Use best possible cause for err.initCause(), substituting the
+     * cause for err itself if the cause has the same (or better) type.
+     *
+    static private Error initCauseFrom(Error err, Exception ex) {
+        Throwable th = ex.getCause();
+        if (err.getClass().isInstance(th))
+           return (Error) th;
+        err.initCause(th == null ? ex : th);
+        return err;
+    }
+
+    /**
+     * Is this method a caller-sensitive method?
+     * I.e., does it call Reflection.getCallerClass or a similer method
+     * to ask about the identity of its caller?
+     *
+    static boolean isCallerSensitive(MemberName mem) {
+        if (!mem.isInvocable())  return false;  // fields are not caller sensitive
+
+        return mem.isCallerSensitive() || canBeCalledVirtual(mem);
+    }
+
+    static boolean canBeCalledVirtual(MemberName mem) {
+        assert(mem.isInvocable());
+        Class<?> defc = mem.getDeclaringClass();
+        switch (mem.getName()) {
+        case "checkMemberAccess":
+            return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+        case "getContextClassLoader":
+            return canBeCalledVirtual(mem, java.lang.Thread.class);
+        }
+        return false;
+    }
+
+    static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
+        Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
+        if (symbolicRefClass == definingClass)  return true;
+        if (symbolicRef.isStatic() || symbolicRef.isPrivate())  return false;
+        return (definingClass.isAssignableFrom(symbolicRefClass) ||  // Msym overrides Mdef
+                symbolicRefClass.isInterface());                     // Mdef implements Msym
+    }
+    */
+    // END Android-removed: Unused implementation code.
+}
diff --git a/java/lang/invoke/MethodHandleStatics.java b/java/lang/invoke/MethodHandleStatics.java
new file mode 100644
index 0000000..90265cc
--- /dev/null
+++ b/java/lang/invoke/MethodHandleStatics.java
@@ -0,0 +1,169 @@
+/*
+ * 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 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();
+
+    // Android-changed: Remove debugging related static fields.
+    // They are unused and have no equivalent on Android.
+    /*
+    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-removed: Methods operating on MethodHandles that are currently unused on Android.
+    /*
+    /*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/java/lang/invoke/MethodHandles.java b/java/lang/invoke/MethodHandles.java
new file mode 100644
index 0000000..1188ac6
--- /dev/null
+++ b/java/lang/invoke/MethodHandles.java
@@ -0,0 +1,3521 @@
+/*
+ * Copyright (c) 2008, 2017, 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.reflect.*;
+import java.nio.ByteOrder;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import sun.invoke.util.VerifyAccess;
+import sun.invoke.util.Wrapper;
+import sun.reflect.Reflection;
+
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * This class consists exclusively of static methods that operate on or return
+ * method handles. They fall into several categories:
+ * <ul>
+ * <li>Lookup methods which help create method handles for methods and fields.
+ * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
+ * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
+ * </ul>
+ * <p>
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class MethodHandles {
+
+    private MethodHandles() { }  // do not instantiate
+
+    // Android-changed: We do not use MemberName / MethodHandleImpl.
+    //
+    // private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+    // static { MethodHandleImpl.initStatics(); }
+    // See IMPL_LOOKUP below.
+
+    //// Method handle creation from ordinary methods.
+
+    /**
+     * Returns a {@link Lookup lookup object} with
+     * full capabilities to emulate all supported bytecode behaviors of the caller.
+     * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
+     * Factory methods on the lookup object can create
+     * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
+     * for any member that the caller has access to via bytecodes,
+     * including protected and private fields and methods.
+     * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
+     * Do not store it in place where untrusted code can access it.
+     * <p>
+     * This method is caller sensitive, which means that it may return different
+     * values to different callers.
+     * <p>
+     * For any given caller class {@code C}, the lookup object returned by this call
+     * has equivalent capabilities to any lookup object
+     * supplied by the JVM to the bootstrap method of an
+     * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
+     * executing in the same caller class {@code C}.
+     * @return a lookup object for the caller of this method, with private access
+     */
+    // Android-changed: Remove caller sensitive.
+    // @CallerSensitive
+    public static Lookup lookup() {
+        return new Lookup(Reflection.getCallerClass());
+    }
+
+    /**
+     * Returns a {@link Lookup lookup object} which is trusted minimally.
+     * It can only be used to create method handles to
+     * publicly accessible fields and methods.
+     * <p>
+     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+     * of this lookup object will be {@link java.lang.Object}.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * The lookup class can be changed to any other class {@code C} using an expression of the form
+     * {@link Lookup#in publicLookup().in(C.class)}.
+     * Since all classes have equal access to public names,
+     * such a change would confer no new access rights.
+     * A public lookup object is always subject to
+     * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
+     * Also, it cannot access
+     * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
+     * @return a lookup object which is trusted minimally
+     */
+    public static Lookup publicLookup() {
+        return Lookup.PUBLIC_LOOKUP;
+    }
+
+    /**
+     * Performs an unchecked "crack" of a
+     * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
+     * The result is as if the user had obtained a lookup object capable enough
+     * to crack the target method handle, called
+     * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
+     * on the target to obtain its symbolic reference, and then called
+     * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
+     * to resolve the symbolic reference to a member.
+     * <p>
+     * If there is a security manager, its {@code checkPermission} method
+     * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
+     * @param <T> the desired type of the result, either {@link Member} or a subtype
+     * @param target a direct method handle to crack into symbolic reference components
+     * @param expected a class object representing the desired result type {@code T}
+     * @return a reference to the method, constructor, or field object
+     * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
+     * @exception NullPointerException if either argument is {@code null}
+     * @exception IllegalArgumentException if the target is not a direct method handle
+     * @exception ClassCastException if the member is not of the expected type
+     * @since 1.8
+     */
+    public static <T extends Member> T
+    reflectAs(Class<T> expected, MethodHandle target) {
+        MethodHandleImpl directTarget = getMethodHandleImpl(target);
+        // Given that this is specified to be an "unchecked" crack, we can directly allocate
+        // a member from the underlying ArtField / Method and bypass all associated access checks.
+        return expected.cast(directTarget.getMemberInternal());
+    }
+
+    /**
+     * A <em>lookup object</em> is a factory for creating method handles,
+     * when the creation requires access checking.
+     * Method handles do not perform
+     * access checks when they are called, but rather when they are created.
+     * Therefore, method handle access
+     * restrictions must be enforced when a method handle is created.
+     * The caller class against which those restrictions are enforced
+     * is known as the {@linkplain #lookupClass lookup class}.
+     * <p>
+     * A lookup class which needs to create method handles will call
+     * {@link #lookup MethodHandles.lookup} to create a factory for itself.
+     * When the {@code Lookup} factory object is created, the identity of the lookup class is
+     * determined, and securely stored in the {@code Lookup} object.
+     * The lookup class (or its delegates) may then use factory methods
+     * on the {@code Lookup} object to create method handles for access-checked members.
+     * This includes all methods, constructors, and fields which are allowed to the lookup class,
+     * even private ones.
+     *
+     * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
+     * The factory methods on a {@code Lookup} object correspond to all major
+     * use cases for methods, constructors, and fields.
+     * Each method handle created by a factory method is the functional
+     * equivalent of a particular <em>bytecode behavior</em>.
+     * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
+     * Here is a summary of the correspondence between these factory methods and
+     * the behavior the resulting method handles:
+     * <table border=1 cellpadding=5 summary="lookup method behaviors">
+     * <tr>
+     *     <th><a name="equiv"></a>lookup expression</th>
+     *     <th>member</th>
+     *     <th>bytecode behavior</th>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
+     *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
+     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
+     *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
+     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
+     *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
+     *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
+     *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
+     *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
+     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
+     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
+     *     <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
+     * </tr>
+     * <tr>
+     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+     * </tr>
+     * </table>
+     *
+     * Here, the type {@code C} is the class or interface being searched for a member,
+     * documented as a parameter named {@code refc} in the lookup methods.
+     * The method type {@code MT} is composed from the return type {@code T}
+     * and the sequence of argument types {@code A*}.
+     * The constructor also has a sequence of argument types {@code A*} and
+     * is deemed to return the newly-created object of type {@code C}.
+     * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
+     * The formal parameter {@code this} stands for the self-reference of type {@code C};
+     * if it is present, it is always the leading argument to the method handle invocation.
+     * (In the case of some {@code protected} members, {@code this} may be
+     * restricted in type to the lookup class; see below.)
+     * The name {@code arg} stands for all the other method handle arguments.
+     * In the code examples for the Core Reflection API, the name {@code thisOrNull}
+     * stands for a null reference if the accessed method or field is static,
+     * and {@code this} otherwise.
+     * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
+     * for reflective objects corresponding to the given members.
+     * <p>
+     * In cases where the given member is of variable arity (i.e., a method or constructor)
+     * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
+     * In all other cases, the returned method handle will be of fixed arity.
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * The equivalence between looked-up method handles and underlying
+     * class members and bytecode behaviors
+     * can break down in a few ways:
+     * <ul style="font-size:smaller;">
+     * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
+     * the lookup can still succeed, even when there is no equivalent
+     * Java expression or bytecoded constant.
+     * <li>Likewise, if {@code T} or {@code MT}
+     * is not symbolically accessible from the lookup class's loader,
+     * the lookup can still succeed.
+     * For example, lookups for {@code MethodHandle.invokeExact} and
+     * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
+     * <li>If there is a security manager installed, it can forbid the lookup
+     * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
+     * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
+     * constant is not subject to security manager checks.
+     * <li>If the looked-up method has a
+     * <a href="MethodHandle.html#maxarity">very large arity</a>,
+     * the method handle creation may fail, due to the method handle
+     * type having too many parameters.
+     * </ul>
+     *
+     * <h1><a name="access"></a>Access checking</h1>
+     * Access checks are applied in the factory methods of {@code Lookup},
+     * when a method handle is created.
+     * This is a key difference from the Core Reflection API, since
+     * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+     * performs access checking against every caller, on every call.
+     * <p>
+     * All access checks start from a {@code Lookup} object, which
+     * compares its recorded lookup class against all requests to
+     * create method handles.
+     * A single {@code Lookup} object can be used to create any number
+     * of access-checked method handles, all checked against a single
+     * lookup class.
+     * <p>
+     * A {@code Lookup} object can be shared with other trusted code,
+     * such as a metaobject protocol.
+     * A shared {@code Lookup} object delegates the capability
+     * to create method handles on private members of the lookup class.
+     * Even if privileged code uses the {@code Lookup} object,
+     * the access checking is confined to the privileges of the
+     * original lookup class.
+     * <p>
+     * A lookup can fail, because
+     * the containing class is not accessible to the lookup class, or
+     * because the desired class member is missing, or because the
+     * desired class member is not accessible to the lookup class, or
+     * because the lookup object is not trusted enough to access the member.
+     * In any of these cases, a {@code ReflectiveOperationException} will be
+     * thrown from the attempted lookup.  The exact class will be one of
+     * the following:
+     * <ul>
+     * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
+     * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
+     * <li>IllegalAccessException &mdash; if the member exists but an access check fails
+     * </ul>
+     * <p>
+     * In general, the conditions under which a method handle may be
+     * looked up for a method {@code M} are no more restrictive than the conditions
+     * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
+     * Where the JVM would raise exceptions like {@code NoSuchMethodError},
+     * a method handle lookup will generally raise a corresponding
+     * checked exception, such as {@code NoSuchMethodException}.
+     * And the effect of invoking the method handle resulting from the lookup
+     * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
+     * to executing the compiled, verified, and resolved call to {@code M}.
+     * The same point is true of fields and constructors.
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * Access checks only apply to named and reflected methods,
+     * constructors, and fields.
+     * Other method handle creation methods, such as
+     * {@link MethodHandle#asType MethodHandle.asType},
+     * do not require any access checks, and are used
+     * independently of any {@code Lookup} object.
+     * <p>
+     * If the desired member is {@code protected}, the usual JVM rules apply,
+     * including the requirement that the lookup class must be either be in the
+     * same package as the desired member, or must inherit that member.
+     * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
+     * In addition, if the desired member is a non-static field or method
+     * in a different package, the resulting method handle may only be applied
+     * to objects of the lookup class or one of its subclasses.
+     * This requirement is enforced by narrowing the type of the leading
+     * {@code this} parameter from {@code C}
+     * (which will necessarily be a superclass of the lookup class)
+     * to the lookup class itself.
+     * <p>
+     * The JVM imposes a similar requirement on {@code invokespecial} instruction,
+     * that the receiver argument must match both the resolved method <em>and</em>
+     * the current class.  Again, this requirement is enforced by narrowing the
+     * type of the leading parameter to the resulting method handle.
+     * (See the Java Virtual Machine Specification, section 4.10.1.9.)
+     * <p>
+     * The JVM represents constructors and static initializer blocks as internal methods
+     * with special names ({@code "<init>"} and {@code "<clinit>"}).
+     * The internal syntax of invocation instructions allows them to refer to such internal
+     * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
+     * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
+     * <p>
+     * In some cases, access between nested classes is obtained by the Java compiler by creating
+     * an wrapper method to access a private method of another class
+     * in the same top-level declaration.
+     * For example, a nested class {@code C.D}
+     * can access private members within other related classes such as
+     * {@code C}, {@code C.D.E}, or {@code C.B},
+     * but the Java compiler may need to generate wrapper methods in
+     * those related classes.  In such cases, a {@code Lookup} object on
+     * {@code C.E} would be unable to those private members.
+     * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
+     * which can transform a lookup on {@code C.E} into one on any of those other
+     * classes, without special elevation of privilege.
+     * <p>
+     * The accesses permitted to a given lookup object may be limited,
+     * according to its set of {@link #lookupModes lookupModes},
+     * to a subset of members normally accessible to the lookup class.
+     * For example, the {@link #publicLookup publicLookup}
+     * method produces a lookup object which is only allowed to access
+     * public members in public classes.
+     * The caller sensitive method {@link #lookup lookup}
+     * produces a lookup object with full capabilities relative to
+     * its caller class, to emulate all supported bytecode behaviors.
+     * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
+     * with fewer access modes than the original lookup object.
+     *
+     * <p style="font-size:smaller;">
+     * <a name="privacc"></a>
+     * <em>Discussion of private access:</em>
+     * We say that a lookup has <em>private access</em>
+     * if its {@linkplain #lookupModes lookup modes}
+     * include the possibility of accessing {@code private} members.
+     * As documented in the relevant methods elsewhere,
+     * only lookups with private access possess the following capabilities:
+     * <ul style="font-size:smaller;">
+     * <li>access private fields, methods, and constructors of the lookup class
+     * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
+     *     such as {@code Class.forName}
+     * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
+     * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
+     *     for classes accessible to the lookup class
+     * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
+     *     within the same package member
+     * </ul>
+     * <p style="font-size:smaller;">
+     * Each of these permissions is a consequence of the fact that a lookup object
+     * with private access can be securely traced back to an originating class,
+     * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
+     * can be reliably determined and emulated by method handles.
+     *
+     * <h1><a name="secmgr"></a>Security manager interactions</h1>
+     * Although bytecode instructions can only refer to classes in
+     * a related class loader, this API can search for methods in any
+     * class, as long as a reference to its {@code Class} object is
+     * available.  Such cross-loader references are also possible with the
+     * Core Reflection API, and are impossible to bytecode instructions
+     * such as {@code invokestatic} or {@code getfield}.
+     * There is a {@linkplain java.lang.SecurityManager security manager API}
+     * to allow applications to check such cross-loader references.
+     * These checks apply to both the {@code MethodHandles.Lookup} API
+     * and the Core Reflection API
+     * (as found on {@link java.lang.Class Class}).
+     * <p>
+     * If a security manager is present, member lookups are subject to
+     * additional checks.
+     * From one to three calls are made to the security manager.
+     * Any of these calls can refuse access by throwing a
+     * {@link java.lang.SecurityException SecurityException}.
+     * Define {@code smgr} as the security manager,
+     * {@code lookc} as the lookup class of the current lookup object,
+     * {@code refc} as the containing class in which the member
+     * is being sought, and {@code defc} as the class in which the
+     * member is actually defined.
+     * The value {@code lookc} is defined as <em>not present</em>
+     * if the current lookup object does not have
+     * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
+     * The calls are made according to the following rules:
+     * <ul>
+     * <li><b>Step 1:</b>
+     *     If {@code lookc} is not present, or if its class loader is not
+     *     the same as or an ancestor of the class loader of {@code refc},
+     *     then {@link SecurityManager#checkPackageAccess
+     *     smgr.checkPackageAccess(refcPkg)} is called,
+     *     where {@code refcPkg} is the package of {@code refc}.
+     * <li><b>Step 2:</b>
+     *     If the retrieved member is not public and
+     *     {@code lookc} is not present, then
+     *     {@link SecurityManager#checkPermission smgr.checkPermission}
+     *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
+     * <li><b>Step 3:</b>
+     *     If the retrieved member is not public,
+     *     and if {@code lookc} is not present,
+     *     and if {@code defc} and {@code refc} are different,
+     *     then {@link SecurityManager#checkPackageAccess
+     *     smgr.checkPackageAccess(defcPkg)} is called,
+     *     where {@code defcPkg} is the package of {@code defc}.
+     * </ul>
+     * Security checks are performed after other access checks have passed.
+     * Therefore, the above rules presuppose a member that is public,
+     * or else that is being accessed from a lookup class that has
+     * rights to access the member.
+     *
+     * <h1><a name="callsens"></a>Caller sensitive methods</h1>
+     * A small number of Java methods have a special property called caller sensitivity.
+     * A <em>caller-sensitive</em> method can behave differently depending on the
+     * identity of its immediate caller.
+     * <p>
+     * If a method handle for a caller-sensitive method is requested,
+     * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
+     * but they take account of the lookup class in a special way.
+     * The resulting method handle behaves as if it were called
+     * from an instruction contained in the lookup class,
+     * so that the caller-sensitive method detects the lookup class.
+     * (By contrast, the invoker of the method handle is disregarded.)
+     * Thus, in the case of caller-sensitive methods,
+     * different lookup classes may give rise to
+     * differently behaving method handles.
+     * <p>
+     * In cases where the lookup object is
+     * {@link #publicLookup publicLookup()},
+     * or some other lookup object without
+     * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
+     * the lookup class is disregarded.
+     * In such cases, no caller-sensitive method handle can be created,
+     * access is forbidden, and the lookup fails with an
+     * {@code IllegalAccessException}.
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * For example, the caller-sensitive method
+     * {@link java.lang.Class#forName(String) Class.forName(x)}
+     * can return varying classes or throw varying exceptions,
+     * depending on the class loader of the class that calls it.
+     * A public lookup of {@code Class.forName} will fail, because
+     * there is no reasonable way to determine its bytecode behavior.
+     * <p style="font-size:smaller;">
+     * If an application caches method handles for broad sharing,
+     * it should use {@code publicLookup()} to create them.
+     * If there is a lookup of {@code Class.forName}, it will fail,
+     * and the application must take appropriate action in that case.
+     * It may be that a later lookup, perhaps during the invocation of a
+     * bootstrap method, can incorporate the specific identity
+     * of the caller, making the method accessible.
+     * <p style="font-size:smaller;">
+     * The function {@code MethodHandles.lookup} is caller sensitive
+     * so that there can be a secure foundation for lookups.
+     * Nearly all other methods in the JSR 292 API rely on lookup
+     * objects to check access requests.
+     */
+    // Android-changed: Change link targets from MethodHandles#[public]Lookup to
+    // #[public]Lookup to work around complaints from javadoc.
+    public static final
+    class Lookup {
+        /** The class on behalf of whom the lookup is being performed. */
+        /* @NonNull */ private final Class<?> lookupClass;
+
+        /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
+        private final int allowedModes;
+
+        /** A single-bit mask representing {@code public} access,
+         *  which may contribute to the result of {@link #lookupModes lookupModes}.
+         *  The value, {@code 0x01}, happens to be the same as the value of the
+         *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
+         */
+        public static final int PUBLIC = Modifier.PUBLIC;
+
+        /** A single-bit mask representing {@code private} access,
+         *  which may contribute to the result of {@link #lookupModes lookupModes}.
+         *  The value, {@code 0x02}, happens to be the same as the value of the
+         *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
+         */
+        public static final int PRIVATE = Modifier.PRIVATE;
+
+        /** A single-bit mask representing {@code protected} access,
+         *  which may contribute to the result of {@link #lookupModes lookupModes}.
+         *  The value, {@code 0x04}, happens to be the same as the value of the
+         *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
+         */
+        public static final int PROTECTED = Modifier.PROTECTED;
+
+        /** A single-bit mask representing {@code package} access (default access),
+         *  which may contribute to the result of {@link #lookupModes lookupModes}.
+         *  The value is {@code 0x08}, which does not correspond meaningfully to
+         *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
+         */
+        public static final int PACKAGE = Modifier.STATIC;
+
+        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
+
+        // Android-note: Android has no notion of a trusted lookup. If required, such lookups
+        // are performed by the runtime. As a result, we always use lookupClass, which will always
+        // be non-null in our implementation.
+        //
+        // private static final int TRUSTED   = -1;
+
+        private static int fixmods(int mods) {
+            mods &= (ALL_MODES - PACKAGE);
+            return (mods != 0) ? mods : PACKAGE;
+        }
+
+        /** Tells which class is performing the lookup.  It is this class against
+         *  which checks are performed for visibility and access permissions.
+         *  <p>
+         *  The class implies a maximum level of access permission,
+         *  but the permissions may be additionally limited by the bitmask
+         *  {@link #lookupModes lookupModes}, which controls whether non-public members
+         *  can be accessed.
+         *  @return the lookup class, on behalf of which this lookup object finds members
+         */
+        public Class<?> lookupClass() {
+            return lookupClass;
+        }
+
+        /** Tells which access-protection classes of members this lookup object can produce.
+         *  The result is a bit-mask of the bits
+         *  {@linkplain #PUBLIC PUBLIC (0x01)},
+         *  {@linkplain #PRIVATE PRIVATE (0x02)},
+         *  {@linkplain #PROTECTED PROTECTED (0x04)},
+         *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
+         *  <p>
+         *  A freshly-created lookup object
+         *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
+         *  has all possible bits set, since the caller class can access all its own members.
+         *  A lookup object on a new lookup class
+         *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
+         *  may have some mode bits set to zero.
+         *  The purpose of this is to restrict access via the new lookup object,
+         *  so that it can access only names which can be reached by the original
+         *  lookup object, and also by the new lookup class.
+         *  @return the lookup modes, which limit the kinds of access performed by this lookup object
+         */
+        public int lookupModes() {
+            return allowedModes & ALL_MODES;
+        }
+
+        /** Embody the current class (the lookupClass) as a lookup class
+         * for method handle creation.
+         * Must be called by from a method in this package,
+         * which in turn is called by a method not in this package.
+         */
+        Lookup(Class<?> lookupClass) {
+            this(lookupClass, ALL_MODES);
+            // make sure we haven't accidentally picked up a privileged class:
+            checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
+        }
+
+        private Lookup(Class<?> lookupClass, int allowedModes) {
+            this.lookupClass = lookupClass;
+            this.allowedModes = allowedModes;
+        }
+
+        /**
+         * Creates a lookup on the specified new lookup class.
+         * The resulting object will report the specified
+         * class as its own {@link #lookupClass lookupClass}.
+         * <p>
+         * However, the resulting {@code Lookup} object is guaranteed
+         * to have no more access capabilities than the original.
+         * In particular, access capabilities can be lost as follows:<ul>
+         * <li>If the new lookup class differs from the old one,
+         * protected members will not be accessible by virtue of inheritance.
+         * (Protected members may continue to be accessible because of package sharing.)
+         * <li>If the new lookup class is in a different package
+         * than the old one, protected and default (package) members will not be accessible.
+         * <li>If the new lookup class is not within the same package member
+         * as the old one, private members will not be accessible.
+         * <li>If the new lookup class is not accessible to the old lookup class,
+         * then no members, not even public members, will be accessible.
+         * (In all other cases, public members will continue to be accessible.)
+         * </ul>
+         *
+         * @param requestedLookupClass the desired lookup class for the new lookup object
+         * @return a lookup object which reports the desired lookup class
+         * @throws NullPointerException if the argument is null
+         */
+        public Lookup in(Class<?> requestedLookupClass) {
+            requestedLookupClass.getClass();  // null check
+            // Android-changed: There's no notion of a trusted lookup.
+            // if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
+            //    return new Lookup(requestedLookupClass, ALL_MODES);
+
+            if (requestedLookupClass == this.lookupClass)
+                return this;  // keep same capabilities
+            int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+            if ((newModes & PACKAGE) != 0
+                && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
+                newModes &= ~(PACKAGE|PRIVATE);
+            }
+            // Allow nestmate lookups to be created without special privilege:
+            if ((newModes & PRIVATE) != 0
+                && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
+                newModes &= ~PRIVATE;
+            }
+            if ((newModes & PUBLIC) != 0
+                && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
+                // The requested class it not accessible from the lookup class.
+                // No permissions.
+                newModes = 0;
+            }
+            checkUnprivilegedlookupClass(requestedLookupClass, newModes);
+            return new Lookup(requestedLookupClass, newModes);
+        }
+
+        // Make sure outer class is initialized first.
+        //
+        // Android-changed: Removed unnecessary reference to IMPL_NAMES.
+        // static { IMPL_NAMES.getClass(); }
+
+        /** Version of lookup which is trusted minimally.
+         *  It can only be used to create method handles to
+         *  publicly accessible members.
+         */
+        static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
+
+        /** Package-private version of lookup which is trusted. */
+        static final Lookup IMPL_LOOKUP = new Lookup(Object.class, ALL_MODES);
+
+        private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
+            String name = lookupClass.getName();
+            if (name.startsWith("java.lang.invoke."))
+                throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
+
+            // For caller-sensitive MethodHandles.lookup()
+            // disallow lookup more restricted packages
+            //
+            // Android-changed: The bootstrap classloader isn't null.
+            if (allowedModes == ALL_MODES &&
+                    lookupClass.getClassLoader() == Object.class.getClassLoader()) {
+                if (name.startsWith("java.") ||
+                        (name.startsWith("sun.")
+                                && !name.startsWith("sun.invoke.")
+                                && !name.equals("sun.reflect.ReflectionFactory"))) {
+                    throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
+                }
+            }
+        }
+
+        /**
+         * Displays the name of the class from which lookups are to be made.
+         * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
+         * If there are restrictions on the access permitted to this lookup,
+         * this is indicated by adding a suffix to the class name, consisting
+         * of a slash and a keyword.  The keyword represents the strongest
+         * allowed access, and is chosen as follows:
+         * <ul>
+         * <li>If no access is allowed, the suffix is "/noaccess".
+         * <li>If only public access is allowed, the suffix is "/public".
+         * <li>If only public and package access are allowed, the suffix is "/package".
+         * <li>If only public, package, and private access are allowed, the suffix is "/private".
+         * </ul>
+         * If none of the above cases apply, it is the case that full
+         * access (public, package, private, and protected) is allowed.
+         * In this case, no suffix is added.
+         * This is true only of an object obtained originally from
+         * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
+         * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
+         * always have restricted access, and will display a suffix.
+         * <p>
+         * (It may seem strange that protected access should be
+         * stronger than private access.  Viewed independently from
+         * package access, protected access is the first to be lost,
+         * because it requires a direct subclass relationship between
+         * caller and callee.)
+         * @see #in
+         */
+        @Override
+        public String toString() {
+            String cname = lookupClass.getName();
+            switch (allowedModes) {
+            case 0:  // no privileges
+                return cname + "/noaccess";
+            case PUBLIC:
+                return cname + "/public";
+            case PUBLIC|PACKAGE:
+                return cname + "/package";
+            case ALL_MODES & ~PROTECTED:
+                return cname + "/private";
+            case ALL_MODES:
+                return cname;
+            // Android-changed: No support for TRUSTED callers.
+            // case TRUSTED:
+            //    return "/trusted";  // internal only; not exported
+            default:  // Should not happen, but it's a bitfield...
+                cname = cname + "/" + Integer.toHexString(allowedModes);
+                assert(false) : cname;
+                return cname;
+            }
+        }
+
+        /**
+         * Produces a method handle for a static method.
+         * The type of the method handle will be that of the method.
+         * (Since static methods do not take receivers, there is no
+         * additional receiver argument inserted into the method handle type,
+         * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
+         * The method and all its argument types must be accessible to the lookup object.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the method's class will
+         * be initialized, if it has not already been initialized.
+         * <p><b>Example:</b>
+         * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
+  "asList", methodType(List.class, Object[].class));
+assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
+         * }</pre></blockquote>
+         * @param refc the class from which the method is accessed
+         * @param name the name of the method
+         * @param type the type of the method
+         * @return the desired method handle
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails,
+         *                                or if the method is not {@code static},
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public
+        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            Method method = refc.getDeclaredMethod(name, type.ptypes());
+            final int modifiers = method.getModifiers();
+            if (!Modifier.isStatic(modifiers)) {
+                throw new IllegalAccessException("Method" + method + " is not static");
+            }
+            checkReturnType(method, type);
+            checkAccess(refc, method.getDeclaringClass(), modifiers, method.getName());
+            return createMethodHandle(method, MethodHandle.INVOKE_STATIC, type);
+        }
+
+        private MethodHandle findVirtualForMH(String name, MethodType type) {
+            // these names require special lookups because of the implicit MethodType argument
+            if ("invoke".equals(name))
+                return invoker(type);
+            if ("invokeExact".equals(name))
+                return exactInvoker(type);
+            return null;
+        }
+
+        private MethodHandle findVirtualForVH(String name, MethodType type) {
+            VarHandle.AccessMode accessMode;
+            try {
+                accessMode = VarHandle.AccessMode.valueFromMethodName(name);
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+            return varHandleInvoker(accessMode, type);
+        }
+
+        private static MethodHandle createMethodHandle(Method method, int handleKind,
+                                                       MethodType methodType) {
+            MethodHandle mh = new MethodHandleImpl(method.getArtMethod(), handleKind, methodType);
+            if (method.isVarArgs()) {
+                return new Transformers.VarargsCollector(mh);
+            } else {
+                return mh;
+            }
+        }
+
+        /**
+         * Produces a method handle for a virtual method.
+         * The type of the method handle will be that of the method,
+         * with the receiver type (usually {@code refc}) prepended.
+         * The method and all its argument types must be accessible to the lookup object.
+         * <p>
+         * When called, the handle will treat the first argument as a receiver
+         * and dispatch on the receiver's type to determine which method
+         * implementation to enter.
+         * (The dispatching action is identical with that performed by an
+         * {@code invokevirtual} or {@code invokeinterface} instruction.)
+         * <p>
+         * The first argument will be of type {@code refc} if the lookup
+         * class has full privileges to access the member.  Otherwise
+         * the member must be {@code protected} and the first argument
+         * will be restricted in type to the lookup class.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
+         * instructions and method handles produced by {@code findVirtual},
+         * if the class is {@code MethodHandle} and the name string is
+         * {@code invokeExact} or {@code invoke}, the resulting
+         * method handle is equivalent to one produced by
+         * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
+         * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
+         * with the same {@code type} argument.
+         *
+         * <b>Example:</b>
+         * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_concat = publicLookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
+  "hashCode", methodType(int.class));
+MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
+  "hashCode", methodType(int.class));
+assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
+assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
+assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
+// interface method:
+MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
+  "subSequence", methodType(CharSequence.class, int.class, int.class));
+assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
+// constructor "internal method" must be accessed differently:
+MethodType MT_newString = methodType(void.class); //()V for new String()
+try { assertEquals("impossible", lookup()
+        .findVirtual(String.class, "<init>", MT_newString));
+ } catch (NoSuchMethodException ex) { } // OK
+MethodHandle MH_newString = publicLookup()
+  .findConstructor(String.class, MT_newString);
+assertEquals("", (String) MH_newString.invokeExact());
+         * }</pre></blockquote>
+         *
+         * @param refc the class or interface from which the method is accessed
+         * @param name the name of the method
+         * @param type the type of the method, with the receiver argument omitted
+         * @return the desired method handle
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails,
+         *                                or if the method is {@code static}
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            // Special case : when we're looking up a virtual method on the MethodHandles class
+            // itself, we can return one of our specialized invokers.
+            if (refc == MethodHandle.class) {
+                MethodHandle mh = findVirtualForMH(name, type);
+                if (mh != null) {
+                    return mh;
+                }
+            } else if (refc == VarHandle.class) {
+                // Returns an non-exact invoker.
+                MethodHandle mh = findVirtualForVH(name, type);
+                if (mh != null) {
+                    return mh;
+                }
+            }
+
+            Method method = refc.getInstanceMethod(name, type.ptypes());
+            if (method == null) {
+                // This is pretty ugly and a consequence of the MethodHandles API. We have to throw
+                // an IAE and not an NSME if the method exists but is static (even though the RI's
+                // IAE has a message that says "no such method"). We confine the ugliness and
+                // slowness to the failure case, and allow getInstanceMethod to remain fairly
+                // general.
+                try {
+                    Method m = refc.getDeclaredMethod(name, type.ptypes());
+                    if (Modifier.isStatic(m.getModifiers())) {
+                        throw new IllegalAccessException("Method" + m + " is static");
+                    }
+                } catch (NoSuchMethodException ignored) {
+                }
+
+                throw new NoSuchMethodException(name + " "  + Arrays.toString(type.ptypes()));
+            }
+            checkReturnType(method, type);
+
+            // We have a valid method, perform access checks.
+            checkAccess(refc, method.getDeclaringClass(), method.getModifiers(), method.getName());
+
+            // Insert the leading reference parameter.
+            MethodType handleType = type.insertParameterTypes(0, refc);
+            return createMethodHandle(method, MethodHandle.INVOKE_VIRTUAL, handleType);
+        }
+
+        /**
+         * Produces a method handle which creates an object and initializes it, using
+         * the constructor of the specified type.
+         * The parameter types of the method handle will be those of the constructor,
+         * while the return type will be a reference to the constructor's class.
+         * The constructor and all its argument types must be accessible to the lookup object.
+         * <p>
+         * The requested type must have a return type of {@code void}.
+         * (This is consistent with the JVM's treatment of constructor type descriptors.)
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the constructor's class will
+         * be initialized, if it has not already been initialized.
+         * <p><b>Example:</b>
+         * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_newArrayList = publicLookup().findConstructor(
+  ArrayList.class, methodType(void.class, Collection.class));
+Collection orig = Arrays.asList("x", "y");
+Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
+assert(orig != copy);
+assertEquals(orig, copy);
+// a variable-arity constructor:
+MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
+  ProcessBuilder.class, methodType(void.class, String[].class));
+ProcessBuilder pb = (ProcessBuilder)
+  MH_newProcessBuilder.invoke("x", "y", "z");
+assertEquals("[x, y, z]", pb.command().toString());
+         * }</pre></blockquote>
+         * @param refc the class or interface from which the method is accessed
+         * @param type the type of the method, with the receiver argument omitted, and a void return type
+         * @return the desired method handle
+         * @throws NoSuchMethodException if the constructor does not exist
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            if (refc.isArray()) {
+                throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+            }
+            // The queried |type| is (PT1,PT2,..)V
+            Constructor constructor = refc.getDeclaredConstructor(type.ptypes());
+            if (constructor == null) {
+                throw new NoSuchMethodException(
+                    "No constructor for " + constructor.getDeclaringClass() + " matching " + type);
+            }
+            checkAccess(refc, constructor.getDeclaringClass(), constructor.getModifiers(),
+                    constructor.getName());
+
+            return createMethodHandleForConstructor(constructor);
+        }
+
+        private MethodHandle createMethodHandleForConstructor(Constructor constructor) {
+            Class<?> refc = constructor.getDeclaringClass();
+            MethodType constructorType =
+                    MethodType.methodType(refc, constructor.getParameterTypes());
+            MethodHandle mh;
+            if (refc == String.class) {
+                // String constructors have optimized StringFactory methods
+                // that matches returned type. These factory methods combine the
+                // memory allocation and initialization calls for String objects.
+                mh = new MethodHandleImpl(constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT,
+                                          constructorType);
+            } else {
+                // Constructors for all other classes use a Construct transformer to perform
+                // their memory allocation and call to <init>.
+                MethodType initType = initMethodType(constructorType);
+                MethodHandle initHandle = new MethodHandleImpl(
+                    constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT, initType);
+                mh = new Transformers.Construct(initHandle, constructorType);
+            }
+
+            if (constructor.isVarArgs()) {
+                mh = new Transformers.VarargsCollector(mh);
+            }
+            return mh;
+        }
+
+        private static MethodType initMethodType(MethodType constructorType) {
+            // Returns a MethodType appropriate for class <init>
+            // methods. Constructor MethodTypes have the form
+            // (PT1,PT2,...)C and class <init> MethodTypes have the
+            // form (C,PT1,PT2,...)V.
+            assert constructorType.rtype() != void.class;
+
+            // Insert constructorType C as the first parameter type in
+            // the MethodType for <init>.
+            Class<?> [] initPtypes = new Class<?> [constructorType.ptypes().length + 1];
+            initPtypes[0] = constructorType.rtype();
+            System.arraycopy(constructorType.ptypes(), 0, initPtypes, 1,
+                             constructorType.ptypes().length);
+
+            // Set the return type for the <init> MethodType to be void.
+            return MethodType.methodType(void.class, initPtypes);
+        }
+
+        /**
+         * Produces an early-bound method handle for a virtual method.
+         * It will bypass checks for overriding methods on the receiver,
+         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+         * instruction from within the explicitly specified {@code specialCaller}.
+         * The type of the method handle will be that of the method,
+         * with a suitably restricted receiver type prepended.
+         * (The receiver type will be {@code specialCaller} or a subtype.)
+         * The method and all its argument types must be accessible
+         * to the lookup object.
+         * <p>
+         * Before method resolution,
+         * if the explicitly specified caller class is not identical with the
+         * lookup class, or if this lookup object does not have
+         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
+         * privileges, the access fails.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p style="font-size:smaller;">
+         * <em>(Note:  JVM internal methods named {@code "<init>"} are not visible to this API,
+         * even though the {@code invokespecial} instruction can refer to them
+         * in special circumstances.  Use {@link #findConstructor findConstructor}
+         * to access instance initialization methods in a safe manner.)</em>
+         * <p><b>Example:</b>
+         * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+static class Listie extends ArrayList {
+  public String toString() { return "[wee Listie]"; }
+  static Lookup lookup() { return MethodHandles.lookup(); }
+}
+...
+// no access to constructor via invokeSpecial:
+MethodHandle MH_newListie = Listie.lookup()
+  .findConstructor(Listie.class, methodType(void.class));
+Listie l = (Listie) MH_newListie.invokeExact();
+try { assertEquals("impossible", Listie.lookup().findSpecial(
+        Listie.class, "<init>", methodType(void.class), Listie.class));
+ } catch (NoSuchMethodException ex) { } // OK
+// access to super and self methods via invokeSpecial:
+MethodHandle MH_super = Listie.lookup().findSpecial(
+  ArrayList.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_this = Listie.lookup().findSpecial(
+  Listie.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_duper = Listie.lookup().findSpecial(
+  Object.class, "toString" , methodType(String.class), Listie.class);
+assertEquals("[]", (String) MH_super.invokeExact(l));
+assertEquals(""+l, (String) MH_this.invokeExact(l));
+assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
+try { assertEquals("inaccessible", Listie.lookup().findSpecial(
+        String.class, "toString", methodType(String.class), Listie.class));
+ } catch (IllegalAccessException ex) { } // OK
+Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
+assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
+         * }</pre></blockquote>
+         *
+         * @param refc the class or interface from which the method is accessed
+         * @param name the name of the method (which must not be "&lt;init&gt;")
+         * @param type the type of the method, with the receiver argument omitted
+         * @param specialCaller the proposed calling class to perform the {@code invokespecial}
+         * @return the desired method handle
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
+                                        Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
+            if (specialCaller == null) {
+                throw new NullPointerException("specialCaller == null");
+            }
+
+            if (type == null) {
+                throw new NullPointerException("type == null");
+            }
+
+            if (name == null) {
+                throw new NullPointerException("name == null");
+            }
+
+            if (refc == null) {
+                throw new NullPointerException("ref == null");
+            }
+
+            // Make sure that the special caller is identical to the lookup class or that we have
+            // private access.
+            // Android-changed: Also allow access to any interface methods.
+            checkSpecialCaller(specialCaller, refc);
+
+            // Even though constructors are invoked using a "special" invoke, handles to them can't
+            // be created using findSpecial. Callers must use findConstructor instead. Similarly,
+            // there is no path for calling static class initializers.
+            if (name.startsWith("<")) {
+                throw new NoSuchMethodException(name + " is not a valid method name.");
+            }
+
+            Method method = refc.getDeclaredMethod(name, type.ptypes());
+            checkReturnType(method, type);
+            return findSpecial(method, type, refc, specialCaller);
+        }
+
+        private MethodHandle findSpecial(Method method, MethodType type,
+                                         Class<?> refc, Class<?> specialCaller)
+                throws IllegalAccessException {
+            if (Modifier.isStatic(method.getModifiers())) {
+                throw new IllegalAccessException("expected a non-static method:" + method);
+            }
+
+            if (Modifier.isPrivate(method.getModifiers())) {
+                // Since this is a private method, we'll need to also make sure that the
+                // lookup class is the same as the refering class. We've already checked that
+                // the specialCaller is the same as the special lookup class, both of these must
+                // be the same as the declaring class(*) in order to access the private method.
+                //
+                // (*) Well, this isn't true for nested classes but OpenJDK doesn't support those
+                // either.
+                if (refc != lookupClass()) {
+                    throw new IllegalAccessException("no private access for invokespecial : "
+                            + refc + ", from" + this);
+                }
+
+                // This is a private method, so there's nothing special to do.
+                MethodType handleType = type.insertParameterTypes(0, refc);
+                return createMethodHandle(method, MethodHandle.INVOKE_DIRECT, handleType);
+            }
+
+            // This is a public, protected or package-private method, which means we're expecting
+            // invoke-super semantics. We'll have to restrict the receiver type appropriately on the
+            // handle once we check that there really is a "super" relationship between them.
+            if (!method.getDeclaringClass().isAssignableFrom(specialCaller)) {
+                throw new IllegalAccessException(refc + "is not assignable from " + specialCaller);
+            }
+
+            // Note that we restrict the receiver to "specialCaller" instances.
+            MethodType handleType = type.insertParameterTypes(0, specialCaller);
+            return createMethodHandle(method, MethodHandle.INVOKE_SUPER, handleType);
+        }
+
+        /**
+         * Produces a method handle giving read access to a non-static field.
+         * The type of the method handle will have a return type of the field's
+         * value type.
+         * The method handle's single argument will be the instance containing
+         * the field.
+         * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
+         * @param name the field's name
+         * @param type the field's type
+         * @return a method handle which can load values from the field
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            return findAccessor(refc, name, type, MethodHandle.IGET);
+        }
+
+        private MethodHandle findAccessor(Class<?> refc, String name, Class<?> type, int kind)
+            throws NoSuchFieldException, IllegalAccessException {
+            final Field field = findFieldOfType(refc, name, type);
+            return findAccessor(field, refc, type, kind, true /* performAccessChecks */);
+        }
+
+        private MethodHandle findAccessor(Field field, Class<?> refc, Class<?> type, int kind,
+                                          boolean performAccessChecks)
+                throws IllegalAccessException {
+            final boolean isSetterKind = kind == MethodHandle.IPUT || kind == MethodHandle.SPUT;
+            final boolean isStaticKind = kind == MethodHandle.SGET || kind == MethodHandle.SPUT;
+            commonFieldChecks(field, refc, type, isStaticKind, performAccessChecks);
+            if (performAccessChecks) {
+                final int modifiers = field.getModifiers();
+                if (isSetterKind && Modifier.isFinal(modifiers)) {
+                    throw new IllegalAccessException("Field " + field + " is final");
+                }
+            }
+
+            final MethodType methodType;
+            switch (kind) {
+                case MethodHandle.SGET:
+                    methodType = MethodType.methodType(type);
+                    break;
+                case MethodHandle.SPUT:
+                    methodType = MethodType.methodType(void.class, type);
+                    break;
+                case MethodHandle.IGET:
+                    methodType = MethodType.methodType(type, refc);
+                    break;
+                case MethodHandle.IPUT:
+                    methodType = MethodType.methodType(void.class, refc, type);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid kind " + kind);
+            }
+            return new MethodHandleImpl(field.getArtField(), kind, methodType);
+        }
+
+        /**
+         * Produces a method handle giving write access to a non-static field.
+         * The type of the method handle will have a void return type.
+         * The method handle will take two arguments, the instance containing
+         * the field, and the value to be stored.
+         * The second argument will be of the field's value type.
+         * Access checking is performed immediately on behalf of the lookup class.
+         * @param refc the class or interface from which the method is accessed
+         * @param name the field's name
+         * @param type the field's type
+         * @return a method handle which can store values into the field
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            return findAccessor(refc, name, type, MethodHandle.IPUT);
+        }
+
+        // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+        /**
+         * Produces a VarHandle giving access to a non-static field {@code name}
+         * of type {@code type} declared in a class of type {@code recv}.
+         * The VarHandle's variable type is {@code type} and it has one
+         * coordinate type, {@code recv}.
+         * <p>
+         * Access checking is performed immediately on behalf of the lookup
+         * class.
+         * <p>
+         * Certain access modes of the returned VarHandle are unsupported under
+         * the following conditions:
+         * <ul>
+         * <li>if the field is declared {@code final}, then the write, atomic
+         *     update, numeric atomic update, and bitwise atomic update access
+         *     modes are unsupported.
+         * <li>if the field type is anything other than {@code byte},
+         *     {@code short}, {@code char}, {@code int}, {@code long},
+         *     {@code float}, or {@code double} then numeric atomic update
+         *     access modes are unsupported.
+         * <li>if the field type is anything other than {@code boolean},
+         *     {@code byte}, {@code short}, {@code char}, {@code int} or
+         *     {@code long} then bitwise atomic update access modes are
+         *     unsupported.
+         * </ul>
+         * <p>
+         * If the field is declared {@code volatile} then the returned VarHandle
+         * will override access to the field (effectively ignore the
+         * {@code volatile} declaration) in accordance to its specified
+         * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
+         * @param recv the receiver class, of type {@code R}, that declares the
+         * non-static field
+         * @param name the field's name
+         * @param type the field's type, of type {@code T}
+         * @return a VarHandle giving access to non-static fields.
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         * @since 9
+         * @hide
+         */
+        public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            final Field field = findFieldOfType(recv, name, type);
+            final boolean isStatic = false;
+            final boolean performAccessChecks = true;
+            commonFieldChecks(field, recv, type, isStatic, performAccessChecks);
+            return FieldVarHandle.create(field);
+        }
+        // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+        // BEGIN Android-added: Common field resolution and access check methods.
+        private Field findFieldOfType(final Class<?> refc, String name, Class<?> type)
+                throws NoSuchFieldException {
+            Field field = null;
+
+            // Search refc and super classes for the field.
+            for (Class<?> cls = refc; cls != null; cls = cls.getSuperclass()) {
+                try {
+                    field = cls.getDeclaredField(name);
+                    break;
+                } catch (NoSuchFieldException e) {
+                }
+            }
+
+            if (field == null) {
+                // Force failure citing refc.
+                field = refc.getDeclaredField(name);
+            }
+
+            final Class<?> fieldType = field.getType();
+            if (fieldType != type) {
+                throw new NoSuchFieldException(name);
+            }
+            return field;
+        }
+
+        private void commonFieldChecks(Field field, Class<?> refc, Class<?> type,
+                                       boolean isStatic, boolean performAccessChecks)
+                throws IllegalAccessException {
+            final int modifiers = field.getModifiers();
+            if (performAccessChecks) {
+                checkAccess(refc, field.getDeclaringClass(), modifiers, field.getName());
+            }
+            if (Modifier.isStatic(modifiers) != isStatic) {
+                String reason = "Field " + field + " is " +
+                        (isStatic ? "not " : "") + "static";
+                throw new IllegalAccessException(reason);
+            }
+        }
+        // END Android-added: Common field resolution and access check methods.
+
+        /**
+         * Produces a method handle giving read access to a static field.
+         * The type of the method handle will have a return type of the field's
+         * value type.
+         * The method handle will take no arguments.
+         * Access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
+         * @param refc the class or interface from which the method is accessed
+         * @param name the field's name
+         * @param type the field's type
+         * @return a method handle which can load values from the field
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            return findAccessor(refc, name, type, MethodHandle.SGET);
+        }
+
+        /**
+         * Produces a method handle giving write access to a static field.
+         * The type of the method handle will have a void return type.
+         * The method handle will take a single
+         * argument, of the field's value type, the value to be stored.
+         * Access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
+         * @param refc the class or interface from which the method is accessed
+         * @param name the field's name
+         * @param type the field's type
+         * @return a method handle which can store values into the field
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            return findAccessor(refc, name, type, MethodHandle.SPUT);
+        }
+
+        // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+        /**
+         * Produces a VarHandle giving access to a static field {@code name} of
+         * type {@code type} declared in a class of type {@code decl}.
+         * The VarHandle's variable type is {@code type} and it has no
+         * coordinate types.
+         * <p>
+         * Access checking is performed immediately on behalf of the lookup
+         * class.
+         * <p>
+         * If the returned VarHandle is operated on, the declaring class will be
+         * initialized, if it has not already been initialized.
+         * <p>
+         * Certain access modes of the returned VarHandle are unsupported under
+         * the following conditions:
+         * <ul>
+         * <li>if the field is declared {@code final}, then the write, atomic
+         *     update, numeric atomic update, and bitwise atomic update access
+         *     modes are unsupported.
+         * <li>if the field type is anything other than {@code byte},
+         *     {@code short}, {@code char}, {@code int}, {@code long},
+         *     {@code float}, or {@code double}, then numeric atomic update
+         *     access modes are unsupported.
+         * <li>if the field type is anything other than {@code boolean},
+         *     {@code byte}, {@code short}, {@code char}, {@code int} or
+         *     {@code long} then bitwise atomic update access modes are
+         *     unsupported.
+         * </ul>
+         * <p>
+         * If the field is declared {@code volatile} then the returned VarHandle
+         * will override access to the field (effectively ignore the
+         * {@code volatile} declaration) in accordance to its specified
+         * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
+         * @param decl the class that declares the static field
+         * @param name the field's name
+         * @param type the field's type, of type {@code T}
+         * @return a VarHandle giving access to a static field
+         * @throws NoSuchFieldException if the field does not exist
+         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         * @since 9
+         * @hide
+         */
+        public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+            final Field field = findFieldOfType(decl, name, type);
+            final boolean isStatic = true;
+            final boolean performAccessChecks = true;
+            commonFieldChecks(field, decl, type, isStatic, performAccessChecks);
+            return FieldVarHandle.create(field);
+        }
+        // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+        /**
+         * Produces an early-bound method handle for a non-static method.
+         * The receiver must have a supertype {@code defc} in which a method
+         * of the given name and type is accessible to the lookup class.
+         * The method and all its argument types must be accessible to the lookup object.
+         * The type of the method handle will be that of the method,
+         * without any insertion of an additional receiver parameter.
+         * The given receiver will be bound into the method handle,
+         * so that every call to the method handle will invoke the
+         * requested method on the given receiver.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set
+         * <em>and</em> the trailing array argument is not the only argument.
+         * (If the trailing array argument is the only argument,
+         * the given receiver value will be bound to it.)
+         * <p>
+         * This is equivalent to the following code:
+         * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle mh0 = lookup().findVirtual(defc, name, type);
+MethodHandle mh1 = mh0.bindTo(receiver);
+MethodType mt1 = mh1.type();
+if (mh0.isVarargsCollector())
+  mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
+return mh1;
+         * }</pre></blockquote>
+         * where {@code defc} is either {@code receiver.getClass()} or a super
+         * type of that class, in which the requested method is accessible
+         * to the lookup class.
+         * (Note that {@code bindTo} does not preserve variable arity.)
+         * @param receiver the object from which the method is accessed
+         * @param name the name of the method
+         * @param type the type of the method, with the receiver argument omitted
+         * @return the desired method handle
+         * @throws NoSuchMethodException if the method does not exist
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException if any argument is null
+         * @see MethodHandle#bindTo
+         * @see #findVirtual
+         */
+        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            MethodHandle handle = findVirtual(receiver.getClass(), name, type);
+            MethodHandle adapter = handle.bindTo(receiver);
+            MethodType adapterType = adapter.type();
+            if (handle.isVarargsCollector()) {
+                adapter = adapter.asVarargsCollector(
+                        adapterType.parameterType(adapterType.parameterCount() - 1));
+            }
+
+            return adapter;
+        }
+
+        /**
+         * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+         * to <i>m</i>, if the lookup class has permission.
+         * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
+         * If <i>m</i> is virtual, overriding is respected on every call.
+         * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
+         * The type of the method handle will be that of the method,
+         * with the receiver type prepended (but only if it is non-static).
+         * If the method's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class.
+         * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If <i>m</i> is static, and
+         * if the returned method handle is invoked, the method's class will
+         * be initialized, if it has not already been initialized.
+         * @param m the reflected method
+         * @return a method handle which can invoke the reflected method
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @throws NullPointerException if the argument is null
+         */
+        public MethodHandle unreflect(Method m) throws IllegalAccessException {
+            if (m == null) {
+                throw new NullPointerException("m == null");
+            }
+
+            MethodType methodType = MethodType.methodType(m.getReturnType(),
+                    m.getParameterTypes());
+
+            // We should only perform access checks if setAccessible hasn't been called yet.
+            if (!m.isAccessible()) {
+                checkAccess(m.getDeclaringClass(), m.getDeclaringClass(), m.getModifiers(),
+                        m.getName());
+            }
+
+            if (Modifier.isStatic(m.getModifiers())) {
+                return createMethodHandle(m, MethodHandle.INVOKE_STATIC, methodType);
+            } else {
+                methodType = methodType.insertParameterTypes(0, m.getDeclaringClass());
+                return createMethodHandle(m, MethodHandle.INVOKE_VIRTUAL, methodType);
+            }
+        }
+
+        /**
+         * Produces a method handle for a reflected method.
+         * It will bypass checks for overriding methods on the receiver,
+         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+         * instruction from within the explicitly specified {@code specialCaller}.
+         * The type of the method handle will be that of the method,
+         * with a suitably restricted receiver type prepended.
+         * (The receiver type will be {@code specialCaller} or a subtype.)
+         * If the method's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class,
+         * as if {@code invokespecial} instruction were being linked.
+         * <p>
+         * Before method resolution,
+         * if the explicitly specified caller class is not identical with the
+         * lookup class, or if this lookup object does not have
+         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
+         * privileges, the access fails.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * @param m the reflected method
+         * @param specialCaller the class nominally calling the method
+         * @return a method handle which can invoke the reflected method
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @throws NullPointerException if any argument is null
+         */
+        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
+            if (m == null) {
+                throw new NullPointerException("m == null");
+            }
+
+            if (specialCaller == null) {
+                throw new NullPointerException("specialCaller == null");
+            }
+
+            if (!m.isAccessible()) {
+                // Android-changed: Match Java language 9 behavior where unreflectSpecial continues
+                // to require exact caller lookupClass match.
+                checkSpecialCaller(specialCaller, null);
+            }
+
+            final MethodType methodType = MethodType.methodType(m.getReturnType(),
+                    m.getParameterTypes());
+            return findSpecial(m, methodType, m.getDeclaringClass() /* refc */, specialCaller);
+        }
+
+        /**
+         * Produces a method handle for a reflected constructor.
+         * The type of the method handle will be that of the constructor,
+         * with the return type changed to the declaring class.
+         * The method handle will perform a {@code newInstance} operation,
+         * creating a new instance of the constructor's class on the
+         * arguments passed to the method handle.
+         * <p>
+         * If the constructor's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * The returned method handle will have
+         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the constructor's class will
+         * be initialized, if it has not already been initialized.
+         * @param c the reflected constructor
+         * @return a method handle which can invoke the reflected constructor
+         * @throws IllegalAccessException if access checking fails
+         *                                or if the method's variable arity modifier bit
+         *                                is set and {@code asVarargsCollector} fails
+         * @throws NullPointerException if the argument is null
+         */
+        public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
+            if (c == null) {
+                throw new NullPointerException("c == null");
+            }
+
+            if (!c.isAccessible()) {
+                checkAccess(c.getDeclaringClass(), c.getDeclaringClass(), c.getModifiers(),
+                        c.getName());
+            }
+
+            return createMethodHandleForConstructor(c);
+        }
+
+        /**
+         * Produces a method handle giving read access to a reflected field.
+         * The type of the method handle will have a return type of the field's
+         * value type.
+         * If the field is static, the method handle will take no arguments.
+         * Otherwise, its single argument will be the instance containing
+         * the field.
+         * If the field's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the field is static, and
+         * if the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
+         * @param f the reflected field
+         * @return a method handle which can load values from the reflected field
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
+         */
+        public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
+            return findAccessor(f, f.getDeclaringClass(), f.getType(),
+                    Modifier.isStatic(f.getModifiers()) ? MethodHandle.SGET : MethodHandle.IGET,
+                    !f.isAccessible() /* performAccessChecks */);
+        }
+
+        /**
+         * Produces a method handle giving write access to a reflected field.
+         * The type of the method handle will have a void return type.
+         * If the field is static, the method handle will take a single
+         * argument, of the field's value type, the value to be stored.
+         * Otherwise, the two arguments will be the instance containing
+         * the field, and the value to be stored.
+         * If the field's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the field is static, and
+         * if the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
+         * @param f the reflected field
+         * @return a method handle which can store values into the reflected field
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
+         */
+        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
+            return findAccessor(f, f.getDeclaringClass(), f.getType(),
+                    Modifier.isStatic(f.getModifiers()) ? MethodHandle.SPUT : MethodHandle.IPUT,
+                    !f.isAccessible() /* performAccessChecks */);
+        }
+
+        // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+        /**
+         * Produces a VarHandle giving access to a reflected field {@code f}
+         * of type {@code T} declared in a class of type {@code R}.
+         * The VarHandle's variable type is {@code T}.
+         * If the field is non-static the VarHandle has one coordinate type,
+         * {@code R}.  Otherwise, the field is static, and the VarHandle has no
+         * coordinate types.
+         * <p>
+         * Access checking is performed immediately on behalf of the lookup
+         * class, regardless of the value of the field's {@code accessible}
+         * flag.
+         * <p>
+         * If the field is static, and if the returned VarHandle is operated
+         * on, the field's declaring class will be initialized, if it has not
+         * already been initialized.
+         * <p>
+         * Certain access modes of the returned VarHandle are unsupported under
+         * the following conditions:
+         * <ul>
+         * <li>if the field is declared {@code final}, then the write, atomic
+         *     update, numeric atomic update, and bitwise atomic update access
+         *     modes are unsupported.
+         * <li>if the field type is anything other than {@code byte},
+         *     {@code short}, {@code char}, {@code int}, {@code long},
+         *     {@code float}, or {@code double} then numeric atomic update
+         *     access modes are unsupported.
+         * <li>if the field type is anything other than {@code boolean},
+         *     {@code byte}, {@code short}, {@code char}, {@code int} or
+         *     {@code long} then bitwise atomic update access modes are
+         *     unsupported.
+         * </ul>
+         * <p>
+         * If the field is declared {@code volatile} then the returned VarHandle
+         * will override access to the field (effectively ignore the
+         * {@code volatile} declaration) in accordance to its specified
+         * access modes.
+         * <p>
+         * If the field type is {@code float} or {@code double} then numeric
+         * and atomic update access modes compare values using their bitwise
+         * representation (see {@link Float#floatToRawIntBits} and
+         * {@link Double#doubleToRawLongBits}, respectively).
+         * @apiNote
+         * Bitwise comparison of {@code float} values or {@code double} values,
+         * as performed by the numeric and atomic update access modes, differ
+         * from the primitive {@code ==} operator and the {@link Float#equals}
+         * and {@link Double#equals} methods, specifically with respect to
+         * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+         * Care should be taken when performing a compare and set or a compare
+         * and exchange operation with such values since the operation may
+         * unexpectedly fail.
+         * There are many possible NaN values that are considered to be
+         * {@code NaN} in Java, although no IEEE 754 floating-point operation
+         * provided by Java can distinguish between them.  Operation failure can
+         * occur if the expected or witness value is a NaN value and it is
+         * transformed (perhaps in a platform specific manner) into another NaN
+         * value, and thus has a different bitwise representation (see
+         * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+         * details).
+         * The values {@code -0.0} and {@code +0.0} have different bitwise
+         * representations but are considered equal when using the primitive
+         * {@code ==} operator.  Operation failure can occur if, for example, a
+         * numeric algorithm computes an expected value to be say {@code -0.0}
+         * and previously computed the witness value to be say {@code +0.0}.
+         * @param f the reflected field, with a field of type {@code T}, and
+         * a declaring class of type {@code R}
+         * @return a VarHandle giving access to non-static fields or a static
+         * field
+         * @throws IllegalAccessException if access checking fails
+         * @throws NullPointerException if the argument is null
+         * @since 9
+         * @hide
+         */
+        public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
+            final boolean isStatic = Modifier.isStatic(f.getModifiers());
+            final boolean performAccessChecks = true;
+            commonFieldChecks(f, f.getDeclaringClass(), f.getType(), isStatic, performAccessChecks);
+            return FieldVarHandle.create(f);
+        }
+        // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+        /**
+         * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+         * created by this lookup object or a similar one.
+         * Security and access checks are performed to ensure that this lookup object
+         * is capable of reproducing the target method handle.
+         * This means that the cracking may fail if target is a direct method handle
+         * but was created by an unrelated lookup object.
+         * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
+         * and was created by a lookup object for a different class.
+         * @param target a direct method handle to crack into symbolic reference components
+         * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
+         * @exception SecurityException if a security manager is present and it
+         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
+         * @exception NullPointerException if the target is {@code null}
+         * @see MethodHandleInfo
+         * @since 1.8
+         */
+        public MethodHandleInfo revealDirect(MethodHandle target) {
+            MethodHandleImpl directTarget = getMethodHandleImpl(target);
+            MethodHandleInfo info = directTarget.reveal();
+
+            try {
+                checkAccess(lookupClass(), info.getDeclaringClass(), info.getModifiers(),
+                        info.getName());
+            } catch (IllegalAccessException exception) {
+                throw new IllegalArgumentException("Unable to access memeber.", exception);
+            }
+
+            return info;
+        }
+
+        private boolean hasPrivateAccess() {
+            return (allowedModes & PRIVATE) != 0;
+        }
+
+        /** Check public/protected/private bits on the symbolic reference class and its member. */
+        void checkAccess(Class<?> refc, Class<?> defc, int mods, String methName)
+                throws IllegalAccessException {
+            int allowedModes = this.allowedModes;
+
+            if (Modifier.isProtected(mods) &&
+                    defc == Object.class &&
+                    "clone".equals(methName) &&
+                    refc.isArray()) {
+                // The JVM does this hack also.
+                // (See ClassVerifier::verify_invoke_instructions
+                // and LinkResolver::check_method_accessability.)
+                // Because the JVM does not allow separate methods on array types,
+                // there is no separate method for int[].clone.
+                // All arrays simply inherit Object.clone.
+                // But for access checking logic, we make Object.clone
+                // (normally protected) appear to be public.
+                // Later on, when the DirectMethodHandle is created,
+                // its leading argument will be restricted to the
+                // requested array type.
+                // N.B. The return type is not adjusted, because
+                // that is *not* the bytecode behavior.
+                mods ^= Modifier.PROTECTED | Modifier.PUBLIC;
+            }
+
+            if (Modifier.isProtected(mods) && Modifier.isConstructor(mods)) {
+                // cannot "new" a protected ctor in a different package
+                mods ^= Modifier.PROTECTED;
+            }
+
+            if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
+                return;  // common case
+            int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
+            if ((requestedModes & allowedModes) != 0) {
+                if (VerifyAccess.isMemberAccessible(refc, defc, mods, lookupClass(), allowedModes))
+                    return;
+            } else {
+                // Protected members can also be checked as if they were package-private.
+                if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
+                        && VerifyAccess.isSamePackage(defc, lookupClass()))
+                    return;
+            }
+
+            throwMakeAccessException(accessFailedMessage(refc, defc, mods), this);
+        }
+
+        String accessFailedMessage(Class<?> refc, Class<?> defc, int mods) {
+            // check the class first:
+            boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
+                    (defc == refc ||
+                            Modifier.isPublic(refc.getModifiers())));
+            if (!classOK && (allowedModes & PACKAGE) != 0) {
+                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
+                        (defc == refc ||
+                                VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
+            }
+            if (!classOK)
+                return "class is not public";
+            if (Modifier.isPublic(mods))
+                return "access to public member failed";  // (how?)
+            if (Modifier.isPrivate(mods))
+                return "member is private";
+            if (Modifier.isProtected(mods))
+                return "member is protected";
+            return "member is private to package";
+        }
+
+        // Android-changed: checkSpecialCaller assumes that ALLOW_NESTMATE_ACCESS = false,
+        // as in upstream OpenJDK.
+        //
+        // private static final boolean ALLOW_NESTMATE_ACCESS = false;
+
+        // Android-changed: Match java language 9 behavior allowing special access if the reflected
+        // class (called 'refc', the class from which the method is being accessed) is an interface
+        // and is implemented by the caller.
+        private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
+            // Android-changed: No support for TRUSTED lookups. Also construct the
+            // IllegalAccessException by hand because the upstream code implicitly assumes
+            // that the lookupClass == specialCaller.
+            //
+            // if (allowedModes == TRUSTED)  return;
+            boolean isInterfaceLookup = (refc != null &&
+                                         refc.isInterface() &&
+                                         refc.isAssignableFrom(specialCaller));
+            if (!hasPrivateAccess() || (specialCaller != lookupClass() && !isInterfaceLookup)) {
+                throw new IllegalAccessException("no private access for invokespecial : "
+                        + specialCaller + ", from" + this);
+            }
+        }
+
+        private void throwMakeAccessException(String message, Object from) throws
+                IllegalAccessException{
+            message = message + ": "+ toString();
+            if (from != null)  message += ", from " + from;
+            throw new IllegalAccessException(message);
+        }
+
+        private void checkReturnType(Method method, MethodType methodType)
+                throws NoSuchMethodException {
+            if (method.getReturnType() != methodType.rtype()) {
+                throw new NoSuchMethodException(method.getName() + methodType);
+            }
+        }
+    }
+
+    /**
+     * "Cracks" {@code target} to reveal the underlying {@code MethodHandleImpl}.
+     */
+    private static MethodHandleImpl getMethodHandleImpl(MethodHandle target) {
+        // Special case : We implement handles to constructors as transformers,
+        // so we must extract the underlying handle from the transformer.
+        if (target instanceof Transformers.Construct) {
+            target = ((Transformers.Construct) target).getConstructorHandle();
+        }
+
+        // Special case: Var-args methods are also implemented as Transformers,
+        // so we should get the underlying handle in that case as well.
+        if (target instanceof Transformers.VarargsCollector) {
+            target = target.asFixedArity();
+        }
+
+        if (target instanceof MethodHandleImpl) {
+            return (MethodHandleImpl) target;
+        }
+
+        throw new IllegalArgumentException(target + " is not a direct handle");
+    }
+
+    // BEGIN Android-added: method to check if a class is an array.
+    private static void checkClassIsArray(Class<?> c) {
+        if (!c.isArray()) {
+            throw new IllegalArgumentException("Not an array type: " + c);
+        }
+    }
+
+    private static void checkTypeIsViewable(Class<?> componentType) {
+        if (componentType == short.class ||
+            componentType == char.class ||
+            componentType == int.class ||
+            componentType == long.class ||
+            componentType == float.class ||
+            componentType == double.class) {
+            return;
+        }
+        throw new UnsupportedOperationException("Component type not supported: " + componentType);
+    }
+    // END Android-added: method to check if a class is an array.
+
+    /**
+     * Produces a method handle giving read access to elements of an array.
+     * The type of the method handle will have a return type of the array's
+     * element type.  Its first argument will be the array type,
+     * and the second will be {@code int}.
+     * @param arrayClass an array type
+     * @return a method handle which can load values from the given array type
+     * @throws NullPointerException if the argument is null
+     * @throws  IllegalArgumentException if arrayClass is not an array type
+     */
+    public static
+    MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
+        checkClassIsArray(arrayClass);
+        final Class<?> componentType = arrayClass.getComponentType();
+        if (componentType.isPrimitive()) {
+            try {
+                return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
+                        "arrayElementGetter",
+                        MethodType.methodType(componentType, arrayClass, int.class));
+            } catch (NoSuchMethodException | IllegalAccessException exception) {
+                throw new AssertionError(exception);
+            }
+        }
+
+        return new Transformers.ReferenceArrayElementGetter(arrayClass);
+    }
+
+    /** @hide */ public static byte arrayElementGetter(byte[] array, int i) { return array[i]; }
+    /** @hide */ public static boolean arrayElementGetter(boolean[] array, int i) { return array[i]; }
+    /** @hide */ public static char arrayElementGetter(char[] array, int i) { return array[i]; }
+    /** @hide */ public static short arrayElementGetter(short[] array, int i) { return array[i]; }
+    /** @hide */ public static int arrayElementGetter(int[] array, int i) { return array[i]; }
+    /** @hide */ public static long arrayElementGetter(long[] array, int i) { return array[i]; }
+    /** @hide */ public static float arrayElementGetter(float[] array, int i) { return array[i]; }
+    /** @hide */ public static double arrayElementGetter(double[] array, int i) { return array[i]; }
+
+    /**
+     * Produces a method handle giving write access to elements of an array.
+     * The type of the method handle will have a void return type.
+     * Its last argument will be the array's element type.
+     * The first and second arguments will be the array type and int.
+     * @param arrayClass the class of an array
+     * @return a method handle which can store values into the array type
+     * @throws NullPointerException if the argument is null
+     * @throws IllegalArgumentException if arrayClass is not an array type
+     */
+    public static
+    MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
+        checkClassIsArray(arrayClass);
+        final Class<?> componentType = arrayClass.getComponentType();
+        if (componentType.isPrimitive()) {
+            try {
+                return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
+                        "arrayElementSetter",
+                        MethodType.methodType(void.class, arrayClass, int.class, componentType));
+            } catch (NoSuchMethodException | IllegalAccessException exception) {
+                throw new AssertionError(exception);
+            }
+        }
+
+        return new Transformers.ReferenceArrayElementSetter(arrayClass);
+    }
+
+    /** @hide */
+    public static void arrayElementSetter(byte[] array, int i, byte val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(boolean[] array, int i, boolean val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(char[] array, int i, char val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(short[] array, int i, short val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(int[] array, int i, int val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(long[] array, int i, long val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(float[] array, int i, float val) { array[i] = val; }
+    /** @hide */
+    public static void arrayElementSetter(double[] array, int i, double val) { array[i] = val; }
+
+    // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory methods.
+    /**
+     * Produces a VarHandle giving access to elements of an array of type
+     * {@code arrayClass}.  The VarHandle's variable type is the component type
+     * of {@code arrayClass} and the list of coordinate types is
+     * {@code (arrayClass, int)}, where the {@code int} coordinate type
+     * corresponds to an argument that is an index into an array.
+     * <p>
+     * Certain access modes of the returned VarHandle are unsupported under
+     * the following conditions:
+     * <ul>
+     * <li>if the component type is anything other than {@code byte},
+     *     {@code short}, {@code char}, {@code int}, {@code long},
+     *     {@code float}, or {@code double} then numeric atomic update access
+     *     modes are unsupported.
+     * <li>if the field type is anything other than {@code boolean},
+     *     {@code byte}, {@code short}, {@code char}, {@code int} or
+     *     {@code long} then bitwise atomic update access modes are
+     *     unsupported.
+     * </ul>
+     * <p>
+     * If the component type is {@code float} or {@code double} then numeric
+     * and atomic update access modes compare values using their bitwise
+     * representation (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
+     * @apiNote
+     * Bitwise comparison of {@code float} values or {@code double} values,
+     * as performed by the numeric and atomic update access modes, differ
+     * from the primitive {@code ==} operator and the {@link Float#equals}
+     * and {@link Double#equals} methods, specifically with respect to
+     * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+     * Care should be taken when performing a compare and set or a compare
+     * and exchange operation with such values since the operation may
+     * unexpectedly fail.
+     * There are many possible NaN values that are considered to be
+     * {@code NaN} in Java, although no IEEE 754 floating-point operation
+     * provided by Java can distinguish between them.  Operation failure can
+     * occur if the expected or witness value is a NaN value and it is
+     * transformed (perhaps in a platform specific manner) into another NaN
+     * value, and thus has a different bitwise representation (see
+     * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+     * details).
+     * The values {@code -0.0} and {@code +0.0} have different bitwise
+     * representations but are considered equal when using the primitive
+     * {@code ==} operator.  Operation failure can occur if, for example, a
+     * numeric algorithm computes an expected value to be say {@code -0.0}
+     * and previously computed the witness value to be say {@code +0.0}.
+     * @param arrayClass the class of an array, of type {@code T[]}
+     * @return a VarHandle giving access to elements of an array
+     * @throws NullPointerException if the arrayClass is null
+     * @throws IllegalArgumentException if arrayClass is not an array type
+     * @since 9
+     * @hide
+     */
+    public static
+    VarHandle arrayElementVarHandle(Class<?> arrayClass) throws IllegalArgumentException {
+        checkClassIsArray(arrayClass);
+        return ArrayElementVarHandle.create(arrayClass);
+    }
+
+    /**
+     * Produces a VarHandle giving access to elements of a {@code byte[]} array
+     * viewed as if it were a different primitive array type, such as
+     * {@code int[]} or {@code long[]}.
+     * The VarHandle's variable type is the component type of
+     * {@code viewArrayClass} and the list of coordinate types is
+     * {@code (byte[], int)}, where the {@code int} coordinate type
+     * corresponds to an argument that is an index into a {@code byte[]} array.
+     * The returned VarHandle accesses bytes at an index in a {@code byte[]}
+     * array, composing bytes to or from a value of the component type of
+     * {@code viewArrayClass} according to the given endianness.
+     * <p>
+     * The supported component types (variables types) are {@code short},
+     * {@code char}, {@code int}, {@code long}, {@code float} and
+     * {@code double}.
+     * <p>
+     * Access of bytes at a given index will result in an
+     * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+     * or greater than the {@code byte[]} array length minus the size (in bytes)
+     * of {@code T}.
+     * <p>
+     * Access of bytes at an index may be aligned or misaligned for {@code T},
+     * with respect to the underlying memory address, {@code A} say, associated
+     * with the array and index.
+     * If access is misaligned then access for anything other than the
+     * {@code get} and {@code set} access modes will result in an
+     * {@code IllegalStateException}.  In such cases atomic access is only
+     * guaranteed with respect to the largest power of two that divides the GCD
+     * of {@code A} and the size (in bytes) of {@code T}.
+     * If access is aligned then following access modes are supported and are
+     * guaranteed to support atomic access:
+     * <ul>
+     * <li>read write access modes for all {@code T}, with the exception of
+     *     access modes {@code get} and {@code set} for {@code long} and
+     *     {@code double} on 32-bit platforms.
+     * <li>atomic update access modes for {@code int}, {@code long},
+     *     {@code float} or {@code double}.
+     *     (Future major platform releases of the JDK may support additional
+     *     types for certain currently unsupported access modes.)
+     * <li>numeric atomic update access modes for {@code int} and {@code long}.
+     *     (Future major platform releases of the JDK may support additional
+     *     numeric types for certain currently unsupported access modes.)
+     * <li>bitwise atomic update access modes for {@code int} and {@code long}.
+     *     (Future major platform releases of the JDK may support additional
+     *     numeric types for certain currently unsupported access modes.)
+     * </ul>
+     * <p>
+     * Misaligned access, and therefore atomicity guarantees, may be determined
+     * for {@code byte[]} arrays without operating on a specific array.  Given
+     * an {@code index}, {@code T} and it's corresponding boxed type,
+     * {@code T_BOX}, misalignment may be determined as follows:
+     * <pre>{@code
+     * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
+     * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
+     *     alignmentOffset(0, sizeOfT);
+     * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
+     * boolean isMisaligned = misalignedAtIndex != 0;
+     * }</pre>
+     * <p>
+     * If the variable type is {@code float} or {@code double} then atomic
+     * update access modes compare values using their bitwise representation
+     * (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
+     * @param viewArrayClass the view array class, with a component type of
+     * type {@code T}
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code byte} array
+     * @return a VarHandle giving access to elements of a {@code byte[]} array
+     * viewed as if elements corresponding to the components type of the view
+     * array class
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
+     * @throws IllegalArgumentException if viewArrayClass is not an array type
+     * @throws UnsupportedOperationException if the component type of
+     * viewArrayClass is not supported as a variable type
+     * @since 9
+     * @hide
+     */
+    public static
+    VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
+                                     ByteOrder byteOrder) throws IllegalArgumentException {
+        checkClassIsArray(viewArrayClass);
+        checkTypeIsViewable(viewArrayClass.getComponentType());
+        return ByteArrayViewVarHandle.create(viewArrayClass, byteOrder);
+    }
+
+    /**
+     * Produces a VarHandle giving access to elements of a {@code ByteBuffer}
+     * viewed as if it were an array of elements of a different primitive
+     * component type to that of {@code byte}, such as {@code int[]} or
+     * {@code long[]}.
+     * The VarHandle's variable type is the component type of
+     * {@code viewArrayClass} and the list of coordinate types is
+     * {@code (ByteBuffer, int)}, where the {@code int} coordinate type
+     * corresponds to an argument that is an index into a {@code byte[]} array.
+     * The returned VarHandle accesses bytes at an index in a
+     * {@code ByteBuffer}, composing bytes to or from a value of the component
+     * type of {@code viewArrayClass} according to the given endianness.
+     * <p>
+     * The supported component types (variables types) are {@code short},
+     * {@code char}, {@code int}, {@code long}, {@code float} and
+     * {@code double}.
+     * <p>
+     * Access will result in a {@code ReadOnlyBufferException} for anything
+     * other than the read access modes if the {@code ByteBuffer} is read-only.
+     * <p>
+     * Access of bytes at a given index will result in an
+     * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+     * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
+     * {@code T}.
+     * <p>
+     * Access of bytes at an index may be aligned or misaligned for {@code T},
+     * with respect to the underlying memory address, {@code A} say, associated
+     * with the {@code ByteBuffer} and index.
+     * If access is misaligned then access for anything other than the
+     * {@code get} and {@code set} access modes will result in an
+     * {@code IllegalStateException}.  In such cases atomic access is only
+     * guaranteed with respect to the largest power of two that divides the GCD
+     * of {@code A} and the size (in bytes) of {@code T}.
+     * If access is aligned then following access modes are supported and are
+     * guaranteed to support atomic access:
+     * <ul>
+     * <li>read write access modes for all {@code T}, with the exception of
+     *     access modes {@code get} and {@code set} for {@code long} and
+     *     {@code double} on 32-bit platforms.
+     * <li>atomic update access modes for {@code int}, {@code long},
+     *     {@code float} or {@code double}.
+     *     (Future major platform releases of the JDK may support additional
+     *     types for certain currently unsupported access modes.)
+     * <li>numeric atomic update access modes for {@code int} and {@code long}.
+     *     (Future major platform releases of the JDK may support additional
+     *     numeric types for certain currently unsupported access modes.)
+     * <li>bitwise atomic update access modes for {@code int} and {@code long}.
+     *     (Future major platform releases of the JDK may support additional
+     *     numeric types for certain currently unsupported access modes.)
+     * </ul>
+     * <p>
+     * Misaligned access, and therefore atomicity guarantees, may be determined
+     * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an
+     * {@code index}, {@code T} and it's corresponding boxed type,
+     * {@code T_BOX}, as follows:
+     * <pre>{@code
+     * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
+     * ByteBuffer bb = ...
+     * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
+     * boolean isMisaligned = misalignedAtIndex != 0;
+     * }</pre>
+     * <p>
+     * If the variable type is {@code float} or {@code double} then atomic
+     * update access modes compare values using their bitwise representation
+     * (see {@link Float#floatToRawIntBits} and
+     * {@link Double#doubleToRawLongBits}, respectively).
+     * @param viewArrayClass the view array class, with a component type of
+     * type {@code T}
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code ByteBuffer} (Note this overrides the
+     * endianness of a {@code ByteBuffer})
+     * @return a VarHandle giving access to elements of a {@code ByteBuffer}
+     * viewed as if elements corresponding to the components type of the view
+     * array class
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
+     * @throws IllegalArgumentException if viewArrayClass is not an array type
+     * @throws UnsupportedOperationException if the component type of
+     * viewArrayClass is not supported as a variable type
+     * @since 9
+     * @hide
+     */
+    public static
+    VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
+                                      ByteOrder byteOrder) throws IllegalArgumentException {
+        checkClassIsArray(viewArrayClass);
+        checkTypeIsViewable(viewArrayClass.getComponentType());
+        return ByteBufferViewVarHandle.create(viewArrayClass, byteOrder);
+    }
+    // END Android-changed: OpenJDK 9+181 VarHandle API factory methods.
+
+    /// method handle invocation (reflective style)
+
+    /**
+     * Produces a method handle which will invoke any method handle of the
+     * given {@code type}, with a given number of trailing arguments replaced by
+     * a single trailing {@code Object[]} array.
+     * The resulting invoker will be a method handle with the following
+     * arguments:
+     * <ul>
+     * <li>a single {@code MethodHandle} target
+     * <li>zero or more leading values (counted by {@code leadingArgCount})
+     * <li>an {@code Object[]} array containing trailing arguments
+     * </ul>
+     * <p>
+     * The invoker will invoke its target like a call to {@link MethodHandle#invoke invoke} with
+     * the indicated {@code type}.
+     * That is, if the target is exactly of the given {@code type}, it will behave
+     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
+     * is used to convert the target to the required {@code type}.
+     * <p>
+     * The type of the returned invoker will not be the given {@code type}, but rather
+     * will have all parameters except the first {@code leadingArgCount}
+     * replaced by a single array of type {@code Object[]}, which will be
+     * the final parameter.
+     * <p>
+     * Before invoking its target, the invoker will spread the final array, apply
+     * reference casts as necessary, and unbox and widen primitive arguments.
+     * If, when the invoker is called, the supplied array argument does
+     * not have the correct number of elements, the invoker will throw
+     * an {@link IllegalArgumentException} instead of invoking the target.
+     * <p>
+     * This method is equivalent to the following code (though it may be more efficient):
+     * <blockquote><pre>{@code
+MethodHandle invoker = MethodHandles.invoker(type);
+int spreadArgCount = type.parameterCount() - leadingArgCount;
+invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+return invoker;
+     * }</pre></blockquote>
+     * This method throws no reflective or security exceptions.
+     * @param type the desired target type
+     * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
+     * @return a method handle suitable for invoking any method handle of the given type
+     * @throws NullPointerException if {@code type} is null
+     * @throws IllegalArgumentException if {@code leadingArgCount} is not in
+     *                  the range from 0 to {@code type.parameterCount()} inclusive,
+     *                  or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     */
+    static public
+    MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
+        if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
+            throw newIllegalArgumentException("bad argument count", leadingArgCount);
+
+        MethodHandle invoker = MethodHandles.invoker(type);
+        int spreadArgCount = type.parameterCount() - leadingArgCount;
+        invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+        return invoker;
+    }
+
+    /**
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
+     * The resulting invoker will have a type which is
+     * exactly equal to the desired type, except that it will accept
+     * an additional leading argument of type {@code MethodHandle}.
+     * <p>
+     * This method is equivalent to the following code (though it may be more efficient):
+     * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * Invoker method handles can be useful when working with variable method handles
+     * of unknown types.
+     * For example, to emulate an {@code invokeExact} call to a variable method
+     * handle {@code M}, extract its type {@code T},
+     * look up the invoker method {@code X} for {@code T},
+     * and call the invoker method, as {@code X.invoke(T, A...)}.
+     * (It would not work to call {@code X.invokeExact}, since the type {@code T}
+     * is unknown.)
+     * If spreading, collecting, or other argument transformations are required,
+     * they can be applied once to the invoker {@code X} and reused on many {@code M}
+     * method handle values, as long as they are compatible with the type of {@code X}.
+     * <p style="font-size:smaller;">
+     * <em>(Note:  The invoker method is not available via the Core Reflection API.
+     * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+     * on the declared {@code invokeExact} or {@code invoke} method will raise an
+     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
+     * <p>
+     * This method throws no reflective or security exceptions.
+     * @param type the desired target type
+     * @return a method handle suitable for invoking any method handle of the given type
+     * @throws IllegalArgumentException if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     */
+    static public
+    MethodHandle exactInvoker(MethodType type) {
+        return new Transformers.Invoker(type, true /* isExactInvoker */);
+    }
+
+    /**
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
+     * The resulting invoker will have a type which is
+     * exactly equal to the desired type, except that it will accept
+     * an additional leading argument of type {@code MethodHandle}.
+     * <p>
+     * Before invoking its target, if the target differs from the expected type,
+     * the invoker will apply reference casts as
+     * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
+     * Similarly, the return value will be converted as necessary.
+     * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
+     * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
+     * <p>
+     * This method is equivalent to the following code (though it may be more efficient):
+     * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)}
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * A {@linkplain MethodType#genericMethodType general method type} is one which
+     * mentions only {@code Object} arguments and return values.
+     * An invoker for such a type is capable of calling any method handle
+     * of the same arity as the general type.
+     * <p style="font-size:smaller;">
+     * <em>(Note:  The invoker method is not available via the Core Reflection API.
+     * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+     * on the declared {@code invokeExact} or {@code invoke} method will raise an
+     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
+     * <p>
+     * This method throws no reflective or security exceptions.
+     * @param type the desired target type
+     * @return a method handle suitable for invoking any method handle convertible to the given type
+     * @throws IllegalArgumentException if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     */
+    static public
+    MethodHandle invoker(MethodType type) {
+        return new Transformers.Invoker(type, false /* isExactInvoker */);
+    }
+
+    // BEGIN Android-added: resolver for VarHandle accessor methods.
+    static private MethodHandle methodHandleForVarHandleAccessor(VarHandle.AccessMode accessMode,
+                                                                 MethodType type,
+                                                                 boolean isExactInvoker) {
+        Class<?> refc = VarHandle.class;
+        Method method;
+        try {
+            method = refc.getDeclaredMethod(accessMode.methodName(), Object[].class);
+        } catch (NoSuchMethodException e) {
+            throw new InternalError("No method for AccessMode " + accessMode, e);
+        }
+        MethodType methodType = type.insertParameterTypes(0, VarHandle.class);
+        int kind = isExactInvoker ? MethodHandle.INVOKE_VAR_HANDLE_EXACT
+                                  : MethodHandle.INVOKE_VAR_HANDLE;
+        return new MethodHandleImpl(method.getArtMethod(), kind, methodType);
+    }
+    // END Android-added: resolver for VarHandle accessor methods.
+
+    /**
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke a signature-polymorphic access mode method on any VarHandle whose
+     * associated access mode type is compatible with the given type.
+     * The resulting invoker will have a type which is exactly equal to the
+     * desired given type, except that it will accept an additional leading
+     * argument of type {@code VarHandle}.
+     *
+     * @param accessMode the VarHandle access mode
+     * @param type the desired target type
+     * @return a method handle suitable for invoking an access mode method of
+     *         any VarHandle whose access mode type is of the given type.
+     * @since 9
+     * @hide
+     */
+    static public
+    MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+        return methodHandleForVarHandleAccessor(accessMode, type, true /* isExactInvoker */);
+    }
+
+    /**
+     * Produces a special <em>invoker method handle</em> which can be used to
+     * invoke a signature-polymorphic access mode method on any VarHandle whose
+     * associated access mode type is compatible with the given type.
+     * The resulting invoker will have a type which is exactly equal to the
+     * desired given type, except that it will accept an additional leading
+     * argument of type {@code VarHandle}.
+     * <p>
+     * Before invoking its target, if the access mode type differs from the
+     * desired given type, the invoker will apply reference casts as necessary
+     * and box, unbox, or widen primitive values, as if by
+     * {@link MethodHandle#asType asType}.  Similarly, the return value will be
+     * converted as necessary.
+     * <p>
+     * This method is equivalent to the following code (though it may be more
+     * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)}
+     *
+     * @param accessMode the VarHandle access mode
+     * @param type the desired target type
+     * @return a method handle suitable for invoking an access mode method of
+     *         any VarHandle whose access mode type is convertible to the given
+     *         type.
+     * @since 9
+     * @hide
+     */
+    static public
+    MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+        return methodHandleForVarHandleAccessor(accessMode, type, false /* isExactInvoker */);
+    }
+
+    // Android-changed: Basic invokers are not supported.
+    //
+    // static /*non-public*/
+    // MethodHandle basicInvoker(MethodType type) {
+    //     return type.invokers().basicInvoker();
+    // }
+
+     /// method handle modification (creation from other method handles)
+
+    /**
+     * Produces a method handle which adapts the type of the
+     * given method handle to a new type by pairwise argument and return type conversion.
+     * The original type and new type must have the same number of arguments.
+     * The resulting method handle is guaranteed to report a type
+     * which is equal to the desired new type.
+     * <p>
+     * If the original type and new type are equal, returns target.
+     * <p>
+     * The same conversions are allowed as for {@link MethodHandle#asType MethodHandle.asType},
+     * and some additional conversions are also applied if those conversions fail.
+     * Given types <em>T0</em>, <em>T1</em>, one of the following conversions is applied
+     * if possible, before or instead of any conversions done by {@code asType}:
+     * <ul>
+     * <li>If <em>T0</em> and <em>T1</em> are references, and <em>T1</em> is an interface type,
+     *     then the value of type <em>T0</em> is passed as a <em>T1</em> without a cast.
+     *     (This treatment of interfaces follows the usage of the bytecode verifier.)
+     * <li>If <em>T0</em> is boolean and <em>T1</em> is another primitive,
+     *     the boolean is converted to a byte value, 1 for true, 0 for false.
+     *     (This treatment follows the usage of the bytecode verifier.)
+     * <li>If <em>T1</em> is boolean and <em>T0</em> is another primitive,
+     *     <em>T0</em> is converted to byte via Java casting conversion (JLS 5.5),
+     *     and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
+     * <li>If <em>T0</em> and <em>T1</em> are primitives other than boolean,
+     *     then a Java casting conversion (JLS 5.5) is applied.
+     *     (Specifically, <em>T0</em> will convert to <em>T1</em> by
+     *     widening and/or narrowing.)
+     * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
+     *     conversion will be applied at runtime, possibly followed
+     *     by a Java casting conversion (JLS 5.5) on the primitive value,
+     *     possibly followed by a conversion from byte to boolean by testing
+     *     the low-order bit.
+     * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive,
+     *     and if the reference is null at runtime, a zero value is introduced.
+     * </ul>
+     * @param target the method handle to invoke after arguments are retyped
+     * @param newType the expected type of the new method handle
+     * @return a method handle which delegates to the target after performing
+     *           any necessary argument conversions, and arranges for any
+     *           necessary return value conversions
+     * @throws NullPointerException if either argument is null
+     * @throws WrongMethodTypeException if the conversion cannot be made
+     * @see MethodHandle#asType
+     */
+    public static
+    MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
+        explicitCastArgumentsChecks(target, newType);
+        // use the asTypeCache when possible:
+        MethodType oldType = target.type();
+        if (oldType == newType) return target;
+        if (oldType.explicitCastEquivalentToAsType(newType)) {
+            if (Transformers.Transformer.class.isAssignableFrom(target.getClass())) {
+                // The StackFrameReader and StackFrameWriter used to perform transforms on
+                // EmulatedStackFrames (in Transformers.java) do not how to perform asType()
+                // conversions, but we know here that an explicit cast transform is the same as
+                // having called asType() on the method handle.
+                return new Transformers.ExplicitCastArguments(target.asFixedArity(), newType);
+            } else {
+                // Runtime will perform asType() conversion during invocation.
+                return target.asFixedArity().asType(newType);
+            }
+        }
+        return new Transformers.ExplicitCastArguments(target, newType);
+    }
+
+    private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
+        if (target.type().parameterCount() != newType.parameterCount()) {
+            throw new WrongMethodTypeException("cannot explicitly cast " + target +
+                                               " to " + newType);
+        }
+    }
+
+    /**
+     * Produces a method handle which adapts the calling sequence of the
+     * given method handle to a new type, by reordering the arguments.
+     * The resulting method handle is guaranteed to report a type
+     * which is equal to the desired new type.
+     * <p>
+     * The given array controls the reordering.
+     * Call {@code #I} the number of incoming parameters (the value
+     * {@code newType.parameterCount()}, and call {@code #O} the number
+     * of outgoing parameters (the value {@code target.type().parameterCount()}).
+     * Then the length of the reordering array must be {@code #O},
+     * and each element must be a non-negative number less than {@code #I}.
+     * For every {@code N} less than {@code #O}, the {@code N}-th
+     * outgoing argument will be taken from the {@code I}-th incoming
+     * argument, where {@code I} is {@code reorder[N]}.
+     * <p>
+     * No argument or return value conversions are applied.
+     * The type of each incoming argument, as determined by {@code newType},
+     * must be identical to the type of the corresponding outgoing parameter
+     * or parameters in the target method handle.
+     * The return type of {@code newType} must be identical to the return
+     * type of the original target.
+     * <p>
+     * The reordering array need not specify an actual permutation.
+     * An incoming argument will be duplicated if its index appears
+     * more than once in the array, and an incoming argument will be dropped
+     * if its index does not appear in the array.
+     * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
+     * incoming arguments which are not mentioned in the reordering array
+     * are may be any type, as determined only by {@code newType}.
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodType intfn1 = methodType(int.class, int.class);
+MethodType intfn2 = methodType(int.class, int.class, int.class);
+MethodHandle sub = ... (int x, int y) -> (x-y) ...;
+assert(sub.type().equals(intfn2));
+MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
+MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
+assert((int)rsub.invokeExact(1, 100) == 99);
+MethodHandle add = ... (int x, int y) -> (x+y) ...;
+assert(add.type().equals(intfn2));
+MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
+assert(twice.type().equals(intfn1));
+assert((int)twice.invokeExact(21) == 42);
+     * }</pre></blockquote>
+     * @param target the method handle to invoke after arguments are reordered
+     * @param newType the expected type of the new method handle
+     * @param reorder an index array which controls the reordering
+     * @return a method handle which delegates to the target after it
+     *           drops unused arguments and moves and/or duplicates the other arguments
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the index array length is not equal to
+     *                  the arity of the target, or if any index array element
+     *                  not a valid index for a parameter of {@code newType},
+     *                  or if two corresponding parameter types in
+     *                  {@code target.type()} and {@code newType} are not identical,
+     */
+    public static
+    MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
+        reorder = reorder.clone();  // get a private copy
+        MethodType oldType = target.type();
+        permuteArgumentChecks(reorder, newType, oldType);
+
+        return new Transformers.PermuteArguments(newType, target, reorder);
+    }
+
+    // Android-changed: findFirstDupOrDrop is unused and removed.
+    // private static int findFirstDupOrDrop(int[] reorder, int newArity);
+
+    private static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType) {
+        if (newType.returnType() != oldType.returnType())
+            throw newIllegalArgumentException("return types do not match",
+                    oldType, newType);
+        if (reorder.length == oldType.parameterCount()) {
+            int limit = newType.parameterCount();
+            boolean bad = false;
+            for (int j = 0; j < reorder.length; j++) {
+                int i = reorder[j];
+                if (i < 0 || i >= limit) {
+                    bad = true; break;
+                }
+                Class<?> src = newType.parameterType(i);
+                Class<?> dst = oldType.parameterType(j);
+                if (src != dst)
+                    throw newIllegalArgumentException("parameter types do not match after reorder",
+                            oldType, newType);
+            }
+            if (!bad)  return true;
+        }
+        throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
+    }
+
+    /**
+     * Produces a method handle of the requested return type which returns the given
+     * constant value every time it is invoked.
+     * <p>
+     * Before the method handle is returned, the passed-in value is converted to the requested type.
+     * If the requested type is primitive, widening primitive conversions are attempted,
+     * else reference conversions are attempted.
+     * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
+     * @param type the return type of the desired method handle
+     * @param value the value to return
+     * @return a method handle of the given return type and no arguments, which always returns the given value
+     * @throws NullPointerException if the {@code type} argument is null
+     * @throws ClassCastException if the value cannot be converted to the required return type
+     * @throws IllegalArgumentException if the given type is {@code void.class}
+     */
+    public static
+    MethodHandle constant(Class<?> type, Object value) {
+        if (type.isPrimitive()) {
+            if (type == void.class)
+                throw newIllegalArgumentException("void type");
+            Wrapper w = Wrapper.forPrimitiveType(type);
+            value = w.convert(value, type);
+        }
+
+        return new Transformers.Constant(type, value);
+    }
+
+    /**
+     * Produces a method handle which returns its sole argument when invoked.
+     * @param type the type of the sole parameter and return value of the desired method handle
+     * @return a unary method handle which accepts and returns the given type
+     * @throws NullPointerException if the argument is null
+     * @throws IllegalArgumentException if the given type is {@code void.class}
+     */
+    public static
+    MethodHandle identity(Class<?> type) {
+        if (type == null) {
+            throw new NullPointerException("type == null");
+        }
+
+        if (type.isPrimitive()) {
+            try {
+                return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class, "identity",
+                        MethodType.methodType(type, type));
+            } catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        return new Transformers.ReferenceIdentity(type);
+    }
+
+    /** @hide */ public static byte identity(byte val) { return val; }
+    /** @hide */ public static boolean identity(boolean val) { return val; }
+    /** @hide */ public static char identity(char val) { return val; }
+    /** @hide */ public static short identity(short val) { return val; }
+    /** @hide */ public static int identity(int val) { return val; }
+    /** @hide */ public static long identity(long val) { return val; }
+    /** @hide */ public static float identity(float val) { return val; }
+    /** @hide */ public static double identity(double val) { return val; }
+
+    /**
+     * Provides a target method handle with one or more <em>bound arguments</em>
+     * in advance of the method handle's invocation.
+     * The formal parameters to the target corresponding to the bound
+     * arguments are called <em>bound parameters</em>.
+     * Returns a new method handle which saves away the bound arguments.
+     * When it is invoked, it receives arguments for any non-bound parameters,
+     * binds the saved arguments to their corresponding parameters,
+     * and calls the original target.
+     * <p>
+     * The type of the new method handle will drop the types for the bound
+     * parameters from the original target type, since the new method handle
+     * will no longer require those arguments to be supplied by its callers.
+     * <p>
+     * Each given argument object must match the corresponding bound parameter type.
+     * If a bound parameter type is a primitive, the argument object
+     * must be a wrapper, and will be unboxed to produce the primitive value.
+     * <p>
+     * The {@code pos} argument selects which parameters are to be bound.
+     * It may range between zero and <i>N-L</i> (inclusively),
+     * where <i>N</i> is the arity of the target method handle
+     * and <i>L</i> is the length of the values array.
+     * @param target the method handle to invoke after the argument is inserted
+     * @param pos where to insert the argument (zero for the first)
+     * @param values the series of arguments to insert
+     * @return a method handle which inserts an additional argument,
+     *         before calling the original method handle
+     * @throws NullPointerException if the target or the {@code values} array is null
+     * @see MethodHandle#bindTo
+     */
+    public static
+    MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
+        int insCount = values.length;
+        Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos);
+        if (insCount == 0)  {
+            return target;
+        }
+
+        // Throw ClassCastExceptions early if we can't cast any of the provided values
+        // to the required type.
+        for (int i = 0; i < insCount; i++) {
+            final Class<?> ptype = ptypes[pos + i];
+            if (!ptype.isPrimitive()) {
+                ptypes[pos + i].cast(values[i]);
+            } else {
+                // Will throw a ClassCastException if something terrible happens.
+                values[i] = Wrapper.forPrimitiveType(ptype).convert(values[i], ptype);
+            }
+        }
+
+        return new Transformers.InsertArguments(target, pos, values);
+    }
+
+    // Android-changed: insertArgumentPrimitive is unused.
+    //
+    // private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
+    //                                                          Class<?> ptype, Object value) {
+    //     Wrapper w = Wrapper.forPrimitiveType(ptype);
+    //     // perform unboxing and/or primitive conversion
+    //     value = w.convert(value, ptype);
+    //     switch (w) {
+    //     case INT:     return result.bindArgumentI(pos, (int)value);
+    //     case LONG:    return result.bindArgumentJ(pos, (long)value);
+    //     case FLOAT:   return result.bindArgumentF(pos, (float)value);
+    //     case DOUBLE:  return result.bindArgumentD(pos, (double)value);
+    //     default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
+    //     }
+    // }
+
+    private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {
+        MethodType oldType = target.type();
+        int outargs = oldType.parameterCount();
+        int inargs  = outargs - insCount;
+        if (inargs < 0)
+            throw newIllegalArgumentException("too many values to insert");
+        if (pos < 0 || pos > inargs)
+            throw newIllegalArgumentException("no argument type to append");
+        return oldType.ptypes();
+    }
+
+    /**
+     * Produces a method handle which will discard some dummy arguments
+     * before calling some other specified <i>target</i> method handle.
+     * The type of the new method handle will be the same as the target's type,
+     * except it will also include the dummy argument types,
+     * at some given position.
+     * <p>
+     * The {@code pos} argument may range between zero and <i>N</i>,
+     * where <i>N</i> is the arity of the target.
+     * If {@code pos} is zero, the dummy arguments will precede
+     * the target's real arguments; if {@code pos} is <i>N</i>
+     * they will come after.
+     * <p>
+     * <b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
+MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
+assertEquals(bigType, d0.type());
+assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
+     * }</pre></blockquote>
+     * <p>
+     * This method is also equivalent to the following code:
+     * <blockquote><pre>
+     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}{@code (target, pos, valueTypes.toArray(new Class[0]))}
+     * </pre></blockquote>
+     * @param target the method handle to invoke after the arguments are dropped
+     * @param valueTypes the type(s) of the argument(s) to drop
+     * @param pos position of first argument to drop (zero for the leftmost)
+     * @return a method handle which drops arguments of the given types,
+     *         before calling the original method handle
+     * @throws NullPointerException if the target is null,
+     *                              or if the {@code valueTypes} list or any of its elements is null
+     * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
+     *                  or if {@code pos} is negative or greater than the arity of the target,
+     *                  or if the new method handle's type would have too many parameters
+     */
+    public static
+    MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
+        valueTypes = copyTypes(valueTypes);
+        MethodType oldType = target.type();  // get NPE
+        int dropped = dropArgumentChecks(oldType, pos, valueTypes);
+
+        MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
+        if (dropped == 0) {
+            return target;
+        }
+
+        return new Transformers.DropArguments(newType, target, pos, valueTypes.size());
+    }
+
+    private static List<Class<?>> copyTypes(List<Class<?>> types) {
+        Object[] a = types.toArray();
+        return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
+    }
+
+    private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
+        int dropped = valueTypes.size();
+        MethodType.checkSlotCount(dropped);
+        int outargs = oldType.parameterCount();
+        int inargs  = outargs + dropped;
+        if (pos < 0 || pos > outargs)
+            throw newIllegalArgumentException("no argument type to remove"
+                    + Arrays.asList(oldType, pos, valueTypes, inargs, outargs)
+                    );
+        return dropped;
+    }
+
+    /**
+     * Produces a method handle which will discard some dummy arguments
+     * before calling some other specified <i>target</i> method handle.
+     * The type of the new method handle will be the same as the target's type,
+     * except it will also include the dummy argument types,
+     * at some given position.
+     * <p>
+     * The {@code pos} argument may range between zero and <i>N</i>,
+     * where <i>N</i> is the arity of the target.
+     * If {@code pos} is zero, the dummy arguments will precede
+     * the target's real arguments; if {@code pos} is <i>N</i>
+     * they will come after.
+     * <p>
+     * <b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle d0 = dropArguments(cat, 0, String.class);
+assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
+MethodHandle d1 = dropArguments(cat, 1, String.class);
+assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
+MethodHandle d2 = dropArguments(cat, 2, String.class);
+assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
+MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
+assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
+     * }</pre></blockquote>
+     * <p>
+     * This method is also equivalent to the following code:
+     * <blockquote><pre>
+     * {@link #dropArguments(MethodHandle,int,List) dropArguments}{@code (target, pos, Arrays.asList(valueTypes))}
+     * </pre></blockquote>
+     * @param target the method handle to invoke after the arguments are dropped
+     * @param valueTypes the type(s) of the argument(s) to drop
+     * @param pos position of first argument to drop (zero for the leftmost)
+     * @return a method handle which drops arguments of the given types,
+     *         before calling the original method handle
+     * @throws NullPointerException if the target is null,
+     *                              or if the {@code valueTypes} array or any of its elements is null
+     * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
+     *                  or if {@code pos} is negative or greater than the arity of the target,
+     *                  or if the new method handle's type would have
+     *                  <a href="MethodHandle.html#maxarity">too many parameters</a>
+     */
+    public static
+    MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
+        return dropArguments(target, pos, Arrays.asList(valueTypes));
+    }
+
+    /**
+     * Adapts a target method handle by pre-processing
+     * one or more of its arguments, each with its own unary filter function,
+     * and then calling the target with each pre-processed argument
+     * replaced by the result of its corresponding filter function.
+     * <p>
+     * The pre-processing is performed by one or more method handles,
+     * specified in the elements of the {@code filters} array.
+     * The first element of the filter array corresponds to the {@code pos}
+     * argument of the target, and so on in sequence.
+     * <p>
+     * Null arguments in the array are treated as identity functions,
+     * and the corresponding arguments left unchanged.
+     * (If there are no non-null elements in the array, the original target is returned.)
+     * Each filter is applied to the corresponding argument of the adapter.
+     * <p>
+     * If a filter {@code F} applies to the {@code N}th argument of
+     * the target, then {@code F} must be a method handle which
+     * takes exactly one argument.  The type of {@code F}'s sole argument
+     * replaces the corresponding argument type of the target
+     * in the resulting adapted method handle.
+     * The return type of {@code F} must be identical to the corresponding
+     * parameter type of the target.
+     * <p>
+     * It is an error if there are elements of {@code filters}
+     * (null or not)
+     * which do not correspond to argument positions in the target.
+     * <p><b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle upcase = lookup().findVirtual(String.class,
+  "toUpperCase", methodType(String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle f0 = filterArguments(cat, 0, upcase);
+assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
+MethodHandle f1 = filterArguments(cat, 1, upcase);
+assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
+MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
+assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
+     * }</pre></blockquote>
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * V target(P... p, A[i]... a[i], B... b);
+     * A[i] filter[i](V[i]);
+     * T adapter(P... p, V[i]... v[i], B... b) {
+     *   return target(p..., f[i](v[i])..., b...);
+     * }
+     * }</pre></blockquote>
+     *
+     * @param target the method handle to invoke after arguments are filtered
+     * @param pos the position of the first argument to filter
+     * @param filters method handles to call initially on filtered arguments
+     * @return method handle which incorporates the specified argument filtering logic
+     * @throws NullPointerException if the target is null
+     *                              or if the {@code filters} array is null
+     * @throws IllegalArgumentException if a non-null element of {@code filters}
+     *          does not match a corresponding argument type of target as described above,
+     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
+     *          or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     */
+    public static
+    MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
+        filterArgumentsCheckArity(target, pos, filters);
+
+        for (int i = 0; i < filters.length; ++i) {
+            filterArgumentChecks(target, i + pos, filters[i]);
+        }
+
+        return new Transformers.FilterArguments(target, pos, filters);
+    }
+
+    private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
+        MethodType targetType = target.type();
+        int maxPos = targetType.parameterCount();
+        if (pos + filters.length > maxPos)
+            throw newIllegalArgumentException("too many filters");
+    }
+
+    private static void filterArgumentChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+        MethodType targetType = target.type();
+        MethodType filterType = filter.type();
+        if (filterType.parameterCount() != 1
+            || filterType.returnType() != targetType.parameterType(pos))
+            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+    }
+
+    /**
+     * Adapts a target method handle by pre-processing
+     * a sub-sequence of its arguments with a filter (another method handle).
+     * The pre-processed arguments are replaced by the result (if any) of the
+     * filter function.
+     * The target is then called on the modified (usually shortened) argument list.
+     * <p>
+     * If the filter returns a value, the target must accept that value as
+     * its argument in position {@code pos}, preceded and/or followed by
+     * any arguments not passed to the filter.
+     * If the filter returns void, the target must accept all arguments
+     * not passed to the filter.
+     * No arguments are reordered, and a result returned from the filter
+     * replaces (in order) the whole subsequence of arguments originally
+     * passed to the adapter.
+     * <p>
+     * The argument types (if any) of the filter
+     * replace zero or one argument types of the target, at position {@code pos},
+     * in the resulting adapted method handle.
+     * The return type of the filter (if any) must be identical to the
+     * argument type of the target at position {@code pos}, and that target argument
+     * is supplied by the return value of the filter.
+     * <p>
+     * In all cases, {@code pos} must be greater than or equal to zero, and
+     * {@code pos} must also be less than or equal to the target's arity.
+     * <p><b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle deepToString = publicLookup()
+  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+
+MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
+assertEquals("[strange]", (String) ts1.invokeExact("strange"));
+
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
+
+MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
+MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
+assertEquals("[top, [up, down], strange]",
+             (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
+assertEquals("[top, [up, down], [strange]]",
+             (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
+assertEquals("[top, [[up, down, strange], charm], bottom]",
+             (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
+     * }</pre></blockquote>
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * T target(A...,V,C...);
+     * V filter(B...);
+     * T adapter(A... a,B... b,C... c) {
+     *   V v = filter(b...);
+     *   return target(a...,v,c...);
+     * }
+     * // and if the filter has no arguments:
+     * T target2(A...,V,C...);
+     * V filter2();
+     * T adapter2(A... a,C... c) {
+     *   V v = filter2();
+     *   return target2(a...,v,c...);
+     * }
+     * // and if the filter has a void return:
+     * T target3(A...,C...);
+     * void filter3(B...);
+     * void adapter3(A... a,B... b,C... c) {
+     *   filter3(b...);
+     *   return target3(a...,c...);
+     * }
+     * }</pre></blockquote>
+     * <p>
+     * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to
+     * one which first "folds" the affected arguments, and then drops them, in separate
+     * steps as follows:
+     * <blockquote><pre>{@code
+     * mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
+     * mh = MethodHandles.foldArguments(mh, coll); //step 1
+     * }</pre></blockquote>
+     * If the target method handle consumes no arguments besides than the result
+     * (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)}
+     * is equivalent to {@code filterReturnValue(coll, mh)}.
+     * If the filter method handle {@code coll} consumes one argument and produces
+     * a non-void result, then {@code collectArguments(mh, N, coll)}
+     * is equivalent to {@code filterArguments(mh, N, coll)}.
+     * Other equivalences are possible but would require argument permutation.
+     *
+     * @param target the method handle to invoke after filtering the subsequence of arguments
+     * @param pos the position of the first adapter argument to pass to the filter,
+     *            and/or the target argument which receives the result of the filter
+     * @param filter method handle to call on the subsequence of arguments
+     * @return method handle which incorporates the specified argument subsequence filtering logic
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if the return type of {@code filter}
+     *          is non-void and is not the same as the {@code pos} argument of the target,
+     *          or if {@code pos} is not between 0 and the target's arity, inclusive,
+     *          or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     * @see MethodHandles#foldArguments
+     * @see MethodHandles#filterArguments
+     * @see MethodHandles#filterReturnValue
+     */
+    public static
+    MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
+        MethodType newType = collectArgumentsChecks(target, pos, filter);
+        return new Transformers.CollectArguments(target, filter, pos, newType);
+    }
+
+    private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+        MethodType targetType = target.type();
+        MethodType filterType = filter.type();
+        Class<?> rtype = filterType.returnType();
+        List<Class<?>> filterArgs = filterType.parameterList();
+        if (rtype == void.class) {
+            return targetType.insertParameterTypes(pos, filterArgs);
+        }
+        if (rtype != targetType.parameterType(pos)) {
+            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+        }
+        return targetType.dropParameterTypes(pos, pos+1).insertParameterTypes(pos, filterArgs);
+    }
+
+    /**
+     * Adapts a target method handle by post-processing
+     * its return value (if any) with a filter (another method handle).
+     * The result of the filter is returned from the adapter.
+     * <p>
+     * If the target returns a value, the filter must accept that value as
+     * its only argument.
+     * If the target returns void, the filter must accept no arguments.
+     * <p>
+     * The return type of the filter
+     * replaces the return type of the target
+     * in the resulting adapted method handle.
+     * The argument type of the filter (if any) must be identical to the
+     * return type of the target.
+     * <p><b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle length = lookup().findVirtual(String.class,
+  "length", methodType(int.class));
+System.out.println((String) cat.invokeExact("x", "y")); // xy
+MethodHandle f0 = filterReturnValue(cat, length);
+System.out.println((int) f0.invokeExact("x", "y")); // 2
+     * }</pre></blockquote>
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * V target(A...);
+     * T filter(V);
+     * T adapter(A... a) {
+     *   V v = target(a...);
+     *   return filter(v);
+     * }
+     * // and if the target has a void return:
+     * void target2(A...);
+     * T filter2();
+     * T adapter2(A... a) {
+     *   target2(a...);
+     *   return filter2();
+     * }
+     * // and if the filter has a void return:
+     * V target3(A...);
+     * void filter3(V);
+     * void adapter3(A... a) {
+     *   V v = target3(a...);
+     *   filter3(v);
+     * }
+     * }</pre></blockquote>
+     * @param target the method handle to invoke before filtering the return value
+     * @param filter method handle to call on the return value
+     * @return method handle which incorporates the specified return value filtering logic
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if the argument list of {@code filter}
+     *          does not match the return type of target as described above
+     */
+    public static
+    MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
+        MethodType targetType = target.type();
+        MethodType filterType = filter.type();
+        filterReturnValueChecks(targetType, filterType);
+
+        return new Transformers.FilterReturnValue(target, filter);
+    }
+
+    private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
+        Class<?> rtype = targetType.returnType();
+        int filterValues = filterType.parameterCount();
+        if (filterValues == 0
+                ? (rtype != void.class)
+                : (rtype != filterType.parameterType(0) || filterValues != 1))
+            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+    }
+
+    /**
+     * Adapts a target method handle by pre-processing
+     * some of its arguments, and then calling the target with
+     * the result of the pre-processing, inserted into the original
+     * sequence of arguments.
+     * <p>
+     * The pre-processing is performed by {@code combiner}, a second method handle.
+     * Of the arguments passed to the adapter, the first {@code N} arguments
+     * are copied to the combiner, which is then called.
+     * (Here, {@code N} is defined as the parameter count of the combiner.)
+     * After this, control passes to the target, with any result
+     * from the combiner inserted before the original {@code N} incoming
+     * arguments.
+     * <p>
+     * If the combiner returns a value, the first parameter type of the target
+     * must be identical with the return type of the combiner, and the next
+     * {@code N} parameter types of the target must exactly match the parameters
+     * of the combiner.
+     * <p>
+     * If the combiner has a void return, no result will be inserted,
+     * and the first {@code N} parameter types of the target
+     * must exactly match the parameters of the combiner.
+     * <p>
+     * The resulting adapter is the same type as the target, except that the
+     * first parameter type is dropped,
+     * if it corresponds to the result of the combiner.
+     * <p>
+     * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
+     * that either the combiner or the target does not wish to receive.
+     * If some of the incoming arguments are destined only for the combiner,
+     * consider using {@link MethodHandle#asCollector asCollector} instead, since those
+     * arguments will not need to be live on the stack on entry to the
+     * target.)
+     * <p><b>Example:</b>
+     * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
+  "println", methodType(void.class, String.class))
+    .bindTo(System.out);
+MethodHandle cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
+MethodHandle catTrace = foldArguments(cat, trace);
+// also prints "boo":
+assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
+     * }</pre></blockquote>
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * // there are N arguments in A...
+     * T target(V, A[N]..., B...);
+     * V combiner(A...);
+     * T adapter(A... a, B... b) {
+     *   V v = combiner(a...);
+     *   return target(v, a..., b...);
+     * }
+     * // and if the combiner has a void return:
+     * T target2(A[N]..., B...);
+     * void combiner2(A...);
+     * T adapter2(A... a, B... b) {
+     *   combiner2(a...);
+     *   return target2(a..., b...);
+     * }
+     * }</pre></blockquote>
+     * @param target the method handle to invoke after arguments are combined
+     * @param combiner method handle to call initially on the incoming arguments
+     * @return method handle which incorporates the specified argument folding logic
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if {@code combiner}'s return type
+     *          is non-void and not the same as the first argument type of
+     *          the target, or if the initial {@code N} argument types
+     *          of the target
+     *          (skipping one matching the {@code combiner}'s return type)
+     *          are not identical with the argument types of {@code combiner}
+     */
+    public static
+    MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
+        int foldPos = 0;
+        MethodType targetType = target.type();
+        MethodType combinerType = combiner.type();
+        Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
+
+        return new Transformers.FoldArguments(target, combiner);
+    }
+
+    private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
+        int foldArgs   = combinerType.parameterCount();
+        Class<?> rtype = combinerType.returnType();
+        int foldVals = rtype == void.class ? 0 : 1;
+        int afterInsertPos = foldPos + foldVals;
+        boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
+        if (ok && !(combinerType.parameterList()
+                    .equals(targetType.parameterList().subList(afterInsertPos,
+                                                               afterInsertPos + foldArgs))))
+            ok = false;
+        if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(0))
+            ok = false;
+        if (!ok)
+            throw misMatchedTypes("target and combiner types", targetType, combinerType);
+        return rtype;
+    }
+
+    /**
+     * Makes a method handle which adapts a target method handle,
+     * by guarding it with a test, a boolean-valued method handle.
+     * If the guard fails, a fallback handle is called instead.
+     * All three method handles must have the same corresponding
+     * argument and return types, except that the return type
+     * of the test must be boolean, and the test is allowed
+     * to have fewer arguments than the other two method handles.
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * boolean test(A...);
+     * T target(A...,B...);
+     * T fallback(A...,B...);
+     * T adapter(A... a,B... b) {
+     *   if (test(a...))
+     *     return target(a..., b...);
+     *   else
+     *     return fallback(a..., b...);
+     * }
+     * }</pre></blockquote>
+     * Note that the test arguments ({@code a...} in the pseudocode) cannot
+     * be modified by execution of the test, and so are passed unchanged
+     * from the caller to the target or fallback as appropriate.
+     * @param test method handle used for test, must return boolean
+     * @param target method handle to call if test passes
+     * @param fallback method handle to call if test fails
+     * @return method handle which incorporates the specified if/then/else logic
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if {@code test} does not return boolean,
+     *          or if all three method types do not match (with the return
+     *          type of {@code test} changed to match that of the target).
+     */
+    public static
+    MethodHandle guardWithTest(MethodHandle test,
+                               MethodHandle target,
+                               MethodHandle fallback) {
+        MethodType gtype = test.type();
+        MethodType ttype = target.type();
+        MethodType ftype = fallback.type();
+        if (!ttype.equals(ftype))
+            throw misMatchedTypes("target and fallback types", ttype, ftype);
+        if (gtype.returnType() != boolean.class)
+            throw newIllegalArgumentException("guard type is not a predicate "+gtype);
+        List<Class<?>> targs = ttype.parameterList();
+        List<Class<?>> gargs = gtype.parameterList();
+        if (!targs.equals(gargs)) {
+            int gpc = gargs.size(), tpc = targs.size();
+            if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
+                throw misMatchedTypes("target and test types", ttype, gtype);
+            test = dropArguments(test, gpc, targs.subList(gpc, tpc));
+            gtype = test.type();
+        }
+
+        return new Transformers.GuardWithTest(test, target, fallback);
+    }
+
+    static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
+        return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
+    }
+
+    /**
+     * Makes a method handle which adapts a target method handle,
+     * by running it inside an exception handler.
+     * If the target returns normally, the adapter returns that value.
+     * If an exception matching the specified type is thrown, the fallback
+     * handle is called instead on the exception, plus the original arguments.
+     * <p>
+     * The target and handler must have the same corresponding
+     * argument and return types, except that handler may omit trailing arguments
+     * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
+     * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * T target(A..., B...);
+     * T handler(ExType, A...);
+     * T adapter(A... a, B... b) {
+     *   try {
+     *     return target(a..., b...);
+     *   } catch (ExType ex) {
+     *     return handler(ex, a...);
+     *   }
+     * }
+     * }</pre></blockquote>
+     * Note that the saved arguments ({@code a...} in the pseudocode) cannot
+     * be modified by execution of the target, and so are passed unchanged
+     * from the caller to the handler, if the handler is invoked.
+     * <p>
+     * The target and handler must return the same type, even if the handler
+     * always throws.  (This might happen, for instance, because the handler
+     * is simulating a {@code finally} clause).
+     * To create such a throwing handler, compose the handler creation logic
+     * with {@link #throwException throwException},
+     * in order to create a method handle of the correct return type.
+     * @param target method handle to call
+     * @param exType the type of exception which the handler will catch
+     * @param handler method handle to call if a matching exception is thrown
+     * @return method handle which incorporates the specified try/catch logic
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if {@code handler} does not accept
+     *          the given exception type, or if the method handle types do
+     *          not match in their return types and their
+     *          corresponding parameters
+     */
+    public static
+    MethodHandle catchException(MethodHandle target,
+                                Class<? extends Throwable> exType,
+                                MethodHandle handler) {
+        MethodType ttype = target.type();
+        MethodType htype = handler.type();
+        if (htype.parameterCount() < 1 ||
+            !htype.parameterType(0).isAssignableFrom(exType))
+            throw newIllegalArgumentException("handler does not accept exception type "+exType);
+        if (htype.returnType() != ttype.returnType())
+            throw misMatchedTypes("target and handler return types", ttype, htype);
+        List<Class<?>> targs = ttype.parameterList();
+        List<Class<?>> hargs = htype.parameterList();
+        hargs = hargs.subList(1, hargs.size());  // omit leading parameter from handler
+        if (!targs.equals(hargs)) {
+            int hpc = hargs.size(), tpc = targs.size();
+            if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
+                throw misMatchedTypes("target and handler types", ttype, htype);
+        }
+
+        return new Transformers.CatchException(target, handler, exType);
+    }
+
+    /**
+     * Produces a method handle which will throw exceptions of the given {@code exType}.
+     * The method handle will accept a single argument of {@code exType},
+     * and immediately throw it as an exception.
+     * The method type will nominally specify a return of {@code returnType}.
+     * The return type may be anything convenient:  It doesn't matter to the
+     * method handle's behavior, since it will never return normally.
+     * @param returnType the return type of the desired method handle
+     * @param exType the parameter type of the desired method handle
+     * @return method handle which can throw the given exceptions
+     * @throws NullPointerException if either argument is null
+     */
+    public static
+    MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
+        if (!Throwable.class.isAssignableFrom(exType))
+            throw new ClassCastException(exType.getName());
+
+        return new Transformers.AlwaysThrow(returnType, exType);
+    }
+}
diff --git a/java/lang/invoke/MethodType.java b/java/lang/invoke/MethodType.java
new file mode 100644
index 0000000..4652c93
--- /dev/null
+++ b/java/lang/invoke/MethodType.java
@@ -0,0 +1,1328 @@
+/*
+ * 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 {@link MethodHandle#invokeExact MethodHandle.invokeExact}
+ * and {@link 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
+ */
+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-removed: Cache of higher order adapters.
+    // 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; }
+    // Android-changed: Make rtype()/ptypes() public @hide for implementation use.
+    // /*trusted*/ Class<?> rtype() { return rtype; }
+    // /*trusted*/ Class<?>[] ptypes() { return ptypes; }
+    /*trusted*/ /** @hide */ public Class<?> rtype() { return rtype; }
+    /*trusted*/ /** @hide */ public Class<?>[] ptypes() { return ptypes; }
+
+    // Android-removed: Implementation methods unused on Android.
+    // 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();
+    }
+
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
+    /**
+     * 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 {@link MethodHandle#invokeBasic invokeBasic}.
+     * @return a version of the original type with all reference and subword types replaced
+     *
+    /*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() {
+        return insertParameterTypes(0, MethodHandle.class);
+    }
+    */
+    // END Android-removed: Implementation methods unused on Android.
+
+    /**
+     * 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();
+    }
+
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
+    /** 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.
+     *
+    /*non-public*
+    boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
+        if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
+            return false;
+        return parametersAreViewableAs(newType, keepInterfaces);
+    }
+    /** True if the new parameters can be viewed (w/o casting) under the old parameter types. *
+    /*non-public*
+    boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
+        if (form == newType.form && form.erasedType == this)
+            return true;  // my reference parameters are all Object
+        if (ptypes == newType.ptypes)
+            return true;
+        int argc = parameterCount();
+        if (argc != newType.parameterCount())
+            return false;
+        for (int i = 0; i < argc; i++) {
+            if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i), keepInterfaces))
+                return false;
+        }
+        return true;
+    }
+    */
+    // END Android-removed: Implementation methods unused on Android.
+
+    /*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
+     *  2a. 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.
+     *  2b. conversion of void->primitive means explicit cast has to insert zero/false/null.
+     *  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;
+        }
+    }
+
+    /// Queries which have to do with the bytecode architecture
+
+    /** 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();
+    }
+
+    // BEGIN Android-removed: Cache of higher order adapters.
+    /*
+    /*non-public* Invokers invokers() {
+        Invokers inv = invokers;
+        if (inv != null)  return inv;
+        invokers = inv = new Invokers(this);
+        return inv;
+    }
+    */
+    // END Android-removed: Cache of higher order adapters.
+
+    // BEGIN Android-removed: Implementation methods unused on Android.
+    /*
+    /** Reports the number of JVM stack slots which carry all parameters including and after
+     * the given position, which must be in the range of 0 to
+     * {@code parameterCount} inclusive.  Successive parameters are
+     * more shallowly stacked, and parameters are indexed in the bytecodes
+     * according to their trailing edge.  Thus, to obtain the depth
+     * in the outgoing call stack of parameter {@code N}, obtain
+     * the {@code parameterSlotDepth} of its trailing edge
+     * at position {@code N+1}.
+     * <p>
+     * Parameters of type {@code long} and {@code double} occupy
+     * two stack slots (for historical reasons) and all others occupy one.
+     * Therefore, the number returned is the number of arguments
+     * <em>including</em> and <em>after</em> the given parameter,
+     * <em>plus</em> the number of long or double arguments
+     * at or after after the argument for the given parameter.
+     * <p>
+     * This method is included for the benefit of applications that must
+     * generate bytecodes that process method handles and invokedynamic.
+     * @param num an index (zero-based, inclusive) within the parameter types
+     * @return the index of the (shallowest) JVM stack slot transmitting the
+     *         given parameter
+     * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+     *
+    /*non-public* int parameterSlotDepth(int num) {
+        if (num < 0 || num > ptypes.length)
+            parameterType(num);  // force a range check
+        return form.parameterToArgSlot(num-1);
+    }
+
+    /** Reports the number of JVM stack slots required to receive a return value
+     * from a method of this type.
+     * If the {@link #returnType() return type} is void, it will be zero,
+     * else if the return type is long or double, it will be two, else one.
+     * <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 (0, 1, or 2) for this type's return value
+     * Will be removed for PFD.
+     *
+    /*non-public* int returnSlotCount() {
+        return form.returnSlotCount();
+    }
+    */
+    // END Android-removed: Implementation methods unused on Android.
+
+    /**
+     * 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/java/lang/invoke/MethodTypeForm.java b/java/lang/invoke/MethodTypeForm.java
new file mode 100644
index 0000000..6f6c2a8
--- /dev/null
+++ b/java/lang/invoke/MethodTypeForm.java
@@ -0,0 +1,439 @@
+/*
+ * 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
+
+    // BEGIN Android-removed: Cached adaptors / lambda forms.
+    // The upstream caching mechanism will not work on Android because of fundamental differences
+    // in the Android runtime/implementation of MethodHandle. LambdaForm is not supported on
+    // Android for similar reasons.
+    /*
+    // Cached adapter information:
+    @Stable final SoftReference<MethodHandle>[] methodHandles;
+    // Indexes into methodHandles:
+    static final int
+            MH_BASIC_INV      =  0,  // cached instance of MH.invokeBasic
+            MH_NF_INV         =  1,  // cached helper for LF.NamedFunction
+            MH_UNINIT_CS      =  2,  // uninitialized call site
+            MH_LIMIT          =  3;
+
+    // Cached lambda form information, for basic types only:
+    final @Stable SoftReference<LambdaForm>[] lambdaForms;
+    // Indexes into lambdaForms:
+    static final int
+            LF_INVVIRTUAL              =  0,  // DMH invokeVirtual
+            LF_INVSTATIC               =  1,
+            LF_INVSPECIAL              =  2,
+            LF_NEWINVSPECIAL           =  3,
+            LF_INVINTERFACE            =  4,
+            LF_INVSTATIC_INIT          =  5,  // DMH invokeStatic with <clinit> barrier
+            LF_INTERPRET               =  6,  // LF interpreter
+            LF_REBIND                  =  7,  // BoundMethodHandle
+            LF_DELEGATE                =  8,  // DelegatingMethodHandle
+            LF_DELEGATE_BLOCK_INLINING =  9,  // Counting DelegatingMethodHandle w/ @DontInline
+            LF_EX_LINKER               = 10,  // invokeExact_MT (for invokehandle)
+            LF_EX_INVOKER              = 11,  // MHs.invokeExact
+            LF_GEN_LINKER              = 12,  // generic invoke_MT (for invokehandle)
+            LF_GEN_INVOKER             = 13,  // generic MHs.invoke
+            LF_CS_LINKER               = 14,  // linkToCallSite_CS
+            LF_MH_LINKER               = 15,  // linkToCallSite_MH
+            LF_GWC                     = 16,  // guardWithCatch (catchException)
+            LF_GWT                     = 17,  // guardWithTest
+            LF_LIMIT                   = 18;
+    */
+    // END Android-removed: Cached adaptors / lambda forms.
+
+    /** 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;
+    }
+
+    // BEGIN Android-removed: Cached adaptors / lambda forms.
+    /*
+    public MethodHandle cachedMethodHandle(int which) {
+        assert(assertIsBasicType());
+        SoftReference<MethodHandle> entry = methodHandles[which];
+        return (entry != null) ? entry.get() : null;
+    }
+
+    synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        SoftReference<MethodHandle> entry = methodHandles[which];
+        if (entry != null) {
+            MethodHandle prev = entry.get();
+            if (prev != null) {
+                return prev;
+            }
+        }
+        methodHandles[which] = new SoftReference<>(mh);
+        return mh;
+    }
+
+    public LambdaForm cachedLambdaForm(int which) {
+        assert(assertIsBasicType());
+        SoftReference<LambdaForm> entry = lambdaForms[which];
+        return (entry != null) ? entry.get() : null;
+    }
+
+    synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        SoftReference<LambdaForm> entry = lambdaForms[which];
+        if (entry != null) {
+            LambdaForm prev = entry.get();
+            if (prev != null) {
+                return prev;
+            }
+        }
+        lambdaForms[which] = new SoftReference<>(form);
+        return form;
+    }
+    */
+    // END Android-removed: Cached adaptors / lambda forms.
+
+    /**
+     * 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-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-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/java/lang/invoke/MutableCallSite.java b/java/lang/invoke/MutableCallSite.java
new file mode 100644
index 0000000..305579f
--- /dev/null
+++ b/java/lang/invoke/MutableCallSite.java
@@ -0,0 +1,282 @@
+/*
+ * 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;
+
+// Android-changed: removed references to MutableCallSite.syncAll().
+/**
+ * A {@code MutableCallSite} is a {@link CallSite} whose target variable
+ * behaves like an ordinary field.
+ * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
+ * all calls to the site's current target.
+ * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
+ * also delegates each call to the site's current target.
+ * <p>
+ * Here is an example of a mutable call site which introduces a
+ * state variable into a method handle chain.
+ * <!-- JavaDocExamplesTest.testMutableCallSite -->
+ * <blockquote><pre>{@code
+MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
+MethodHandle MH_name = name.dynamicInvoker();
+MethodType MT_str1 = MethodType.methodType(String.class);
+MethodHandle MH_upcase = MethodHandles.lookup()
+    .findVirtual(String.class, "toUpperCase", MT_str1);
+MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
+name.setTarget(MethodHandles.constant(String.class, "Rocky"));
+assertEquals("ROCKY", (String) worker1.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Fred"));
+assertEquals("FRED", (String) worker1.invokeExact());
+// (mutation can be continued indefinitely)
+ * }</pre></blockquote>
+ * <p>
+ * The same call site may be used in several places at once.
+ * <blockquote><pre>{@code
+MethodType MT_str2 = MethodType.methodType(String.class, String.class);
+MethodHandle MH_cat = lookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle MH_dear = MethodHandles.insertArguments(MH_cat, 1, ", dear?");
+MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
+assertEquals("Fred, dear?", (String) worker2.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Wilma"));
+assertEquals("WILMA", (String) worker1.invokeExact());
+assertEquals("Wilma, dear?", (String) worker2.invokeExact());
+ * }</pre></blockquote>
+ * <p>
+ * <em>Non-synchronization of target values:</em>
+ * A write to a mutable call site's target does not force other threads
+ * to become aware of the updated value.  Threads which do not perform
+ * suitable synchronization actions relative to the updated call site
+ * may cache the old target value and delay their use of the new target
+ * value indefinitely.
+ * (This is a normal consequence of the Java Memory Model as applied
+ * to object fields.)
+ * <p>
+ * For target values which will be frequently updated, consider using
+ * a {@linkplain VolatileCallSite volatile call site} instead.
+ * @author John Rose, JSR 292 EG
+ */
+public class MutableCallSite extends CallSite {
+    /**
+     * Creates a blank call site object with the given method type.
+     * The initial target is set to a method handle of the given type
+     * which will throw an {@link IllegalStateException} if called.
+     * <p>
+     * The type of the call site is permanently set to the given type.
+     * <p>
+     * Before this {@code CallSite} object is returned from a bootstrap method,
+     * or invoked in some other manner,
+     * it is usually provided with a more useful target method,
+     * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+     * @param type the method type that this call site will have
+     * @throws NullPointerException if the proposed type is null
+     */
+    public MutableCallSite(MethodType type) {
+        super(type);
+    }
+
+    /**
+     * Creates a call site object with an initial target method handle.
+     * The type of the call site is permanently set to the initial target's type.
+     * @param target the method handle that will be the initial target of the call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    public MutableCallSite(MethodHandle target) {
+        super(target);
+    }
+
+    /**
+     * Returns the target method of the call site, which behaves
+     * like a normal field of the {@code MutableCallSite}.
+     * <p>
+     * The interactions of {@code getTarget} with memory are the same
+     * as of a read from an ordinary variable, such as an array element or a
+     * non-volatile, non-final field.
+     * <p>
+     * In particular, the current thread may choose to reuse the result
+     * of a previous read of the target from memory, and may fail to see
+     * a recent update to the target by another thread.
+     *
+     * @return the linkage state of this call site, a method handle which can change over time
+     * @see #setTarget
+     */
+    @Override public final MethodHandle getTarget() {
+        return target;
+    }
+
+    /**
+     * Updates the target method of this call site, as a normal variable.
+     * The type of the new target must agree with the type of the old target.
+     * <p>
+     * The interactions with memory are the same
+     * as of a write to an ordinary variable, such as an array element or a
+     * non-volatile, non-final field.
+     * <p>
+     * In particular, unrelated threads may fail to see the updated target
+     * until they perform a read from memory.
+     * Stronger guarantees can be created by putting appropriate operations
+     * into the bootstrap method and/or the target methods used
+     * at any given call site.
+     *
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see #getTarget
+     */
+    @Override public void setTarget(MethodHandle newTarget) {
+        checkTargetChange(this.target, newTarget);
+        setTargetNormal(newTarget);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return makeDynamicInvoker();
+    }
+
+    // BEGIN Android-removed: syncAll() implementation is incomplete.
+    /**
+     * Performs a synchronization operation on each call site in the given array,
+     * forcing all other threads to throw away any cached values previously
+     * loaded from the target of any of the call sites.
+     * <p>
+     * This operation does not reverse any calls that have already started
+     * on an old target value.
+     * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
+     * <p>
+     * The overall effect is to force all future readers of each call site's target
+     * to accept the most recently stored value.
+     * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+     * Conversely, the {@code syncAll} call may block until all readers have
+     * (somehow) decached all previous versions of each call site's target.
+     * <p>
+     * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
+     * should generally be performed under some sort of mutual exclusion.
+     * Note that reader threads may observe an updated target as early
+     * as the {@code setTarget} call that install the value
+     * (and before the {@code syncAll} that confirms the value).
+     * On the other hand, reader threads may observe previous versions of
+     * the target until the {@code syncAll} call returns
+     * (and after the {@code setTarget} that attempts to convey the updated version).
+     * <p>
+     * This operation is likely to be expensive and should be used sparingly.
+     * If possible, it should be buffered for batch processing on sets of call sites.
+     * <p>
+     * If {@code sites} contains a null element,
+     * a {@code NullPointerException} will be raised.
+     * In this case, some non-null elements in the array may be
+     * processed before the method returns abnormally.
+     * Which elements these are (if any) is implementation-dependent.
+     *
+     * <h1>Java Memory Model details</h1>
+     * In terms of the Java Memory Model, this operation performs a synchronization
+     * action which is comparable in effect to the writing of a volatile variable
+     * by the current thread, and an eventual volatile read by every other thread
+     * that may access one of the affected call sites.
+     * <p>
+     * The following effects are apparent, for each individual call site {@code S}:
+     * <ul>
+     * <li>A new volatile variable {@code V} is created, and written by the current thread.
+     *     As defined by the JMM, this write is a global synchronization event.
+     * <li>As is normal with thread-local ordering of write events,
+     *     every action already performed by the current thread is
+     *     taken to happen before the volatile write to {@code V}.
+     *     (In some implementations, this means that the current thread
+     *     performs a global release operation.)
+     * <li>Specifically, the write to the current target of {@code S} is
+     *     taken to happen before the volatile write to {@code V}.
+     * <li>The volatile write to {@code V} is placed
+     *     (in an implementation specific manner)
+     *     in the global synchronization order.
+     * <li>Consider an arbitrary thread {@code T} (other than the current thread).
+     *     If {@code T} executes a synchronization action {@code A}
+     *     after the volatile write to {@code V} (in the global synchronization order),
+     *     it is therefore required to see either the current target
+     *     of {@code S}, or a later write to that target,
+     *     if it executes a read on the target of {@code S}.
+     *     (This constraint is called "synchronization-order consistency".)
+     * <li>The JMM specifically allows optimizing compilers to elide
+     *     reads or writes of variables that are known to be useless.
+     *     Such elided reads and writes have no effect on the happens-before
+     *     relation.  Regardless of this fact, the volatile {@code V}
+     *     will not be elided, even though its written value is
+     *     indeterminate and its read value is not used.
+     * </ul>
+     * Because of the last point, the implementation behaves as if a
+     * volatile read of {@code V} were performed by {@code T}
+     * immediately after its action {@code A}.  In the local ordering
+     * of actions in {@code T}, this read happens before any future
+     * read of the target of {@code S}.  It is as if the
+     * implementation arbitrarily picked a read of {@code S}'s target
+     * by {@code T}, and forced a read of {@code V} to precede it,
+     * thereby ensuring communication of the new target value.
+     * <p>
+     * As long as the constraints of the Java Memory Model are obeyed,
+     * implementations may delay the completion of a {@code syncAll}
+     * operation while other threads ({@code T} above) continue to
+     * use previous values of {@code S}'s target.
+     * However, implementations are (as always) encouraged to avoid
+     * livelock, and to eventually require all threads to take account
+     * of the updated target.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * For performance reasons, {@code syncAll} is not a virtual method
+     * on a single call site, but rather applies to a set of call sites.
+     * Some implementations may incur a large fixed overhead cost
+     * for processing one or more synchronization operations,
+     * but a small incremental cost for each additional call site.
+     * In any case, this operation is likely to be costly, since
+     * other threads may have to be somehow interrupted
+     * in order to make them notice the updated target value.
+     * However, it may be observed that a single call to synchronize
+     * several sites has the same formal effect as many calls,
+     * each on just one of the sites.
+     *
+     * <p style="font-size:smaller;">
+     * <em>Implementation Note:</em>
+     * Simple implementations of {@code MutableCallSite} may use
+     * a volatile variable for the target of a mutable call site.
+     * In such an implementation, the {@code syncAll} method can be a no-op,
+     * and yet it will conform to the JMM behavior documented above.
+     *
+     * @param sites an array of call sites to be synchronized
+     * @throws NullPointerException if the {@code sites} array reference is null
+     *                              or the array contains a null
+     *
+    public static void syncAll(MutableCallSite[] sites) {
+        if (sites.length == 0)  return;
+        STORE_BARRIER.lazySet(0);
+        for (int i = 0; i < sites.length; i++) {
+            sites[i].getClass();  // trigger NPE on first null
+        }
+        // FIXME: NYI
+    }
+    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+    */
+    // END Android-removed: syncAll() implementation is incomplete.
+}
diff --git a/java/lang/invoke/SerializedLambda.java b/java/lang/invoke/SerializedLambda.java
new file mode 100644
index 0000000..55ec670
--- /dev/null
+++ b/java/lang/invoke/SerializedLambda.java
@@ -0,0 +1,82 @@
+/*
+ * 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.io.Serializable;
+
+public final class SerializedLambda implements Serializable {
+
+    public SerializedLambda(Class<?> capturingClass,
+                            String functionalInterfaceClass,
+                            String functionalInterfaceMethodName,
+                            String functionalInterfaceMethodSignature,
+                            int implMethodKind,
+                            String implClass,
+                            String implMethodName,
+                            String implMethodSignature,
+                            String instantiatedMethodType,
+                            Object[] capturedArgs) { }
+
+    public String getCapturingClass() { return null; }
+
+    public String getFunctionalInterfaceClass() {
+        return null;
+    }
+
+    public String getFunctionalInterfaceMethodName() {
+        return null;
+    }
+
+    public String getFunctionalInterfaceMethodSignature() { return null; }
+
+    public String getImplClass() {
+        return null;
+    }
+
+    public String getImplMethodName() {
+        return null;
+    }
+
+    public String getImplMethodSignature() {
+        return null;
+    }
+
+    public int getImplMethodKind() {
+        return 0;
+    }
+
+    public final String getInstantiatedMethodType() {
+        return null;
+    }
+
+    public int getCapturedArgCount() {
+        return 0;
+    }
+
+    public Object getCapturedArg(int i) {
+        return null;
+    }
+
+}
diff --git a/java/lang/invoke/Stable.java b/java/lang/invoke/Stable.java
new file mode 100644
index 0000000..a0a413e
--- /dev/null
+++ b/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 > 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/java/lang/invoke/Transformers.java b/java/lang/invoke/Transformers.java
new file mode 100644
index 0000000..15546a8
--- /dev/null
+++ b/java/lang/invoke/Transformers.java
@@ -0,0 +1,2307 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+package java.lang.invoke;
+
+import dalvik.system.EmulatedStackFrame;
+import dalvik.system.EmulatedStackFrame.Range;
+import dalvik.system.EmulatedStackFrame.StackFrameAccessor;
+import dalvik.system.EmulatedStackFrame.StackFrameReader;
+import dalvik.system.EmulatedStackFrame.StackFrameWriter;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import sun.invoke.util.Wrapper;
+import sun.misc.Unsafe;
+import static dalvik.system.EmulatedStackFrame.StackFrameAccessor.copyNext;
+
+/**
+ * @hide Public for testing only.
+ */
+public class Transformers {
+    private Transformers() {}
+
+    static {
+        try {
+            TRANSFORM_INTERNAL = MethodHandle.class.getDeclaredMethod("transformInternal",
+                    EmulatedStackFrame.class);
+        } catch (NoSuchMethodException nsme) {
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Method reference to the private {@code MethodHandle.transformInternal} method. This is
+     * cached here because it's the point of entry for all transformers.
+     */
+    private static final Method TRANSFORM_INTERNAL;
+
+    /** @hide */
+    public static abstract class Transformer extends MethodHandle implements Cloneable {
+        protected Transformer(MethodType type) {
+            super(TRANSFORM_INTERNAL.getArtMethod(), MethodHandle.INVOKE_TRANSFORM, type);
+        }
+
+        protected Transformer(MethodType type, int invokeKind) {
+            super(TRANSFORM_INTERNAL.getArtMethod(), invokeKind, type);
+        }
+
+        @Override
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+    }
+
+    /**
+     * A method handle that always throws an exception of a specified type.
+     *
+     * The handle declares a nominal return type, which is immaterial to the execution
+     * of the handle because it never returns.
+     *
+     * @hide
+     */
+    public static class AlwaysThrow extends Transformer {
+        private final Class<? extends Throwable> exceptionType;
+
+        public AlwaysThrow(Class<?> nominalReturnType, Class<? extends  Throwable> exType) {
+            super(MethodType.methodType(nominalReturnType, exType));
+            this.exceptionType = exType;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            throw emulatedStackFrame.getReference(0, exceptionType);
+        }
+    }
+
+    /**
+     * Implements {@code MethodHandles.dropArguments}.
+     */
+    public static class DropArguments extends Transformer {
+        private final MethodHandle delegate;
+
+        private final EmulatedStackFrame.Range range1;
+
+        /**
+         * Note that {@code range2} will be null if the arguments that are being dropped
+         * are the last {@code n}.
+         */
+        /* @Nullable */ private final EmulatedStackFrame.Range range2;
+
+        public DropArguments(MethodType type, MethodHandle delegate,
+                             int startPos, int numDropped) {
+            super(type);
+
+            this.delegate = delegate;
+
+            // We pre-calculate the ranges of values we have to copy through to the delegate
+            // handle at the time of instantiation so that the actual invoke is performant.
+            this.range1 = EmulatedStackFrame.Range.of(type, 0, startPos);
+            final int numArgs = type.ptypes().length;
+            if (startPos + numDropped < numArgs) {
+                this.range2 = EmulatedStackFrame.Range.of(type, startPos + numDropped, numArgs);
+            } else {
+                this.range2 = null;
+            }
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(delegate.type());
+
+            emulatedStackFrame.copyRangeTo(calleeFrame, range1,
+                    0 /* referencesStart */, 0 /* stackFrameStart */);
+
+            if (range2 != null) {
+                final int referencesStart = range1.numReferences;
+                final int stackFrameStart = range1.numBytes;
+
+                emulatedStackFrame.copyRangeTo(calleeFrame, range2,
+                        referencesStart, stackFrameStart);
+            }
+
+            delegate.invoke(calleeFrame);
+            calleeFrame.copyReturnValueTo(emulatedStackFrame);
+        }
+    }
+
+    /**
+     * Implements {@code MethodHandles.catchException}.
+     */
+    public static class CatchException extends Transformer {
+        private final MethodHandle target;
+        private final MethodHandle handler;
+        private final Class<?> exType;
+
+        private final EmulatedStackFrame.Range handlerArgsRange;
+
+        public CatchException(MethodHandle target, MethodHandle handler, Class<?> exType) {
+            super(target.type());
+
+            this.target = target;
+            this.handler = handler;
+            this.exType = exType;
+
+            // We only copy the first "count" args, dropping others if required. Note that
+            // we subtract one because the first handler arg is the exception thrown by the
+            // target.
+            handlerArgsRange = EmulatedStackFrame.Range.of(target.type(), 0,
+                    (handler.type().parameterCount() - 1));
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            try {
+                target.invoke(emulatedStackFrame);
+            } catch (Throwable th) {
+                if (th.getClass() == exType) {
+                    // We've gotten an exception of the appropriate type, so we need to call
+                    // the handler. Create a new frame of the appropriate size.
+                    EmulatedStackFrame fallback = EmulatedStackFrame.create(handler.type());
+
+                    // The first argument to the handler is the actual exception.
+                    fallback.setReference(0, th);
+
+                    // We then copy other arguments that need to be passed through to the handler.
+                    // Note that we might drop arguments at the end, if needed. Note that
+                    // referencesStart == 1 because the first argument is the exception type.
+                    emulatedStackFrame.copyRangeTo(fallback, handlerArgsRange,
+                            1 /* referencesStart */, 0 /* stackFrameStart */);
+
+                    // Perform the invoke and return the appropriate value.
+                    handler.invoke(fallback);
+                    fallback.copyReturnValueTo(emulatedStackFrame);
+                } else {
+                    // The exception is not of the expected type, we throw it.
+                    throw th;
+                }
+            }
+        }
+    }
+
+    /**
+     * Implements {@code MethodHandles.GuardWithTest}.
+     */
+    public static class GuardWithTest extends Transformer {
+        private final MethodHandle test;
+        private final MethodHandle target;
+        private final MethodHandle fallback;
+
+        private final EmulatedStackFrame.Range testArgsRange;
+
+        public GuardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback) {
+            super(target.type());
+
+            this.test = test;
+            this.target = target;
+            this.fallback = fallback;
+
+            // The test method might have a subset of the arguments of the handle / target.
+            testArgsRange = EmulatedStackFrame.Range.of(target.type(), 0, test.type().parameterCount());
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            EmulatedStackFrame testFrame = EmulatedStackFrame.create(test.type());
+            emulatedStackFrame.copyRangeTo(testFrame, testArgsRange, 0, 0);
+
+            // We know that the return value for test is going to be boolean.class, so we don't have
+            // to do the copyReturnValue dance.
+            final boolean value = (boolean) test.invoke(testFrame);
+            if (value) {
+                target.invoke(emulatedStackFrame);
+            } else {
+                fallback.invoke(emulatedStackFrame);
+            }
+        }
+    }
+
+    /**
+     * Implementation of MethodHandles.arrayElementGetter for reference types.
+     */
+    public static class ReferenceArrayElementGetter extends Transformer {
+        private final Class<?> arrayClass;
+
+        public ReferenceArrayElementGetter(Class<?> arrayClass) {
+            super(MethodType.methodType(arrayClass.getComponentType(),
+                    new Class<?>[]{arrayClass, int.class}));
+            this.arrayClass = arrayClass;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(emulatedStackFrame);
+
+            // Read the array object and the index from the stack frame.
+            final Object[] array = (Object[]) reader.nextReference(arrayClass);
+            final int index = reader.nextInt();
+
+            // Write the array element back to the stack frame.
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(emulatedStackFrame);
+            writer.makeReturnValueAccessor();
+            writer.putNextReference(array[index], arrayClass.getComponentType());
+        }
+    }
+
+    /**
+     * Implementation of MethodHandles.arrayElementSetter for reference types.
+     */
+    public static class ReferenceArrayElementSetter extends Transformer {
+        private final Class<?> arrayClass;
+
+        public ReferenceArrayElementSetter(Class<?> arrayClass) {
+            super(MethodType.methodType(void.class,
+                    new Class<?>[] { arrayClass, int.class, arrayClass.getComponentType() }));
+            this.arrayClass = arrayClass;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(emulatedStackFrame);
+
+            // Read the array object, index and the value to write from the stack frame.
+            final Object[] array = (Object[]) reader.nextReference(arrayClass);
+            final int index = reader.nextInt();
+            final Object value = reader.nextReference(arrayClass.getComponentType());
+
+            array[index] = value;
+        }
+    }
+
+    /**
+     * Implementation of MethodHandles.identity() for reference types.
+     */
+    public static class ReferenceIdentity extends Transformer {
+        private final Class<?> type;
+
+        public ReferenceIdentity(Class<?> type) {
+            super(MethodType.methodType(type, type));
+            this.type = type;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(emulatedStackFrame);
+
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(emulatedStackFrame);
+            writer.makeReturnValueAccessor();
+            writer.putNextReference(reader.nextReference(type), type);
+        }
+    }
+
+    /**
+     * Implementation of MethodHandles.constant.
+     */
+    public static class Constant extends Transformer {
+        private final Class<?> type;
+
+        // NOTE: This implementation turned out to be more awkward than expected becuase
+        // of the type system. We could simplify this considerably at the cost of making
+        // the emulated stack frame API uglier or by transitioning into JNI.
+        //
+        // We could consider implementing this in terms of bind() once that's implemented.
+        // This would then just become : MethodHandles.identity(type).bind(value).
+        private int asInt;
+        private long asLong;
+        private float asFloat;
+        private double asDouble;
+        private Object asReference;
+
+        private char typeChar;
+
+        public Constant(Class<?> type, Object value) {
+            super(MethodType.methodType(type));
+            this.type = type;
+
+            if (!type.isPrimitive()) {
+                asReference = value;
+                typeChar = 'L';
+            } else if (type == int.class) {
+                asInt = (int) value;
+                typeChar = 'I';
+            } else if (type == char.class) {
+                asInt = (int) (char) value;
+                typeChar = 'C';
+            } else if (type == short.class) {
+                asInt = (int) (short) value;
+                typeChar = 'S';
+            } else if (type == byte.class) {
+                asInt = (int) (byte) value;
+                typeChar = 'B';
+            } else if (type == boolean.class) {
+                asInt = ((boolean) value) ? 1 : 0;
+                typeChar = 'Z';
+            } else if (type == long.class) {
+                asLong = (long) value;
+                typeChar = 'J';
+            } else if (type == float.class) {
+                asFloat = (float) value;
+                typeChar = 'F';
+            } else if (type == double.class) {
+                asDouble = (double) value;
+                typeChar = 'D';
+            } else {
+                throw new AssertionError("unknown type: " + typeChar);
+            }
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(emulatedStackFrame);
+            writer.makeReturnValueAccessor();
+
+            switch (typeChar) {
+                case 'L' : { writer.putNextReference(asReference, type); break; }
+                case 'I' : { writer.putNextInt(asInt); break; }
+                case 'C' : { writer.putNextChar((char) asInt); break; }
+                case 'S' : { writer.putNextShort((short) asInt); break; }
+                case 'B' : { writer.putNextByte((byte) asInt); break; }
+                case 'Z' : { writer.putNextBoolean(asInt == 1); break; }
+                case 'J' : { writer.putNextLong(asLong); break; }
+                case 'F' : { writer.putNextFloat(asFloat); break; }
+                case 'D' : { writer.putNextDouble(asDouble); break; }
+                default:
+                    throw new AssertionError("Unexpected typeChar: " + typeChar);
+            }
+        }
+    }
+
+    /*package*/ static class Construct extends Transformer {
+        private final MethodHandle constructorHandle;
+        private final EmulatedStackFrame.Range callerRange;
+
+        /*package*/ Construct(MethodHandle constructorHandle, MethodType returnedType) {
+            super(returnedType);
+            this.constructorHandle = constructorHandle;
+            this.callerRange = EmulatedStackFrame.Range.all(type());
+        }
+
+        MethodHandle getConstructorHandle() {
+            return constructorHandle;
+        }
+
+        private static boolean isAbstract(Class<?> klass) {
+            return (klass.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
+        }
+
+        private static void checkInstantiable(Class<?> klass) throws InstantiationException {
+            if (isAbstract(klass)) {
+                String s = klass.isInterface() ? "interface " : "abstract class ";
+                throw new InstantiationException("Can't instantiate " + s + klass);
+            }
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final Class<?> receiverType = constructorHandle.type().parameterType(0);
+            checkInstantiable(receiverType);
+
+            // Allocate memory for receiver.
+            Object receiver = Unsafe.getUnsafe().allocateInstance(receiverType);
+
+            // The MethodHandle type for the caller has the form of
+            // {rtype=T,ptypes=A1..An}. The constructor MethodHandle is of
+            // the form {rtype=void,ptypes=T,A1...An}. So the frame for
+            // the constructor needs to have a slot with the receiver
+            // in position 0.
+            EmulatedStackFrame constructorFrame =
+                    EmulatedStackFrame.create(constructorHandle.type());
+            constructorFrame.setReference(0, receiver);
+            emulatedStackFrame.copyRangeTo(constructorFrame, callerRange, 1, 0);
+            constructorHandle.invoke(constructorFrame);
+
+            // Set return result for caller.
+            emulatedStackFrame.setReturnValueTo(receiver);
+        }
+    }
+
+    /**
+     * Implements MethodHandle.bindTo.
+     *
+     * @hide
+     */
+    public static class BindTo extends Transformer {
+        private final MethodHandle delegate;
+        private final Object receiver;
+
+        private final EmulatedStackFrame.Range range;
+
+        public BindTo(MethodHandle delegate, Object receiver) {
+            super(delegate.type().dropParameterTypes(0, 1));
+
+            this.delegate = delegate;
+            this.receiver = receiver;
+
+            this.range = EmulatedStackFrame.Range.all(this.type());
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            // Create a new emulated stack frame with the full type (including the leading
+            // receiver reference).
+            EmulatedStackFrame stackFrame = EmulatedStackFrame.create(delegate.type());
+
+            // The first reference argument must be the receiver.
+            stackFrame.setReference(0, receiver);
+            // Copy all other arguments.
+            emulatedStackFrame.copyRangeTo(stackFrame, range,
+                    1 /* referencesStart */, 0 /* stackFrameStart */);
+
+            // Perform the invoke.
+            delegate.invoke(stackFrame);
+            stackFrame.copyReturnValueTo(emulatedStackFrame);
+        }
+    }
+
+    /**
+     * Implements MethodHandle.filterReturnValue.
+     */
+    public static class FilterReturnValue extends Transformer {
+        private final MethodHandle target;
+        private final MethodHandle filter;
+
+        private final EmulatedStackFrame.Range allArgs;
+
+        public FilterReturnValue(MethodHandle target, MethodHandle filter) {
+            super(MethodType.methodType(filter.type().rtype(), target.type().ptypes()));
+
+            this.target = target;
+            this.filter = filter;
+
+            allArgs = EmulatedStackFrame.Range.all(type());
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            // Create a new frame with the target's type and copy all arguments over.
+            // This frame differs in return type with |emulatedStackFrame| but will have
+            // the same parameter shapes.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+            emulatedStackFrame.copyRangeTo(targetFrame, allArgs, 0, 0);
+            target.invoke(targetFrame);
+
+            // Perform the invoke.
+            final StackFrameReader returnValueReader = new StackFrameReader();
+            returnValueReader.attach(targetFrame);
+            returnValueReader.makeReturnValueAccessor();
+
+            // Create an emulated frame for the filter and copy all its arguments across.
+            EmulatedStackFrame filterFrame = EmulatedStackFrame.create(filter.type());
+            final StackFrameWriter filterWriter = new StackFrameWriter();
+            filterWriter.attach(filterFrame);
+
+            final Class<?> returnType = target.type().rtype();
+            if (!returnType.isPrimitive()) {
+                filterWriter.putNextReference(returnValueReader.nextReference(returnType),
+                        returnType);
+            } else if (returnType == boolean.class) {
+                filterWriter.putNextBoolean(returnValueReader.nextBoolean());
+            } else if (returnType == byte.class) {
+                filterWriter.putNextByte(returnValueReader.nextByte());
+            } else if (returnType == char.class) {
+                filterWriter.putNextChar(returnValueReader.nextChar());
+            } else if (returnType == short.class) {
+                filterWriter.putNextShort(returnValueReader.nextShort());
+            } else if (returnType == int.class) {
+                filterWriter.putNextInt(returnValueReader.nextInt());
+            } else if (returnType == long.class) {
+                filterWriter.putNextLong(returnValueReader.nextLong());
+            } else if (returnType == float.class) {
+                filterWriter.putNextFloat(returnValueReader.nextFloat());
+            } else if (returnType == double.class) {
+                filterWriter.putNextDouble(returnValueReader.nextDouble());
+            }
+
+            // Invoke the filter and copy its return value back to the original frame.
+            filter.invoke(filterFrame);
+            filterFrame.copyReturnValueTo(emulatedStackFrame);
+        }
+    }
+
+    /*
+     * Implements MethodHandles.permuteArguments.
+     *
+     * @hide
+     */
+    public static class PermuteArguments extends Transformer {
+        private final MethodHandle target;
+        private final int[] reorder;
+
+        public PermuteArguments(MethodType type, MethodHandle target, int[] reorder) {
+            super(type);
+
+            this.target = target;
+            this.reorder = reorder;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(emulatedStackFrame);
+
+            // In the interests of simplicity, we box / unbox arguments while performing
+            // the permutation. We first iterate through the incoming stack frame and box
+            // each argument. We then unbox and write out the argument to the target frame
+            // according to the specified reordering.
+            Object[] arguments = new Object[reorder.length];
+            final Class<?>[] ptypes = type().ptypes();
+            for (int i = 0; i < ptypes.length; ++i) {
+                final Class<?> ptype = ptypes[i];
+                if (!ptype.isPrimitive()) {
+                    arguments[i] = reader.nextReference(ptype);
+                } else if (ptype == boolean.class) {
+                    arguments[i] = reader.nextBoolean();
+                } else if (ptype == byte.class) {
+                    arguments[i] = reader.nextByte();
+                } else if (ptype == char.class) {
+                    arguments[i] = reader.nextChar();
+                } else if (ptype == short.class) {
+                    arguments[i] = reader.nextShort();
+                } else if (ptype == int.class) {
+                    arguments[i] = reader.nextInt();
+                } else if (ptype == long.class) {
+                    arguments[i] = reader.nextLong();
+                } else if (ptype == float.class) {
+                    arguments[i] = reader.nextFloat();
+                } else if (ptype == double.class) {
+                    arguments[i] = reader.nextDouble();
+                } else {
+                    throw new AssertionError("Unexpected type: " + ptype);
+                }
+            }
+
+            EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(target.type());
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(calleeFrame);
+
+            for (int i = 0; i < ptypes.length; ++i) {
+                int idx = reorder[i];
+                final Class<?> ptype = ptypes[idx];
+                final Object argument = arguments[idx];
+
+                if (!ptype.isPrimitive()) {
+                    writer.putNextReference(argument, ptype);
+                } else if (ptype == boolean.class) {
+                    writer.putNextBoolean((boolean) argument);
+                } else if (ptype == byte.class) {
+                    writer.putNextByte((byte) argument);
+                } else if (ptype == char.class) {
+                    writer.putNextChar((char) argument);
+                } else if (ptype == short.class) {
+                    writer.putNextShort((short) argument);
+                } else if (ptype == int.class) {
+                    writer.putNextInt((int) argument);
+                } else if (ptype == long.class) {
+                    writer.putNextLong((long) argument);
+                } else if (ptype == float.class) {
+                    writer.putNextFloat((float) argument);
+                } else if (ptype == double.class) {
+                    writer.putNextDouble((double) argument);
+                } else {
+                    throw new AssertionError("Unexpected type: " + ptype);
+                }
+            }
+
+            target.invoke(calleeFrame);
+            calleeFrame.copyReturnValueTo(emulatedStackFrame);
+        }
+    }
+
+    /**
+     * Converts methods with a trailing array argument to variable arity
+     * methods. So (A,B,C[])R can be invoked with any number of convertible
+     * arguments after B, e.g. (A,B)R or (A, B, C0)R or (A, B, C0...Cn)R.
+     *
+     * @hide
+     */
+    /*package*/ static class VarargsCollector extends Transformer {
+        final MethodHandle target;
+
+        /*package*/ VarargsCollector(MethodHandle target) {
+            super(target.type(), MethodHandle.INVOKE_CALLSITE_TRANSFORM);
+            if (!lastParameterTypeIsAnArray(target.type().ptypes())) {
+                throw new IllegalArgumentException("target does not have array as last parameter");
+            }
+            this.target = target;
+        }
+
+        private static boolean lastParameterTypeIsAnArray(Class<?>[] parameterTypes) {
+            if (parameterTypes.length == 0) return false;
+            return parameterTypes[parameterTypes.length - 1].isArray();
+        }
+
+        @Override
+        public boolean isVarargsCollector() { return true; }
+
+        @Override
+        public MethodHandle asFixedArity() { return target; }
+
+        @Override
+        public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+            MethodType callerFrameType = callerFrame.getMethodType();
+            Class<?>[] callerPTypes = callerFrameType.ptypes();
+            Class<?>[] targetPTypes = type().ptypes();
+
+            int lastTargetIndex = targetPTypes.length - 1;
+            if (callerPTypes.length == targetPTypes.length &&
+                targetPTypes[lastTargetIndex].isAssignableFrom(callerPTypes[lastTargetIndex])) {
+                // Caller frame matches target frame in the arity array parameter. Invoke
+                // immediately, and let the invoke() dispatch perform any necessary conversions
+                // on the other parameters present.
+                target.invoke(callerFrame);
+                return;
+            }
+
+            if (callerPTypes.length < targetPTypes.length - 1) {
+                // Too few arguments to be compatible with variable arity invocation.
+                throwWrongMethodTypeException(callerFrameType, type());
+            }
+
+            if (!MethodType.canConvert(type().rtype(), callerFrameType.rtype())) {
+                // Incompatible return type.
+                throwWrongMethodTypeException(callerFrameType, type());
+            }
+
+            Class<?> elementType = targetPTypes[lastTargetIndex].getComponentType();
+            if (!arityArgumentsConvertible(callerPTypes, lastTargetIndex, elementType)) {
+                // Wrong types to be compatible with variable arity invocation.
+                throwWrongMethodTypeException(callerFrameType, type());
+            }
+
+            // Allocate targetFrame.
+            MethodType targetFrameType = makeTargetFrameType(callerFrameType, type());
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(targetFrameType);
+            prepareFrame(callerFrame, targetFrame);
+
+            // Invoke target.
+            target.invoke(targetFrame);
+
+            // Copy return value to the caller's frame.
+            targetFrame.copyReturnValueTo(callerFrame);
+        }
+
+        private static void throwWrongMethodTypeException(MethodType from, MethodType to) {
+            throw new WrongMethodTypeException("Cannot convert " + from + " to " + to);
+        }
+
+        private static boolean arityArgumentsConvertible(Class<?>[] ptypes, int arityStart,
+                                                         Class<?> elementType) {
+            if (ptypes.length - 1 == arityStart) {
+                if (ptypes[arityStart].isArray() &&
+                    ptypes[arityStart].getComponentType() == elementType) {
+                    // The last ptype is in the same position as the arity
+                    // array and has the same type.
+                    return true;
+                }
+            }
+
+            for (int i = arityStart; i < ptypes.length; ++i) {
+                if (!MethodType.canConvert(ptypes[i], elementType)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private static Object referenceArray(StackFrameReader reader, Class<?>[] ptypes,
+                                             Class<?> elementType, int offset, int length) {
+            Object arityArray = Array.newInstance(elementType, length);
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                Object o = null;
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { o = reader.nextReference(argumentType); break; }
+                    case 'I': { o = reader.nextInt(); break; }
+                    case 'J': { o = reader.nextLong(); break; }
+                    case 'B': { o = reader.nextByte(); break; }
+                    case 'S': { o = reader.nextShort(); break; }
+                    case 'C': { o = reader.nextChar(); break; }
+                    case 'Z': { o = reader.nextBoolean(); break; }
+                    case 'F': { o = reader.nextFloat(); break; }
+                    case 'D': { o = reader.nextDouble(); break; }
+                }
+                Array.set(arityArray, i, elementType.cast(o));
+            }
+            return arityArray;
+        }
+
+        private static Object intArray(StackFrameReader reader, Class<?> ptypes[],
+                                       int offset, int length) {
+            int[] arityArray = new int[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'I': { arityArray[i] = reader.nextInt(); break; }
+                    case 'S': { arityArray[i] = reader.nextShort(); break; }
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: {
+                        arityArray[i] = (Integer) reader.nextReference(argumentType);
+                        break;
+                    }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object longArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            long[] arityArray = new long[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'J': { arityArray[i] = reader.nextLong(); break; }
+                    case 'I': { arityArray[i] = reader.nextInt(); break; }
+                    case 'S': { arityArray[i] = reader.nextShort(); break; }
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: { arityArray[i] = (Long) reader.nextReference(argumentType); break; }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object byteArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            byte[] arityArray = new byte[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: { arityArray[i] = (Byte) reader.nextReference(argumentType); break; }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object shortArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            short[] arityArray = new short[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'S': { arityArray[i] = reader.nextShort(); break; }
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: { arityArray[i] = (Short) reader.nextReference(argumentType); break; }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object charArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            char[] arityArray = new char[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'C': { arityArray[i] = reader.nextChar(); break; }
+                    default: {
+                        arityArray[i] = (Character) reader.nextReference(argumentType);
+                        break;
+                    }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object booleanArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            boolean[] arityArray = new boolean[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'Z': { arityArray[i] = reader.nextBoolean(); break; }
+                    default:
+                        arityArray[i] = (Boolean) reader.nextReference(argumentType);
+                        break;
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object floatArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            float[] arityArray = new float[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'F': { arityArray[i] = reader.nextFloat(); break; }
+                    case 'J': { arityArray[i] = reader.nextLong(); break; }
+                    case 'I': { arityArray[i] = reader.nextInt(); break; }
+                    case 'S': { arityArray[i] = reader.nextShort(); break; }
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: {
+                        arityArray[i] = (Float) reader.nextReference(argumentType);
+                        break;
+                    }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object doubleArray(StackFrameReader reader, Class<?> ptypes[],
+                                        int offset, int length) {
+            double[] arityArray = new double[length];
+            for (int i = 0; i < length; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'D': { arityArray[i] = reader.nextDouble(); break; }
+                    case 'F': { arityArray[i] = reader.nextFloat(); break; }
+                    case 'J': { arityArray[i] = reader.nextLong(); break; }
+                    case 'I': { arityArray[i] = reader.nextInt(); break; }
+                    case 'S': { arityArray[i] = reader.nextShort(); break; }
+                    case 'B': { arityArray[i] = reader.nextByte(); break; }
+                    default: {
+                        arityArray[i] = (Double) reader.nextReference(argumentType);
+                        break;
+                    }
+                }
+            }
+            return arityArray;
+        }
+
+        private static Object makeArityArray(MethodType callerFrameType,
+                                             StackFrameReader callerFrameReader,
+                                             int indexOfArityArray,
+                                             Class<?> arityArrayType) {
+            int arityArrayLength = callerFrameType.ptypes().length - indexOfArityArray;
+            Class<?> elementType = arityArrayType.getComponentType();
+            Class<?>[] callerPTypes = callerFrameType.ptypes();
+
+            char elementBasicType = Wrapper.basicTypeChar(elementType);
+            switch (elementBasicType) {
+                case 'L': return referenceArray(callerFrameReader, callerPTypes, elementType,
+                                                indexOfArityArray, arityArrayLength);
+                case 'I': return intArray(callerFrameReader, callerPTypes,
+                                          indexOfArityArray, arityArrayLength);
+                case 'J': return longArray(callerFrameReader, callerPTypes,
+                                           indexOfArityArray, arityArrayLength);
+                case 'B': return byteArray(callerFrameReader, callerPTypes,
+                                           indexOfArityArray, arityArrayLength);
+                case 'S': return shortArray(callerFrameReader, callerPTypes,
+                                            indexOfArityArray, arityArrayLength);
+                case 'C': return charArray(callerFrameReader, callerPTypes,
+                                           indexOfArityArray, arityArrayLength);
+                case 'Z': return booleanArray(callerFrameReader, callerPTypes,
+                                              indexOfArityArray, arityArrayLength);
+                case 'F': return floatArray(callerFrameReader, callerPTypes,
+                                            indexOfArityArray, arityArrayLength);
+                case 'D': return doubleArray(callerFrameReader, callerPTypes,
+                                             indexOfArityArray, arityArrayLength);
+            }
+            throw new InternalError("Unexpected type: " + elementType);
+        }
+
+        public static Object collectArguments(char basicComponentType, Class<?> componentType,
+                                              StackFrameReader reader, Class<?>[] types,
+                                              int startIdx, int length) {
+            switch (basicComponentType) {
+                case 'L': return referenceArray(reader, types, componentType, startIdx, length);
+                case 'I': return intArray(reader, types, startIdx, length);
+                case 'J': return longArray(reader, types, startIdx, length);
+                case 'B': return byteArray(reader, types, startIdx, length);
+                case 'S': return shortArray(reader, types, startIdx, length);
+                case 'C': return charArray(reader, types, startIdx, length);
+                case 'Z': return booleanArray(reader, types, startIdx, length);
+                case 'F': return floatArray(reader, types, startIdx, length);
+                case 'D': return doubleArray(reader, types, startIdx, length);
+            }
+            throw new InternalError("Unexpected type: " + basicComponentType);
+        }
+
+        private static void copyParameter(StackFrameReader reader, StackFrameWriter writer,
+                                          Class<?> ptype) {
+            switch (Wrapper.basicTypeChar(ptype)) {
+                case 'L': { writer.putNextReference(reader.nextReference(ptype), ptype); break; }
+                case 'I': { writer.putNextInt(reader.nextInt()); break; }
+                case 'J': { writer.putNextLong(reader.nextLong()); break; }
+                case 'B': { writer.putNextByte(reader.nextByte()); break; }
+                case 'S': { writer.putNextShort(reader.nextShort()); break; }
+                case 'C': { writer.putNextChar(reader.nextChar()); break; }
+                case 'Z': { writer.putNextBoolean(reader.nextBoolean()); break; }
+                case 'F': { writer.putNextFloat(reader.nextFloat()); break; }
+                case 'D': { writer.putNextDouble(reader.nextDouble()); break; }
+                default: throw new InternalError("Unexpected type: " + ptype);
+            }
+        }
+
+        private static void prepareFrame(EmulatedStackFrame callerFrame,
+                                         EmulatedStackFrame targetFrame) {
+            StackFrameWriter targetWriter = new StackFrameWriter();
+            targetWriter.attach(targetFrame);
+            StackFrameReader callerReader = new StackFrameReader();
+            callerReader.attach(callerFrame);
+
+            // Copy parameters from |callerFrame| to |targetFrame| leaving room for arity array.
+            MethodType targetMethodType = targetFrame.getMethodType();
+            int indexOfArityArray = targetMethodType.ptypes().length - 1;
+            for (int i = 0; i < indexOfArityArray; ++i) {
+                Class<?> ptype = targetMethodType.ptypes()[i];
+                copyParameter(callerReader, targetWriter, ptype);
+            }
+
+            // Add arity array as last parameter in |targetFrame|.
+            Class<?> arityArrayType = targetMethodType.ptypes()[indexOfArityArray];
+            Object arityArray = makeArityArray(callerFrame.getMethodType(), callerReader,
+                                               indexOfArityArray, arityArrayType);
+            targetWriter.putNextReference(arityArray, arityArrayType);
+        }
+
+        /**
+         * Computes the frame type to invoke the target method handle with. This
+         * is the same as the caller frame type, but with the trailing argument
+         * being the array type that is the trailing argument in the target method
+         * handle.
+         *
+         * Suppose the targetType is (T0, T1, T2[])RT and the callerType is (C0, C1, C2, C3)RC
+         * then the constructed type is (C0, C1, T2[])RC.
+         */
+        private static MethodType makeTargetFrameType(MethodType callerType,
+                                                      MethodType targetType) {
+            final int ptypesLength = targetType.ptypes().length;
+            final Class<?>[] ptypes = new Class<?>[ptypesLength];
+            // Copy types from caller types to new methodType.
+            System.arraycopy(callerType.ptypes(), 0, ptypes, 0, ptypesLength - 1);
+            // Set the last element in the type array to be the
+            // varargs array of the target.
+            ptypes[ptypesLength - 1] = targetType.ptypes()[ptypesLength - 1];
+            return MethodType.methodType(callerType.rtype(), ptypes);
+        }
+    }
+
+    /**
+     * Implements MethodHandles.invoker & MethodHandles.exactInvoker.
+     */
+    static class Invoker extends Transformer {
+        private final MethodType targetType;
+        private final boolean isExactInvoker;
+        private final EmulatedStackFrame.Range copyRange;
+
+        Invoker(MethodType targetType, boolean isExactInvoker) {
+            super(targetType.insertParameterTypes(0, MethodHandle.class));
+            this.targetType = targetType;
+            this.isExactInvoker = isExactInvoker;
+            copyRange = EmulatedStackFrame.Range.of(type(), 1, type().parameterCount());
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+            // We need to artifically throw a WrongMethodTypeException here because we
+            // can't call invokeExact on the target inside the transformer.
+            if (isExactInvoker) {
+                // TODO: We should do the comparison by hand if this new type creation
+                // on every invoke proves too expensive.
+                MethodType callType = emulatedStackFrame.getCallsiteType().dropParameterTypes(0, 1);
+                if (!targetType.equals(callType)) {
+                    throw new WrongMethodTypeException("Wrong type, Expected: " + targetType
+                            + " was: " + callType);
+                }
+            }
+
+            // The first argument to the stack frame is the handle that needs to be invoked.
+            MethodHandle target = emulatedStackFrame.getReference(0, MethodHandle.class);
+
+            // All other arguments must be copied to the target frame.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(targetType);
+            emulatedStackFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+            // Finally, invoke the handle and copy the return value.
+            target.invoke(targetFrame);
+            targetFrame.copyReturnValueTo(emulatedStackFrame);
+        }
+    }
+
+    /**
+     * Implements MethodHandle.asSpreader / MethodHandles.spreadInvoker.
+     */
+    static class Spreader extends Transformer {
+        /** The method handle we're delegating to. */
+        private final MethodHandle target;
+
+        /**
+         * The offset of the trailing array argument in the list of arguments to
+         * this transformer. The array argument is always the last argument.
+         */
+        private final int arrayOffset;
+
+        /**
+         * The type char of the component type of the array.
+         */
+        private final char arrayTypeChar;
+
+        /**
+         * The number of input arguments that will be present in the array. In other words,
+         * this is the expected array length.
+         */
+        private final int numArrayArgs;
+
+        /**
+         * Range of arguments to copy verbatim from the input frame, This will cover all
+         * arguments that aren't a part of the trailing array.
+         */
+        private final Range copyRange;
+
+        Spreader(MethodHandle target, MethodType spreaderType, int numArrayArgs) {
+            super(spreaderType);
+            this.target = target;
+            // Copy all arguments except the last argument (which is the trailing array argument
+            // that needs to be spread).
+            arrayOffset = spreaderType.parameterCount() - 1;
+
+            // Get and cache the component type of the input array.
+            final Class<?> componentType = spreaderType.ptypes()[arrayOffset].getComponentType();
+            if (componentType == null) {
+                throw new AssertionError("Trailing argument must be an array.");
+            }
+            arrayTypeChar = Wrapper.basicTypeChar(componentType);
+
+            this.numArrayArgs = numArrayArgs;
+            // Copy all args except for the last argument.
+            this.copyRange = EmulatedStackFrame.Range.of(spreaderType, 0, arrayOffset);
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+            // Create a new stack frame for the callee.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+            // Copy all arguments except for the trailing array argument.
+            callerFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+            // Attach the writer, prepare to spread the trailing array arguments into
+            // the callee frame.
+            StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(targetFrame,
+                    arrayOffset,
+                    copyRange.numReferences,
+                    copyRange.numBytes);
+
+            // Get the array reference and check that its length is as expected.
+            Object arrayObj = callerFrame.getReference(
+                    copyRange.numReferences, this.type().ptypes()[arrayOffset]);
+            final int arrayLength = Array.getLength(arrayObj);
+            if (arrayLength != numArrayArgs) {
+                throw new IllegalArgumentException("Invalid array length: " + arrayLength);
+            }
+
+            final MethodType type = target.type();
+            switch (arrayTypeChar) {
+                case 'L':
+                    spreadArray((Object[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'I':
+                    spreadArray((int[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'J':
+                    spreadArray((long[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'B':
+                    spreadArray((byte[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'S':
+                    spreadArray((short[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'C':
+                    spreadArray((char[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'Z':
+                    spreadArray((boolean[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'F':
+                    spreadArray((float[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'D':
+                    spreadArray((double[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+
+            }
+
+            target.invoke(targetFrame);
+            targetFrame.copyReturnValueTo(callerFrame);
+        }
+
+        public static void spreadArray(Object[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                Object o = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(o, argumentType); break; }
+                    case 'I': { writer.putNextInt((int) o); break; }
+                    case 'J': { writer.putNextLong((long) o); break; }
+                    case 'B': { writer.putNextByte((byte) o); break; }
+                    case 'S': { writer.putNextShort((short) o); break; }
+                    case 'C': { writer.putNextChar((char) o); break; }
+                    case 'Z': { writer.putNextBoolean((boolean) o); break; }
+                    case 'F': { writer.putNextFloat((float) o); break; }
+                    case 'D': { writer.putNextDouble((double) o); break; }
+                }
+            }
+        }
+
+        public static void spreadArray(int[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                int j = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(j, argumentType); break; }
+                    case 'I': { writer.putNextInt(j); break; }
+                    case 'J': { writer.putNextLong(j); break; }
+                    case 'F': { writer.putNextFloat(j); break; }
+                    case 'D': { writer.putNextDouble(j); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(long[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                long l = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(l, argumentType); break; }
+                    case 'J': { writer.putNextLong(l); break; }
+                    case 'F': { writer.putNextFloat((float) l); break; }
+                    case 'D': { writer.putNextDouble((double) l); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(byte[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                byte b = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(b, argumentType); break; }
+                    case 'I': { writer.putNextInt(b); break; }
+                    case 'J': { writer.putNextLong(b); break; }
+                    case 'B': { writer.putNextByte(b); break; }
+                    case 'S': { writer.putNextShort(b); break; }
+                    case 'F': { writer.putNextFloat(b); break; }
+                    case 'D': { writer.putNextDouble(b); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(short[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                short s = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(s, argumentType); break; }
+                    case 'I': { writer.putNextInt(s); break; }
+                    case 'J': { writer.putNextLong(s); break; }
+                    case 'S': { writer.putNextShort(s); break; }
+                    case 'F': { writer.putNextFloat(s); break; }
+                    case 'D': { writer.putNextDouble(s); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(char[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                char c = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(c, argumentType); break; }
+                    case 'I': { writer.putNextInt(c); break; }
+                    case 'J': { writer.putNextLong(c); break; }
+                    case 'C': { writer.putNextChar(c); break; }
+                    case 'F': { writer.putNextFloat(c); break; }
+                    case 'D': { writer.putNextDouble(c); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(boolean[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                boolean z = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(z, argumentType); break; }
+                    case 'Z': { writer.putNextBoolean(z); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(double[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                double d = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(d, argumentType); break; }
+                    case 'D': { writer.putNextDouble(d); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(float[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                float f = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(f, argumentType); break; }
+                    case 'D': { writer.putNextDouble((double) f); break; }
+                    case 'F': { writer.putNextFloat(f); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+    }
+
+    /**
+     * Implements MethodHandle.asCollector.
+     */
+    static class Collector extends Transformer {
+        private final MethodHandle target;
+
+        /**
+         * The offset of the trailing array argument in the list of arguments to
+         * this transformer. The array argument is always the last argument.
+         */
+        private final int arrayOffset;
+
+        /**
+         * The number of input arguments that will be present in the array. In other words,
+         * this is the expected array length.
+         */
+        private final int numArrayArgs;
+
+        /**
+         * The type char of the component type of the array.
+         */
+        private final char arrayTypeChar;
+
+        /**
+         * Range of arguments to copy verbatim from the input frame, This will cover all
+         * arguments that aren't a part of the trailing array.
+         */
+        private final Range copyRange;
+
+        Collector(MethodHandle delegate, Class<?> arrayType, int length) {
+            super(delegate.type().asCollectorType(arrayType, length));
+
+            target = delegate;
+            // Copy all arguments except the last argument (which is the trailing array argument
+            // that needs to be spread).
+            arrayOffset = delegate.type().parameterCount() - 1;
+            arrayTypeChar = Wrapper.basicTypeChar(arrayType.getComponentType());
+            numArrayArgs = length;
+
+            // Copy all args except for the last argument.
+            copyRange = EmulatedStackFrame.Range.of(delegate.type(), 0, arrayOffset);
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+            // Create a new stack frame for the callee.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+            // Copy all arguments except for the trailing array argument.
+            callerFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+            // Attach the writer, prepare to spread the trailing array arguments into
+            // the callee frame.
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(targetFrame, arrayOffset, copyRange.numReferences, copyRange.numBytes);
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(callerFrame, arrayOffset, copyRange.numReferences, copyRange.numBytes);
+
+            switch (arrayTypeChar) {
+                case 'L': {
+                    // Reference arrays are the only case where the component type of the
+                    // array we construct might differ from the type of the reference we read
+                    // from the stack frame.
+                    final Class<?> targetType = target.type().ptypes()[arrayOffset];
+                    final Class<?> targetComponentType = targetType.getComponentType();
+                    final Class<?> adapterComponentType = type().lastParameterType();
+
+                    Object[] arr = (Object[]) Array.newInstance(targetComponentType, numArrayArgs);
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        arr[i] = reader.nextReference(adapterComponentType);
+                    }
+
+                    writer.putNextReference(arr, targetType);
+                    break;
+                }
+                case 'I': {
+                    int[] array = new int[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextInt();
+                    }
+                    writer.putNextReference(array, int[].class);
+                    break;
+                }
+                case 'J': {
+                    long[] array = new long[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextLong();
+                    }
+                    writer.putNextReference(array, long[].class);
+                    break;
+                }
+                case 'B': {
+                    byte[] array = new byte[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextByte();
+                    }
+                    writer.putNextReference(array, byte[].class);
+                    break;
+                }
+                case 'S': {
+                    short[] array = new short[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextShort();
+                    }
+                    writer.putNextReference(array, short[].class);
+                    break;
+                }
+                case 'C': {
+                    char[] array = new char[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextChar();
+                    }
+                    writer.putNextReference(array, char[].class);
+                    break;
+                }
+                case 'Z': {
+                    boolean[] array = new boolean[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextBoolean();
+                    }
+                    writer.putNextReference(array, boolean[].class);
+                    break;
+                }
+                case 'F': {
+                    float[] array = new float[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextFloat();
+                    }
+                    writer.putNextReference(array, float[].class);
+                    break;
+                }
+                case 'D': {
+                    double[] array = new double[numArrayArgs];
+                    for (int i = 0; i < numArrayArgs; ++i) {
+                        array[i] = reader.nextDouble();
+                    }
+                    writer.putNextReference(array, double[].class);
+                    break;
+                }
+            }
+
+            target.invoke(targetFrame);
+            targetFrame.copyReturnValueTo(callerFrame);
+        }
+    }
+
+    /*
+     * Implements MethodHandles.filterArguments.
+     */
+    static class FilterArguments extends Transformer {
+        /** The target handle. */
+        private final MethodHandle target;
+        /** Index of the first argument to filter */
+        private final int pos;
+        /** The list of filters to apply */
+        private final MethodHandle[] filters;
+
+        FilterArguments(MethodHandle target, int pos, MethodHandle[] filters) {
+            super(deriveType(target, pos, filters));
+
+            this.target = target;
+            this.pos = pos;
+            this.filters = filters;
+
+        }
+
+        private static MethodType deriveType(MethodHandle target, int pos, MethodHandle[] filters) {
+            final Class<?>[] filterArgs = new Class<?>[filters.length];
+            for (int i = 0; i < filters.length; ++i) {
+                filterArgs[i] = filters[i].type().parameterType(0);
+            }
+
+            return target.type().replaceParameterTypes(pos, pos + filters.length, filterArgs);
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(stackFrame);
+
+            EmulatedStackFrame transformedFrame = EmulatedStackFrame.create(target.type());
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(transformedFrame);
+
+            final Class<?>[] ptypes = target.type().ptypes();
+            for (int i = 0; i < ptypes.length; ++i) {
+                // Check whether the current argument has a filter associated with it.
+                // If it has no filter, no further action need be taken.
+                final Class<?> ptype = ptypes[i];
+                final MethodHandle filter;
+                if (i < pos) {
+                    filter = null;
+                } else if (i >= pos + filters.length) {
+                    filter = null;
+                } else {
+                    filter = filters[i - pos];
+                }
+
+                if (filter != null) {
+                    // Note that filter.type() must be (ptype)ptype - this is checked before
+                    // this transformer is created.
+                    EmulatedStackFrame filterFrame = EmulatedStackFrame.create(filter.type());
+
+                    //  Copy the next argument from the stack frame to the filter frame.
+                    final StackFrameWriter filterWriter = new StackFrameWriter();
+                    filterWriter.attach(filterFrame);
+                    copyNext(reader, filterWriter, filter.type().ptypes()[0]);
+
+                    filter.invoke(filterFrame);
+
+                    // Copy the argument back from the filter frame to the stack frame.
+                    final StackFrameReader filterReader = new StackFrameReader();
+                    filterReader.attach(filterFrame);
+                    filterReader.makeReturnValueAccessor();
+                    copyNext(filterReader, writer, ptype);
+                } else {
+                    // There's no filter associated with this frame, just copy the next argument
+                    // over.
+                    copyNext(reader, writer, ptype);
+                }
+            }
+
+            target.invoke(transformedFrame);
+            transformedFrame.copyReturnValueTo(stackFrame);
+        }
+    }
+
+    /**
+     * Implements MethodHandles.collectArguments.
+     */
+    static class CollectArguments extends Transformer {
+        private final MethodHandle target;
+        private final MethodHandle collector;
+        private final int pos;
+
+        /** The range of input arguments we copy to the collector. */
+        private final Range collectorRange;
+
+        /**
+         * The first range of arguments we copy to the target. These are arguments
+         * in the range [0, pos). Note that arg[pos] is the return value of the filter.
+         */
+        private final Range range1;
+
+        /**
+         * The second range of arguments we copy to the target. These are arguments in the range
+         * (pos, N], where N is the number of target arguments.
+         */
+        private final Range range2;
+
+        private final int referencesOffset;
+        private final int stackFrameOffset;
+
+        CollectArguments(MethodHandle target, MethodHandle collector, int pos,
+                         MethodType adapterType) {
+            super(adapterType);
+
+            this.target = target;
+            this.collector = collector;
+            this.pos = pos;
+
+            final int numFilterArgs = collector.type().parameterCount();
+            final int numAdapterArgs = type().parameterCount();
+            collectorRange = Range.of(type(), pos, pos + numFilterArgs);
+
+            range1 = Range.of(type(), 0, pos);
+            if (pos + numFilterArgs < numAdapterArgs) {
+                this.range2 = Range.of(type(), pos + numFilterArgs, numAdapterArgs);
+            } else {
+                this.range2 = null;
+            }
+
+            // Calculate the number of primitive bytes (or references) we copy to the
+            // target frame based on the return value of the combiner.
+            final Class<?> collectorRType = collector.type().rtype();
+            if (collectorRType == void.class) {
+                stackFrameOffset = 0;
+                referencesOffset = 0;
+            } else if (collectorRType.isPrimitive()) {
+                stackFrameOffset = EmulatedStackFrame.getSize(collectorRType);
+                referencesOffset = 0;
+            } else {
+                stackFrameOffset = 0;
+                referencesOffset = 1;
+            }
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+            // First invoke the collector.
+            EmulatedStackFrame filterFrame = EmulatedStackFrame.create(collector.type());
+            stackFrame.copyRangeTo(filterFrame, collectorRange, 0, 0);
+            collector.invoke(filterFrame);
+
+            // Start constructing the target frame.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+            stackFrame.copyRangeTo(targetFrame, range1, 0, 0);
+
+            // If one of these offsets is not zero, we have a return value to copy.
+            if (referencesOffset != 0 || stackFrameOffset != 0) {
+                final StackFrameReader reader = new StackFrameReader();
+                reader.attach(filterFrame).makeReturnValueAccessor();
+                final StackFrameWriter writer = new StackFrameWriter();
+                writer.attach(targetFrame, pos, range1.numReferences, range1.numBytes);
+                copyNext(reader, writer, target.type().ptypes()[0]);
+            }
+
+            if (range2 != null) {
+                stackFrame.copyRangeTo(targetFrame, range2,
+                        range1.numReferences + referencesOffset,
+                        range2.numBytes + stackFrameOffset);
+            }
+
+            target.invoke(targetFrame);
+            targetFrame.copyReturnValueTo(stackFrame);
+        }
+    }
+
+    /**
+     * Implements MethodHandles.foldArguments.
+     */
+    static class FoldArguments extends Transformer {
+        private final MethodHandle target;
+        private final MethodHandle combiner;
+
+        private final Range combinerArgs;
+        private final Range targetArgs;
+
+        private final int referencesOffset;
+        private final int stackFrameOffset;
+
+        FoldArguments(MethodHandle target, MethodHandle combiner) {
+            super(deriveType(target, combiner));
+
+            this.target = target;
+            this.combiner = combiner;
+
+            combinerArgs = Range.all(combiner.type());
+            targetArgs = Range.all(type());
+
+            final Class<?> combinerRType = combiner.type().rtype();
+            if (combinerRType == void.class) {
+                stackFrameOffset = 0;
+                referencesOffset = 0;
+            } else if (combinerRType.isPrimitive()) {
+                stackFrameOffset = EmulatedStackFrame.getSize(combinerRType);
+                referencesOffset = 0;
+            } else {
+                stackFrameOffset = 0;
+                referencesOffset = 1;
+            }
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+            // First construct the combiner frame and invoke it.
+            EmulatedStackFrame combinerFrame = EmulatedStackFrame.create(combiner.type());
+            stackFrame.copyRangeTo(combinerFrame, combinerArgs, 0, 0);
+            combiner.invoke(combinerFrame);
+
+            // Create the stack frame for the target.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+            // If one of these offsets is not zero, we have a return value to copy.
+            if (referencesOffset != 0 || stackFrameOffset != 0) {
+                final StackFrameReader reader = new StackFrameReader();
+                reader.attach(combinerFrame).makeReturnValueAccessor();
+                final StackFrameWriter writer = new StackFrameWriter();
+                writer.attach(targetFrame);
+                copyNext(reader, writer, target.type().ptypes()[0]);
+            }
+
+            stackFrame.copyRangeTo(targetFrame, targetArgs, referencesOffset, stackFrameOffset);
+            target.invoke(targetFrame);
+
+            targetFrame.copyReturnValueTo(stackFrame);
+        }
+
+        private static MethodType deriveType(MethodHandle target, MethodHandle combiner) {
+            if (combiner.type().rtype() == void.class) {
+                return target.type();
+            }
+
+            return target.type().dropParameterTypes(0, 1);
+        }
+    }
+
+    /**
+     * Implements MethodHandles.insertArguments.
+     */
+    static class InsertArguments extends Transformer {
+        private final MethodHandle target;
+        private final int pos;
+        private final Object[] values;
+
+        private final Range range1;
+        private final Range range2;
+
+        InsertArguments(MethodHandle target, int pos, Object[] values) {
+            super(target.type().dropParameterTypes(pos, pos + values.length));
+            this.target = target;
+            this.pos = pos;
+            this.values = values;
+
+            final MethodType type = type();
+            range1 = EmulatedStackFrame.Range.of(type, 0, pos);
+            range2 = Range.of(type, pos, type.parameterCount());
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+            EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(target.type());
+
+            // Copy all arguments before |pos|.
+            stackFrame.copyRangeTo(calleeFrame, range1, 0, 0);
+
+            // Attach a stack frame writer so that we can copy the next |values.length|
+            // arguments.
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(calleeFrame, pos, range1.numReferences, range1.numBytes);
+
+            // Copy all the arguments supplied in |values|.
+            int referencesCopied = 0;
+            int bytesCopied = 0;
+            final Class<?>[] ptypes = target.type().ptypes();
+            for (int i = 0; i < values.length; ++i) {
+                final Class<?> ptype = ptypes[i + pos];
+                if (ptype.isPrimitive()) {
+                    if (ptype == boolean.class) {
+                        writer.putNextBoolean((boolean) values[i]);
+                    } else if (ptype == byte.class) {
+                        writer.putNextByte((byte) values[i]);
+                    } else if (ptype == char.class) {
+                        writer.putNextChar((char) values[i]);
+                    } else if (ptype == short.class) {
+                        writer.putNextShort((short) values[i]);
+                    } else if (ptype == int.class) {
+                        writer.putNextInt((int) values[i]);
+                    } else if (ptype == long.class) {
+                        writer.putNextLong((long) values[i]);
+                    } else if (ptype == float.class) {
+                        writer.putNextFloat((float) values[i]);
+                    } else if (ptype == double.class) {
+                        writer.putNextDouble((double) values[i]);
+                    }
+
+                    bytesCopied += EmulatedStackFrame.getSize(ptype);
+                } else {
+                    writer.putNextReference(values[i], ptype);
+                    referencesCopied++;
+                }
+            }
+
+            // Copy all remaining arguments.
+            if (range2 != null) {
+                stackFrame.copyRangeTo(calleeFrame, range2,
+                        range1.numReferences + referencesCopied,
+                        range1.numBytes + bytesCopied);
+            }
+
+            target.invoke(calleeFrame);
+            calleeFrame.copyReturnValueTo(stackFrame);
+        }
+    }
+
+
+    /**
+     * Implements {@link java.lang.invokeMethodHandles#explicitCastArguments()}.
+     */
+    public static class ExplicitCastArguments extends Transformer {
+        private final MethodHandle target;
+
+        public ExplicitCastArguments(MethodHandle target, MethodType type) {
+            super(type);
+            this.target = target;
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+            // Create a new stack frame for the target.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+            explicitCastArguments(callerFrame, targetFrame);
+            target.invoke(targetFrame);
+            explicitCastReturnValue(callerFrame, targetFrame);
+        }
+
+        private void explicitCastArguments(final EmulatedStackFrame callerFrame,
+                                           final EmulatedStackFrame targetFrame) {
+            final StackFrameReader reader = new StackFrameReader();
+            reader.attach(callerFrame);
+            final StackFrameWriter writer = new StackFrameWriter();
+            writer.attach(targetFrame);
+
+            final Class<?>[] fromTypes = type().ptypes();
+            final Class<?>[] toTypes = target.type().ptypes();
+            for (int i = 0; i < fromTypes.length; ++i) {
+                explicitCast(reader, fromTypes[i], writer, toTypes[i]);
+            }
+        }
+
+        private void explicitCastReturnValue(final EmulatedStackFrame callerFrame,
+                                             final EmulatedStackFrame targetFrame) {
+            Class<?> from = target.type().rtype();
+            Class<?> to = type().rtype();
+            if (to != void.class) {
+                final StackFrameWriter writer = new StackFrameWriter();
+                writer.attach(callerFrame);
+                writer.makeReturnValueAccessor();
+                if (from == void.class) {
+                    if (to.isPrimitive()) {
+                        unboxNull(writer, to);
+                    } else {
+                        writer.putNextReference(null, to);
+                    }
+                } else {
+                    final StackFrameReader reader = new StackFrameReader();
+                    reader.attach(targetFrame);
+                    reader.makeReturnValueAccessor();
+                    explicitCast(reader, target.type().rtype(), writer, type().rtype());
+                }
+            }
+        }
+
+        private static void throwUnexpectedType(final Class<?> unexpectedType) {
+            throw new InternalError("Unexpected type: " + unexpectedType);
+        }
+
+        @SuppressWarnings("unchecked")
+        private static void badCast(final Class<?> from, final Class<?> to) {
+            throw new ClassCastException("Cannot cast " + from.getName() + " to " + to.getName());
+        }
+
+        /**
+         * Converts byte value to boolean according to
+         * {@link java.lang.invoke.MethodHandles#explicitCast()}
+         */
+        private static boolean toBoolean(byte value) {
+            return (value & 1) == 1;
+        }
+
+        private static byte readPrimitiveAsByte(final StackFrameReader reader,
+                                                final Class<?> from) {
+            if (from == byte.class) {
+                return (byte) reader.nextByte();
+            } else if (from == char.class) {
+                return (byte) reader.nextChar();
+            } else if (from == short.class) {
+                return (byte) reader.nextShort();
+            } else if (from == int.class) {
+                return (byte) reader.nextInt();
+            } else if (from == long.class) {
+                return (byte) reader.nextLong();
+            } else if (from == float.class) {
+                return (byte) reader.nextFloat();
+            } else if (from == double.class) {
+                return (byte) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? (byte) 1 : (byte) 0;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static char readPrimitiveAsChar(final StackFrameReader reader,
+                                                final Class<?> from) {
+            if (from == byte.class) {
+                return (char) reader.nextByte();
+            } else if (from == char.class) {
+                return (char) reader.nextChar();
+            } else if (from == short.class) {
+                return (char) reader.nextShort();
+            } else if (from == int.class) {
+                return (char) reader.nextInt();
+            } else if (from == long.class) {
+                return (char) reader.nextLong();
+            } else if (from == float.class) {
+                return (char) reader.nextFloat();
+            } else if (from == double.class) {
+                return (char) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? (char) 1 : (char) 0;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static short readPrimitiveAsShort(final StackFrameReader reader,
+                                                  final Class<?> from) {
+            if (from == byte.class) {
+                return (short) reader.nextByte();
+            } else if (from == char.class) {
+                return (short) reader.nextChar();
+            } else if (from == short.class) {
+                return (short) reader.nextShort();
+            } else if (from == int.class) {
+                return (short) reader.nextInt();
+            } else if (from == long.class) {
+                return (short) reader.nextLong();
+            } else if (from == float.class) {
+                return (short) reader.nextFloat();
+            } else if (from == double.class) {
+                return (short) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? (short) 1 : (short) 0;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static int readPrimitiveAsInt(final StackFrameReader reader,
+                                              final Class<?> from) {
+            if (from == byte.class) {
+                return (int) reader.nextByte();
+            } else if (from == char.class) {
+                return (int) reader.nextChar();
+            } else if (from == short.class) {
+                return (int) reader.nextShort();
+            } else if (from == int.class) {
+                return (int) reader.nextInt();
+            } else if (from == long.class) {
+                return (int) reader.nextLong();
+            } else if (from == float.class) {
+                return (int) reader.nextFloat();
+            } else if (from == double.class) {
+                return (int) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? 1 : 0;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static long readPrimitiveAsLong(final StackFrameReader reader,
+                                                final Class<?> from) {
+            if (from == byte.class) {
+                return (long) reader.nextByte();
+            } else if (from == char.class) {
+                return (long) reader.nextChar();
+            } else if (from == short.class) {
+                return (long) reader.nextShort();
+            } else if (from == int.class) {
+                return (long) reader.nextInt();
+            } else if (from == long.class) {
+                return (long) reader.nextLong();
+            } else if (from == float.class) {
+                return (long) reader.nextFloat();
+            } else if (from == double.class) {
+                return (long) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? 1L : 0L;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static float readPrimitiveAsFloat(final StackFrameReader reader,
+                                                  final Class<?> from) {
+            if (from == byte.class) {
+                return (float) reader.nextByte();
+            } else if (from == char.class) {
+                return (float) reader.nextChar();
+            } else if (from == short.class) {
+                return (float) reader.nextShort();
+            } else if (from == int.class) {
+                return (float) reader.nextInt();
+            } else if (from == long.class) {
+                return (float) reader.nextLong();
+            } else if (from == float.class) {
+                return (float) reader.nextFloat();
+            } else if (from == double.class) {
+                return (float) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? 1.0f : 0.0f;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static double readPrimitiveAsDouble(final StackFrameReader reader,
+                                                    final Class<?> from) {
+            if (from == byte.class) {
+                return (double) reader.nextByte();
+            } else if (from == char.class) {
+                return (double) reader.nextChar();
+            } else if (from == short.class) {
+                return (double) reader.nextShort();
+            } else if (from == int.class) {
+                return (double) reader.nextInt();
+            } else if (from == long.class) {
+                return (double) reader.nextLong();
+            } else if (from == float.class) {
+                return (double) reader.nextFloat();
+            } else if (from == double.class) {
+                return (double) reader.nextDouble();
+            } else if (from == boolean.class) {
+                return reader.nextBoolean() ? 1.0 : 0.0;
+            } else {
+                throwUnexpectedType(from);
+                return 0;
+            }
+        }
+
+        private static void explicitCastPrimitives(final StackFrameReader reader,
+                                                   final Class<?> from,
+                                                   final StackFrameWriter writer,
+                                                   final Class<?> to) {
+            if (to == byte.class) {
+                byte value = readPrimitiveAsByte(reader, from);
+                writer.putNextByte(value);
+            } else if (to == char.class) {
+                char value = readPrimitiveAsChar(reader, from);
+                writer.putNextChar(value);
+            } else if (to == short.class) {
+                short value = readPrimitiveAsShort(reader, from);
+                writer.putNextShort(value);
+            } else if (to == int.class) {
+                int value = readPrimitiveAsInt(reader, from);
+                writer.putNextInt(value);
+            } else if (to == long.class) {
+                long value = readPrimitiveAsLong(reader, from);
+                writer.putNextLong(value);
+            } else if (to == float.class) {
+                float value = readPrimitiveAsFloat(reader, from);
+                writer.putNextFloat(value);
+            } else if (to == double.class) {
+                double value = readPrimitiveAsDouble(reader, from);
+                writer.putNextDouble(value);
+            } else if (to == boolean.class) {
+                byte byteValue = readPrimitiveAsByte(reader, from);
+                writer.putNextBoolean(toBoolean(byteValue));
+            } else {
+                throwUnexpectedType(to);
+            }
+        }
+
+        private static void unboxNull(final StackFrameWriter writer, final Class<?> to) {
+            if (to == boolean.class) {
+                writer.putNextBoolean(false);
+            } else if (to == byte.class) {
+                writer.putNextByte((byte) 0);
+            } else if (to == char.class) {
+                writer.putNextChar((char) 0);
+            } else if (to == short.class) {
+                writer.putNextShort((short) 0);
+            } else if (to == int.class) {
+                writer.putNextInt((int) 0);
+            } else if (to == long.class) {
+                writer.putNextLong((long) 0);
+            } else if (to == float.class) {
+                writer.putNextFloat((float) 0);
+            } else if (to == double.class) {
+                writer.putNextDouble((double) 0);
+            } else {
+                throwUnexpectedType(to);
+            }
+        }
+
+        private static void unboxNonNull(final Object ref, final Class<?> from,
+                                         final StackFrameWriter writer, final Class<?> to) {
+            if (from == Boolean.class) {
+                boolean z = (boolean) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean(z);
+                } else if (to == byte.class) {
+                    writer.putNextByte(z ? (byte) 1 : (byte) 0);
+                } else if (to == short.class) {
+                    writer.putNextShort(z ? (short) 1 : (short) 0);
+                } else if (to == char.class) {
+                    writer.putNextChar(z ? (char) 1 : (char) 0);
+                } else if (to == int.class) {
+                    writer.putNextInt(z ? 1 : 0);
+                } else if (to == long.class) {
+                    writer.putNextLong(z ? 1l : 0l);
+                } else if (to == float.class) {
+                    writer.putNextFloat(z ? 1.0f : 0.0f);
+                } else if (to == double.class) {
+                    writer.putNextDouble(z ? 1.0 : 0.0);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Byte.class) {
+                byte b = (byte) ref;
+                if (to == byte.class) {
+                    writer.putNextByte(b);
+                } else if (to == boolean.class) {
+                    writer.putNextBoolean(toBoolean(b));
+                } else if (to == short.class) {
+                    writer.putNextShort((short) b);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) b);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) b);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) b);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) b);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) b);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Short.class) {
+                short s = (short) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean((s & 1) == 1);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) s);
+                } else if (to == short.class) {
+                    writer.putNextShort(s);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) s);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) s);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) s);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) s);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) s);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Character.class) {
+                char c = (char) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean((c & (char) 1) == (char) 1);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) c);
+                } else if (to == short.class) {
+                    writer.putNextShort((short) c);
+                } else if (to == char.class) {
+                    writer.putNextChar(c);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) c);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) c);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) c);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) c);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Integer.class) {
+                int i = (int) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean((i & 1) == 1);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) i);
+                } else if (to == short.class) {
+                    writer.putNextShort((short) i);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) i);
+                } else if (to == int.class) {
+                    writer.putNextInt(i);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) i);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) i);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) i);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Long.class) {
+                long j = (long) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean((j & 1l) == 1l);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) j);
+                } else if (to == short.class) {
+                    writer.putNextShort((short) j);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) j);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) j);
+                } else if (to == long.class) {
+                    writer.putNextLong(j);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) j);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) j);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Float.class) {
+                float f = (float) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean(((byte) f & 1) != 0);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) f);
+                } else if (to == short.class) {
+                    writer.putNextShort((short) f);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) f);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) f);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) f);
+                } else if (to == float.class) {
+                    writer.putNextFloat(f);
+                } else if (to == double.class) {
+                    writer.putNextDouble((double) f);
+                } else {
+                    badCast(from, to);
+                }
+            } else if (from == Double.class) {
+                double d = (double) ref;
+                if (to == boolean.class) {
+                    writer.putNextBoolean(((byte) d & 1) != 0);
+                } else if (to == byte.class) {
+                    writer.putNextByte((byte) d);
+                } else if (to == short.class) {
+                    writer.putNextShort((short) d);
+                } else if (to == char.class) {
+                    writer.putNextChar((char) d);
+                } else if (to == int.class) {
+                    writer.putNextInt((int) d);
+                } else if (to == long.class) {
+                    writer.putNextLong((long) d);
+                } else if (to == float.class) {
+                    writer.putNextFloat((float) d);
+                } else if (to == double.class) {
+                    writer.putNextDouble(d);
+                } else {
+                    badCast(from, to);
+                }
+            } else {
+                badCast(from, to);
+            }
+        }
+
+        private static void unbox(final Object ref, final Class<?> from,
+                                  final StackFrameWriter writer, final Class<?> to) {
+            if (ref == null) {
+                unboxNull(writer, to);
+            } else {
+                unboxNonNull(ref, from, writer, to);
+            }
+        }
+
+        private static void box(final StackFrameReader reader, final Class<?> from,
+                                final StackFrameWriter writer, final Class<?> to) {
+            Object boxed = null;
+            if (from == boolean.class) {
+                boxed = Boolean.valueOf(reader.nextBoolean());
+            } else if (from == byte.class) {
+                boxed = Byte.valueOf(reader.nextByte());
+            } else if (from == char.class) {
+                boxed = Character.valueOf(reader.nextChar());
+            } else if (from == short.class) {
+                boxed = Short.valueOf(reader.nextShort());
+            } else if (from == int.class) {
+                boxed = Integer.valueOf(reader.nextInt());
+            } else if (from == long.class) {
+                boxed = Long.valueOf(reader.nextLong());
+            } else if (from == float.class) {
+                boxed = Float.valueOf(reader.nextFloat());
+            } else if (from == double.class) {
+                boxed = Double.valueOf(reader.nextDouble());
+            } else {
+                throwUnexpectedType(from);
+            }
+            writer.putNextReference(to.cast(boxed), to);
+        }
+
+        private static void explicitCast(final StackFrameReader reader, final Class<?> from,
+                                         final StackFrameWriter writer, final Class<?> to) {
+            if (from.equals(to)) {
+                StackFrameAccessor.copyNext(reader, writer, from);
+                return;
+            }
+
+            if (from.isPrimitive()) {
+                if (to.isPrimitive()) {
+                    // |from| and |to| are primitive types.
+                    explicitCastPrimitives(reader, from, writer, to);
+                } else {
+                    // |from| is a primitive type, |to| is a reference type.
+                    box(reader, from, writer, to);
+                }
+            } else {
+                // |from| is a reference type.
+                Object ref = reader.nextReference(from);
+                if (to.isPrimitive()) {
+                    // |from| is a reference type, |to| is a primitive type,
+                    unbox(ref, from, writer, to);
+                } else if (to.isInterface()) {
+                    // Pass from without a cast according to description for
+                    // {@link java.lang.invoke.MethodHandles#explicitCastArguments()}.
+                    writer.putNextReference(ref, to);
+                } else {
+                    // |to| and from |from| are reference types, perform class cast check.
+                    writer.putNextReference(to.cast(ref), to);
+                }
+            }
+        }
+    }
+}
diff --git a/java/lang/invoke/VarHandle.java b/java/lang/invoke/VarHandle.java
new file mode 100644
index 0000000..7b5ac00
--- /dev/null
+++ b/java/lang/invoke/VarHandle.java
@@ -0,0 +1,2386 @@
+/*
+ * Copyright (c) 2014, 2017, 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 dalvik.system.VMRuntime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A VarHandle is a dynamically strongly typed reference to a variable, or to a
+ * parametrically-defined family of variables, including static fields,
+ * non-static fields, array elements, or components of an off-heap data
+ * structure.  Access to such variables is supported under various
+ * <em>access modes</em>, including plain read/write access, volatile
+ * read/write access, and compare-and-swap.
+ *
+ * <p>VarHandles are immutable and have no visible state.  VarHandles cannot be
+ * subclassed by the user.
+ *
+ * <p>A VarHandle has:
+ * <ul>
+ * <li>a {@link #varType variable type} T, the type of every variable referenced
+ * by this VarHandle; and
+ * <li>a list of {@link #coordinateTypes coordinate types}
+ * {@code CT1, CT2, ..., CTn}, the types of <em>coordinate expressions</em> that
+ * jointly locate a variable referenced by this VarHandle.
+ * </ul>
+ * Variable and coordinate types may be primitive or reference, and are
+ * represented by {@code Class} objects.  The list of coordinate types may be
+ * empty.
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the supported variable type and the list
+ * of coordinate types.
+ *
+ * <p>Each access mode is associated with one <em>access mode method</em>, a
+ * <a href="MethodHandle.html#sigpoly">signature polymorphic</a> method named
+ * for the access mode.  When an access mode method is invoked on a VarHandle
+ * instance, the initial arguments to the invocation are coordinate expressions
+ * that indicate in precisely which object the variable is to be accessed.
+ * Trailing arguments to the invocation represent values of importance to the
+ * access mode.  For example, the various compare-and-set or compare-and-exchange
+ * access modes require two trailing arguments for the variable's expected value
+ * and new value.
+ *
+ * <p>The arity and types of arguments to the invocation of an access mode
+ * method are not checked statically.  Instead, each access mode method
+ * specifies an {@link #accessModeType(AccessMode) access mode type},
+ * represented as an instance of {@link MethodType}, that serves as a kind of
+ * method signature against which the arguments are checked dynamically.  An
+ * access mode type gives formal parameter types in terms of the coordinate
+ * types of a VarHandle instance and the types for values of importance to the
+ * access mode.  An access mode type also gives a return type, often in terms of
+ * the variable type of a VarHandle instance.  When an access mode method is
+ * invoked on a VarHandle instance, the symbolic type descriptor at the
+ * call site, the run time types of arguments to the invocation, and the run
+ * time type of the return value, must <a href="#invoke">match</a> the types
+ * given in the access mode type.  A runtime exception will be thrown if the
+ * match fails.
+ *
+ * For example, the access mode method {@link #compareAndSet} specifies that if
+ * its receiver is a VarHandle instance with coordinate types
+ * {@code CT1, ..., CTn} and variable type {@code T}, then its access mode type
+ * is {@code (CT1 c1, ..., CTn cn, T expectedValue, T newValue)boolean}.
+ * Suppose that a VarHandle instance can access array elements, and that its
+ * coordinate types are {@code String[]} and {@code int} while its variable type
+ * is {@code String}.  The access mode type for {@code compareAndSet} on this
+ * VarHandle instance would be
+ * {@code (String[] c1, int c2, String expectedValue, String newValue)boolean}.
+ * Such a VarHandle instance may produced by the
+ * {@link MethodHandles#arrayElementVarHandle(Class) array factory method} and
+ * access array elements as follows:
+ * <pre> {@code
+ * String[] sa = ...
+ * VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
+ * boolean r = avh.compareAndSet(sa, 10, "expected", "new");
+ * }</pre>
+ *
+ * <p>Access modes control atomicity and consistency properties.
+ * <em>Plain</em> read ({@code get}) and write ({@code set})
+ * accesses are guaranteed to be bitwise atomic only for references
+ * and for primitive values of at most 32 bits, and impose no observable
+ * ordering constraints with respect to threads other than the
+ * executing thread. <em>Opaque</em> operations are bitwise atomic and
+ * coherently ordered with respect to accesses to the same variable.
+ * In addition to obeying Opaque properties, <em>Acquire</em> mode
+ * reads and their subsequent accesses are ordered after matching
+ * <em>Release</em> mode writes and their previous accesses.  In
+ * addition to obeying Acquire and Release properties, all
+ * <em>Volatile</em> operations are totally ordered with respect to
+ * each other.
+ *
+ * <p>Access modes are grouped into the following categories:
+ * <ul>
+ * <li>read access modes that get the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #get get},
+ * {@link #getVolatile getVolatile},
+ * {@link #getAcquire getAcquire},
+ * {@link #getOpaque getOpaque}.
+ * <li>write access modes that set the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #set set},
+ * {@link #setVolatile setVolatile},
+ * {@link #setRelease setRelease},
+ * {@link #setOpaque setOpaque}.
+ * <li>atomic update access modes that, for example, atomically compare and set
+ * the value of a variable under specified memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #compareAndSet compareAndSet},
+ * {@link #weakCompareAndSetPlain weakCompareAndSetPlain},
+ * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
+ * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
+ * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
+ * {@link #compareAndExchange compareAndExchange},
+ * {@link #compareAndExchangeRelease compareAndExchangeRelease},
+ * {@link #getAndSet getAndSet},
+ * {@link #getAndSetAcquire getAndSetAcquire},
+ * {@link #getAndSetRelease getAndSetRelease}.
+ * <li>numeric atomic update access modes that, for example, atomically get and
+ * set with addition the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndAdd getAndAdd},
+ * {@link #getAndAddAcquire getAndAddAcquire},
+ * {@link #getAndAddRelease getAndAddRelease},
+ * <li>bitwise atomic update access modes that, for example, atomically get and
+ * bitwise OR the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndBitwiseOr getAndBitwiseOr},
+ * {@link #getAndBitwiseOrAcquire getAndBitwiseOrAcquire},
+ * {@link #getAndBitwiseOrRelease getAndBitwiseOrRelease},
+ * {@link #getAndBitwiseAnd getAndBitwiseAnd},
+ * {@link #getAndBitwiseAndAcquire getAndBitwiseAndAcquire},
+ * {@link #getAndBitwiseAndRelease getAndBitwiseAndRelease},
+ * {@link #getAndBitwiseXor getAndBitwiseXor},
+ * {@link #getAndBitwiseXorAcquire getAndBitwiseXorAcquire},
+ * {@link #getAndBitwiseXorRelease getAndBitwiseXorRelease}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the set of access modes that are
+ * supported, which may also include documenting restrictions based on the
+ * variable type and whether a variable is read-only.  If an access mode is not
+ * supported then the corresponding access mode method will on invocation throw
+ * an {@code UnsupportedOperationException}.  Factory methods should document
+ * any additional undeclared exceptions that may be thrown by access mode
+ * methods.
+ * The {@link #get get} access mode is supported for all
+ * VarHandle instances and the corresponding method never throws
+ * {@code UnsupportedOperationException}.
+ * If a VarHandle references a read-only variable (for example a {@code final}
+ * field) then write, atomic update, numeric atomic update, and bitwise atomic
+ * update access modes are not supported and corresponding methods throw
+ * {@code UnsupportedOperationException}.
+ * Read/write access modes (if supported), with the exception of
+ * {@code get} and {@code set}, provide atomic access for
+ * reference types and all primitive types.
+ * Unless stated otherwise in the documentation of a factory method, the access
+ * modes {@code get} and {@code set} (if supported) provide atomic access for
+ * reference types and all primitives types, with the exception of {@code long}
+ * and {@code double} on 32-bit platforms.
+ *
+ * <p>Access modes will override any memory ordering effects specified at
+ * the declaration site of a variable.  For example, a VarHandle accessing a
+ * a field using the {@code get} access mode will access the field as
+ * specified <em>by its access mode</em> even if that field is declared
+ * {@code volatile}.  When mixed access is performed extreme care should be
+ * taken since the Java Memory Model may permit surprising results.
+ *
+ * <p>In addition to supporting access to variables under various access modes,
+ * a set of static methods, referred to as memory fence methods, is also
+ * provided for fine-grained control of memory ordering.
+ *
+ * The Java Language Specification permits other threads to observe operations
+ * as if they were executed in orders different than are apparent in program
+ * source code, subject to constraints arising, for example, from the use of
+ * locks, {@code volatile} fields or VarHandles.  The static methods,
+ * {@link #fullFence fullFence}, {@link #acquireFence acquireFence},
+ * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and
+ * {@link #storeStoreFence storeStoreFence}, can also be used to impose
+ * constraints.  Their specifications, as is the case for certain access modes,
+ * are phrased in terms of the lack of "reorderings" -- observable ordering
+ * effects that might otherwise occur if the fence was not present.  More
+ * precise phrasing of the specification of access mode methods and memory fence
+ * methods may accompany future updates of the Java Language Specification.
+ *
+ * <h1>Compiling invocation of access mode methods</h1>
+ * A Java method call expression naming an access mode method can invoke a
+ * VarHandle from Java source code.  From the viewpoint of source code, these
+ * methods can take any arguments and their polymorphic result (if expressed)
+ * can be cast to any return type.  Formally this is accomplished by giving the
+ * access mode methods variable arity {@code Object} arguments and
+ * {@code Object} return types (if the return type is polymorphic), but they
+ * have an additional quality called <em>signature polymorphism</em> which
+ * connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to access mode methods
+ * compile to an {@code invokevirtual} instruction.  More unusually, the
+ * compiler must record the actual argument types, and may not perform method
+ * invocation conversions on the arguments.  Instead, it must generate
+ * instructions to push them on the stack according to their own unconverted
+ * types.  The VarHandle object itself will be pushed on the stack before the
+ * arguments.  The compiler then generates an {@code invokevirtual} instruction
+ * that invokes the access mode method with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also
+ * determine the return type (if polymorphic).  This is based on a cast on the
+ * method invocation expression, if there is one, or else {@code Object} if the
+ * invocation is an expression, or else {@code void} if the invocation is a
+ * statement.  The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given a symbolic type
+ * descriptor of {@code java.lang.Void}.  The ambiguity with the type
+ * {@code Void} is harmless, since there are no references of type {@code Void}
+ * except the null reference.
+ *
+ *
+ * <h1><a id="invoke">Performing invocation of access mode methods</a></h1>
+ * The first time an {@code invokevirtual} instruction is executed it is linked
+ * by symbolically resolving the names in the instruction and verifying that
+ * the method call is statically legal.  This also holds for calls to access mode
+ * methods.  In this case, the symbolic type descriptor emitted by the compiler
+ * is checked for correct syntax, and names it contains are resolved.  Thus, an
+ * {@code invokevirtual} instruction which invokes an access mode method will
+ * always link, as long as the symbolic type descriptor is syntactically
+ * well-formed and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking, the receiving
+ * VarHandle's access mode type is first checked by the JVM to ensure that it
+ * matches the symbolic type descriptor.  If the type
+ * match fails, it means that the access mode method which the caller is
+ * invoking is not present on the individual VarHandle being invoked.
+ *
+ * <p>
+ * Invocation of an access mode method behaves as if an invocation of
+ * {@link MethodHandle#invoke}, where the receiving method handle accepts the
+ * VarHandle instance as the leading argument.  More specifically, the
+ * following, where {@code {access-mode}} corresponds to the access mode method
+ * name:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
+ * }</pre>
+ * behaves as if:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ *                       am,
+ *                       vh.accessModeType(am));
+ *
+ * R r = (R) mh.invoke(vh, p1, p2, ..., pN)
+ * }</pre>
+ * (modulo access mode methods do not declare throwing of {@code Throwable}).
+ * This is equivalent to:
+ * <pre> {@code
+ * MethodHandle mh = MethodHandles.lookup().findVirtual(
+ *                       VarHandle.class,
+ *                       "{access-mode}",
+ *                       MethodType.methodType(R, p1, p2, ..., pN));
+ *
+ * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
+ * }</pre>
+ * where the desired method type is the symbolic type descriptor and a
+ * {@link MethodHandle#invokeExact} is performed, since before invocation of the
+ * target, the handle will apply reference casts as necessary and box, unbox, or
+ * widen primitive values, as if by {@link MethodHandle#asType asType} (see also
+ * {@link MethodHandles#varHandleInvoker}).
+ *
+ * More concisely, such behaviour is equivalent to:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
+ * MethodHandle mh = vh.toMethodHandle(am);
+ *
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * Where, in this case, the method handle is bound to the VarHandle instance.
+ *
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, VarHandle access mode type matching will usually
+ * succeed.  But if a match fails, the JVM will throw a
+ * {@link WrongMethodTypeException}.
+ * <p>
+ * Thus, an access mode type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as a dynamic
+ * {@code WrongMethodTypeException} in a program which uses VarHandles.
+ * <p>
+ * Because access mode types contain "live" {@code Class} objects, method type
+ * matching takes into account both type names and class loaders.
+ * Thus, even if a VarHandle {@code VH} is created in one class loader
+ * {@code L1} and used in another {@code L2}, VarHandle access mode method
+ * calls are type-safe, because the caller's symbolic type descriptor, as
+ * resolved in {@code L2}, is matched against the original callee method's
+ * symbolic type descriptor, as resolved in {@code L1}.  The resolution in
+ * {@code L1} happens when {@code VH} is created and its access mode types are
+ * assigned, while the resolution in {@code L2} happens when the
+ * {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from type descriptor checks, a VarHandles's capability to
+ * access it's variables is unrestricted.
+ * If a VarHandle is formed on a non-public variable by a class that has access
+ * to that variable, the resulting VarHandle can be used in any place by any
+ * caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time a
+ * reflective method is invoked, VarHandle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the VarHandle is
+ * created</a>.
+ * Thus, VarHandles to non-public variables, or to variables in non-public
+ * classes, should generally be kept secret.  They should not be passed to
+ * untrusted code unless their use from the untrusted code would be harmless.
+ *
+ *
+ * <h1>VarHandle creation</h1>
+ * Java code can create a VarHandle that directly accesses any field that is
+ * accessible to that code.  This is done via a reflective, capability-based
+ * API called {@link java.lang.invoke.MethodHandles.Lookup
+ * MethodHandles.Lookup}.
+ * For example, a VarHandle for a non-static field can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle
+ * Lookup.findVarHandle}.
+ * There is also a conversion method from Core Reflection API objects,
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * <p>
+ * Access to protected field members is restricted to receivers only of the
+ * accessing class, or one of its subclasses, and the accessing class must in
+ * turn be a subclass (or package sibling) of the protected member's defining
+ * class.  If a VarHandle refers to a protected non-static field of a declaring
+ * class outside the current package, the receiver argument will be narrowed to
+ * the type of the accessing class.
+ *
+ * <h1>Interoperation between VarHandles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup
+ * Lookup} API, any field represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent VarHandle.
+ * For example, a reflective {@link java.lang.reflect.Field Field} can
+ * be converted to a VarHandle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * The resulting VarHandles generally provide more direct and efficient
+ * access to the underlying fields.
+ * <p>
+ * As a special case, when the Core Reflection API is used to view the
+ * signature polymorphic access mode methods in this class, they appear as
+ * ordinary non-polymorphic methods.  Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers
+ * Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs}
+ * bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be invoked
+ * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke},
+ * via JNI, or indirectly via
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * However, such reflective calls do not result in access mode method
+ * invocations.  Such a call, if passed the required argument (a single one, of
+ * type {@code Object[]}), will ignore the argument and will throw an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively invoke VarHandle
+ * access mode methods under any symbolic type descriptor, this reflective view
+ * conflicts with the normal presentation of these methods via bytecodes.
+ * Thus, these native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular access mode type,
+ * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.  The
+ * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle to call an access mode method for
+ * any specified access mode type and is equivalent in behaviour to
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
+ *
+ * <h1>Interoperation between VarHandles and Java generics</h1>
+ * A VarHandle can be obtained for a variable, such as a a field, which is
+ * declared with Java generic types.  As with the Core Reflection API, the
+ * VarHandle's variable type will be constructed from the erasure of the
+ * source-level type.  When a VarHandle access mode method is invoked, the
+ * types
+ * of its arguments or the return value cast type may be generic types or type
+ * instances.  If this occurs, the compiler will replace those types by their
+ * erasures when it constructs the symbolic type descriptor for the
+ * {@code invokevirtual} instruction.
+ *
+ * @see MethodHandle
+ * @see MethodHandles
+ * @see MethodType
+ * @since 9
+ * @hide
+ */
+public abstract class VarHandle {
+    // Android-added: Using sun.misc.Unsafe for fence implementation.
+    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+
+    // BEGIN Android-removed: No VarForm in Android implementation.
+    /*
+    final VarForm vform;
+
+    VarHandle(VarForm vform) {
+        this.vform = vform;
+    }
+    */
+    // END Android-removed: No VarForm in Android implementation.
+
+    // BEGIN Android-added: fields for common metadata.
+    /** The target type for accesses. */
+    private final Class<?> varType;
+
+    /** This VarHandle's first coordinate, or null if this VarHandle has no coordinates. */
+    private final Class<?> coordinateType0;
+
+    /** This VarHandle's second coordinate, or null if this VarHandle has less than two
+     * coordinates. */
+    private final Class<?> coordinateType1;
+
+    /** BitMask of supported access mode indexed by AccessMode.ordinal(). */
+    private final int accessModesBitMask;
+    // END Android-added: fields for common metadata.
+
+    // Plain accessors
+
+    /**
+     * Returns the value of a variable, with memory semantics of reading as
+     * if the variable was declared non-{@code volatile}.  Commonly referred to
+     * as plain read access.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code get}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
+     *
+     * <p>This access mode is supported by all VarHandle instances and never
+     * throws {@code UnsupportedOperationException}.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the value of the
+     * variable
+     * , statically represented using {@code Object}.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object get(Object... args);
+
+    /**
+     * Sets the value of a variable to the {@code newValue}, with memory
+     * semantics of setting as if the variable was declared non-{@code volatile}
+     * and non-{@code final}.  Commonly referred to as plain write access.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}
+     *
+     * <p>The symbolic type descriptor at the call site of {@code set}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    void set(Object... args);
+
+
+    // Volatile accessors
+
+    /**
+     * Returns the value of a variable, with memory semantics of reading as if
+     * the variable was declared {@code volatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getVolatile}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the value of the
+     * variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getVolatile(Object... args);
+
+    /**
+     * Sets the value of a variable to the {@code newValue}, with memory
+     * semantics of setting as if the variable was declared {@code volatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code setVolatile}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
+     * VarHandle.
+     *
+     * @apiNote
+     * Ignoring the many semantic differences from C and C++, this method has
+     * memory ordering effects compatible with {@code memory_order_seq_cst}.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    void setVolatile(Object... args);
+
+
+    /**
+     * Returns the value of a variable, accessed in program order, but with no
+     * assurance of memory ordering effects with respect to other threads.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getOpaque}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the value of the
+     * variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getOpaque(Object... args);
+
+    /**
+     * Sets the value of a variable to the {@code newValue}, in program order,
+     * but with no assurance of memory ordering effects with respect to other
+     * threads.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code setOpaque}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    void setOpaque(Object... args);
+
+
+    // Lazy accessors
+
+    /**
+     * Returns the value of a variable, and ensures that subsequent loads and
+     * stores are not reordered before this access.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @apiNote
+     * Ignoring the many semantic differences from C and C++, this method has
+     * memory ordering effects compatible with {@code memory_order_acquire}
+     * ordering.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the value of the
+     * variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAcquire(Object... args);
+
+    /**
+     * Sets the value of a variable to the {@code newValue}, and ensures that
+     * prior loads and stores are not reordered after this access.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code setRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
+     * VarHandle.
+     *
+     * @apiNote
+     * Ignoring the many semantic differences from C and C++, this method has
+     * memory ordering effects compatible with {@code memory_order_release}
+     * ordering.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    void setRelease(Object... args);
+
+
+    // Compare and set accessors
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #setVolatile} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * compareAndSet} must match the access mode type that is the result of
+     * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
+     * this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    boolean compareAndSet(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #setVolatile} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * compareAndExchange}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the witness value, which
+     * will be the same as the {@code expectedValue} if successful
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type is not
+     * compatible with the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type is compatible with the
+     * caller's symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object compareAndExchange(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #set} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * compareAndExchangeAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
+     * this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the witness value, which
+     * will be the same as the {@code expectedValue} if successful
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #getAcquire(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object compareAndExchangeAcquire(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #setRelease} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * compareAndExchangeRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the witness value, which
+     * will be the same as the {@code expectedValue} if successful
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setRelease(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object compareAndExchangeRelease(Object... args);
+
+    // Weak (spurious failures allowed)
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the semantics of {@link #set} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetPlain} must match the access mode type that is the result of
+     * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetPlain(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the memory semantics of {@link #setVolatile} if the variable's
+     * current value, referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSet} must match the access mode type that is the
+     * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSet(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the semantics of {@link #set} if the variable's current value,
+     * referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #getAcquire(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetAcquire(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the semantics of {@link #setRelease} if the variable's current
+     * value, referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setRelease(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetRelease(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #setVolatile} and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndSet}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndSet(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #set} and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndSetAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndSetAcquire(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the {@code newValue} with the
+     * memory semantics of {@link #setRelease} and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndSetRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_RELEASE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndSetRelease(Object... args);
+
+    // Primitive adders
+    // Throw UnsupportedOperationException for refs
+
+    /**
+     * Atomically adds the {@code value} to the current value of a variable with
+     * the memory semantics of {@link #setVolatile}, and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T value)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndAdd(Object... args);
+
+    /**
+     * Atomically adds the {@code value} to the current value of a variable with
+     * the memory semantics of {@link #set}, and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndAddAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T value)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndAddAcquire(Object... args);
+
+    /**
+     * Atomically adds the {@code value} to the current value of a variable with
+     * the memory semantics of {@link #setRelease}, and returns the variable's
+     * previous value, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndAddRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_RELEASE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T value)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndAddRelease(Object... args);
+
+
+    // Bitwise operations
+    // Throw UnsupportedOperationException for refs
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise OR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setVolatile} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical OR is performed instead of a bitwise OR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOr}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseOr(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise OR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #set} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical OR is performed instead of a bitwise OR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #getAcquire(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseOrAcquire(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise OR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setRelease} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical OR is performed instead of a bitwise OR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setRelease(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseOrRelease(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise AND between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setVolatile} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical AND is performed instead of a bitwise AND.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAnd}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseAnd(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise AND between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #set} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical AND is performed instead of a bitwise AND.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #getAcquire(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseAndAcquire(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise AND between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setRelease} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical AND is performed instead of a bitwise AND.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setRelease(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseAndRelease(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise XOR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setVolatile} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical XOR is performed instead of a bitwise XOR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXor}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseXor(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise XOR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #set} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #getAcquire}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical XOR is performed instead of a bitwise XOR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorAcquire}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #set(Object...)
+     * @see #getAcquire(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseXorAcquire(Object... args);
+
+    /**
+     * Atomically sets the value of a variable to the result of
+     * bitwise XOR between the variable's current value and the {@code mask}
+     * with the memory semantics of {@link #setRelease} and returns the
+     * variable's previous value, as accessed with the memory semantics of
+     * {@link #get}.
+     *
+     * <p>If the variable type is the non-integral {@code boolean} type then a
+     * logical XOR is performed instead of a bitwise XOR.
+     *
+     * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorRelease}
+     * must match the access mode type that is the result of calling
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)} on this
+     * VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+     * , statically represented using varargs.
+     * @return the signature-polymorphic result that is the previous value of
+     * the variable
+     * , statically represented using {@code Object}.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type does not
+     * match the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type matches the caller's
+     * symbolic type descriptor, but a reference cast fails.
+     * @see #setRelease(Object...)
+     * @see #get(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    // Android-removed: unsupported annotation.
+    // @HotSpotIntrinsicCandidate
+    Object getAndBitwiseXorRelease(Object... args);
+
+
+    // Android-changed: remove unused return type in AccessType constructor.
+    enum AccessType {
+        GET,
+        SET,
+        COMPARE_AND_SWAP,
+        COMPARE_AND_EXCHANGE,
+        GET_AND_UPDATE,
+        // Android-added: Finer grained access types.
+        // These are used to help categorize the access modes that a VarHandle supports.
+        GET_AND_UPDATE_BITWISE,
+        GET_AND_UPDATE_NUMERIC;
+
+        MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                  Class<?>... intermediate) {
+            Class<?>[] ps;
+            int i;
+            switch (this) {
+                case GET:
+                    ps = allocateParameters(0, receiver, intermediate);
+                    fillParameters(ps, receiver, intermediate);
+                    return MethodType.methodType(value, ps);
+                case SET:
+                    ps = allocateParameters(1, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i] = value;
+                    return MethodType.methodType(void.class, ps);
+                case COMPARE_AND_SWAP:
+                    ps = allocateParameters(2, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i++] = value;
+                    ps[i] = value;
+                    return MethodType.methodType(boolean.class, ps);
+                case COMPARE_AND_EXCHANGE:
+                    ps = allocateParameters(2, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i++] = value;
+                    ps[i] = value;
+                    return MethodType.methodType(value, ps);
+                case GET_AND_UPDATE:
+                case GET_AND_UPDATE_BITWISE:
+                case GET_AND_UPDATE_NUMERIC:
+                    ps = allocateParameters(1, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i] = value;
+                    return MethodType.methodType(value, ps);
+                default:
+                    throw new InternalError("Unknown AccessType");
+            }
+        }
+
+        private static Class<?>[] allocateParameters(int values,
+                                                     Class<?> receiver, Class<?>... intermediate) {
+            int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
+            return new Class<?>[size];
+        }
+
+        private static int fillParameters(Class<?>[] ps,
+                                          Class<?> receiver, Class<?>... intermediate) {
+            int i = 0;
+            if (receiver != null)
+                ps[i++] = receiver;
+            for (int j = 0; j < intermediate.length; j++)
+                ps[i++] = intermediate[j];
+            return i;
+        }
+    }
+
+    /**
+     * The set of access modes that specify how a variable, referenced by a
+     * VarHandle, is accessed.
+     */
+    public enum AccessMode {
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#get VarHandle.get}
+         */
+        GET("get", AccessType.GET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#set VarHandle.set}
+         */
+        SET("set", AccessType.SET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getVolatile VarHandle.getVolatile}
+         */
+        GET_VOLATILE("getVolatile", AccessType.GET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#setVolatile VarHandle.setVolatile}
+         */
+        SET_VOLATILE("setVolatile", AccessType.SET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAcquire VarHandle.getAcquire}
+         */
+        GET_ACQUIRE("getAcquire", AccessType.GET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#setRelease VarHandle.setRelease}
+         */
+        SET_RELEASE("setRelease", AccessType.SET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getOpaque VarHandle.getOpaque}
+         */
+        GET_OPAQUE("getOpaque", AccessType.GET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#setOpaque VarHandle.setOpaque}
+         */
+        SET_OPAQUE("setOpaque", AccessType.SET),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
+         */
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#compareAndExchange VarHandle.compareAndExchange}
+         */
+        COMPARE_AND_EXCHANGE("compareAndExchange", AccessType.COMPARE_AND_EXCHANGE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
+         */
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
+         */
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetPlain VarHandle.weakCompareAndSetPlain}
+         */
+        WEAK_COMPARE_AND_SET_PLAIN("weakCompareAndSetPlain", AccessType.COMPARE_AND_SWAP),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
+         */
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
+         */
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
+         */
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndSet VarHandle.getAndSet}
+         */
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndSetAcquire VarHandle.getAndSetAcquire}
+         */
+        GET_AND_SET_ACQUIRE("getAndSetAcquire", AccessType.GET_AND_UPDATE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndSetRelease VarHandle.getAndSetRelease}
+         */
+        GET_AND_SET_RELEASE("getAndSetRelease", AccessType.GET_AND_UPDATE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
+         */
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE_NUMERIC),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndAddAcquire VarHandle.getAndAddAcquire}
+         */
+        GET_AND_ADD_ACQUIRE("getAndAddAcquire", AccessType.GET_AND_UPDATE_NUMERIC),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndAddRelease VarHandle.getAndAddRelease}
+         */
+        GET_AND_ADD_RELEASE("getAndAddRelease", AccessType.GET_AND_UPDATE_NUMERIC),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseOr VarHandle.getAndBitwiseOr}
+         */
+        GET_AND_BITWISE_OR("getAndBitwiseOr", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseOrRelease VarHandle.getAndBitwiseOrRelease}
+         */
+        GET_AND_BITWISE_OR_RELEASE("getAndBitwiseOrRelease", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseOrAcquire VarHandle.getAndBitwiseOrAcquire}
+         */
+        GET_AND_BITWISE_OR_ACQUIRE("getAndBitwiseOrAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseAnd VarHandle.getAndBitwiseAnd}
+         */
+        GET_AND_BITWISE_AND("getAndBitwiseAnd", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseAndRelease VarHandle.getAndBitwiseAndRelease}
+         */
+        GET_AND_BITWISE_AND_RELEASE("getAndBitwiseAndRelease", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseAndAcquire VarHandle.getAndBitwiseAndAcquire}
+         */
+        GET_AND_BITWISE_AND_ACQUIRE("getAndBitwiseAndAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseXor VarHandle.getAndBitwiseXor}
+         */
+        GET_AND_BITWISE_XOR("getAndBitwiseXor", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseXorRelease VarHandle.getAndBitwiseXorRelease}
+         */
+        GET_AND_BITWISE_XOR_RELEASE("getAndBitwiseXorRelease", AccessType.GET_AND_UPDATE_BITWISE),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#getAndBitwiseXorAcquire VarHandle.getAndBitwiseXorAcquire}
+         */
+        GET_AND_BITWISE_XOR_ACQUIRE("getAndBitwiseXorAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+        ;
+
+        static final Map<String, AccessMode> methodNameToAccessMode;
+        static {
+            // Initial capacity of # values is sufficient to avoid resizes
+            // for the smallest table size (32)
+            methodNameToAccessMode = new HashMap<>(AccessMode.values().length);
+            for (AccessMode am : AccessMode.values()) {
+                methodNameToAccessMode.put(am.methodName, am);
+            }
+        }
+
+        final String methodName;
+        final AccessType at;
+
+        AccessMode(final String methodName, AccessType at) {
+            this.methodName = methodName;
+            this.at = at;
+        }
+
+        /**
+         * Returns the {@code VarHandle} signature-polymorphic method name
+         * associated with this {@code AccessMode} value.
+         *
+         * @return the signature-polymorphic method name
+         * @see #valueFromMethodName
+         */
+        public String methodName() {
+            return methodName;
+        }
+
+        /**
+         * Returns the {@code AccessMode} value associated with the specified
+         * {@code VarHandle} signature-polymorphic method name.
+         *
+         * @param methodName the signature-polymorphic method name
+         * @return the {@code AccessMode} value
+         * @throws IllegalArgumentException if there is no {@code AccessMode}
+         *         value associated with method name (indicating the method
+         *         name does not correspond to a {@code VarHandle}
+         *         signature-polymorphic method name).
+         * @see #methodName
+         */
+        public static AccessMode valueFromMethodName(String methodName) {
+            AccessMode am = methodNameToAccessMode.get(methodName);
+            if (am != null) return am;
+            throw new IllegalArgumentException("No AccessMode value for method name " + methodName);
+        }
+
+        // BEGIN Android-removed: MemberName and VarForm are not used in the Android implementation.
+        /*
+        @ForceInline
+        static MemberName getMemberName(int ordinal, VarForm vform) {
+            return vform.memberName_table[ordinal];
+        }
+        */
+        // END Android-removed: MemberName and VarForm are not used in the Android implementation.
+    }
+
+    // BEGIN Android-removed: AccessDescriptor not used in Android implementation.
+    /*
+    static final class AccessDescriptor {
+        final MethodType symbolicMethodTypeErased;
+        final MethodType symbolicMethodTypeInvoker;
+        final Class<?> returnType;
+        final int type;
+        final int mode;
+
+        public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
+            this.symbolicMethodTypeErased = symbolicMethodType.erase();
+            this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
+            this.returnType = symbolicMethodType.returnType();
+            this.type = type;
+            this.mode = mode;
+        }
+    }
+    */
+    // END Android-removed: AccessDescriptor not used in Android implementation.
+
+    /**
+     * Returns the variable type of variables referenced by this VarHandle.
+     *
+     * @return the variable type of variables referenced by this VarHandle
+     */
+    public final Class<?> varType() {
+        // Android-removed: existing implementation.
+        // MethodType typeSet = accessModeType(AccessMode.SET);
+        // return typeSet.parameterType(typeSet.parameterCount() - 1)
+        // Android-added: return instance field.
+        return varType;
+    }
+
+    /**
+     * Returns the coordinate types for this VarHandle.
+     *
+     * @return the coordinate types for this VarHandle. The returned
+     * list is unmodifiable
+     */
+    public final List<Class<?>> coordinateTypes() {
+        // Android-removed: existing implementation.
+        // MethodType typeGet = accessModeType(AccessMode.GET);
+        // return typeGet.parameterList();
+        // Android-added: Android specific implementation.
+        if (coordinateType0 == null) {
+            return Collections.EMPTY_LIST;
+        } else if (coordinateType1 == null) {
+            return Collections.singletonList(coordinateType0);
+        } else {
+            return Collections.unmodifiableList(Arrays.asList(coordinateType0, coordinateType1));
+        }
+    }
+
+    /**
+     * Obtains the access mode type for this VarHandle and a given access mode.
+     *
+     * <p>The access mode type's parameter types will consist of a prefix that
+     * is the coordinate types of this VarHandle followed by further
+     * types as defined by the access mode method.
+     * The access mode type's return type is defined by the return type of the
+     * access mode method.
+     *
+     * @param accessMode the access mode, corresponding to the
+     * signature-polymorphic method of the same name
+     * @return the access mode type for the given access mode
+     */
+    public final MethodType accessModeType(AccessMode accessMode) {
+        // BEGIN Android-removed: Relies on internal class that is not part of the
+        // Android implementation.
+        /*
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
+        if (mt == null) {
+            mt = tis.methodType_table[accessMode.at.ordinal()] =
+                    accessModeTypeUncached(accessMode);
+        }
+        return mt;
+        */
+        // END Android-removed: Relies on internal class that is not part of the
+        // Android implementation.
+        // Android-added: alternative implementation.
+        if (coordinateType1 == null) {
+            // accessModeType() treats the first argument as the
+            // receiver and adapts accordingly if it is null.
+            return accessMode.at.accessModeType(coordinateType0, varType);
+        } else {
+            return accessMode.at.accessModeType(coordinateType0, varType, coordinateType1);
+        }
+    }
+
+    // Android-removed: Not part of the Android implementation.
+    // abstract MethodType accessModeTypeUncached(AccessMode accessMode);
+
+    /**
+     * Returns {@code true} if the given access mode is supported, otherwise
+     * {@code false}.
+     *
+     * <p>The return of a {@code false} value for a given access mode indicates
+     * that an {@code UnsupportedOperationException} is thrown on invocation
+     * of the corresponding access mode method.
+     *
+     * @param accessMode the access mode, corresponding to the
+     * signature-polymorphic method of the same name
+     * @return {@code true} if the given access mode is supported, otherwise
+     * {@code false}.
+     */
+    public final boolean isAccessModeSupported(AccessMode accessMode) {
+        // Android-removed: Refers to unused field vform.
+        // return AccessMode.getMemberName(accessMode.ordinal(), vform) != null;
+        // Android-added: use accessModesBitsMask field.
+        final int testBit = 1 << accessMode.ordinal();
+        return (accessModesBitMask & testBit) == testBit;
+    }
+
+    /**
+     * Obtains a method handle bound to this VarHandle and the given access
+     * mode.
+     *
+     * @apiNote This method, for a VarHandle {@code vh} and access mode
+     * {@code {access-mode}}, returns a method handle that is equivalent to
+     * method handle {@code bmh} in the following code (though it may be more
+     * efficient):
+     * <pre>{@code
+     * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+     *                       vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+     *
+     * MethodHandle bmh = mh.bindTo(vh);
+     * }</pre>
+     *
+     * @param accessMode the access mode, corresponding to the
+     * signature-polymorphic method of the same name
+     * @return a method handle bound to this VarHandle and the given access mode
+     */
+    public final MethodHandle toMethodHandle(AccessMode accessMode) {
+        // BEGIN Android-removed: no vform field in Android implementation.
+        /*
+        MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
+        if (mn != null) {
+            MethodHandle mh = getMethodHandle(accessMode.ordinal());
+            return mh.bindTo(this);
+        }
+        else {
+            // Ensure an UnsupportedOperationException is thrown
+            return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
+                    bindTo(this);
+        }
+        */
+        // END Android-removed: no vform field in Android implementation.
+
+        // Android-added: basic implementation following description in javadoc for this method.
+        MethodType type = accessModeType(accessMode);
+        return MethodHandles.varHandleExactInvoker(accessMode, type).bindTo(this);
+    }
+
+    // BEGIN Android-removed: Not used in Android implementation.
+    /*
+    @Stable
+    TypesAndInvokers typesAndInvokers;
+
+    static class TypesAndInvokers {
+        final @Stable
+        MethodType[] methodType_table =
+                new MethodType[VarHandle.AccessType.values().length];
+
+        final @Stable
+        MethodHandle[] methodHandle_table =
+                new MethodHandle[AccessMode.values().length];
+    }
+
+    @ForceInline
+    private final TypesAndInvokers getTypesAndInvokers() {
+        TypesAndInvokers tis = typesAndInvokers;
+        if (tis == null) {
+            tis = typesAndInvokers = new TypesAndInvokers();
+        }
+        return tis;
+    }
+
+    @ForceInline
+    final MethodHandle getMethodHandle(int mode) {
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodHandle mh = tis.methodHandle_table[mode];
+        if (mh == null) {
+            mh = tis.methodHandle_table[mode] = getMethodHandleUncached(mode);
+        }
+        return mh;
+    }
+    private final MethodHandle getMethodHandleUncached(int mode) {
+        MethodType mt = accessModeType(AccessMode.values()[mode]).
+                insertParameterTypes(0, VarHandle.class);
+        MemberName mn = vform.getMemberName(mode);
+        DirectMethodHandle dmh = DirectMethodHandle.make(mn);
+        // Such a method handle must not be publically exposed directly
+        // otherwise it can be cracked, it must be transformed or rebound
+        // before exposure
+        MethodHandle mh = dmh.copyWith(mt, dmh.form);
+        assert mh.type().erase() == mn.getMethodType().erase();
+        return mh;
+    }
+    */
+    // END Android-removed: Not used in Android implementation.
+
+    // BEGIN Android-removed: No VarForm in Android implementation.
+    /*non-public*/
+    /*
+    final void updateVarForm(VarForm newVForm) {
+        if (vform == newVForm) return;
+        UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
+        UNSAFE.fullFence();
+    }
+
+    static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException>
+            AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter(
+            new Function<String, ArrayIndexOutOfBoundsException>() {
+                @Override
+                public ArrayIndexOutOfBoundsException apply(String s) {
+                    return new ArrayIndexOutOfBoundsException(s);
+                }
+            });
+
+    private static final long VFORM_OFFSET;
+
+    static {
+        try {
+            VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
+        }
+        catch (ReflectiveOperationException e) {
+            throw newInternalError(e);
+        }
+
+        // The VarHandleGuards must be initialized to ensure correct
+        // compilation of the guard methods
+        UNSAFE.ensureClassInitialized(VarHandleGuards.class);
+    }
+    */
+    // END Android-removed: No VarForm in Android implementation.
+
+    // Fence methods
+
+    /**
+     * Ensures that loads and stores before the fence will not be reordered
+     * with
+     * loads and stores after the fence.
+     *
+     * @apiNote Ignoring the many semantic differences from C and C++, this
+     * method has memory ordering effects compatible with
+     * {@code atomic_thread_fence(memory_order_seq_cst)}
+     */
+    // Android-removed: @ForceInline is an unsupported attribute.
+    // @ForceInline
+    public static void fullFence() {
+        UNSAFE.fullFence();
+    }
+
+    /**
+     * Ensures that loads before the fence will not be reordered with loads and
+     * stores after the fence.
+     *
+     * @apiNote Ignoring the many semantic differences from C and C++, this
+     * method has memory ordering effects compatible with
+     * {@code atomic_thread_fence(memory_order_acquire)}
+     */
+    // Android-removed: @ForceInline is an unsupported attribute.
+    // @ForceInline
+    public static void acquireFence() {
+        UNSAFE.loadFence();
+    }
+
+    /**
+     * Ensures that loads and stores before the fence will not be
+     * reordered with stores after the fence.
+     *
+     * @apiNote Ignoring the many semantic differences from C and C++, this
+     * method has memory ordering effects compatible with
+     * {@code atomic_thread_fence(memory_order_release)}
+     */
+    // Android-removed: @ForceInline is an unsupported attribute.
+    // @ForceInline
+    public static void releaseFence() {
+        UNSAFE.storeFence();
+    }
+
+    /**
+     * Ensures that loads before the fence will not be reordered with
+     * loads after the fence.
+     */
+    // Android-removed: @ForceInline is an unsupported attribute.
+    // @ForceInline
+    public static void loadLoadFence() {
+        // Android-changed: Not using UNSAFE.loadLoadFence() as not present on Android.
+        // NB The compiler recognizes all the fences here as intrinsics.
+        UNSAFE.loadFence();
+    }
+
+    /**
+     * Ensures that stores before the fence will not be reordered with
+     * stores after the fence.
+     */
+    // Android-removed: @ForceInline is an unsupported attribute.
+    // @ForceInline
+    public static void storeStoreFence() {
+        // Android-changed: Not using UNSAFE.storeStoreFence() as not present on Android.
+        // NB The compiler recognizes all the fences here as intrinsics.
+        UNSAFE.storeFence();
+    }
+
+    // BEGIN Android-added: package private constructors.
+    /**
+     * Constructor for VarHandle with no coordinates.
+     *
+     * @param varType the variable type of variables to be referenced
+     * @param isFinal whether the target variables are final (non-modifiable)
+     * @hide
+     */
+    VarHandle(Class<?> varType, boolean isFinal) {
+        this.varType = Objects.requireNonNull(varType);
+        this.coordinateType0 = null;
+        this.coordinateType1 = null;
+        this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+    }
+
+    /**
+     * Constructor for VarHandle with one coordinate.
+     *
+     * @param varType the variable type of variables to be referenced
+     * @param isFinal  whether the target variables are final (non-modifiable)
+     * @param coordinateType the coordinate
+     * @hide
+     */
+    VarHandle(Class<?> varType, boolean isFinal, Class<?> coordinateType) {
+        this.varType = Objects.requireNonNull(varType);
+        this.coordinateType0 = Objects.requireNonNull(coordinateType);
+        this.coordinateType1 = null;
+        this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+    }
+
+    /**
+     * Constructor for VarHandle with two coordinates.
+     *
+     * @param varType the variable type of variables to be referenced
+     * @param backingArrayType the type of the array accesses will be performed on
+     * @param isFinal whether the target variables are final (non-modifiable)
+     * @param coordinateType0 the first coordinate
+     * @param coordinateType1 the second coordinate
+     * @hide
+     */
+    VarHandle(Class<?> varType, Class<?> backingArrayType,  boolean isFinal,
+              Class<?> coordinateType0, Class<?> coordinateType1) {
+        this.varType = Objects.requireNonNull(varType);
+        this.coordinateType0 = Objects.requireNonNull(coordinateType0);
+        this.coordinateType1 = Objects.requireNonNull(coordinateType1);
+        Objects.requireNonNull(backingArrayType);
+        Class<?> backingArrayComponentType = backingArrayType.getComponentType();
+        if (backingArrayComponentType != varType && backingArrayComponentType != byte.class) {
+            throw new InternalError("Unsupported backingArrayType: " + backingArrayType);
+        }
+
+        if (backingArrayType.getComponentType() == varType) {
+            this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+        } else {
+            this.accessModesBitMask = unalignedAccessModesBitMask(varType);
+        }
+    }
+    // END Android-added: package private constructors.
+
+    // BEGIN Android-added: helper state for VarHandle properties.
+
+    /** BitMask of access modes that do not change the memory referenced by a VarHandle.
+     * An example being a read of a variable with volatile ordering effects. */
+    private final static int READ_ACCESS_MODES_BIT_MASK;
+
+    /** BitMask of access modes that write to the memory referenced by
+     * a VarHandle.  This does not include any compare and update
+     * access modes, nor any bitwise or numeric access modes. An
+     * example being a write to variable with release ordering
+     * effects.
+     */
+    private final static int WRITE_ACCESS_MODES_BIT_MASK;
+
+    /** BitMask of access modes that are applicable to types
+     * supporting for atomic updates.  This includes access modes that
+     * both read and write a variable such as compare-and-set.
+     */
+    private final static int ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+    /** BitMask of access modes that are applicable to types
+     * supporting numeric atomic update operations. */
+    private final static int NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+    /** BitMask of access modes that are applicable to types
+     * supporting bitwise atomic update operations. */
+    private final static int BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+    /** BitMask of all access modes. */
+    private final static int ALL_MODES_BIT_MASK;
+
+    static {
+        // Check we're not about to overflow the storage of the
+        // bitmasks here and in the accessModesBitMask field.
+        if (AccessMode.values().length > Integer.SIZE) {
+            throw new InternalError("accessModes overflow");
+        }
+
+        // Access modes bit mask declarations and initialization order
+        // follows the presentation order in JEP193.
+        READ_ACCESS_MODES_BIT_MASK = accessTypesToBitMask(EnumSet.of(AccessType.GET));
+
+        WRITE_ACCESS_MODES_BIT_MASK = accessTypesToBitMask(EnumSet.of(AccessType.SET));
+
+        ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+                accessTypesToBitMask(EnumSet.of(AccessType.COMPARE_AND_EXCHANGE,
+                                                AccessType.COMPARE_AND_SWAP,
+                                                AccessType.GET_AND_UPDATE));
+
+        NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+                accessTypesToBitMask(EnumSet.of(AccessType.GET_AND_UPDATE_NUMERIC));
+
+        BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+                accessTypesToBitMask(EnumSet.of(AccessType.GET_AND_UPDATE_BITWISE));
+
+        ALL_MODES_BIT_MASK = (READ_ACCESS_MODES_BIT_MASK |
+                              WRITE_ACCESS_MODES_BIT_MASK |
+                              ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK |
+                              NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK |
+                              BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK);
+    }
+
+    static int accessTypesToBitMask(final EnumSet<AccessType> accessTypes) {
+        int m = 0;
+        for (AccessMode accessMode : AccessMode.values()) {
+            if (accessTypes.contains(accessMode.at)) {
+                m |= 1 << accessMode.ordinal();
+            }
+        }
+        return m;
+    }
+
+    static int alignedAccessModesBitMask(Class<?> varType, boolean isFinal) {
+        // For aligned accesses, the supported access modes are described in:
+        // @see java.lang.invoke.MethodHandles.Lookup#findVarHandle
+        int bitMask = ALL_MODES_BIT_MASK;
+
+        // If the field is declared final, keep only the read access modes.
+        if (isFinal) {
+            bitMask &= READ_ACCESS_MODES_BIT_MASK;
+        }
+
+        // If the field is anything other than byte, short, char, int,
+        // long, float, double then remove the numeric atomic update
+        // access modes.
+        if (varType != byte.class && varType != short.class && varType != char.class &&
+            varType != int.class && varType != long.class
+            && varType != float.class && varType != double.class) {
+            bitMask &= ~NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+        }
+
+        // If the field is not integral, remove the bitwise atomic update access modes.
+        if (varType != boolean.class && varType != byte.class && varType != short.class &&
+            varType != char.class && varType != int.class && varType != long.class) {
+            bitMask &= ~BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+        }
+        return bitMask;
+    }
+
+    static int unalignedAccessModesBitMask(Class<?> varType) {
+        // The VarHandle refers to a view of byte array or a
+        // view of a byte buffer.  The corresponding accesses
+        // maybe unaligned so the access modes are more
+        // restrictive than field or array element accesses.
+        //
+        // The supported access modes are described in:
+        // @see java.lang.invoke.MethodHandles#byteArrayViewVarHandle
+
+        // Read/write access modes supported for all types including
+        // long and double on 32-bit platforms (though these accesses
+        // may not be atomic).
+        int bitMask = READ_ACCESS_MODES_BIT_MASK | WRITE_ACCESS_MODES_BIT_MASK;
+
+        // int, long, float, double support atomic update modes per documentation.
+        if (varType == int.class || varType == long.class ||
+            varType == float.class || varType == double.class) {
+            bitMask |= ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+        }
+
+        // int and long support numeric updates per documentation.
+        if (varType == int.class || varType == long.class) {
+            bitMask |= NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+        }
+
+        // int and long support bitwise updates per documentation.
+        if (varType == int.class || varType == long.class) {
+            bitMask |= BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+        }
+        return bitMask;
+    }
+    // END Android-added: helper state for VarHandle properties.
+}
diff --git a/java/lang/invoke/VolatileCallSite.java b/java/lang/invoke/VolatileCallSite.java
new file mode 100644
index 0000000..47d2689
--- /dev/null
+++ b/java/lang/invoke/VolatileCallSite.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010, 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 java.lang.invoke;
+
+// Android-changed: Removed references to MutableCallSite.syncAll().
+/**
+ * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
+ * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
+ * to its call site target immediately, even if the update occurs in another thread.
+ * There may be a performance penalty for such tight coupling between threads.
+ * <p>
+ * In other respects, a {@code VolatileCallSite} is interchangeable
+ * with {@code MutableCallSite}.
+ * @see MutableCallSite
+ * @author John Rose, JSR 292 EG
+ */
+public class VolatileCallSite extends CallSite {
+    /**
+     * Creates a call site with a volatile binding to its target.
+     * The initial target is set to a method handle
+     * of the given type which will throw an {@code IllegalStateException} if called.
+     * @param type the method type that this call site will have
+     * @throws NullPointerException if the proposed type is null
+     */
+    public VolatileCallSite(MethodType type) {
+        super(type);
+    }
+
+    /**
+     * Creates a call site with a volatile binding to its target.
+     * The target is set to the given value.
+     * @param target the method handle that will be the initial target of the call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    public VolatileCallSite(MethodHandle target) {
+        super(target);
+    }
+
+    /**
+     * Returns the target method of the call site, which behaves
+     * like a {@code volatile} field of the {@code VolatileCallSite}.
+     * <p>
+     * The interactions of {@code getTarget} with memory are the same
+     * as of a read from a {@code volatile} field.
+     * <p>
+     * In particular, the current thread is required to issue a fresh
+     * read of the target from memory, and must not fail to see
+     * a recent update to the target by another thread.
+     *
+     * @return the linkage state of this call site, a method handle which can change over time
+     * @see #setTarget
+     */
+    @Override public final MethodHandle getTarget() {
+        return getTargetVolatile();
+    }
+
+    /**
+     * Updates the target method of this call site, as a volatile variable.
+     * The type of the new target must agree with the type of the old target.
+     * <p>
+     * The interactions with memory are the same as of a write to a volatile field.
+     * In particular, any threads is guaranteed to see the updated target
+     * the next time it calls {@code getTarget}.
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see #getTarget
+     */
+    @Override public void setTarget(MethodHandle newTarget) {
+        checkTargetChange(getTargetVolatile(), newTarget);
+        setTargetVolatile(newTarget);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return makeDynamicInvoker();
+    }
+}
diff --git a/java/lang/invoke/WrongMethodTypeException.java b/java/lang/invoke/WrongMethodTypeException.java
new file mode 100644
index 0000000..d55e3cd
--- /dev/null
+++ b/java/lang/invoke/WrongMethodTypeException.java
@@ -0,0 +1,85 @@
+/*
+ * 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 java.lang.invoke;
+
+/**
+ * Thrown to indicate that code has attempted to call a method handle
+ * via the wrong method type.  As with the bytecode representation of
+ * normal Java method calls, method handle calls are strongly typed
+ * to a specific type descriptor associated with a call site.
+ * <p>
+ * This exception may also be thrown when two method handles are
+ * composed, and the system detects that their types cannot be
+ * matched up correctly.  This amounts to an early evaluation
+ * of the type mismatch, at method handle construction time,
+ * instead of when the mismatched method handle is called.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class WrongMethodTypeException extends RuntimeException {
+    private static final long serialVersionUID = 292L;
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with no detail message.
+     */
+    public WrongMethodTypeException() {
+        super();
+    }
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with the specified
+     * detail message.
+     *
+     * @param s the detail message.
+     */
+    public WrongMethodTypeException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with the specified
+     * detail message and cause.
+     *
+     * @param s the detail message.
+     * @param cause the cause of the exception, or null.
+     */
+    //FIXME: make this public in MR1
+    /*non-public*/ WrongMethodTypeException(String s, Throwable cause) {
+        super(s, cause);
+    }
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with the specified
+     * cause.
+     *
+     * @param cause the cause of the exception, or null.
+     */
+    //FIXME: make this public in MR1
+    /*non-public*/ WrongMethodTypeException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/lang/package-info.java b/java/lang/package-info.java
new file mode 100644
index 0000000..aa7a79d
--- /dev/null
+++ b/java/lang/package-info.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1998, 2006, 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.
+ */
+
+/**
+ * Provides classes that are fundamental to the design of the Java
+ * programming language. The most important classes are {@code
+ * Object}, which is the root of the class hierarchy, and {@code
+ * Class}, instances of which represent classes at run time.
+ *
+ * <p>Frequently it is necessary to represent a value of primitive
+ * type as if it were an object. The wrapper classes {@code Boolean},
+ * {@code Character}, {@code Integer}, {@code Long}, {@code Float},
+ * and {@code Double} serve this purpose.  An object of type {@code
+ * Double}, for example, contains a field whose type is double,
+ * representing that value in such a way that a reference to it can be
+ * stored in a variable of reference type.  These classes also provide
+ * a number of methods for converting among primitive values, as well
+ * as supporting such standard methods as equals and hashCode.  The
+ * {@code Void} class is a non-instantiable class that holds a
+ * reference to a {@code Class} object representing the type void.
+ *
+ * <p>The class {@code Math} provides commonly used mathematical
+ * functions such as sine, cosine, and square root. The classes {@code
+ * String}, {@code StringBuffer}, and {@code StringBuilder} similarly
+ * provide commonly used operations on character strings.
+ *
+ * <p>Classes {@code ClassLoader}, {@code Process}, {@code
+ * ProcessBuilder}, {@code Runtime}, {@code SecurityManager}, and
+ * {@code System} provide "system operations" that manage the dynamic
+ * loading of classes, creation of external processes, host
+ * environment inquiries such as the time of day, and enforcement of
+ * security policies.
+ *
+ * <p>Class {@code Throwable} encompasses objects that may be thrown
+ * by the {@code throw} statement. Subclasses of {@code Throwable}
+ * represent errors and exceptions.
+ *
+ * <a name="charenc"></a>
+ * <h3>Character Encodings</h3>
+ *
+ * The specification of the {@link java.nio.charset.Charset
+ * java.nio.charset.Charset} class describes the naming conventions
+ * for character encodings as well as the set of standard encodings
+ * that must be supported by every implementation of the Java
+ * platform.
+ *
+ * @since JDK1.0
+ */
+package java.lang;
diff --git a/java/lang/ref/FinalizerReference.java b/java/lang/ref/FinalizerReference.java
new file mode 100644
index 0000000..037af4a
--- /dev/null
+++ b/java/lang/ref/FinalizerReference.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.ref;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * @hide
+ */
+public final class FinalizerReference<T> extends Reference<T> {
+    // This queue contains those objects eligible for finalization.
+    @UnsupportedAppUsage
+    public static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+
+    // Guards the list (not the queue).
+    private static final Object LIST_LOCK = new Object();
+
+    // This list contains a FinalizerReference for every finalizable object in the heap.
+    // Objects in this list may or may not be eligible for finalization yet.
+    @UnsupportedAppUsage
+    private static FinalizerReference<?> head = null;
+
+    // The links used to construct the list.
+    private FinalizerReference<?> prev;
+    @UnsupportedAppUsage
+    private FinalizerReference<?> next;
+
+    // When the GC wants something finalized, it moves it from the 'referent' field to
+    // the 'zombie' field instead.
+    private T zombie;
+
+    public FinalizerReference(T r, ReferenceQueue<? super T> q) {
+        super(r, q);
+    }
+
+    @Override public T get() {
+        return zombie;
+    }
+
+    @Override public void clear() {
+        zombie = null;
+    }
+
+    @UnsupportedAppUsage
+    public static void add(Object referent) {
+        FinalizerReference<?> reference = new FinalizerReference<Object>(referent, queue);
+        synchronized (LIST_LOCK) {
+            reference.prev = null;
+            reference.next = head;
+            if (head != null) {
+                head.prev = reference;
+            }
+            head = reference;
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static void remove(FinalizerReference<?> reference) {
+        synchronized (LIST_LOCK) {
+            FinalizerReference<?> next = reference.next;
+            FinalizerReference<?> prev = reference.prev;
+            reference.next = null;
+            reference.prev = null;
+            if (prev != null) {
+                prev.next = next;
+            } else {
+                head = next;
+            }
+            if (next != null) {
+                next.prev = prev;
+            }
+        }
+    }
+
+    /**
+     * Waits for all currently-enqueued references to be finalized.
+     */
+    public static void finalizeAllEnqueued(long timeout) throws InterruptedException {
+        // Alloate a new sentinel, this creates a FinalizerReference.
+        Sentinel sentinel;
+        // Keep looping until we safely enqueue our sentinel FinalizerReference.
+        // This is done to prevent races where the GC updates the pendingNext
+        // before we get the chance.
+        do {
+            sentinel = new Sentinel();
+        } while (!enqueueSentinelReference(sentinel));
+        sentinel.awaitFinalization(timeout);
+    }
+
+    private static boolean enqueueSentinelReference(Sentinel sentinel) {
+        synchronized (LIST_LOCK) {
+            // When a finalizable object is allocated, a FinalizerReference is added to the list.
+            // We search the list for that FinalizerReference (it should be at or near the head),
+            // and then put it on the queue so that it can be finalized.
+            for (FinalizerReference<?> r = head; r != null; r = r.next) {
+                // Use getReferent() instead of directly accessing the referent field not to race
+                // with GC reference processing. Can't use get() either because it's overridden to
+                // return the zombie.
+                if (r.getReferent() == sentinel) {
+                    FinalizerReference<Sentinel> sentinelReference = (FinalizerReference<Sentinel>) r;
+                    sentinelReference.clearReferent();
+                    sentinelReference.zombie = sentinel;
+                    // Make a single element list, then enqueue the reference on the daemon unenqueued
+                    // list. This is required instead of enqueuing directly on the finalizer queue
+                    // since there could be recently freed objects in the unqueued list which are not
+                    // yet on the finalizer queue. This could cause the sentinel to run before the
+                    // objects are finalized. b/17381967
+                    // Make circular list if unenqueued goes through native so that we can prevent
+                    // races where the GC updates the pendingNext before we do. If it is non null, then
+                    // we update the pending next to make a circular list while holding a lock.
+                    // b/17462553
+                    if (!sentinelReference.makeCircularListIfUnenqueued()) {
+                        return false;
+                    }
+                    ReferenceQueue.add(sentinelReference);
+                    return true;
+                }
+            }
+        }
+        // We just created a finalizable object and still hold a reference to it.
+        // It must be on the list.
+        throw new AssertionError("newly-created live Sentinel not on list!");
+    }
+
+    @FastNative
+    private final native T getReferent();
+    @FastNative
+    private native boolean makeCircularListIfUnenqueued();
+
+    /**
+     * A marker object that we can immediately enqueue. When this object's
+     * finalize() method is called, we know all previously-enqueued finalizable
+     * references have been finalized.
+     */
+    private static class Sentinel {
+        boolean finalized = false;
+
+        @Override protected synchronized void finalize() throws Throwable {
+            if (finalized) {
+                throw new AssertionError();
+            }
+            finalized = true;
+            notifyAll();
+        }
+
+        synchronized void awaitFinalization(long timeout) throws InterruptedException {
+            final long startTime = System.nanoTime();
+            final long endTime = startTime + timeout;
+            while (!finalized) {
+                // 0 signifies no timeout.
+                if (timeout != 0) {
+                    final long currentTime = System.nanoTime();
+                    if (currentTime >= endTime) {
+                        break;
+                    } else {
+                        final long deltaTime = endTime - currentTime;
+                        wait(deltaTime / 1000000, (int)(deltaTime % 1000000));
+                    }
+                } else {
+                    wait();
+                }
+            }
+        }
+    }
+}
diff --git a/java/lang/ref/PhantomReference.java b/java/lang/ref/PhantomReference.java
new file mode 100644
index 0000000..1c1364a
--- /dev/null
+++ b/java/lang/ref/PhantomReference.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+
+/**
+ * Phantom reference objects, which are enqueued after the collector
+ * determines that their referents may otherwise be reclaimed.  Phantom
+ * references are most often used for scheduling pre-mortem cleanup actions in
+ * a more flexible way than is possible with the Java finalization mechanism.
+ *
+ * <p> If the garbage collector determines at a certain point in time that the
+ * referent of a phantom reference is <a
+ * href="package-summary.html#reachability">phantom reachable</a>, then at that
+ * time or at some later time it will enqueue the reference.
+ *
+ * <p> In order to ensure that a reclaimable object remains so, the referent of
+ * a phantom reference may not be retrieved: The <code>get</code> method of a
+ * phantom reference always returns <code>null</code>.
+ *
+ * <p> Unlike soft and weak references, phantom references are not
+ * automatically cleared by the garbage collector as they are enqueued.  An
+ * object that is reachable via phantom references will remain so until all
+ * such references are cleared or themselves become unreachable.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+
+public class PhantomReference<T> extends Reference<T> {
+
+    /**
+     * Returns this reference object's referent.  Because the referent of a
+     * phantom reference is always inaccessible, this method always returns
+     * <code>null</code>.
+     *
+     * @return  <code>null</code>
+     */
+    public T get() {
+        return null;
+    }
+
+    /**
+     * Creates a new phantom reference that refers to the given object and
+     * is registered with the given queue.
+     *
+     * <p> It is possible to create a phantom reference with a <tt>null</tt>
+     * queue, but such a reference is completely useless: Its <tt>get</tt>
+     * method will always return null and, since it does not have a queue, it
+     * will never be enqueued.
+     *
+     * @param referent the object the new phantom reference will refer to
+     * @param q the queue with which the reference is to be registered,
+     *          or <tt>null</tt> if registration is not required
+     */
+    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
+        super(referent, q);
+    }
+
+}
diff --git a/java/lang/ref/Reference.java b/java/lang/ref/Reference.java
new file mode 100644
index 0000000..e5126b5
--- /dev/null
+++ b/java/lang/ref/Reference.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2017, 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.ref;
+
+import dalvik.annotation.optimization.FastNative;
+
+
+/**
+ * Abstract base class for reference objects.  This class defines the
+ * operations common to all reference objects.  Because reference objects are
+ * implemented in close cooperation with the garbage collector, this class may
+ * not be subclassed directly.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+
+public abstract class Reference<T> {
+    // BEGIN Android-changed: Reimplemented to accommodate a different GC and compiler.
+    // ClassLinker knows about the fields of this class.
+
+    /**
+     * Forces JNI path.
+     * If GC is not in progress (ie: not going through slow path), the referent
+     * can be quickly returned through intrinsic without passing through JNI.
+     * This flag forces the JNI path so that it can be tested and benchmarked.
+     */
+    private static boolean disableIntrinsic = false;
+
+    /**
+     * Slow path flag for the reference processor.
+     * Used by the reference processor to determine whether or not the referent
+     * can be immediately returned. Because the referent might get swept during
+     * GC, the slow path, which passes through JNI, must be taken.
+     */
+    private static boolean slowPathEnabled = false;
+
+    // Treated specially by GC. ART's ClassLinker::LinkFields() knows this is the
+    // alphabetically last non-static field.
+    volatile T referent;
+
+    final ReferenceQueue<? super T> queue;
+
+    /*
+     * This field forms a singly-linked list of reference objects that have
+     * been enqueued. The queueNext field is non-null if and only if this
+     * reference has been enqueued. After this reference has been enqueued and
+     * before it has been removed from its queue, the queueNext field points
+     * to the next reference on the queue. The last reference on a queue
+     * points to itself. Once this reference has been removed from the
+     * reference queue, the queueNext field points to the
+     * ReferenceQueue.sQueueNextUnenqueued sentinel reference object for the
+     * rest of this reference's lifetime.
+     * <p>
+     * Access to the queueNext field is guarded by synchronization on a lock
+     * internal to 'queue'.
+     */
+    Reference queueNext;
+
+    /**
+     * The pendingNext field is initially set by the GC. After the GC forms a
+     * complete circularly linked list, the list is handed off to the
+     * ReferenceQueueDaemon using the ReferenceQueue.class lock. The
+     * ReferenceQueueDaemon can then read the pendingNext fields without
+     * additional synchronization.
+     */
+    Reference<?> pendingNext;
+
+    /* -- Referent accessor and setters -- */
+
+    /**
+     * Returns this reference object's referent.  If this reference object has
+     * been cleared, either by the program or by the garbage collector, then
+     * this method returns <code>null</code>.
+     *
+     * @return   The object to which this reference refers, or
+     *           <code>null</code> if this reference object has been cleared
+     */
+    public T get() {
+        return getReferent();
+    }
+
+    @FastNative
+    private final native T getReferent();
+
+    /**
+     * Clears this reference object.  Invoking this method will not cause this
+     * object to be enqueued.
+     *
+     * <p> This method is invoked only by Java code; when the garbage collector
+     * clears references it does so directly, without invoking this method.
+     */
+    public void clear() {
+        clearReferent();
+    }
+
+    // Direct access to the referent is prohibited, clearReferent blocks and set
+    // the referent to null when it is safe to do so.
+    @FastNative
+    native void clearReferent();
+
+    /* -- Queue operations -- */
+
+    /**
+     * Tells whether or not this reference object has been enqueued, either by
+     * the program or by the garbage collector.  If this reference object was
+     * not registered with a queue when it was created, then this method will
+     * always return <code>false</code>.
+     *
+     * @return   <code>true</code> if and only if this reference object has
+     *           been enqueued
+     */
+    public boolean isEnqueued() {
+        // Contrary to what the documentation says, this method returns false
+        // after this reference object has been removed from its queue
+        // (b/26647823). ReferenceQueue.isEnqueued preserves this historically
+        // incorrect behavior.
+        return queue != null && queue.isEnqueued(this);
+    }
+
+    /**
+     * Adds this reference object to the queue with which it is registered,
+     * if any.
+     *
+     * <p> This method is invoked only by Java code; when the garbage collector
+     * enqueues references it does so directly, without invoking this method.
+     *
+     * @return   <code>true</code> if this reference object was successfully
+     *           enqueued; <code>false</code> if it was already enqueued or if
+     *           it was not registered with a queue when it was created
+     */
+    public boolean enqueue() {
+       return queue != null && queue.enqueue(this);
+    }
+
+    /* -- Constructors -- */
+
+    Reference(T referent) {
+        this(referent, null);
+    }
+
+    Reference(T referent, ReferenceQueue<? super T> queue) {
+        this.referent = referent;
+        this.queue = queue;
+    }
+    // END Android-changed: Reimplemented to accommodate a different GC and compiler.
+
+    // BEGIN Android-added: reachabilityFence() from upstream OpenJDK9+181.
+    // The actual implementation differs from OpenJDK9.
+    /**
+     * Ensures that the object referenced by the given reference remains
+     * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
+     * regardless of any prior actions of the program that might otherwise cause
+     * the object to become unreachable; thus, the referenced object is not
+     * reclaimable by garbage collection at least until after the invocation of
+     * this method.  Invocation of this method does not itself initiate garbage
+     * collection or finalization.
+     *
+     * <p> This method establishes an ordering for
+     * <a href="package-summary.html#reachability"><em>strong reachability</em></a>
+     * with respect to garbage collection.  It controls relations that are
+     * otherwise only implicit in a program -- the reachability conditions
+     * triggering garbage collection.  This method is designed for use in
+     * uncommon situations of premature finalization where using
+     * {@code synchronized} blocks or methods, or using other synchronization
+     * facilities are not possible or do not provide the desired control.  This
+     * method is applicable only when reclamation may have visible effects,
+     * which is possible for objects with finalizers (See
+     * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.6">
+     * Section 12.6 17 of <cite>The Java&trade; Language Specification</cite></a>)
+     * that are implemented in ways that rely on ordering control for correctness.
+     *
+     * @apiNote
+     * Finalization may occur whenever the virtual machine detects that no
+     * reference to an object will ever be stored in the heap: The garbage
+     * collector may reclaim an object even if the fields of that object are
+     * still in use, so long as the object has otherwise become unreachable.
+     * This may have surprising and undesirable effects in cases such as the
+     * following example in which the bookkeeping associated with a class is
+     * managed through array indices.  Here, method {@code action} uses a
+     * {@code reachabilityFence} to ensure that the {@code Resource} object is
+     * not reclaimed before bookkeeping on an associated
+     * {@code ExternalResource} has been performed; in particular here, to
+     * ensure that the array slot holding the {@code ExternalResource} is not
+     * nulled out in method {@link Object#finalize}, which may otherwise run
+     * concurrently.
+     *
+     * <pre> {@code
+     * class Resource {
+     *   private static ExternalResource[] externalResourceArray = ...
+     *
+     *   int myIndex;
+     *   Resource(...) {
+     *     myIndex = ...
+     *     externalResourceArray[myIndex] = ...;
+     *     ...
+     *   }
+     *   protected void finalize() {
+     *     externalResourceArray[myIndex] = null;
+     *     ...
+     *   }
+     *   public void action() {
+     *     try {
+     *       // ...
+     *       int i = myIndex;
+     *       Resource.update(externalResourceArray[i]);
+     *     } finally {
+     *       Reference.reachabilityFence(this);
+     *     }
+     *   }
+     *   private static void update(ExternalResource ext) {
+     *     ext.status = ...;
+     *   }
+     * }}</pre>
+     *
+     * Here, the invocation of {@code reachabilityFence} is nonintuitively
+     * placed <em>after</em> the call to {@code update}, to ensure that the
+     * array slot is not nulled out by {@link Object#finalize} before the
+     * update, even if the call to {@code action} was the last use of this
+     * object.  This might be the case if, for example a usage in a user program
+     * had the form {@code new Resource().action();} which retains no other
+     * reference to this {@code Resource}.  While probably overkill here,
+     * {@code reachabilityFence} is placed in a {@code finally} block to ensure
+     * that it is invoked across all paths in the method.  In a method with more
+     * complex control paths, you might need further precautions to ensure that
+     * {@code reachabilityFence} is encountered along all of them.
+     *
+     * <p> It is sometimes possible to better encapsulate use of
+     * {@code reachabilityFence}.  Continuing the above example, if it were
+     * acceptable for the call to method {@code update} to proceed even if the
+     * finalizer had already executed (nulling out slot), then you could
+     * localize use of {@code reachabilityFence}:
+     *
+     * <pre> {@code
+     * public void action2() {
+     *   // ...
+     *   Resource.update(getExternalResource());
+     * }
+     * private ExternalResource getExternalResource() {
+     *   ExternalResource ext = externalResourceArray[myIndex];
+     *   Reference.reachabilityFence(this);
+     *   return ext;
+     * }}</pre>
+     *
+     * <p> Method {@code reachabilityFence} is not required in constructions
+     * that themselves ensure reachability.  For example, because objects that
+     * are locked cannot, in general, be reclaimed, it would suffice if all
+     * accesses of the object, in all methods of class {@code Resource}
+     * (including {@code finalize}) were enclosed in {@code synchronized (this)}
+     * blocks.  (Further, such blocks must not include infinite loops, or
+     * themselves be unreachable, which fall into the corner case exceptions to
+     * the "in general" disclaimer.)  However, method {@code reachabilityFence}
+     * remains a better option in cases where this approach is not as efficient,
+     * desirable, or possible; for example because it would encounter deadlock.
+     *
+     * @param ref the reference. If {@code null}, this method has no effect.
+     * @since 9
+     */
+    // @DontInline
+    public static void reachabilityFence(Object ref) {
+        // This code is usually replaced by much faster intrinsic implementations.
+        // It will be executed for tests run with the access checks interpreter in
+        // ART, e.g. with --verify-soft-fail.  Since this is a volatile store, it
+        // cannot easily be moved up past prior accesses, even if this method is
+        // inlined.
+        SinkHolder.sink = ref;
+        // Leaving SinkHolder set to ref is unpleasant, since it keeps ref live
+        // until the next reachabilityFence call. This causes e.g. 036-finalizer
+        // to fail. Clear it again in a way that's unlikely to be optimizable.
+        // The fact that finalize_count is volatile makes it hard to move the test up.
+        if (SinkHolder.finalize_count == 0) {
+            SinkHolder.sink = null;
+        }
+    }
+
+    private static class SinkHolder {
+        static volatile Object sink;
+
+        // Ensure that sink looks live to even a reasonably clever compiler.
+        private static volatile int finalize_count = 0;
+
+        private static Object sinkUser = new Object() {
+            protected void finalize() {
+                if (sink == null && finalize_count > 0) {
+                    throw new AssertionError("Can't get here");
+                }
+                finalize_count++;
+            }
+        };
+    }
+    // END Android-added: reachabilityFence() from upstream OpenJDK9+181.
+}
diff --git a/java/lang/ref/ReferenceQueue.java b/java/lang/ref/ReferenceQueue.java
new file mode 100644
index 0000000..72e55c1
--- /dev/null
+++ b/java/lang/ref/ReferenceQueue.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2005, 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.ref;
+
+import sun.misc.Cleaner;
+
+/**
+ * Reference queues, to which registered reference objects are appended by the
+ * garbage collector after the appropriate reachability changes are detected.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+// BEGIN Android-changed: Reimplemented to accomodate a different GC and compiler.
+
+public class ReferenceQueue<T> {
+
+    // Reference.queueNext will be set to sQueueNextUnenqueued to indicate
+    // when a reference has been enqueued and removed from its queue.
+    private static final Reference sQueueNextUnenqueued = new PhantomReference(null, null);
+
+    // NOTE: This implementation of ReferenceQueue is FIFO (queue-like) whereas
+    // the OpenJdk implementation is LIFO (stack-like).
+    private Reference<? extends T> head = null;
+    private Reference<? extends T> tail = null;
+
+    private final Object lock = new Object();
+
+    /**
+     * Constructs a new reference-object queue.
+     */
+    public ReferenceQueue() { }
+
+    /**
+     * Enqueue the given reference onto this queue.
+     * The caller is responsible for ensuring the lock is held on this queue,
+     * and for calling notifyAll on this queue after the reference has been
+     * enqueued. Returns true if the reference was enqueued successfully,
+     * false if the reference had already been enqueued.
+     * @GuardedBy("lock")
+     */
+    private boolean enqueueLocked(Reference<? extends T> r) {
+        // Verify the reference has not already been enqueued.
+        if (r.queueNext != null) {
+            return false;
+        }
+
+        if (r instanceof Cleaner) {
+            // If this reference is a Cleaner, then simply invoke the clean method instead
+            // of enqueueing it in the queue. Cleaners are associated with dummy queues that
+            // are never polled and objects are never enqueued on them.
+            Cleaner cl = (sun.misc.Cleaner) r;
+            cl.clean();
+
+            // Update queueNext to indicate that the reference has been
+            // enqueued, but is now removed from the queue.
+            r.queueNext = sQueueNextUnenqueued;
+            return true;
+        }
+
+        if (tail == null) {
+            head = r;
+        } else {
+            tail.queueNext = r;
+        }
+        tail = r;
+        tail.queueNext = r;
+        return true;
+    }
+
+    /**
+     * Test if the given reference object has been enqueued but not yet
+     * removed from the queue, assuming this is the reference object's queue.
+     */
+    boolean isEnqueued(Reference<? extends T> reference) {
+        synchronized (lock) {
+            return reference.queueNext != null && reference.queueNext != sQueueNextUnenqueued;
+        }
+    }
+
+    /**
+     * Enqueue the reference object on the receiver.
+     *
+     * @param reference
+     *            reference object to be enqueued.
+     * @return true if the reference was enqueued.
+     */
+    boolean enqueue(Reference<? extends T> reference) {
+        synchronized (lock) {
+            if (enqueueLocked(reference)) {
+                lock.notifyAll();
+                return true;
+            }
+            return false;
+        }
+    }
+
+    // @GuardedBy("lock")
+    private Reference<? extends T> reallyPollLocked() {
+        if (head != null) {
+            Reference<? extends T> r = head;
+            if (head == tail) {
+                tail = null;
+                head = null;
+            } else {
+                head = head.queueNext;
+            }
+
+            // Update queueNext to indicate that the reference has been
+            // enqueued, but is now removed from the queue.
+            r.queueNext = sQueueNextUnenqueued;
+            return r;
+        }
+
+        return null;
+    }
+
+    /**
+     * Polls this queue to see if a reference object is available.  If one is
+     * available without further delay then it is removed from the queue and
+     * returned.  Otherwise this method immediately returns <tt>null</tt>.
+     *
+     * @return  A reference object, if one was immediately available,
+     *          otherwise <code>null</code>
+     */
+    public Reference<? extends T> poll() {
+        synchronized (lock) {
+            if (head == null)
+                return null;
+
+            return reallyPollLocked();
+        }
+    }
+
+    /**
+     * Removes the next reference object in this queue, blocking until either
+     * one becomes available or the given timeout period expires.
+     *
+     * <p> This method does not offer real-time guarantees: It schedules the
+     * timeout as if by invoking the {@link Object#wait(long)} method.
+     *
+     * @param  timeout  If positive, block for up to <code>timeout</code>
+     *                  milliseconds while waiting for a reference to be
+     *                  added to this queue.  If zero, block indefinitely.
+     *
+     * @return  A reference object, if one was available within the specified
+     *          timeout period, otherwise <code>null</code>
+     *
+     * @throws  IllegalArgumentException
+     *          If the value of the timeout argument is negative
+     *
+     * @throws  InterruptedException
+     *          If the timeout wait is interrupted
+     */
+    public Reference<? extends T> remove(long timeout)
+        throws IllegalArgumentException, InterruptedException
+    {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("Negative timeout value");
+        }
+        synchronized (lock) {
+            Reference<? extends T> r = reallyPollLocked();
+            if (r != null) return r;
+            long start = (timeout == 0) ? 0 : System.nanoTime();
+            for (;;) {
+                lock.wait(timeout);
+                r = reallyPollLocked();
+                if (r != null) return r;
+                if (timeout != 0) {
+                    long end = System.nanoTime();
+                    timeout -= (end - start) / 1000_000;
+                    if (timeout <= 0) return null;
+                    start = end;
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes the next reference object in this queue, blocking until one
+     * becomes available.
+     *
+     * @return A reference object, blocking until one becomes available
+     * @throws  InterruptedException  If the wait is interrupted
+     */
+    public Reference<? extends T> remove() throws InterruptedException {
+        return remove(0);
+    }
+
+    /**
+     * Enqueue the given list of currently pending (unenqueued) references.
+     *
+     * @hide
+     */
+    public static void enqueuePending(Reference<?> list) {
+        Reference<?> start = list;
+        do {
+            ReferenceQueue queue = list.queue;
+            if (queue == null) {
+                Reference<?> next = list.pendingNext;
+
+                // Make pendingNext a self-loop to preserve the invariant that
+                // once enqueued, pendingNext is non-null -- without leaking
+                // the object pendingNext was previously pointing to.
+                list.pendingNext = list;
+                list = next;
+            } else {
+                // To improve performance, we try to avoid repeated
+                // synchronization on the same queue by batching enqueue of
+                // consecutive references in the list that have the same
+                // queue.
+                synchronized (queue.lock) {
+                    do {
+                        Reference<?> next = list.pendingNext;
+
+                        // Make pendingNext a self-loop to preserve the
+                        // invariant that once enqueued, pendingNext is
+                        // non-null -- without leaking the object pendingNext
+                        // was previously pointing to.
+                        list.pendingNext = list;
+                        queue.enqueueLocked(list);
+                        list = next;
+                    } while (list != start && list.queue == queue);
+                    queue.lock.notifyAll();
+                }
+            }
+        } while (list != start);
+    }
+
+    /**
+     * List of references that the GC says need to be enqueued.
+     * Protected by ReferenceQueue.class lock.
+     * @hide
+     */
+    public static Reference<?> unenqueued = null;
+
+    static void add(Reference<?> list) {
+        synchronized (ReferenceQueue.class) {
+            if (unenqueued == null) {
+                unenqueued = list;
+            } else {
+                // Find the last element in unenqueued.
+                Reference<?> last = unenqueued;
+                while (last.pendingNext != unenqueued) {
+                  last = last.pendingNext;
+                }
+                // Add our list to the end. Update the pendingNext to point back to enqueued.
+                last.pendingNext = list;
+                last = list;
+                while (last.pendingNext != list) {
+                    last = last.pendingNext;
+                }
+                last.pendingNext = unenqueued;
+            }
+            ReferenceQueue.class.notifyAll();
+        }
+    }
+}
+// END Android-changed: Reimplemented to accomodate a different GC and compiler.
diff --git a/java/lang/ref/SoftReference.java b/java/lang/ref/SoftReference.java
new file mode 100644
index 0000000..272d1bd
--- /dev/null
+++ b/java/lang/ref/SoftReference.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+// Android-changed: Javadoc change to recommend against using SoftReferences for caches.
+/**
+ * Soft reference objects, which are cleared at the discretion of the garbage
+ * collector in response to memory demand.
+ *
+ * <p> Suppose that the garbage collector determines at a certain point in time
+ * that an object is <a href="package-summary.html#reachability">softly
+ * reachable</a>.  At that time it may choose to clear atomically all soft
+ * references to that object and all soft references to any other
+ * softly-reachable objects from which that object is reachable through a chain
+ * of strong references.  At the same time or at some later time it will
+ * enqueue those newly-cleared soft references that are registered with
+ * reference queues.
+ *
+ * <p> All soft references to softly-reachable objects are guaranteed to have
+ * been cleared before the virtual machine throws an
+ * <code>OutOfMemoryError</code>.  Otherwise no constraints are placed upon the
+ * time at which a soft reference will be cleared or the order in which a set
+ * of such references to different objects will be cleared.  Virtual machine
+ * implementations are, however, encouraged to bias against clearing
+ * recently-created or recently-used soft references.
+ *
+ * <h3>Avoid Soft References for Caching</h3>
+ * In practice, soft references are inefficient for caching. The runtime doesn't
+ * have enough information on which references to clear and which to keep. Most
+ * fatally, it doesn't know what to do when given the choice between clearing a
+ * soft reference and growing the heap.
+ *
+ * <p>The lack of information on the value to your application of each reference
+ * limits the usefulness of soft references. References that are cleared too
+ * early cause unnecessary work; those that are cleared too late waste memory.
+ *
+ * <p>Most applications should use an {@code android.util.LruCache} instead of
+ * soft references. LruCache has an effective eviction policy and lets the user
+ * tune how much memory is allotted.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+
+public class SoftReference<T> extends Reference<T> {
+
+    /**
+     * Timestamp clock, updated by the garbage collector
+     */
+    static private long clock;
+
+    /**
+     * Timestamp updated by each invocation of the get method.  The VM may use
+     * this field when selecting soft references to be cleared, but it is not
+     * required to do so.
+     */
+    private long timestamp;
+
+    /**
+     * Creates a new soft reference that refers to the given object.  The new
+     * reference is not registered with any queue.
+     *
+     * @param referent object the new soft reference will refer to
+     */
+    public SoftReference(T referent) {
+        super(referent);
+        this.timestamp = clock;
+    }
+
+    /**
+     * Creates a new soft reference that refers to the given object and is
+     * registered with the given queue.
+     *
+     * @param referent object the new soft reference will refer to
+     * @param q the queue with which the reference is to be registered,
+     *          or <tt>null</tt> if registration is not required
+     *
+     */
+    public SoftReference(T referent, ReferenceQueue<? super T> q) {
+        super(referent, q);
+        this.timestamp = clock;
+    }
+
+    /**
+     * Returns this reference object's referent.  If this reference object has
+     * been cleared, either by the program or by the garbage collector, then
+     * this method returns <code>null</code>.
+     *
+     * @return   The object to which this reference refers, or
+     *           <code>null</code> if this reference object has been cleared
+     */
+    public T get() {
+        T o = super.get();
+        if (o != null && this.timestamp != clock)
+            this.timestamp = clock;
+        return o;
+    }
+
+}
diff --git a/java/lang/ref/WeakReference.java b/java/lang/ref/WeakReference.java
new file mode 100644
index 0000000..025949a
--- /dev/null
+++ b/java/lang/ref/WeakReference.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+
+/**
+ * Weak reference objects, which do not prevent their referents from being
+ * made finalizable, finalized, and then reclaimed.  Weak references are most
+ * often used to implement canonicalizing mappings.
+ *
+ * <p> Suppose that the garbage collector determines at a certain point in time
+ * that an object is <a href="package-summary.html#reachability">weakly
+ * reachable</a>.  At that time it will atomically clear all weak references to
+ * that object and all weak references to any other weakly-reachable objects
+ * from which that object is reachable through a chain of strong and soft
+ * references.  At the same time it will declare all of the formerly
+ * weakly-reachable objects to be finalizable.  At the same time or at some
+ * later time it will enqueue those newly-cleared weak references that are
+ * registered with reference queues.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+
+public class WeakReference<T> extends Reference<T> {
+
+    /**
+     * Creates a new weak reference that refers to the given object.  The new
+     * reference is not registered with any queue.
+     *
+     * @param referent object the new weak reference will refer to
+     */
+    public WeakReference(T referent) {
+        super(referent);
+    }
+
+    /**
+     * Creates a new weak reference that refers to the given object and is
+     * registered with the given queue.
+     *
+     * @param referent object the new weak reference will refer to
+     * @param q the queue with which the reference is to be registered,
+     *          or <tt>null</tt> if registration is not required
+     */
+    public WeakReference(T referent, ReferenceQueue<? super T> q) {
+        super(referent, q);
+    }
+
+}
diff --git a/java/lang/ref/package-info.java b/java/lang/ref/package-info.java
new file mode 100644
index 0000000..cc7f9ef
--- /dev/null
+++ b/java/lang/ref/package-info.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1998, 2003, 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.
+ */
+
+
+/**
+ * Provides reference-object classes, which support a limited degree of
+ * interaction with the garbage collector.  A program may use a reference object
+ * to maintain a reference to some other object in such a way that the latter
+ * object may still be reclaimed by the collector.  A program may also arrange to
+ * be notified some time after the collector has determined that the reachability
+ * of a given object has changed.
+ *
+ *
+ * <h2>Package Specification</h2>
+ *
+ * A <em>reference object</em> encapsulates a reference to some other object so
+ * that the reference itself may be examined and manipulated like any other
+ * object.  Three types of reference objects are provided, each weaker than the
+ * last: <em>soft</em>, <em>weak</em>, and <em>phantom</em>.  Each type
+ * corresponds to a different level of reachability, as defined below.  Soft
+ * references are for implementing memory-sensitive caches, weak references are
+ * for implementing canonicalizing mappings that do not prevent their keys (or
+ * values) from being reclaimed, and phantom references are for scheduling
+ * pre-mortem cleanup actions in a more flexible way than is possible with the
+ * Java finalization mechanism.
+ *
+ * <p> Each reference-object type is implemented by a subclass of the abstract
+ * base <code>{@link java.lang.ref.Reference}</code> class.  An instance of one of
+ * these subclasses encapsulates a single reference to a particular object, called
+ * the <em>referent</em>.  Every reference object provides methods for getting and
+ * clearing the reference.  Aside from the clearing operation reference objects
+ * are otherwise immutable, so no <code>set</code> operation is provided.  A
+ * program may further subclass these subclasses, adding whatever fields and
+ * methods are required for its purposes, or it may use these subclasses without
+ * change.
+ *
+ *
+ * <h3>Notification</h3>
+ *
+ * A program may request to be notified of changes in an object's reachability by
+ * <em>registering</em> an appropriate reference object with a <em>reference
+ * queue</em> at the time the reference object is created.  Some time after the
+ * garbage collector determines that the reachability of the referent has changed
+ * to the value corresponding to the type of the reference, it will add the
+ * reference to the associated queue.  At this point, the reference is considered
+ * to be <em>enqueued</em>.  The program may remove references from a queue either
+ * by polling or by blocking until a reference becomes available.  Reference
+ * queues are implemented by the <code>{@link java.lang.ref.ReferenceQueue}</code>
+ * class.
+ *
+ * <p> The relationship between a registered reference object and its queue is
+ * one-sided.  That is, a queue does not keep track of the references that are
+ * registered with it.  If a registered reference becomes unreachable itself, then
+ * it will never be enqueued.  It is the responsibility of the program using
+ * reference objects to ensure that the objects remain reachable for as long as
+ * the program is interested in their referents.
+ *
+ * <p> While some programs will choose to dedicate a thread to removing reference
+ * objects from one or more queues and processing them, this is by no means
+ * necessary.  A tactic that often works well is to examine a reference queue in
+ * the course of performing some other fairly-frequent action.  For example, a
+ * hashtable that uses weak references to implement weak keys could poll its
+ * reference queue each time the table is accessed.  This is how the <code>{@link
+ * java.util.WeakHashMap}</code> class works.  Because the <code>{@link
+ * java.lang.ref.ReferenceQueue#poll ReferenceQueue.poll}</code> method simply
+ * checks an internal data structure, this check will add little overhead to the
+ * hashtable access methods.
+ *
+ *
+ * <h3>Automatically-cleared references</h3>
+ *
+ * Soft and weak references are automatically cleared by the collector before
+ * being added to the queues with which they are registered, if any.  Therefore
+ * soft and weak references need not be registered with a queue in order to be
+ * useful, while phantom references do.  An object that is reachable via phantom
+ * references will remain so until all such references are cleared or themselves
+ * become unreachable.
+ *
+ *
+ * <a name="reachability"></a>
+ * <h3>Reachability</h3>
+ *
+ * Going from strongest to weakest, the different levels of reachability reflect
+ * the life cycle of an object.  They are operationally defined as follows:
+ *
+ * <ul>
+ *
+ * <li> An object is <em>strongly reachable</em> if it can be reached by some
+ * thread without traversing any reference objects.  A newly-created object is
+ * strongly reachable by the thread that created it.
+ *
+ * <li> An object is <em>softly reachable</em> if it is not strongly reachable but
+ * can be reached by traversing a soft reference.
+ *
+ * <li> An object is <em>weakly reachable</em> if it is neither strongly nor
+ * softly reachable but can be reached by traversing a weak reference.  When the
+ * weak references to a weakly-reachable object are cleared, the object becomes
+ * eligible for finalization.
+ *
+ * <li> An object is <em>phantom reachable</em> if it is neither strongly, softly,
+ * nor weakly reachable, it has been finalized, and some phantom reference refers
+ * to it.
+ *
+ * <li> Finally, an object is <em>unreachable</em>, and therefore eligible for
+ * reclamation, when it is not reachable in any of the above ways.
+ *
+ * </ul>
+ *
+ *
+ * @author	  Mark Reinhold
+ * @since	  1.2
+ */
+package java.lang.ref;
diff --git a/java/lang/reflect/AccessibleObject.annotated.java b/java/lang/reflect/AccessibleObject.annotated.java
new file mode 100644
index 0000000..f601635
--- /dev/null
+++ b/java/lang/reflect/AccessibleObject.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2014, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
+
+protected AccessibleObject() { throw new RuntimeException("Stub!"); }
+
+public static void setAccessible(java.lang.reflect.AccessibleObject[] array, boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public void setAccessible(boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/AccessibleObject.java b/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 0000000..18442fa
--- /dev/null
+++ b/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2014, 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.reflect;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The AccessibleObject class is the base class for Field, Method and
+ * Constructor objects.  It provides the ability to flag a reflected
+ * object as suppressing default Java language access control checks
+ * when it is used.  The access checks--for public, default (package)
+ * access, protected, and private members--are performed when Fields,
+ * Methods or Constructors are used to set or get fields, to invoke
+ * methods, or to create and initialize new instances of classes,
+ * respectively.
+ *
+ * <p>Setting the {@code accessible} flag in a reflected object
+ * permits sophisticated applications with sufficient privilege, such
+ * as Java Object Serialization or other persistence mechanisms, to
+ * manipulate objects in a manner that would normally be prohibited.
+ *
+ * <p>By default, a reflected object is <em>not</em> accessible.
+ *
+ * @see Field
+ * @see Method
+ * @see Constructor
+ * @see ReflectPermission
+ *
+ * @since 1.2
+ */
+public class AccessibleObject implements AnnotatedElement {
+
+    // Android-removed: Code associated with SecurityManager calls.
+    /*
+    /**
+     * The Permission object that is used to check whether a client
+     * has sufficient privilege to defeat Java language access
+     * control checks.
+     *
+    static final private java.security.Permission ACCESS_PERMISSION =
+        new ReflectPermission("suppressAccessChecks");
+    */
+
+    /**
+     * Convenience method to set the {@code accessible} flag for an
+     * array of objects with a single security check (for efficiency).
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkPermission} method is called with a
+     * {@code ReflectPermission("suppressAccessChecks")} permission.
+     *
+     * <p>A {@code SecurityException} is raised if {@code flag} is
+     * {@code true} but accessibility of any of the elements of the input
+     * {@code array} may not be changed (for example, if the element
+     * object is a {@link Constructor} object for the class {@link
+     * java.lang.Class}).  In the event of such a SecurityException, the
+     * accessibility of objects is set to {@code flag} for array elements
+     * upto (and excluding) the element for which the exception occurred; the
+     * accessibility of elements beyond (and including) the element for which
+     * the exception occurred is unchanged.
+     *
+     * @param array the array of AccessibleObjects
+     * @param flag  the new value for the {@code accessible} flag
+     *              in each object
+     * @throws SecurityException if the request is denied.
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     */
+    public static void setAccessible(AccessibleObject[] array, boolean flag)
+        throws SecurityException {
+        // Android-removed: SecurityManager calls.
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
+        for (int i = 0; i < array.length; i++) {
+            setAccessible0(array[i], flag);
+        }
+    }
+
+    /**
+     * Set the {@code accessible} flag for this object to
+     * the indicated boolean value.  A value of {@code true} indicates that
+     * the reflected object should suppress Java language access
+     * checking when it is used.  A value of {@code false} indicates
+     * that the reflected object should enforce Java language access checks.
+     *
+     * <p>First, if there is a security manager, its
+     * {@code checkPermission} method is called with a
+     * {@code ReflectPermission("suppressAccessChecks")} permission.
+     *
+     * <p>A {@code SecurityException} is raised if {@code flag} is
+     * {@code true} but accessibility of this object may not be changed
+     * (for example, if this element object is a {@link Constructor} object for
+     * the class {@link java.lang.Class}).
+     *
+     * <p>A {@code SecurityException} is raised if this object is a {@link
+     * java.lang.reflect.Constructor} object for the class
+     * {@code java.lang.Class}, and {@code flag} is true.
+     *
+     * @param flag the new value for the {@code accessible} flag
+     * @throws SecurityException if the request is denied.
+     * @see SecurityManager#checkPermission
+     * @see java.lang.RuntimePermission
+     */
+    public void setAccessible(boolean flag) throws SecurityException {
+        // Android-removed: SecurityManager calls.
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
+        setAccessible0(this, flag);
+    }
+
+    /* Check that you aren't exposing java.lang.Class.<init> or sensitive
+       fields in java.lang.Class. */
+    private static void setAccessible0(AccessibleObject obj, boolean flag)
+        throws SecurityException
+    {
+        if (obj instanceof Constructor && flag == true) {
+            Constructor<?> c = (Constructor<?>)obj;
+            // BEGIN Android-changed: Disallow making Method & Field constructors accessible.
+            // if (c.getDeclaringClass() == Class.class) {
+            //     throw new SecurityException("Cannot make a java.lang.Class" +
+            //                                 " constructor accessible");
+            // }
+
+            Class<?> clazz = c.getDeclaringClass();
+            if (c.getDeclaringClass() == Class.class) {
+                throw new SecurityException("Can not make a java.lang.Class" +
+                                            " constructor accessible");
+            } else if (clazz == Method.class) {
+                throw new SecurityException("Can not make a java.lang.reflect.Method" +
+                                            " constructor accessible");
+            } else if (clazz == Field.class) {
+                throw new SecurityException("Can not make a java.lang.reflect.Field" +
+                                            " constructor accessible");
+            }
+            // END Android-changed: Disallow making Method & Field constructors accessible.
+        }
+        obj.override = flag;
+    }
+
+    /**
+     * Get the value of the {@code accessible} flag for this object.
+     *
+     * @return the value of the object's {@code accessible} flag
+     */
+    public boolean isAccessible() {
+        return override;
+    }
+
+    /**
+     * Constructor: only used by the Java Virtual Machine.
+     */
+    protected AccessibleObject() {}
+
+    // Indicates whether language-level access checks are overridden
+    // by this object. Initializes to "false". This field is used by
+    // Field, Method, and Constructor.
+    //
+    // NOTE: for security purposes, this field must not be visible
+    // outside this package.
+    boolean override;
+
+    // Android-removed: reflectionFactory: it is not used on Android.
+    /*
+    // Reflection factory used by subclasses for creating field,
+    // method, and constructor accessors. Note that this is called
+    // very early in the bootstrapping process.
+    static final ReflectionFactory reflectionFactory =
+        AccessController.doPrivileged(
+            new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
+    */
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        throw new AssertionError("All subclasses should override this method");
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+    }
+
+   /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+        throw new AssertionError("All subclasses should override this method");
+    }
+
+    /**
+     * @since 1.5
+     */
+    public Annotation[] getAnnotations() {
+        return getDeclaredAnnotations();
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+        // Only annotations on classes are inherited, for all other
+        // objects getDeclaredAnnotation is the same as
+        // getAnnotation.
+        return getAnnotation(annotationClass);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+        // Only annotations on classes are inherited, for all other
+        // objects getDeclaredAnnotationsByType is the same as
+        // getAnnotationsByType.
+        return getAnnotationsByType(annotationClass);
+    }
+
+    /**
+     * @since 1.5
+     */
+    public Annotation[] getDeclaredAnnotations()  {
+        throw new AssertionError("All subclasses should override this method");
+    }
+
+    // BEGIN Android-removed: Shared access checking logic: Not used on Android.
+    /*
+    // For non-public members or members in package-private classes,
+    // it is necessary to perform somewhat expensive security checks.
+    // If the security check succeeds for a given class, it will
+    // always succeed (it is not affected by the granting or revoking
+    // of permissions); we speed up the check in the common case by
+    // remembering the last Class for which the check succeeded.
+    //
+    // The simple security check for Constructor is to see if
+    // the caller has already been seen, verified, and cached.
+    // (See also Class.newInstance(), which uses a similar method.)
+    //
+    // A more complicated security check cache is needed for Method and Field
+    // The cache can be either null (empty cache), a 2-array of {caller,target},
+    // or a caller (with target implicitly equal to this.clazz).
+    // In the 2-array case, the target is always different from the clazz.
+    volatile Object securityCheckCache;
+
+    void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+        throws IllegalAccessException
+    {
+        if (caller == clazz) {  // quick check
+            return;             // ACCESS IS OK
+        }
+        Object cache = securityCheckCache;  // read volatile
+        Class<?> targetClass = clazz;
+        if (obj != null
+            && Modifier.isProtected(modifiers)
+            && ((targetClass = obj.getClass()) != clazz)) {
+            // Must match a 2-list of { caller, targetClass }.
+            if (cache instanceof Class[]) {
+                Class<?>[] cache2 = (Class<?>[]) cache;
+                if (cache2[1] == targetClass &&
+                    cache2[0] == caller) {
+                    return;     // ACCESS IS OK
+                }
+                // (Test cache[1] first since range check for [1]
+                // subsumes range check for [0].)
+            }
+        } else if (cache == caller) {
+            // Non-protected case (or obj.class == this.clazz).
+            return;             // ACCESS IS OK
+        }
+
+        // If no return, fall through to the slow path.
+        slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+    }
+
+    // Keep all this slow stuff out of line:
+    void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
+                               Class<?> targetClass)
+        throws IllegalAccessException
+    {
+        Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+
+        // Success: Update the cache.
+        Object cache = ((targetClass == clazz)
+                        ? caller
+                        : new Class<?>[] { caller, targetClass });
+
+        // Note:  The two cache elements are not volatile,
+        // but they are effectively final.  The Java memory model
+        // guarantees that the initializing stores for the cache
+        // elements will occur before the volatile write.
+        securityCheckCache = cache;         // write volatile
+    }
+    */
+    // END Android-removed: Shared access checking logic: Not used on Android.
+}
diff --git a/java/lang/reflect/AnnotatedElement.annotated.java b/java/lang/reflect/AnnotatedElement.annotated.java
new file mode 100644
index 0000000..97cb3a2
--- /dev/null
+++ b/java/lang/reflect/AnnotatedElement.annotated.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (c) 2003, 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.reflect;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface AnnotatedElement {
+
+public default boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass);
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations();
+
+public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/AnnotatedElement.java b/java/lang/reflect/AnnotatedElement.java
new file mode 100644
index 0000000..7bb2a60
--- /dev/null
+++ b/java/lang/reflect/AnnotatedElement.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (c) 2003, 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.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+
+// Android-changed: Removed some references to bytecode spec below that do not
+// apply to DEX and added a note about annotation ordering.
+/**
+ * Represents an annotated element of the program currently running in this
+ * VM.  This interface allows annotations to be read reflectively.  All
+ * annotations returned by methods in this interface are immutable and
+ * serializable. The arrays returned by methods of this interface may be modified
+ * by callers without affecting the arrays returned to other callers.
+ *
+ * <p>Android note: methods that return multiple annotations of different types such as
+ * {@link #getAnnotations()} and {@link #getDeclaredAnnotations()} can be affected
+ * by the explicit character-code ordering of annotations types specified by the DEX format.
+ * Annotations of different types on a single element are not guaranteed to be returned in the order
+ * they are declared in source.
+ *
+ * <p>The {@link #getAnnotationsByType(Class)} and {@link
+ * #getDeclaredAnnotationsByType(Class)} methods support multiple
+ * annotations of the same type on an element. If the argument to
+ * either method is a repeatable annotation type (JLS 9.6), then the
+ * method will "look through" a container annotation (JLS 9.7), if
+ * present, and return any annotations inside the container. Container
+ * annotations may be generated at compile-time to wrap multiple
+ * annotations of the argument type.
+ *
+ * <p>The terms <em>directly present</em>, <em>indirectly present</em>,
+ * <em>present</em>, and <em>associated</em> are used throughout this
+ * interface to describe precisely which annotations are returned by
+ * methods:
+ *
+ * <ul>
+ *
+ * <li> An annotation <i>A</i> is <em>directly present</em> on an
+ * element <i>E</i> if <i>E</i> is annotated by <i>A</i> in the original source.
+ *
+ * <li>An annotation <i>A</i> is <em>indirectly present</em> on an
+ * element <i>E</i> if <i>E</i> is annotated by a container annotation
+ * of <i>A</i>.
+ *
+ * <li>An annotation <i>A</i> is present on an element <i>E</i> if either:
+ *
+ * <ul>
+ *
+ * <li><i>A</i> is directly present on <i>E</i>; or
+ *
+ * <li>No annotation of <i>A</i> 's type is directly present on
+ * <i>E</i>, and <i>E</i> is a class, and <i>A</i> 's type is
+ * inheritable, and <i>A</i> is present on the superclass of <i>E</i>.
+ *
+ * </ul>
+ *
+ * <li>An annotation <i>A</i> is <em>associated</em> with an element <i>E</i>
+ * if either:
+ *
+ * <ul>
+ *
+ * <li><i>A</i> is directly or indirectly present on <i>E</i>; or
+ *
+ * <li>No annotation of <i>A</i> 's type is directly or indirectly
+ * present on <i>E</i>, and <i>E</i> is a class, and <i>A</i>'s type
+ * is inheritable, and <i>A</i> is associated with the superclass of
+ * <i>E</i>.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>The table below summarizes which kind of annotation presence
+ * different methods in this interface examine.
+ *
+ * <table border>
+ * <caption>Overview of kind of presence detected by different AnnotatedElement methods</caption>
+ * <tr><th colspan=2></th><th colspan=4>Kind of Presence</th>
+ * <tr><th colspan=2>Method</th><th>Directly Present</th><th>Indirectly Present</th><th>Present</th><th>Associated</th>
+ * <tr><td align=right>{@code T}</td><td>{@link #getAnnotation(Class) getAnnotation(Class&lt;T&gt;)}
+ * <td></td><td></td><td>X</td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getAnnotations getAnnotations()}
+ * <td></td><td></td><td>X</td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code T[]}</td><td>{@link #getAnnotationsByType(Class) getAnnotationsByType(Class&lt;T&gt;)}
+ * <td></td><td></td><td></td><td>X</td>
+ * </tr>
+ * <tr><td align=right>{@code T}</td><td>{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class&lt;T&gt;)}
+ * <td>X</td><td></td><td></td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getDeclaredAnnotations getDeclaredAnnotations()}
+ * <td>X</td><td></td><td></td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code T[]}</td><td>{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class&lt;T&gt;)}
+ * <td>X</td><td>X</td><td></td><td></td>
+ * </tr>
+ * </table>
+ *
+ * <p>For an invocation of {@code get[Declared]AnnotationsByType( Class <
+ * T >)}, the order of annotations which are directly or indirectly
+ * present on an element <i>E</i> is computed as if indirectly present
+ * annotations on <i>E</i> are directly present on <i>E</i> in place
+ * of their container annotation, in the order in which they appear in
+ * the value element of the container annotation.
+ *
+ * <p>There are several compatibility concerns to keep in mind if an
+ * annotation type <i>T</i> is originally <em>not</em> repeatable and
+ * later modified to be repeatable.
+ *
+ * The containing annotation type for <i>T</i> is <i>TC</i>.
+ *
+ * <ul>
+ *
+ * <li>Modifying <i>T</i> to be repeatable is source and binary
+ * compatible with existing uses of <i>T</i> and with existing uses
+ * of <i>TC</i>.
+ *
+ * That is, for source compatibility, source code with annotations of
+ * type <i>T</i> or of type <i>TC</i> will still compile. For binary
+ * compatibility, class files with annotations of type <i>T</i> or of
+ * type <i>TC</i> (or with other kinds of uses of type <i>T</i> or of
+ * type <i>TC</i>) will link against the modified version of <i>T</i>
+ * if they linked against the earlier version.
+ *
+ * (An annotation type <i>TC</i> may informally serve as an acting
+ * containing annotation type before <i>T</i> is modified to be
+ * formally repeatable. Alternatively, when <i>T</i> is made
+ * repeatable, <i>TC</i> can be introduced as a new type.)
+ *
+ * <li>If an annotation type <i>TC</i> is present on an element, and
+ * <i>T</i> is modified to be repeatable with <i>TC</i> as its
+ * containing annotation type then:
+ *
+ * <ul>
+ *
+ * <li>The change to <i>T</i> is behaviorally compatible with respect
+ * to the {@code get[Declared]Annotation(Class<T>)} (called with an
+ * argument of <i>T</i> or <i>TC</i>) and {@code
+ * get[Declared]Annotations()} methods because the results of the
+ * methods will not change due to <i>TC</i> becoming the containing
+ * annotation type for <i>T</i>.
+ *
+ * <li>The change to <i>T</i> changes the results of the {@code
+ * get[Declared]AnnotationsByType(Class<T>)} methods called with an
+ * argument of <i>T</i>, because those methods will now recognize an
+ * annotation of type <i>TC</i> as a container annotation for <i>T</i>
+ * and will "look through" it to expose annotations of type <i>T</i>.
+ *
+ * </ul>
+ *
+ * <li>If an annotation of type <i>T</i> is present on an
+ * element and <i>T</i> is made repeatable and more annotations of
+ * type <i>T</i> are added to the element:
+ *
+ * <ul>
+ *
+ * <li> The addition of the annotations of type <i>T</i> is both
+ * source compatible and binary compatible.
+ *
+ * <li>The addition of the annotations of type <i>T</i> changes the results
+ * of the {@code get[Declared]Annotation(Class<T>)} methods and {@code
+ * get[Declared]Annotations()} methods, because those methods will now
+ * only see a container annotation on the element and not see an
+ * annotation of type <i>T</i>.
+ *
+ * <li>The addition of the annotations of type <i>T</i> changes the
+ * results of the {@code get[Declared]AnnotationsByType(Class<T>)}
+ * methods, because their results will expose the additional
+ * annotations of type <i>T</i> whereas previously they exposed only a
+ * single annotation of type <i>T</i>.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>If an annotation returned by a method in this interface contains
+ * (directly or indirectly) a {@link Class}-valued member referring to
+ * a class that is not accessible in this VM, attempting to read the class
+ * by calling the relevant Class-returning method on the returned annotation
+ * will result in a {@link TypeNotPresentException}.
+ *
+ * <p>Similarly, attempting to read an enum-valued member will result in
+ * a {@link EnumConstantNotPresentException} if the enum constant in the
+ * annotation is no longer present in the enum type.
+ *
+ * <p>If an annotation type <i>T</i> is (meta-)annotated with an
+ * {@code @Repeatable} annotation whose value element indicates a type
+ * <i>TC</i>, but <i>TC</i> does not declare a {@code value()} method
+ * with a return type of <i>T</i>{@code []}, then an exception of type
+ * {@link java.lang.annotation.AnnotationFormatError} is thrown.
+ *
+ * <p>Finally, attempting to read a member whose definition has evolved
+ * incompatibly will result in a {@link
+ * java.lang.annotation.AnnotationTypeMismatchException} or an
+ * {@link java.lang.annotation.IncompleteAnnotationException}.
+ *
+ * @see java.lang.EnumConstantNotPresentException
+ * @see java.lang.TypeNotPresentException
+ * @see AnnotationFormatError
+ * @see java.lang.annotation.AnnotationTypeMismatchException
+ * @see java.lang.annotation.IncompleteAnnotationException
+ * @since 1.5
+ * @author Josh Bloch
+ */
+public interface AnnotatedElement {
+    /**
+     * Returns true if an annotation for the specified type
+     * is <em>present</em> on this element, else false.  This method
+     * is designed primarily for convenient access to marker annotations.
+     *
+     * <p>The truth value returned by this method is equivalent to:
+     * {@code getAnnotation(annotationClass) != null}
+     *
+     * <p>The body of the default method is specified to be the code
+     * above.
+     *
+     * @param annotationClass the Class object corresponding to the
+     *        annotation type
+     * @return true if an annotation for the specified annotation
+     *     type is present on this element, else false
+     * @throws NullPointerException if the given annotation class is null
+     * @since 1.5
+     */
+    default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return getAnnotation(annotationClass) != null;
+    }
+
+   /**
+     * Returns this element's annotation for the specified type if
+     * such an annotation is <em>present</em>, else null.
+     *
+     * @param <T> the type of the annotation to query for and return if present
+     * @param annotationClass the Class object corresponding to the
+     *        annotation type
+     * @return this element's annotation for the specified annotation type if
+     *     present on this element, else null
+     * @throws NullPointerException if the given annotation class is null
+     * @since 1.5
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns annotations that are <em>present</em> on this element.
+     *
+     * If there are no annotations <em>present</em> on this element, the return
+     * value is an array of length 0.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @return annotations present on this element
+     * @since 1.5
+     */
+    Annotation[] getAnnotations();
+
+    /**
+     * Returns annotations that are <em>associated</em> with this element.
+     *
+     * If there are no annotations <em>associated</em> with this element, the return
+     * value is an array of length 0.
+     *
+     * The difference between this method and {@link #getAnnotation(Class)}
+     * is that this method detects if its argument is a <em>repeatable
+     * annotation type</em> (JLS 9.6), and if so, attempts to find one or
+     * more annotations of that type by "looking through" a container
+     * annotation.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @implSpec The default implementation first calls {@link
+     * #getDeclaredAnnotationsByType(Class)} passing {@code
+     * annotationClass} as the argument. If the returned array has
+     * length greater than zero, the array is returned. If the returned
+     * array is zero-length and this {@code AnnotatedElement} is a
+     * class and the argument type is an inheritable annotation type,
+     * and the superclass of this {@code AnnotatedElement} is non-null,
+     * then the returned result is the result of calling {@link
+     * #getAnnotationsByType(Class)} on the superclass with {@code
+     * annotationClass} as the argument. Otherwise, a zero-length
+     * array is returned.
+     *
+     * @param <T> the type of the annotation to query for and return if present
+     * @param annotationClass the Class object corresponding to the
+     *        annotation type
+     * @return all this element's annotations for the specified annotation type if
+     *     associated with this element, else an array of length zero
+     * @throws NullPointerException if the given annotation class is null
+     * @since 1.8
+     */
+    default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+        // Android-changed: Altered method implementation for getAnnotationsByType(Class).
+        // Android's annotation code is customized because of the use of the DEX format on Android
+        // and code sharing with the runtime.
+        // This method does not handle inherited annotations and is intended for use for
+        // {@code Method}, {@code Field}, {@code Package}. The {@link Class#getAnnotationsByType}
+        // is implemented explicitly. Therefore this implementation does not fulfill the documented
+        // default implementation for {@link AnnotatedElement#getAnnotationsByType(Class)} but in an
+        // undetectable way because Class is final.
+        return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+    }
+
+    /**
+     * Returns this element's annotation for the specified type if
+     * such an annotation is <em>directly present</em>, else null.
+     *
+     * This method ignores inherited annotations. (Returns null if no
+     * annotations are directly present on this element.)
+     *
+     * @implSpec The default implementation first performs a null check
+     * and then loops over the results of {@link
+     * #getDeclaredAnnotations} returning the first annotation whose
+     * annotation type matches the argument type.
+     *
+     * @param <T> the type of the annotation to query for and return if directly present
+     * @param annotationClass the Class object corresponding to the
+     *        annotation type
+     * @return this element's annotation for the specified annotation type if
+     *     directly present on this element, else null
+     * @throws NullPointerException if the given annotation class is null
+     * @since 1.8
+     */
+    default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+        Objects.requireNonNull(annotationClass);
+        // Loop over all directly-present annotations looking for a matching one
+        for (Annotation annotation : getDeclaredAnnotations()) {
+            if (annotationClass.equals(annotation.annotationType())) {
+                // More robust to do a dynamic cast at runtime instead
+                // of compile-time only.
+                return annotationClass.cast(annotation);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns this element's annotation(s) for the specified type if
+     * such annotations are either <em>directly present</em> or
+     * <em>indirectly present</em>. This method ignores inherited
+     * annotations.
+     *
+     * If there are no specified annotations directly or indirectly
+     * present on this element, the return value is an array of length
+     * 0.
+     *
+     * The difference between this method and {@link
+     * #getDeclaredAnnotation(Class)} is that this method detects if its
+     * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so,
+     * attempts to find one or more annotations of that type by "looking
+     * through" a container annotation if one is present.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @implSpec The default implementation may call {@link
+     * #getDeclaredAnnotation(Class)} one or more times to find a
+     * directly present annotation and, if the annotation type is
+     * repeatable, to find a container annotation. If annotations of
+     * the annotation type {@code annotationClass} are found to be both
+     * directly and indirectly present, then {@link
+     * #getDeclaredAnnotations()} will get called to determine the
+     * order of the elements in the returned array.
+     *
+     * <p>Alternatively, the default implementation may call {@link
+     * #getDeclaredAnnotations()} a single time and the returned array
+     * examined for both directly and indirectly present
+     * annotations. The results of calling {@link
+     * #getDeclaredAnnotations()} are assumed to be consistent with the
+     * results of calling {@link #getDeclaredAnnotation(Class)}.
+     *
+     * @param <T> the type of the annotation to query for and return
+     * if directly or indirectly present
+     * @param annotationClass the Class object corresponding to the
+     *        annotation type
+     * @return all this element's annotations for the specified annotation type if
+     *     directly or indirectly present on this element, else an array of length zero
+     * @throws NullPointerException if the given annotation class is null
+     * @since 1.8
+     */
+    default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+        // Android-changed: Altered method implementation for getAnnotationsByType(Class).
+        // Android's annotation code is customized because of the use of the DEX format on Android
+        // and code sharing with the runtime.
+        return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+    }
+
+    /**
+     * Returns annotations that are <em>directly present</em> on this element.
+     * This method ignores inherited annotations.
+     *
+     * If there are no annotations <em>directly present</em> on this element,
+     * the return value is an array of length 0.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @return annotations directly present on this element
+     * @since 1.5
+     */
+    Annotation[] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/Array.annotated.java b/java/lang/reflect/Array.annotated.java
new file mode 100644
index 0000000..f0fba5c
--- /dev/null
+++ b/java/lang/reflect/Array.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Array {
+
+Array() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newInstance(@libcore.util.NonNull java.lang.Class<?> componentType, int length) throws java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newInstance(@libcore.util.NonNull java.lang.Class<?> componentType, int... dimensions) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+public static int getLength(@libcore.util.NonNull java.lang.Object array) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object get(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static byte getByte(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static char getChar(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static short getShort(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static int getInt(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static long getLong(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static float getFloat(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static double getDouble(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void set(@libcore.util.NonNull java.lang.Object array, int index, @libcore.util.Nullable java.lang.Object value) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setBoolean(@libcore.util.NonNull java.lang.Object array, int index, boolean z) { throw new RuntimeException("Stub!"); }
+
+public static void setByte(@libcore.util.NonNull java.lang.Object array, int index, byte b) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setChar(@libcore.util.NonNull java.lang.Object array, int index, char c) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setShort(@libcore.util.NonNull java.lang.Object array, int index, short s) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setInt(@libcore.util.NonNull java.lang.Object array, int index, int i) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setLong(@libcore.util.NonNull java.lang.Object array, int index, long l) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setFloat(@libcore.util.NonNull java.lang.Object array, int index, float f) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setDouble(@libcore.util.NonNull java.lang.Object array, int index, double d) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Array.java b/java/lang/reflect/Array.java
new file mode 100644
index 0000000..95a8091
--- /dev/null
+++ b/java/lang/reflect/Array.java
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * The {@code Array} class provides static methods to dynamically create and
+ * access Java arrays.
+ *
+ * <p>{@code Array} permits widening conversions to occur during a get or set
+ * operation, but throws an {@code IllegalArgumentException} if a narrowing
+ * conversion would occur.
+ *
+ * @author Nakul Saraiya
+ */
+public final
+class Array {
+
+    /**
+     * Constructor.  Class Array is not instantiable.
+     */
+    private Array() {}
+
+    /**
+     * Creates a new array with the specified component type and
+     * length.
+     * Invoking this method is equivalent to creating an array
+     * as follows:
+     * <blockquote>
+     * <pre>
+     * int[] x = {length};
+     * Array.newInstance(componentType, x);
+     * </pre>
+     * </blockquote>
+     *
+     * <p>The number of dimensions of the new array must not
+     * exceed 255.
+     *
+     * @param componentType the {@code Class} object representing the
+     * component type of the new array
+     * @param length the length of the new array
+     * @return the new array
+     * @exception NullPointerException if the specified
+     * {@code componentType} parameter is null
+     * @exception IllegalArgumentException if componentType is {@link
+     * Void#TYPE} or if the number of dimensions of the requested array
+     * instance exceed 255.
+     * @exception NegativeArraySizeException if the specified {@code length}
+     * is negative
+     */
+    public static Object newInstance(Class<?> componentType, int length)
+        throws NegativeArraySizeException {
+        return newArray(componentType, length);
+    }
+
+    /**
+     * Creates a new array
+     * with the specified component type and dimensions.
+     * If {@code componentType}
+     * represents a non-array class or interface, the new array
+     * has {@code dimensions.length} dimensions and
+     * {@code componentType} as its component type. If
+     * {@code componentType} represents an array class, the
+     * number of dimensions of the new array is equal to the sum
+     * of {@code dimensions.length} and the number of
+     * dimensions of {@code componentType}. In this case, the
+     * component type of the new array is the component type of
+     * {@code componentType}.
+     *
+     * <p>The number of dimensions of the new array must not
+     * exceed 255.
+     *
+     * @param componentType the {@code Class} object representing the component
+     * type of the new array
+     * @param dimensions an array of {@code int} representing the dimensions of
+     * the new array
+     * @return the new array
+     * @exception NullPointerException if the specified
+     * {@code componentType} argument is null
+     * @exception IllegalArgumentException if the specified {@code dimensions}
+     * argument is a zero-dimensional array, if componentType is {@link
+     * Void#TYPE}, or if the number of dimensions of the requested array
+     * instance exceed 255.
+     * @exception NegativeArraySizeException if any of the components in
+     * the specified {@code dimensions} argument is negative.
+     */
+    public static Object newInstance(Class<?> componentType, int... dimensions)
+        throws IllegalArgumentException, NegativeArraySizeException {
+        // Android-changed: New implementation of newInstance(Class, int...)
+        if (dimensions.length <= 0 || dimensions.length > 255) {
+            throw new IllegalArgumentException("Bad number of dimensions: " + dimensions.length);
+        }
+        if (componentType == void.class) {
+            throw new IllegalArgumentException("Can't allocate an array of void");
+        }
+        if (componentType == null) {
+            throw new NullPointerException("componentType == null");
+        }
+        return createMultiArray(componentType, dimensions);
+    }
+
+    /**
+     * Returns the length of the specified array object, as an {@code int}.
+     *
+     * @param array the array
+     * @return the length of the array
+     * @exception IllegalArgumentException if the object argument is not
+     * an array
+     */
+    // Android-changed: Non-native implementation of getLength(Object)
+    // Android-changed: Removal of explicit throws IllegalArgumentException from method signature.
+    public static int getLength(Object array)
+        /* throws IllegalArgumentException */ {
+        if (array instanceof Object[]) {
+            return ((Object[]) array).length;
+        } else if (array instanceof boolean[]) {
+            return ((boolean[]) array).length;
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array).length;
+        } else if (array instanceof char[]) {
+            return ((char[]) array).length;
+        } else if (array instanceof double[]) {
+            return ((double[]) array).length;
+        } else if (array instanceof float[]) {
+            return ((float[]) array).length;
+        } else if (array instanceof int[]) {
+            return ((int[]) array).length;
+        } else if (array instanceof long[]) {
+            return ((long[]) array).length;
+        } else if (array instanceof short[]) {
+            return ((short[]) array).length;
+        }
+        throw badArray(array);
+      }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object.  The value is automatically wrapped in an object
+     * if it has a primitive type.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the (possibly wrapped) value of the indexed component in
+     * the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     */
+    // Android-changed: Non-native implementation of get(Object, int)
+    public static Object get(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof Object[]) {
+            return ((Object[]) array)[index];
+        }
+        if (array instanceof boolean[]) {
+            return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
+        }
+        if (array instanceof byte[]) {
+            return Byte.valueOf(((byte[]) array)[index]);
+        }
+        if (array instanceof char[]) {
+            return Character.valueOf(((char[]) array)[index]);
+        }
+        if (array instanceof short[]) {
+            return Short.valueOf(((short[]) array)[index]);
+        }
+        if (array instanceof int[]) {
+            return Integer.valueOf(((int[]) array)[index]);
+        }
+        if (array instanceof long[]) {
+            return Long.valueOf(((long[]) array)[index]);
+        }
+        if (array instanceof float[]) {
+            return new Float(((float[]) array)[index]);
+        }
+        if (array instanceof double[]) {
+            return new Double(((double[]) array)[index]);
+        }
+        if (array == null) {
+            throw new NullPointerException("array == null");
+        }
+        throw notAnArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code boolean}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getBoolean(Object, int)
+    public static boolean getBoolean(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof boolean[]) {
+            return ((boolean[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code byte}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getByte(Object, int)
+    public static byte getByte(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code char}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getChar(Object, int)
+    public static char getChar(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof char[]) {
+            return ((char[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code short}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getShort(Object, int)
+    public static short getShort(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof short[]) {
+            return ((short[]) array)[index];
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as an {@code int}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getInt(Object, int)
+    public static int getInt(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof int[]) {
+            return ((int[]) array)[index];
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        } else if (array instanceof char[]) {
+            return ((char[]) array)[index];
+        } else if (array instanceof short[]) {
+            return ((short[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code long}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getLong(Object, int)
+    public static long getLong(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof long[]) {
+            return ((long[]) array)[index];
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        } else if (array instanceof char[]) {
+            return ((char[]) array)[index];
+        } else if (array instanceof int[]) {
+            return ((int[]) array)[index];
+        } else if (array instanceof short[]) {
+            return ((short[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code float}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getFloat(Object, int)
+    public static float getFloat(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof float[]) {
+            return ((float[]) array)[index];
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        } else if (array instanceof char[]) {
+            return ((char[]) array)[index];
+        } else if (array instanceof int[]) {
+            return ((int[]) array)[index];
+        } else if (array instanceof long[]) {
+            return ((long[]) array)[index];
+        } else if (array instanceof short[]) {
+            return ((short[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Returns the value of the indexed component in the specified
+     * array object, as a {@code double}.
+     *
+     * @param array the array
+     * @param index the index
+     * @return the value of the indexed component in the specified array
+     * @exception NullPointerException If the specified object is null
+     * @exception IllegalArgumentException If the specified object is not
+     * an array, or if the indexed element cannot be converted to the
+     * return type by an identity or widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to the
+     * length of the specified array
+     * @see Array#get
+     */
+    // Android-changed: Non-native implementation of getDouble(Object, int)
+    public static double getDouble(Object array, int index)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof double[]) {
+            return ((double[]) array)[index];
+        } else if (array instanceof byte[]) {
+            return ((byte[]) array)[index];
+        } else if (array instanceof char[]) {
+            return ((char[]) array)[index];
+        } else if (array instanceof float[]) {
+            return ((float[]) array)[index];
+        } else if (array instanceof int[]) {
+            return ((int[]) array)[index];
+        } else if (array instanceof long[]) {
+            return ((long[]) array)[index];
+        } else if (array instanceof short[]) {
+            return ((short[]) array)[index];
+        }
+        throw badArray(array);
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified new value.  The new value is first
+     * automatically unwrapped if the array has a primitive component
+     * type.
+     * @param array the array
+     * @param index the index into the array
+     * @param value the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the array component type is primitive and
+     * an unwrapping conversion fails
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     */
+    // Android-changed: Non-native implementation of set(Object, int, Object)
+    public static void set(Object array, int index, Object value)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (!array.getClass().isArray()) {
+            throw notAnArray(array);
+        }
+
+        if (array instanceof Object[]) {
+            if (value != null && !array.getClass().getComponentType().isInstance(value)) {
+                throw incompatibleType(array);
+            }
+            ((Object[]) array)[index] = value;
+        } else {
+            if (value == null) {
+                throw new IllegalArgumentException("Primitive array can't take null values.");
+            }
+            if (value instanceof Boolean) {
+                setBoolean(array, index, ((Boolean) value).booleanValue());
+            } else if (value instanceof Byte) {
+                setByte(array, index, ((Byte) value).byteValue());
+            } else if (value instanceof Character) {
+                setChar(array, index, ((Character) value).charValue());
+            } else if (value instanceof Short) {
+                setShort(array, index, ((Short) value).shortValue());
+            } else if (value instanceof Integer) {
+                setInt(array, index, ((Integer) value).intValue());
+            } else if (value instanceof Long) {
+                setLong(array, index, ((Long) value).longValue());
+            } else if (value instanceof Float) {
+                setFloat(array, index, ((Float) value).floatValue());
+            } else if (value instanceof Double) {
+                setDouble(array, index, ((Double) value).doubleValue());
+            }
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code boolean} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param z the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setBoolean(Object, int, boolean)
+    // Android-changed: Removal of explicit runtime exceptions throws clause
+    public static void setBoolean(Object array, int index, boolean z)
+        /* throws IllegalArgumentException, ArrayIndexOutOfBoundsException */ {
+        if (array instanceof boolean[]) {
+            ((boolean[]) array)[index] = z;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code byte} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param b the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setByte(Object, int, byte)
+    public static void setByte(Object array, int index, byte b)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof byte[]) {
+            ((byte[]) array)[index] = b;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = b;
+        } else if (array instanceof float[]) {
+            ((float[]) array)[index] = b;
+        } else if (array instanceof int[]) {
+            ((int[]) array)[index] = b;
+        } else if (array instanceof long[]) {
+            ((long[]) array)[index] = b;
+        } else if (array instanceof short[]) {
+            ((short[]) array)[index] = b;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code char} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param c the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setChar(Object, int, char)
+    public static void setChar(Object array, int index, char c)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof char[]) {
+            ((char[]) array)[index] = c;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = c;
+        } else if (array instanceof float[]) {
+            ((float[]) array)[index] = c;
+        } else if (array instanceof int[]) {
+            ((int[]) array)[index] = c;
+        } else if (array instanceof long[]) {
+            ((long[]) array)[index] = c;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code short} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param s the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setShort(Object, int, short)
+    public static void setShort(Object array, int index, short s)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof short[]) {
+            ((short[]) array)[index] = s;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = s;
+        } else if (array instanceof float[]) {
+            ((float[]) array)[index] = s;
+        } else if (array instanceof int[]) {
+            ((int[]) array)[index] = s;
+        } else if (array instanceof long[]) {
+            ((long[]) array)[index] = s;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code int} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param i the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setInt(Object, int, int)
+    public static void setInt(Object array, int index, int i)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof int[]) {
+            ((int[]) array)[index] = i;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = i;
+        } else if (array instanceof float[]) {
+            ((float[]) array)[index] = i;
+        } else if (array instanceof long[]) {
+            ((long[]) array)[index] = i;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code long} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param l the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setBoolean(Object, int, long)
+    public static void setLong(Object array, int index, long l)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof long[]) {
+            ((long[]) array)[index] = l;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = l;
+        } else if (array instanceof float[]) {
+            ((float[]) array)[index] = l;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code float} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param f the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    public static void setFloat(Object array, int index, float f)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof float[]) {
+            ((float[]) array)[index] = f;
+        } else if (array instanceof double[]) {
+            ((double[]) array)[index] = f;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /**
+     * Sets the value of the indexed component of the specified array
+     * object to the specified {@code double} value.
+     * @param array the array
+     * @param index the index into the array
+     * @param d the new value of the indexed component
+     * @exception NullPointerException If the specified object argument
+     * is null
+     * @exception IllegalArgumentException If the specified object argument
+     * is not an array, or if the specified value cannot be converted
+     * to the underlying array's component type by an identity or a
+     * primitive widening conversion
+     * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+     * argument is negative, or if it is greater than or equal to
+     * the length of the specified array
+     * @see Array#set
+     */
+    // Android-changed: Non-native implementation of setDouble(Object, int, double)
+    public static void setDouble(Object array, int index, double d)
+        throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+        if (array instanceof double[]) {
+            ((double[]) array)[index] = d;
+        } else {
+            throw badArray(array);
+        }
+    }
+
+    /*
+     * Private
+     */
+
+    // Android-added: Added javadocs for newArray(Class, int)
+    /**
+     * Returns a new array of the specified component type and length.
+     * Equivalent to {@code new componentType[size]}.
+     *
+     * @throws NullPointerException
+     *             if the component type is null
+     * @throws NegativeArraySizeException
+     *             if {@code size < 0}
+     */
+    // Android-changed: Non-native implementation of newArray(Class, int)
+    private static Object newArray(Class<?> componentType, int length)
+        throws NegativeArraySizeException {
+        if (!componentType.isPrimitive()) {
+            return createObjectArray(componentType, length);
+        } else if (componentType == char.class) {
+            return new char[length];
+        } else if (componentType == int.class) {
+            return new int[length];
+        } else if (componentType == byte.class) {
+            return new byte[length];
+        } else if (componentType == boolean.class) {
+            return new boolean[length];
+        } else if (componentType == short.class) {
+            return new short[length];
+        } else if (componentType == long.class) {
+            return new long[length];
+        } else if (componentType == float.class) {
+            return new float[length];
+        } else if (componentType == double.class) {
+            return new double[length];
+        } else if (componentType == void.class) {
+            throw new IllegalArgumentException("Can't allocate an array of void");
+        }
+        throw new AssertionError();
+    }
+
+    // Android-removed: multiNewArray(Class, int[]) method. createMultiArray used instead.
+    /*
+    private static native Object multiNewArray(Class<?> componentType,
+        int[] dimensions)
+        throws IllegalArgumentException, NegativeArraySizeException;
+    */
+
+    // Android-added: createMultiArray(Class, int[]) method. Used instead of multiNewArray
+    /*
+     * Create a multi-dimensional array of objects with the specified type.
+     */
+    @FastNative
+    private static native Object createMultiArray(Class<?> componentType, int[] dimensions)
+            throws NegativeArraySizeException;
+
+    // BEGIN Android-added: Helper methods to support custom method implementations.
+    /*
+     * Create a one-dimensional array of objects with the specified type.
+     */
+    @FastNative
+    private static native Object createObjectArray(Class<?> componentType, int length)
+            throws NegativeArraySizeException;
+
+    private static IllegalArgumentException notAnArray(Object o) {
+        throw new IllegalArgumentException("Not an array: " + o.getClass());
+    }
+
+    private static IllegalArgumentException incompatibleType(Object o) {
+        throw new IllegalArgumentException("Array has incompatible type: " + o.getClass());
+    }
+
+    private static RuntimeException badArray(Object array) {
+        if (array == null) {
+            throw new NullPointerException("array == null");
+        } else if (!array.getClass().isArray()) {
+            throw notAnArray(array);
+        } else {
+            throw incompatibleType(array);
+        }
+    }
+    // END Android-added: Helper methods to support custom method implementations.
+}
diff --git a/java/lang/reflect/Constructor.annotated.java b/java/lang/reflect/Constructor.annotated.java
new file mode 100644
index 0000000..58bd810
--- /dev/null
+++ b/java/lang/reflect/Constructor.annotated.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Constructor<T> extends java.lang.reflect.Executable {
+
+Constructor() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<T> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Class<?> @libcore.util.NonNull [] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getExceptionTypes();
+
+public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public T newInstance(java.lang.Object... initargs) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Constructor.java b/java/lang/reflect/Constructor.java
new file mode 100644
index 0000000..cf6b29f
--- /dev/null
+++ b/java/lang/reflect/Constructor.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import libcore.util.EmptyArray;
+
+import sun.reflect.CallerSensitive;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+
+/**
+ * {@code Constructor} provides information about, and access to, a single
+ * constructor for a class.
+ *
+ * <p>{@code Constructor} permits widening conversions to occur when matching the
+ * actual parameters to newInstance() with the underlying
+ * constructor's formal parameters, but throws an
+ * {@code IllegalArgumentException} if a narrowing conversion would occur.
+ *
+ * @param <T> the class in which the constructor is declared
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructors()
+ *
+ * @author      Kenneth Russell
+ * @author      Nakul Saraiya
+ */
+public final class Constructor<T> extends Executable {
+    // Android-changed: Extensive modifications made throughout the class for ART.
+    // Android-changed: Many fields and methods removed / modified.
+    // Android-removed: Type annotations runtime code. Not supported on Android.
+    // Android-removed: Declared vs actual parameter annotation indexes handling.
+
+    private static final Comparator<Method> ORDER_BY_SIGNATURE = null; // Unused; must match Method.
+
+    private final Class<?> serializationClass;
+    private final Class<?> serializationCtor;
+
+    private Constructor() {
+      this(null, null);
+    }
+
+    private Constructor(Class<?> serializationCtor,
+        Class<?> serializationClass) {
+        this.serializationCtor = serializationCtor;
+        this.serializationClass = serializationClass;
+    }
+
+    /**
+     * @hide
+     */
+    public Constructor<T> serializationCopy(Class<?> ctor, Class<?> cl) {
+        return new Constructor<T>(ctor, cl);
+    }
+
+    @Override
+    boolean hasGenericInformation() {
+        // Android-changed: hasGenericInformation() implemented using Executable.
+        return super.hasGenericInformationInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    // Android-changed: getDeclaringClass() implemented using Executable.
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public Class<T> getDeclaringClass() {
+        return (Class<T>) super.getDeclaringClassInternal();
+    }
+
+    /**
+     * Returns the name of this constructor, as a string.  This is
+     * the binary name of the constructor's declaring class.
+     */
+    @Override
+    public String getName() {
+        return getDeclaringClass().getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getModifiers() {
+        // Android-changed: getModifiers() implemented using Executable.
+        return super.getModifiersInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public TypeVariable<Constructor<T>>[] getTypeParameters() {
+        // Android-changed: getTypeParameters() partly implemented using Executable.
+        GenericInfo info = getMethodOrConstructorGenericInfoInternal();
+        return (TypeVariable<Constructor<T>>[]) info.formalTypeParameters.clone();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<?>[] getParameterTypes() {
+        // Android-changed: getParameterTypes() partly implemented using Executable.
+        Class<?>[] paramTypes = super.getParameterTypesInternal();
+        if (paramTypes == null) {
+            return EmptyArray.CLASS;
+        }
+
+        return paramTypes;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.8
+     */
+    public int getParameterCount() {
+        // Android-changed: getParameterCount() implemented using Executable.
+        return super.getParameterCountInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @throws TypeNotPresentException {@inheritDoc}
+     * @throws MalformedParameterizedTypeException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Type[] getGenericParameterTypes() {
+        return super.getGenericParameterTypes();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    // Android-changed: getExceptionTypes() implemented in native code.
+    @FastNative
+    public native Class<?>[] getExceptionTypes();
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @throws TypeNotPresentException {@inheritDoc}
+     * @throws MalformedParameterizedTypeException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Type[] getGenericExceptionTypes() {
+        return super.getGenericExceptionTypes();
+    }
+
+    /**
+     * Compares this {@code Constructor} against the specified object.
+     * Returns true if the objects are the same.  Two {@code Constructor} objects are
+     * the same if they were declared by the same class and have the
+     * same formal parameter types.
+     */
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof Constructor) {
+            Constructor<?> other = (Constructor<?>)obj;
+            if (getDeclaringClass() == other.getDeclaringClass()) {
+                // Android-changed: Use getParameterTypes() instead of deleted parameterTypes field
+                return equalParamTypes(getParameterTypes(), other.getParameterTypes());
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hashcode for this {@code Constructor}. The hashcode is
+     * the same as the hashcode for the underlying constructor's
+     * declaring class name.
+     */
+    public int hashCode() {
+        return getDeclaringClass().getName().hashCode();
+    }
+
+    /**
+     * Returns a string describing this {@code Constructor}.  The string is
+     * formatted as the constructor access modifiers, if any,
+     * followed by the fully-qualified name of the declaring class,
+     * followed by a parenthesized, comma-separated list of the
+     * constructor's formal parameter types.  For example:
+     * <pre>
+     *    public java.util.Hashtable(int,float)
+     * </pre>
+     *
+     * <p>The only possible modifiers for constructors are the access
+     * modifiers {@code public}, {@code protected} or
+     * {@code private}.  Only one of these may appear, or none if the
+     * constructor has default (package) access.
+     *
+     * @return a string describing this {@code Constructor}
+     * @jls 8.8.3. Constructor Modifiers
+     */
+    public String toString() {
+        // Android-changed: Use getParameterTypes() / getExceptionTypes() instead of deleted fields
+        return sharedToString(Modifier.constructorModifiers(),
+                              false,
+                              getParameterTypes(),
+                              getExceptionTypes());
+    }
+
+    @Override
+    void specificToStringHeader(StringBuilder sb) {
+        sb.append(getDeclaringClass().getTypeName());
+    }
+
+    /**
+     * Returns a string describing this {@code Constructor},
+     * including type parameters.  The string is formatted as the
+     * constructor access modifiers, if any, followed by an
+     * angle-bracketed comma separated list of the constructor's type
+     * parameters, if any, followed by the fully-qualified name of the
+     * declaring class, followed by a parenthesized, comma-separated
+     * list of the constructor's generic formal parameter types.
+     *
+     * If this constructor was declared to take a variable number of
+     * arguments, instead of denoting the last parameter as
+     * "<tt><i>Type</i>[]</tt>", it is denoted as
+     * "<tt><i>Type</i>...</tt>".
+     *
+     * A space is used to separate access modifiers from one another
+     * and from the type parameters or return type.  If there are no
+     * type parameters, the type parameter list is elided; if the type
+     * parameter list is present, a space separates the list from the
+     * class name.  If the constructor is declared to throw
+     * exceptions, the parameter list is followed by a space, followed
+     * by the word "{@code throws}" followed by a
+     * comma-separated list of the thrown exception types.
+     *
+     * <p>The only possible modifiers for constructors are the access
+     * modifiers {@code public}, {@code protected} or
+     * {@code private}.  Only one of these may appear, or none if the
+     * constructor has default (package) access.
+     *
+     * @return a string describing this {@code Constructor},
+     * include type parameters
+     *
+     * @since 1.5
+     * @jls 8.8.3. Constructor Modifiers
+     */
+    @Override
+    public String toGenericString() {
+        return sharedToGenericString(Modifier.constructorModifiers(), false);
+    }
+
+    @Override
+    void specificToGenericStringHeader(StringBuilder sb) {
+        specificToStringHeader(sb);
+    }
+
+    /**
+     * Uses the constructor represented by this {@code Constructor} object to
+     * create and initialize a new instance of the constructor's
+     * declaring class, with the specified initialization parameters.
+     * Individual parameters are automatically unwrapped to match
+     * primitive formal parameters, and both primitive and reference
+     * parameters are subject to method invocation conversions as necessary.
+     *
+     * <p>If the number of formal parameters required by the underlying constructor
+     * is 0, the supplied {@code initargs} array may be of length 0 or null.
+     *
+     * <p>If the constructor's declaring class is an inner class in a
+     * non-static context, the first argument to the constructor needs
+     * to be the enclosing instance; see section 15.9.3 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     *
+     * <p>If the required access and argument checks succeed and the
+     * instantiation will proceed, the constructor's declaring class
+     * is initialized if it has not already been initialized.
+     *
+     * <p>If the constructor completes normally, returns the newly
+     * created and initialized instance.
+     *
+     * @param initargs array of objects to be passed as arguments to
+     * the constructor call; values of primitive types are wrapped in
+     * a wrapper object of the appropriate type (e.g. a {@code float}
+     * in a {@link java.lang.Float Float})
+     *
+     * @return a new object created by calling the constructor
+     * this object represents
+     *
+     * @exception IllegalAccessException    if this {@code Constructor} object
+     *              is enforcing Java language access control and the underlying
+     *              constructor is inaccessible.
+     * @exception IllegalArgumentException  if the number of actual
+     *              and formal parameters differ; if an unwrapping
+     *              conversion for primitive arguments fails; or if,
+     *              after possible unwrapping, a parameter value
+     *              cannot be converted to the corresponding formal
+     *              parameter type by a method invocation conversion; if
+     *              this constructor pertains to an enum type.
+     * @exception InstantiationException    if the class that declares the
+     *              underlying constructor represents an abstract class.
+     * @exception InvocationTargetException if the underlying constructor
+     *              throws an exception.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     */
+    // BEGIN Android-changed: newInstance(Object...) implemented differently.
+    @CallerSensitive
+    public T newInstance(Object ... initargs)
+        throws InstantiationException, IllegalAccessException,
+               IllegalArgumentException, InvocationTargetException
+    {
+        if (serializationClass == null) {
+            return newInstance0(initargs);
+        } else {
+            return (T) newInstanceFromSerialization(serializationCtor, serializationClass);
+        }
+    }
+
+    @FastNative
+    private static native Object newInstanceFromSerialization(Class<?> ctorClass, Class<?> allocClass)
+        throws InstantiationException, IllegalArgumentException, InvocationTargetException;
+
+    @FastNative
+    private native T newInstance0(Object... args) throws InstantiationException,
+            IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+    // END Android-changed: newInstance(Object...) implemented differently.
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public boolean isVarArgs() {
+        return super.isVarArgs();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @jls 13.1 The Form of a Binary
+     * @since 1.5
+     */
+    @Override
+    public boolean isSynthetic() {
+        return super.isSynthetic();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     * @since 1.5
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return super.getAnnotation(annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    public Annotation[] getDeclaredAnnotations()  {
+        return super.getDeclaredAnnotations();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Annotation[][] getParameterAnnotations() {
+        // Android-changed: getParameterAnnotations() implemented using Executable.
+        return super.getParameterAnnotationsInternal();
+    }
+}
diff --git a/java/lang/reflect/Executable.annotated.java b/java/lang/reflect/Executable.annotated.java
new file mode 100644
index 0000000..d964aad
--- /dev/null
+++ b/java/lang/reflect/Executable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * 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.reflect;
+
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member, java.lang.reflect.GenericDeclaration {
+
+Executable() { throw new RuntimeException("Stub!"); }
+
[email protected] public abstract java.lang.Class<?> getDeclaringClass();
+
[email protected] public abstract java.lang.String getName();
+
+public abstract int getModifiers();
+
+public abstract [email protected] TypeVariable<?> @libcore.util.NonNull [] getTypeParameters();
+
+public abstract [email protected] Class<?> @libcore.util.NonNull [] getParameterTypes();
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Type @libcore.util.NonNull [] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Parameter @libcore.util.NonNull [] getParameters() { throw new RuntimeException("Stub!"); }
+
+public abstract [email protected] Class<?> @libcore.util.NonNull [] getExceptionTypes();
+
+public [email protected] Type @libcore.util.NonNull [] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
[email protected] public abstract java.lang.String toGenericString();
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public abstract [email protected] Annotation @libcore.util.NonNull [] @libcore.util.NonNull [] getParameterAnnotations();
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Executable.java b/java/lang/reflect/Executable.java
new file mode 100644
index 0000000..6782d00
--- /dev/null
+++ b/java/lang/reflect/Executable.java
@@ -0,0 +1,750 @@
+/*
+ * 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+
+import java.lang.annotation.Annotation;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.ListOfTypes;
+import libcore.reflect.Types;
+import libcore.util.EmptyArray;
+
+/**
+ * A shared superclass for the common functionality of {@link Method}
+ * and {@link Constructor}.
+ *
+ * @since 1.8
+ */
+public abstract class Executable extends AccessibleObject
+    implements Member, GenericDeclaration {
+
+    // Android-changed: Extensive modifications made throughout the class for ART.
+    // Android-removed: Declared vs actual parameter annotation indexes handling.
+    // Android-removed: Type annotations runtime code. Not supported on Android.
+
+    /*
+     * Only grant package-visibility to the constructor.
+     */
+    Executable() {}
+
+    /**
+     * Does the Executable have generic information.
+     */
+    abstract boolean hasGenericInformation();
+
+    boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
+        /* Avoid unnecessary cloning */
+        if (params1.length == params2.length) {
+            for (int i = 0; i < params1.length; i++) {
+                if (params1[i] != params2[i])
+                    return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    void separateWithCommas(Class<?>[] types, StringBuilder sb) {
+        for (int j = 0; j < types.length; j++) {
+            sb.append(types[j].getTypeName());
+            if (j < (types.length - 1))
+                sb.append(",");
+        }
+
+    }
+
+    void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
+        int mod = getModifiers() & mask;
+
+        if (mod != 0 && !isDefault) {
+            sb.append(Modifier.toString(mod)).append(' ');
+        } else {
+            int access_mod = mod & Modifier.ACCESS_MODIFIERS;
+            if (access_mod != 0)
+                sb.append(Modifier.toString(access_mod)).append(' ');
+            if (isDefault)
+                sb.append("default ");
+            mod = (mod & ~Modifier.ACCESS_MODIFIERS);
+            if (mod != 0)
+                sb.append(Modifier.toString(mod)).append(' ');
+        }
+    }
+
+    String sharedToString(int modifierMask,
+                          boolean isDefault,
+                          Class<?>[] parameterTypes,
+                          Class<?>[] exceptionTypes) {
+        try {
+            StringBuilder sb = new StringBuilder();
+
+            printModifiersIfNonzero(sb, modifierMask, isDefault);
+            specificToStringHeader(sb);
+
+            sb.append('(');
+            separateWithCommas(parameterTypes, sb);
+            sb.append(')');
+            if (exceptionTypes.length > 0) {
+                sb.append(" throws ");
+                separateWithCommas(exceptionTypes, sb);
+            }
+            return sb.toString();
+        } catch (Exception e) {
+            return "<" + e + ">";
+        }
+    }
+
+    /**
+     * Generate toString header information specific to a method or
+     * constructor.
+     */
+    abstract void specificToStringHeader(StringBuilder sb);
+
+    String sharedToGenericString(int modifierMask, boolean isDefault) {
+        try {
+            StringBuilder sb = new StringBuilder();
+
+            printModifiersIfNonzero(sb, modifierMask, isDefault);
+
+            TypeVariable<?>[] typeparms = getTypeParameters();
+            if (typeparms.length > 0) {
+                boolean first = true;
+                sb.append('<');
+                for(TypeVariable<?> typeparm: typeparms) {
+                    if (!first)
+                        sb.append(',');
+                    // Class objects can't occur here; no need to test
+                    // and call Class.getName().
+                    sb.append(typeparm.toString());
+                    first = false;
+                }
+                sb.append("> ");
+            }
+
+            specificToGenericStringHeader(sb);
+
+            sb.append('(');
+            Type[] params = getGenericParameterTypes();
+            for (int j = 0; j < params.length; j++) {
+                String param = params[j].getTypeName();
+                if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
+                    param = param.replaceFirst("\\[\\]$", "...");
+                sb.append(param);
+                if (j < (params.length - 1))
+                    sb.append(',');
+            }
+            sb.append(')');
+            Type[] exceptions = getGenericExceptionTypes();
+            if (exceptions.length > 0) {
+                sb.append(" throws ");
+                for (int k = 0; k < exceptions.length; k++) {
+                    sb.append((exceptions[k] instanceof Class)?
+                              ((Class)exceptions[k]).getName():
+                              exceptions[k].toString());
+                    if (k < (exceptions.length - 1))
+                        sb.append(',');
+                }
+            }
+            return sb.toString();
+        } catch (Exception e) {
+            return "<" + e + ">";
+        }
+    }
+
+    /**
+     * Generate toGenericString header information specific to a
+     * method or constructor.
+     */
+    abstract void specificToGenericStringHeader(StringBuilder sb);
+
+    /**
+     * Returns the {@code Class} object representing the class or interface
+     * that declares the executable represented by this object.
+     */
+    public abstract Class<?> getDeclaringClass();
+
+    /**
+     * Returns the name of the executable represented by this object.
+     */
+    public abstract String getName();
+
+    /**
+     * Returns the Java language {@linkplain Modifier modifiers} for
+     * the executable represented by this object.
+     */
+    public abstract int getModifiers();
+
+    /**
+     * Returns an array of {@code TypeVariable} objects that represent the
+     * type variables declared by the generic declaration represented by this
+     * {@code GenericDeclaration} object, in declaration order.  Returns an
+     * array of length 0 if the underlying generic declaration declares no type
+     * variables.
+     *
+     * @return an array of {@code TypeVariable} objects that represent
+     *     the type variables declared by this generic declaration
+     * @throws GenericSignatureFormatError if the generic
+     *     signature of this generic declaration does not conform to
+     *     the format specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     */
+    public abstract TypeVariable<?>[] getTypeParameters();
+
+    /**
+     * Returns an array of {@code Class} objects that represent the formal
+     * parameter types, in declaration order, of the executable
+     * represented by this object.  Returns an array of length
+     * 0 if the underlying executable takes no parameters.
+     *
+     * @return the parameter types for the executable this object
+     * represents
+     */
+    public abstract Class<?>[] getParameterTypes();
+
+    /**
+     * Returns the number of formal parameters (whether explicitly
+     * declared or implicitly declared or neither) for the executable
+     * represented by this object.
+     *
+     * @return The number of formal parameters for the executable this
+     * object represents
+     */
+    public int getParameterCount() {
+        throw new AbstractMethodError();
+    }
+
+    /**
+     * Returns an array of {@code Type} objects that represent the formal
+     * parameter types, in declaration order, of the executable represented by
+     * this object. Returns an array of length 0 if the
+     * underlying executable takes no parameters.
+     *
+     * <p>If a formal parameter type is a parameterized type,
+     * the {@code Type} object returned for it must accurately reflect
+     * the actual type parameters used in the source code.
+     *
+     * <p>If a formal parameter type is a type variable or a parameterized
+     * type, it is created. Otherwise, it is resolved.
+     *
+     * @return an array of {@code Type}s that represent the formal
+     *     parameter types of the underlying executable, in declaration order
+     * @throws GenericSignatureFormatError
+     *     if the generic method signature does not conform to the format
+     *     specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if any of the parameter
+     *     types of the underlying executable refers to a non-existent type
+     *     declaration
+     * @throws MalformedParameterizedTypeException if any of
+     *     the underlying executable's parameter types refer to a parameterized
+     *     type that cannot be instantiated for any reason
+     */
+    public Type[] getGenericParameterTypes() {
+        // Android-changed: getGenericParameterTypes() implementation for use with ART.
+        return Types.getTypeArray(
+                getMethodOrConstructorGenericInfoInternal().genericParameterTypes, false);
+    }
+
+    /**
+     * Behaves like {@code getGenericParameterTypes}, but returns type
+     * information for all parameters, including synthetic parameters.
+     */
+    Type[] getAllGenericParameterTypes() {
+        final boolean genericInfo = hasGenericInformation();
+
+        // Easy case: we don't have generic parameter information.  In
+        // this case, we just return the result of
+        // getParameterTypes().
+        if (!genericInfo) {
+            return getParameterTypes();
+        } else {
+            final boolean realParamData = hasRealParameterData();
+            final Type[] genericParamTypes = getGenericParameterTypes();
+            final Type[] nonGenericParamTypes = getParameterTypes();
+            final Type[] out = new Type[nonGenericParamTypes.length];
+            final Parameter[] params = getParameters();
+            int fromidx = 0;
+            // If we have real parameter data, then we use the
+            // synthetic and mandate flags to our advantage.
+            if (realParamData) {
+                for (int i = 0; i < out.length; i++) {
+                    final Parameter param = params[i];
+                    if (param.isSynthetic() || param.isImplicit()) {
+                        // If we hit a synthetic or mandated parameter,
+                        // use the non generic parameter info.
+                        out[i] = nonGenericParamTypes[i];
+                    } else {
+                        // Otherwise, use the generic parameter info.
+                        out[i] = genericParamTypes[fromidx];
+                        fromidx++;
+                    }
+                }
+            } else {
+                // Otherwise, use the non-generic parameter data.
+                // Without method parameter reflection data, we have
+                // no way to figure out which parameters are
+                // synthetic/mandated, thus, no way to match up the
+                // indexes.
+                return genericParamTypes.length == nonGenericParamTypes.length ?
+                    genericParamTypes : nonGenericParamTypes;
+            }
+            return out;
+        }
+    }
+
+    /**
+     * Returns an array of {@code Parameter} objects that represent
+     * all the parameters to the underlying executable represented by
+     * this object.  Returns an array of length 0 if the executable
+     * has no parameters.
+     *
+     * <p>The parameters of the underlying executable do not necessarily
+     * have unique names, or names that are legal identifiers in the
+     * Java programming language (JLS 3.8).
+     *
+     * @throws MalformedParametersException if the class file contains
+     * a MethodParameters attribute that is improperly formatted.
+     * @return an array of {@code Parameter} objects representing all
+     * the parameters to the executable this object represents.
+     */
+    public Parameter[] getParameters() {
+        // TODO: This may eventually need to be guarded by security
+        // mechanisms similar to those in Field, Method, etc.
+        //
+        // Need to copy the cached array to prevent users from messing
+        // with it.  Since parameters are immutable, we can
+        // shallow-copy.
+        return privateGetParameters().clone();
+    }
+
+    private Parameter[] synthesizeAllParams() {
+        final int realparams = getParameterCount();
+        final Parameter[] out = new Parameter[realparams];
+        for (int i = 0; i < realparams; i++)
+            // TODO: is there a way to synthetically derive the
+            // modifiers?  Probably not in the general case, since
+            // we'd have no way of knowing about them, but there
+            // may be specific cases.
+            out[i] = new Parameter("arg" + i, 0, this, i);
+        return out;
+    }
+
+    private void verifyParameters(final Parameter[] parameters) {
+        final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
+
+        if (getParameterTypes().length != parameters.length)
+            throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
+
+        for (Parameter parameter : parameters) {
+            final String name = parameter.getRealName();
+            final int mods = parameter.getModifiers();
+
+            if (name != null) {
+                if (name.isEmpty() || name.indexOf('.') != -1 ||
+                    name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
+                    name.indexOf('/') != -1) {
+                    throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
+                }
+            }
+
+            if (mods != (mods & mask)) {
+                throw new MalformedParametersException("Invalid parameter modifiers");
+            }
+        }
+    }
+
+    private Parameter[] privateGetParameters() {
+        // Use tmp to avoid multiple writes to a volatile.
+        Parameter[] tmp = parameters;
+
+        if (tmp == null) {
+
+            // Otherwise, go to the JVM to get them
+            try {
+                tmp = getParameters0();
+            } catch(IllegalArgumentException e) {
+                // Rethrow ClassFormatErrors
+                // Android-changed: Exception changed to be more descriptive.
+                MalformedParametersException e2 =
+                        new MalformedParametersException(
+                                "Invalid parameter metadata in class file");
+                e2.initCause(e);
+                throw e2;
+            }
+
+            // If we get back nothing, then synthesize parameters
+            if (tmp == null) {
+                hasRealParameterData = false;
+                tmp = synthesizeAllParams();
+            } else {
+                hasRealParameterData = true;
+                verifyParameters(tmp);
+            }
+
+            parameters = tmp;
+        }
+
+        return tmp;
+    }
+
+    boolean hasRealParameterData() {
+        // If this somehow gets called before parameters gets
+        // initialized, force it into existence.
+        if (parameters == null) {
+            privateGetParameters();
+        }
+        return hasRealParameterData;
+    }
+
+    private transient volatile boolean hasRealParameterData;
+    private transient volatile Parameter[] parameters;
+
+    // Android-changed: Added @FastNative to getParameters0()
+    @FastNative
+    private native Parameter[] getParameters0();
+
+    /**
+     * Returns an array of {@code Class} objects that represent the
+     * types of exceptions declared to be thrown by the underlying
+     * executable represented by this object.  Returns an array of
+     * length 0 if the executable declares no exceptions in its {@code
+     * throws} clause.
+     *
+     * @return the exception types declared as being thrown by the
+     * executable this object represents
+     */
+    public abstract Class<?>[] getExceptionTypes();
+
+    /**
+     * Returns an array of {@code Type} objects that represent the
+     * exceptions declared to be thrown by this executable object.
+     * Returns an array of length 0 if the underlying executable declares
+     * no exceptions in its {@code throws} clause.
+     *
+     * <p>If an exception type is a type variable or a parameterized
+     * type, it is created. Otherwise, it is resolved.
+     *
+     * @return an array of Types that represent the exception types
+     *     thrown by the underlying executable
+     * @throws GenericSignatureFormatError
+     *     if the generic method signature does not conform to the format
+     *     specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if the underlying executable's
+     *     {@code throws} clause refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if
+     *     the underlying executable's {@code throws} clause refers to a
+     *     parameterized type that cannot be instantiated for any reason
+     */
+    public Type[] getGenericExceptionTypes() {
+        // Android-changed: getGenericExceptionTypes() implementation for use with ART.
+        return Types.getTypeArray(
+                getMethodOrConstructorGenericInfoInternal().genericExceptionTypes, false);
+    }
+
+    /**
+     * Returns a string describing this {@code Executable}, including
+     * any type parameters.
+     * @return a string describing this {@code Executable}, including
+     * any type parameters
+     */
+    public abstract String toGenericString();
+
+    /**
+     * Returns {@code true} if this executable was declared to take a
+     * variable number of arguments; returns {@code false} otherwise.
+     *
+     * @return {@code true} if an only if this executable was declared
+     * to take a variable number of arguments.
+     */
+    public boolean isVarArgs()  {
+        // Android-changed: isVarArgs() made slightly more efficient.
+        return (accessFlags & Modifier.VARARGS) != 0;
+    }
+
+    /**
+     * Returns {@code true} if this executable is a synthetic
+     * construct; returns {@code false} otherwise.
+     *
+     * @return true if and only if this executable is a synthetic
+     * construct as defined by
+     * <cite>The Java&trade; Language Specification</cite>.
+     * @jls 13.1 The Form of a Binary
+     */
+    public boolean isSynthetic() {
+        // Android-changed: isSynthetic() made slightly more efficient.
+        return (accessFlags & Modifier.SYNTHETIC) != 0;
+    }
+
+    /**
+     * Returns an array of arrays of {@code Annotation}s that
+     * represent the annotations on the formal parameters, in
+     * declaration order, of the {@code Executable} represented by
+     * this object.  Synthetic and mandated parameters (see
+     * explanation below), such as the outer "this" parameter to an
+     * inner class constructor will be represented in the returned
+     * array.  If the executable has no parameters (meaning no formal,
+     * no synthetic, and no mandated parameters), a zero-length array
+     * will be returned.  If the {@code Executable} has one or more
+     * parameters, a nested array of length zero is returned for each
+     * parameter with no annotations. The annotation objects contained
+     * in the returned arrays are serializable.  The caller of this
+     * method is free to modify the returned arrays; it will have no
+     * effect on the arrays returned to other callers.
+     *
+     * A compiler may add extra parameters that are implicitly
+     * declared in source ("mandated"), as well as parameters that
+     * are neither implicitly nor explicitly declared in source
+     * ("synthetic") to the parameter list for a method.  See {@link
+     * java.lang.reflect.Parameter} for more information.
+     *
+     * @see java.lang.reflect.Parameter
+     * @see java.lang.reflect.Parameter#getAnnotations
+     * @return an array of arrays that represent the annotations on
+     *    the formal and implicit parameters, in declaration order, of
+     *    the executable represented by this object
+     */
+    public abstract Annotation[][] getParameterAnnotations();
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Objects.requireNonNull(annotationClass);
+        // Android-changed: Implemented getAnnotation(Class) natively.
+        return getAnnotationNative(annotationClass);
+    }
+
+    // Android-changed: Implemented getAnnotation(Class) natively.
+    @FastNative
+    private native <T extends Annotation> T getAnnotationNative(Class<T> annotationClass);
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     */
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+        // Android-changed: getAnnotationsByType(Class), Android uses AnnotatedElements instead.
+        return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Annotation[] getDeclaredAnnotations()  {
+        // Android-changed: Implemented getDeclaredAnnotations() natively.
+        return getDeclaredAnnotationsNative();
+    }
+
+    // Android-added: Implemented getDeclaredAnnotations() natively.
+    @FastNative
+    private native Annotation[] getDeclaredAnnotationsNative();
+
+    // BEGIN Android-added: Additional ART-related fields and logic.
+    // This code is shared for Method and Constructor.
+
+    /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
+    @SuppressWarnings("unused") // set by runtime
+    private int accessFlags;
+
+    /**
+     * The ArtMethod associated with this Executable, required for dispatching due to entrypoints
+     * Classloader is held live by the declaring class.
+     */
+    @SuppressWarnings("unused") // set by runtime
+    private long artMethod;
+
+    /** Executable's declaring class */
+    @SuppressWarnings("unused") // set by runtime
+    private Class<?> declaringClass;
+
+    /**
+     * Overriden method's declaring class (same as declaringClass unless declaringClass is a proxy
+     * class).
+     */
+    @SuppressWarnings("unused") // set by runtime
+    private Class<?> declaringClassOfOverriddenMethod;
+
+    /** The method index of this method within its defining dex file */
+    @SuppressWarnings("unused") // set by runtime
+    private int dexMethodIndex;
+
+    /**
+     * We insert native method stubs for abstract methods so we don't have to
+     * check the access flags at the time of the method call.  This results in
+     * "native abstract" methods, which can't exist.  If we see the "abstract"
+     * flag set, clear the "native" flag.
+     *
+     * We also move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED
+     * position, because the callers of this function are trying to convey
+     * the "traditional" meaning of the flags to their callers.
+     */
+    private static int fixMethodFlags(int flags) {
+        if ((flags & Modifier.ABSTRACT) != 0) {
+            flags &= ~Modifier.NATIVE;
+        }
+        flags &= ~Modifier.SYNCHRONIZED;
+        int ACC_DECLARED_SYNCHRONIZED = 0x00020000;
+        if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {
+            flags |= Modifier.SYNCHRONIZED;
+        }
+        return flags & 0xffff;  // mask out bits not used by Java
+    }
+
+    final int getModifiersInternal() {
+        return fixMethodFlags(accessFlags);
+    }
+
+    final Class<?> getDeclaringClassInternal() {
+        return declaringClass;
+    }
+
+    /**
+     * Returns an array of {@code Class} objects associated with the parameter types of this
+     * Executable. If the Executable was declared with no parameters, {@code null} will be
+     * returned.
+     *
+     * @return the parameter types, or {@code null} if no parameters were declared.
+     */
+    @FastNative
+    final native Class<?>[] getParameterTypesInternal();
+
+    @FastNative
+    final native int getParameterCountInternal();
+
+    // Android provides a more efficient implementation of this method for Executable than the one
+    // implemented in AnnotatedElement.
+    @Override
+    public final boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        Objects.requireNonNull(annotationType);
+        return isAnnotationPresentNative(annotationType);
+    }
+    @FastNative
+    private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
+
+    final Annotation[][] getParameterAnnotationsInternal() {
+        Annotation[][] parameterAnnotations = getParameterAnnotationsNative();
+        if (parameterAnnotations == null) {
+            parameterAnnotations = new Annotation[getParameterTypes().length][0];
+        }
+        return parameterAnnotations;
+    }
+    @FastNative
+    private native Annotation[][] getParameterAnnotationsNative();
+
+    /**
+     * @hide - exposed for use by {@link Class}.
+     */
+    public final int getAccessFlags() {
+        return accessFlags;
+    }
+
+    /**
+     * @hide - exposed for use by {@code java.lang.invoke.*}.
+     */
+    public final long getArtMethod() {
+        return artMethod;
+    }
+
+    static final class GenericInfo {
+        final ListOfTypes genericExceptionTypes;
+        final ListOfTypes genericParameterTypes;
+        final Type genericReturnType;
+        final TypeVariable<?>[] formalTypeParameters;
+
+        GenericInfo(ListOfTypes exceptions, ListOfTypes parameters, Type ret,
+                TypeVariable<?>[] formal) {
+            genericExceptionTypes = exceptions;
+            genericParameterTypes = parameters;
+            genericReturnType = ret;
+            formalTypeParameters = formal;
+        }
+    }
+
+    final boolean hasGenericInformationInternal() {
+        return getSignatureAnnotation() != null;
+    }
+
+    /**
+     * Returns generic information associated with this method/constructor member.
+     */
+    final GenericInfo getMethodOrConstructorGenericInfoInternal() {
+        String signatureAttribute = getSignatureAttribute();
+        Class<?>[] exceptionTypes = this.getExceptionTypes();
+        GenericSignatureParser parser =
+                new GenericSignatureParser(this.getDeclaringClass().getClassLoader());
+        if (this instanceof Method) {
+            parser.parseForMethod(this, signatureAttribute, exceptionTypes);
+        } else {
+            parser.parseForConstructor(this, signatureAttribute, exceptionTypes);
+        }
+        return new GenericInfo(parser.exceptionTypes, parser.parameterTypes,
+                parser.returnType, parser.formalTypeParameters);
+    }
+
+    private String getSignatureAttribute() {
+        String[] annotation = getSignatureAnnotation();
+        if (annotation == null) {
+            return null;
+        }
+        StringBuilder result = new StringBuilder();
+        for (String s : annotation) {
+            result.append(s);
+        }
+        return result.toString();
+    }
+    @FastNative
+    private native String[] getSignatureAnnotation();
+
+    final boolean equalNameAndParametersInternal(Method m) {
+        return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
+    }
+
+    @FastNative
+    native int compareMethodParametersInternal(Method meth);
+
+    @FastNative
+    final native String getMethodNameInternal();
+
+    @FastNative
+    final native Class<?> getMethodReturnTypeInternal();
+
+    /** A cheap implementation for {@link Method#isDefault()}. */
+    final boolean isDefaultMethodInternal() {
+        return (accessFlags & Modifier.DEFAULT) != 0;
+    }
+
+    /** A cheap implementation for {@link Method#isBridge()}. */
+    final boolean isBridgeMethodInternal() {
+        return (accessFlags & Modifier.BRIDGE) != 0;
+    }
+    // END Android-added: Additional ART-related fields and logic.
+
+}
diff --git a/java/lang/reflect/Field.annotated.java b/java/lang/reflect/Field.annotated.java
new file mode 100644
index 0000000..8a26ce3
--- /dev/null
+++ b/java/lang/reflect/Field.annotated.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
+
+Field() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnumConstant() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getGenericType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object get(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native boolean getBoolean(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native byte getByte(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native char getChar(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native short getShort(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native int getInt(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native long getLong(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native float getFloat(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native double getDouble(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void set(@libcore.util.Nullable java.lang.Object obj, @libcore.util.Nullable java.lang.Object value) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setBoolean(@libcore.util.Nullable java.lang.Object obj, boolean z) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setByte(@libcore.util.Nullable java.lang.Object obj, byte b) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setChar(@libcore.util.Nullable java.lang.Object obj, char c) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setShort(@libcore.util.Nullable java.lang.Object obj, short s) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setInt(@libcore.util.Nullable java.lang.Object obj, int i) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setLong(@libcore.util.Nullable java.lang.Object obj, long l) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setFloat(@libcore.util.Nullable java.lang.Object obj, float f) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setDouble(@libcore.util.Nullable java.lang.Object obj, double d) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/Field.java b/java/lang/reflect/Field.java
new file mode 100644
index 0000000..ca5857a
--- /dev/null
+++ b/java/lang/reflect/Field.java
@@ -0,0 +1,950 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import sun.reflect.CallerSensitive;
+import java.lang.annotation.Annotation;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+import libcore.reflect.GenericSignatureParser;
+
+
+/**
+ * A {@code Field} provides information about, and dynamic access to, a
+ * single field of a class or an interface.  The reflected field may
+ * be a class (static) field or an instance field.
+ *
+ * <p>A {@code Field} permits widening conversions to occur during a get or
+ * set access operation, but throws an {@code IllegalArgumentException} if a
+ * narrowing conversion would occur.
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getFields()
+ * @see java.lang.Class#getField(String)
+ * @see java.lang.Class#getDeclaredFields()
+ * @see java.lang.Class#getDeclaredField(String)
+ *
+ * @author Kenneth Russell
+ * @author Nakul Saraiya
+ */
+public final
+class Field extends AccessibleObject implements Member {
+    // Android-changed: Extensive modifications made throughout the class for ART.
+    // Android-changed: Many fields and methods removed / modified.
+    // Android-removed: Type annotations runtime code. Not supported on Android.
+
+    private int accessFlags;
+    private Class<?> declaringClass;
+    private int artFieldIndex;
+    private int offset;
+    private Class<?> type;
+
+    private Field() {
+    }
+
+    /**
+     * Returns the {@code Class} object representing the class or interface
+     * that declares the field represented by this {@code Field} object.
+     */
+    public Class<?> getDeclaringClass() {
+        // Android-changed: Adjust code for different field names.
+        return declaringClass;
+    }
+
+    /**
+     * Returns the name of the field represented by this {@code Field} object.
+     */
+    public String getName() {
+        // Android-changed: getName() implemented differently.
+        if (declaringClass.isProxy()) {
+            // Proxy classes have 1 synthesized static field with no valid dex index.
+            if ((getModifiers() & Modifier.STATIC) == 0) {
+                throw new AssertionError("Invalid modifiers for proxy field: " + getModifiers());
+            }
+            // Only 2 fields are present on proxy classes.
+            switch (artFieldIndex) {
+                case 0: return "interfaces";
+                case 1: return "throws";
+                default: throw new AssertionError("Invalid index for proxy: " + artFieldIndex);
+            }
+        }
+
+        return getNameInternal();
+    }
+
+    // Android-added: getName() implemented differently.
+    @FastNative
+    private native String getNameInternal();
+
+    /**
+     * Returns the Java language modifiers for the field represented
+     * by this {@code Field} object, as an integer. The {@code Modifier} class should
+     * be used to decode the modifiers.
+     *
+     * @see Modifier
+     */
+    public int getModifiers() {
+        // Android-changed: Adjust getModifiers() implementation to mask extra bits used on Android.
+        return accessFlags & 0xffff;  // mask out bits not used by Java
+    }
+
+    /**
+     * Returns {@code true} if this field represents an element of
+     * an enumerated type; returns {@code false} otherwise.
+     *
+     * @return {@code true} if and only if this field represents an element of
+     * an enumerated type.
+     * @since 1.5
+     */
+    public boolean isEnumConstant() {
+        return (getModifiers() & Modifier.ENUM) != 0;
+    }
+
+    /**
+     * Returns {@code true} if this field is a synthetic
+     * field; returns {@code false} otherwise.
+     *
+     * @return true if and only if this field is a synthetic
+     * field as defined by the Java Language Specification.
+     * @since 1.5
+     */
+    public boolean isSynthetic() {
+        return Modifier.isSynthetic(getModifiers());
+    }
+
+    /**
+     * Returns a {@code Class} object that identifies the
+     * declared type for the field represented by this
+     * {@code Field} object.
+     *
+     * @return a {@code Class} object identifying the declared
+     * type of the field represented by this object
+     */
+    public Class<?> getType() {
+        return type;
+    }
+
+    /**
+     * Returns a {@code Type} object that represents the declared type for
+     * the field represented by this {@code Field} object.
+     *
+     * <p>If the {@code Type} is a parameterized type, the
+     * {@code Type} object returned must accurately reflect the
+     * actual type parameters used in the source code.
+     *
+     * <p>If the type of the underlying field is a type variable or a
+     * parameterized type, it is created. Otherwise, it is resolved.
+     *
+     * @return a {@code Type} object that represents the declared type for
+     *     the field represented by this {@code Field} object
+     * @throws GenericSignatureFormatError if the generic field
+     *     signature does not conform to the format specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if the generic type
+     *     signature of the underlying field refers to a non-existent
+     *     type declaration
+     * @throws MalformedParameterizedTypeException if the generic
+     *     signature of the underlying field refers to a parameterized type
+     *     that cannot be instantiated for any reason
+     * @since 1.5
+     */
+    public Type getGenericType() {
+        // Android-changed: getGenericType() implemented differently.
+        String signatureAttribute = getSignatureAttribute();
+        ClassLoader cl = declaringClass.getClassLoader();
+        GenericSignatureParser parser = new GenericSignatureParser(cl);
+        parser.parseForField(declaringClass, signatureAttribute);
+        Type genericType = parser.fieldType;
+        if (genericType == null) {
+            genericType = getType();
+        }
+        return genericType;
+    }
+
+    // BEGIN Android-added: getGenericType() implemented differently.
+    private String getSignatureAttribute() {
+        String[] annotation = getSignatureAnnotation();
+        if (annotation == null) {
+            return null;
+        }
+        StringBuilder result = new StringBuilder();
+        for (String s : annotation) {
+            result.append(s);
+        }
+        return result.toString();
+    }
+    @FastNative
+    private native String[] getSignatureAnnotation();
+    // END Android-added: getGenericType() implemented differently.
+
+
+    /**
+     * Compares this {@code Field} against the specified object.  Returns
+     * true if the objects are the same.  Two {@code Field} objects are the same if
+     * they were declared by the same class and have the same name
+     * and type.
+     */
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof Field) {
+            Field other = (Field)obj;
+            return (getDeclaringClass() == other.getDeclaringClass())
+                && (getName() == other.getName())
+                && (getType() == other.getType());
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hashcode for this {@code Field}.  This is computed as the
+     * exclusive-or of the hashcodes for the underlying field's
+     * declaring class name and its name.
+     */
+    public int hashCode() {
+        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+    }
+
+    /**
+     * Returns a string describing this {@code Field}.  The format is
+     * the access modifiers for the field, if any, followed
+     * by the field type, followed by a space, followed by
+     * the fully-qualified name of the class declaring the field,
+     * followed by a period, followed by the name of the field.
+     * For example:
+     * <pre>
+     *    public static final int java.lang.Thread.MIN_PRIORITY
+     *    private int java.io.FileDescriptor.fd
+     * </pre>
+     *
+     * <p>The modifiers are placed in canonical order as specified by
+     * "The Java Language Specification".  This is {@code public},
+     * {@code protected} or {@code private} first, and then other
+     * modifiers in the following order: {@code static}, {@code final},
+     * {@code transient}, {@code volatile}.
+     *
+     * @return a string describing this {@code Field}
+     * @jls 8.3.1 Field Modifiers
+     */
+    public String toString() {
+        int mod = getModifiers();
+        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+            + getType().getTypeName() + " "
+            + getDeclaringClass().getTypeName() + "."
+            + getName());
+    }
+
+    /**
+     * Returns a string describing this {@code Field}, including
+     * its generic type.  The format is the access modifiers for the
+     * field, if any, followed by the generic field type, followed by
+     * a space, followed by the fully-qualified name of the class
+     * declaring the field, followed by a period, followed by the name
+     * of the field.
+     *
+     * <p>The modifiers are placed in canonical order as specified by
+     * "The Java Language Specification".  This is {@code public},
+     * {@code protected} or {@code private} first, and then other
+     * modifiers in the following order: {@code static}, {@code final},
+     * {@code transient}, {@code volatile}.
+     *
+     * @return a string describing this {@code Field}, including
+     * its generic type
+     *
+     * @since 1.5
+     * @jls 8.3.1 Field Modifiers
+     */
+    public String toGenericString() {
+        int mod = getModifiers();
+        Type fieldType = getGenericType();
+        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+            + fieldType.getTypeName() + " "
+            + getDeclaringClass().getTypeName() + "."
+            + getName());
+    }
+
+    /**
+     * Returns the value of the field represented by this {@code Field}, on
+     * the specified object. The value is automatically wrapped in an
+     * object if it has a primitive type.
+     *
+     * <p>The underlying field's value is obtained as follows:
+     *
+     * <p>If the underlying field is a static field, the {@code obj} argument
+     * is ignored; it may be null.
+     *
+     * <p>Otherwise, the underlying field is an instance field.  If the
+     * specified {@code obj} argument is null, the method throws a
+     * {@code NullPointerException}. If the specified object is not an
+     * instance of the class or interface declaring the underlying
+     * field, the method throws an {@code IllegalArgumentException}.
+     *
+     * <p>If this {@code Field} object is enforcing Java language access control, and
+     * the underlying field is inaccessible, the method throws an
+     * {@code IllegalAccessException}.
+     * If the underlying field is static, the class that declared the
+     * field is initialized if it has not already been initialized.
+     *
+     * <p>Otherwise, the value is retrieved from the underlying instance
+     * or static field.  If the field has a primitive type, the value
+     * is wrapped in an object before being returned, otherwise it is
+     * returned as is.
+     *
+     * <p>If the field is hidden in the type of {@code obj},
+     * the field's value is obtained according to the preceding rules.
+     *
+     * @param obj object from which the represented field's value is
+     * to be extracted
+     * @return the value of the represented field in object
+     * {@code obj}; primitive values are wrapped in an appropriate
+     * object before being returned
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof).
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native Object get(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance {@code boolean} field.
+     *
+     * @param obj the object to extract the {@code boolean} value
+     * from
+     * @return the value of the {@code boolean} field
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code boolean} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native boolean getBoolean(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance {@code byte} field.
+     *
+     * @param obj the object to extract the {@code byte} value
+     * from
+     * @return the value of the {@code byte} field
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code byte} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native byte getByte(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code char} or of another primitive type convertible to
+     * type {@code char} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code char} value
+     * from
+     * @return the value of the field converted to type {@code char}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code char} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native char getChar(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code short} or of another primitive type convertible to
+     * type {@code short} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code short} value
+     * from
+     * @return the value of the field converted to type {@code short}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code short} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native short getShort(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code int} or of another primitive type convertible to
+     * type {@code int} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code int} value
+     * from
+     * @return the value of the field converted to type {@code int}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code int} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native int getInt(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code long} or of another primitive type convertible to
+     * type {@code long} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code long} value
+     * from
+     * @return the value of the field converted to type {@code long}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code long} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native long getLong(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code float} or of another primitive type convertible to
+     * type {@code float} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code float} value
+     * from
+     * @return the value of the field converted to type {@code float}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code float} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native float getFloat(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Gets the value of a static or instance field of type
+     * {@code double} or of another primitive type convertible to
+     * type {@code double} via a widening conversion.
+     *
+     * @param obj the object to extract the {@code double} value
+     * from
+     * @return the value of the field converted to type {@code double}
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is inaccessible.
+     * @exception IllegalArgumentException  if the specified object is not
+     *              an instance of the class or interface declaring the
+     *              underlying field (or a subclass or implementor
+     *              thereof), or if the field value cannot be
+     *              converted to the type {@code double} by a
+     *              widening conversion.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#get
+     */
+    @CallerSensitive
+    // Android-changed: get*(Object) implemented natively.
+    @FastNative
+    public native double getDouble(Object obj)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the field represented by this {@code Field} object on the
+     * specified object argument to the specified new value. The new
+     * value is automatically unwrapped if the underlying field has a
+     * primitive type.
+     *
+     * <p>The operation proceeds as follows:
+     *
+     * <p>If the underlying field is static, the {@code obj} argument is
+     * ignored; it may be null.
+     *
+     * <p>Otherwise the underlying field is an instance field.  If the
+     * specified object argument is null, the method throws a
+     * {@code NullPointerException}.  If the specified object argument is not
+     * an instance of the class or interface declaring the underlying
+     * field, the method throws an {@code IllegalArgumentException}.
+     *
+     * <p>If this {@code Field} object is enforcing Java language access control, and
+     * the underlying field is inaccessible, the method throws an
+     * {@code IllegalAccessException}.
+     *
+     * <p>If the underlying field is final, the method throws an
+     * {@code IllegalAccessException} unless {@code setAccessible(true)}
+     * has succeeded for this {@code Field} object
+     * and the field is non-static. Setting a final field in this way
+     * is meaningful only during deserialization or reconstruction of
+     * instances of classes with blank final fields, before they are
+     * made available for access by other parts of a program. Use in
+     * any other context may have unpredictable effects, including cases
+     * in which other parts of a program continue to use the original
+     * value of this field.
+     *
+     * <p>If the underlying field is of a primitive type, an unwrapping
+     * conversion is attempted to convert the new value to a value of
+     * a primitive type.  If this attempt fails, the method throws an
+     * {@code IllegalArgumentException}.
+     *
+     * <p>If, after possible unwrapping, the new value cannot be
+     * converted to the type of the underlying field by an identity or
+     * widening conversion, the method throws an
+     * {@code IllegalArgumentException}.
+     *
+     * <p>If the underlying field is static, the class that declared the
+     * field is initialized if it has not already been initialized.
+     *
+     * <p>The field is set to the possibly unwrapped and widened new value.
+     *
+     * <p>If the field is hidden in the type of {@code obj},
+     * the field's value is set according to the preceding rules.
+     *
+     * @param obj the object whose field should be modified
+     * @param value the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void set(Object obj, Object value)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code boolean} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, zObj)},
+     * where {@code zObj} is a {@code Boolean} object and
+     * {@code zObj.booleanValue() == z}.
+     *
+     * @param obj the object whose field should be modified
+     * @param z   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setBoolean(Object obj, boolean z)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code byte} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, bObj)},
+     * where {@code bObj} is a {@code Byte} object and
+     * {@code bObj.byteValue() == b}.
+     *
+     * @param obj the object whose field should be modified
+     * @param b   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setByte(Object obj, byte b)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code char} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, cObj)},
+     * where {@code cObj} is a {@code Character} object and
+     * {@code cObj.charValue() == c}.
+     *
+     * @param obj the object whose field should be modified
+     * @param c   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setChar(Object obj, char c)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code short} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, sObj)},
+     * where {@code sObj} is a {@code Short} object and
+     * {@code sObj.shortValue() == s}.
+     *
+     * @param obj the object whose field should be modified
+     * @param s   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setShort(Object obj, short s)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as an {@code int} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, iObj)},
+     * where {@code iObj} is a {@code Integer} object and
+     * {@code iObj.intValue() == i}.
+     *
+     * @param obj the object whose field should be modified
+     * @param i   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setInt(Object obj, int i)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code long} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, lObj)},
+     * where {@code lObj} is a {@code Long} object and
+     * {@code lObj.longValue() == l}.
+     *
+     * @param obj the object whose field should be modified
+     * @param l   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setLong(Object obj, long l)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code float} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, fObj)},
+     * where {@code fObj} is a {@code Float} object and
+     * {@code fObj.floatValue() == f}.
+     *
+     * @param obj the object whose field should be modified
+     * @param f   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setFloat(Object obj, float f)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * Sets the value of a field as a {@code double} on the specified object.
+     * This method is equivalent to
+     * {@code set(obj, dObj)},
+     * where {@code dObj} is a {@code Double} object and
+     * {@code dObj.doubleValue() == d}.
+     *
+     * @param obj the object whose field should be modified
+     * @param d   the new value for the field of {@code obj}
+     * being modified
+     *
+     * @exception IllegalAccessException    if this {@code Field} object
+     *              is enforcing Java language access control and the underlying
+     *              field is either inaccessible or final.
+     * @exception IllegalArgumentException  if the specified object is not an
+     *              instance of the class or interface declaring the underlying
+     *              field (or a subclass or implementor thereof),
+     *              or if an unwrapping conversion fails.
+     * @exception NullPointerException      if the specified object is null
+     *              and the field is an instance field.
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *              by this method fails.
+     * @see       Field#set
+     */
+    @CallerSensitive
+    // Android-changed: set*(Object, ...) implemented natively.
+    @FastNative
+    public native void setDouble(Object obj, double d)
+        throws IllegalArgumentException, IllegalAccessException;
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.5
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Objects.requireNonNull(annotationClass);
+        // Android-changed: getAnnotation(Class) implemented differently.
+        return getAnnotationNative(annotationClass);
+    }
+    // Android-added: getAnnotation(Class) implemented differently.
+    @FastNative
+    private native <A extends Annotation> A getAnnotationNative(Class<A> annotationType);
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+        // Android-added: getAnnotationsByType(Class) implemented differently.
+        return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+    }
+
+    // BEGIN Android-added: isAnnotationPresent(Class) overridden in Field.
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        if (annotationType == null) {
+            throw new NullPointerException("annotationType == null");
+        }
+        return isAnnotationPresentNative(annotationType);
+    }
+    @FastNative
+    private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
+    // END Android-added: isAnnotationPresent(Class) overridden in Field.
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @FastNative
+    public native Annotation[] getDeclaredAnnotations();
+
+    // BEGIN Android-added: Methods for use by Android-specific code.
+    /**
+     * Returns the offset of the field within an instance, or for static fields, the class.
+     *
+     * @hide
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * @hide - export for use by {@code java.lang.invoke.*}
+     */
+    @FastNative
+    public native long getArtField();
+    // END Android-added: Methods for use by Android-specific code.
+}
diff --git a/java/lang/reflect/GenericArrayType.annotated.java b/java/lang/reflect/GenericArrayType.annotated.java
new file mode 100644
index 0000000..c173408
--- /dev/null
+++ b/java/lang/reflect/GenericArrayType.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericArrayType extends java.lang.reflect.Type {
+
[email protected] public java.lang.reflect.Type getGenericComponentType();
+}
+
diff --git a/java/lang/reflect/GenericArrayType.java b/java/lang/reflect/GenericArrayType.java
new file mode 100644
index 0000000..c45399e
--- /dev/null
+++ b/java/lang/reflect/GenericArrayType.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+/**
+ * {@code GenericArrayType} represents an array type whose component
+ * type is either a parameterized type or a type variable.
+ * @since 1.5
+ */
+public interface GenericArrayType extends Type {
+    /**
+     * Returns a {@code Type} object representing the component type
+     * of this array. This method creates the component type of the
+     * array.  See the declaration of {@link
+     * java.lang.reflect.ParameterizedType ParameterizedType} for the
+     * semantics of the creation process for parameterized types and
+     * see {@link java.lang.reflect.TypeVariable TypeVariable} for the
+     * creation process for type variables.
+     *
+     * @return  a {@code Type} object representing the component type
+     *     of this array
+     * @throws TypeNotPresentException if the underlying array type's
+     *     component type refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if  the
+     *     underlying array type's component type refers to a
+     *     parameterized type that cannot be instantiated for any reason
+     */
+    Type getGenericComponentType();
+}
diff --git a/java/lang/reflect/GenericDeclaration.annotated.java b/java/lang/reflect/GenericDeclaration.annotated.java
new file mode 100644
index 0000000..3614d84
--- /dev/null
+++ b/java/lang/reflect/GenericDeclaration.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+
[email protected] public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
+}
+
diff --git a/java/lang/reflect/GenericDeclaration.java b/java/lang/reflect/GenericDeclaration.java
new file mode 100644
index 0000000..042e359
--- /dev/null
+++ b/java/lang/reflect/GenericDeclaration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+/**
+ * A common interface for all entities that declare type variables.
+ *
+ * @since 1.5
+ */
+public interface GenericDeclaration extends AnnotatedElement {
+    /**
+     * Returns an array of {@code TypeVariable} objects that
+     * represent the type variables declared by the generic
+     * declaration represented by this {@code GenericDeclaration}
+     * object, in declaration order.  Returns an array of length 0 if
+     * the underlying generic declaration declares no type variables.
+     *
+     * @return an array of {@code TypeVariable} objects that represent
+     *     the type variables declared by this generic declaration
+     * @throws GenericSignatureFormatError if the generic
+     *     signature of this generic declaration does not conform to
+     *     the format specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     */
+    public TypeVariable<?>[] getTypeParameters();
+}
diff --git a/java/lang/reflect/GenericSignatureFormatError.java b/java/lang/reflect/GenericSignatureFormatError.java
new file mode 100644
index 0000000..3fd70d3
--- /dev/null
+++ b/java/lang/reflect/GenericSignatureFormatError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003, 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 java.lang.reflect;
+
+
+/**
+ * Thrown when a syntactically malformed signature attribute is
+ * encountered by a reflective method that needs to interpret the
+ * generic signature information for a type, method or constructor.
+ *
+ * @since 1.5
+ */
+public class GenericSignatureFormatError extends ClassFormatError {
+    private static final long serialVersionUID = 6709919147137911034L;
+
+    /**
+     * Constructs a new {@code GenericSignatureFormatError}.
+     *
+     */
+    public GenericSignatureFormatError() {
+        super();
+    }
+
+    /**
+     * Constructs a new {@code GenericSignatureFormatError} with the
+     * specified message.
+     *
+     * @param message the detail message, may be {@code null}
+     */
+    public GenericSignatureFormatError(String message) {
+        super(message);
+    }
+}
diff --git a/java/lang/reflect/InvocationHandler.java b/java/lang/reflect/InvocationHandler.java
new file mode 100644
index 0000000..c35e460
--- /dev/null
+++ b/java/lang/reflect/InvocationHandler.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999, 2006, 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.reflect;
+
+/**
+ * {@code InvocationHandler} is the interface implemented by
+ * the <i>invocation handler</i> of a proxy instance.
+ *
+ * <p>Each proxy instance has an associated invocation handler.
+ * When a method is invoked on a proxy instance, the method
+ * invocation is encoded and dispatched to the {@code invoke}
+ * method of its invocation handler.
+ *
+ * @author      Peter Jones
+ * @see         Proxy
+ * @since       1.3
+ */
+public interface InvocationHandler {
+
+    /**
+     * Processes a method invocation on a proxy instance and returns
+     * the result.  This method will be invoked on an invocation handler
+     * when a method is invoked on a proxy instance that it is
+     * associated with.
+     *
+     * @param   proxy the proxy instance that the method was invoked on
+     *
+     * @param   method the {@code Method} instance corresponding to
+     * the interface method invoked on the proxy instance.  The declaring
+     * class of the {@code Method} object will be the interface that
+     * the method was declared in, which may be a superinterface of the
+     * proxy interface that the proxy class inherits the method through.
+     *
+     * @param   args an array of objects containing the values of the
+     * arguments passed in the method invocation on the proxy instance,
+     * or {@code null} if interface method takes no arguments.
+     * Arguments of primitive types are wrapped in instances of the
+     * appropriate primitive wrapper class, such as
+     * {@code java.lang.Integer} or {@code java.lang.Boolean}.
+     *
+     * @return  the value to return from the method invocation on the
+     * proxy instance.  If the declared return type of the interface
+     * method is a primitive type, then the value returned by
+     * this method must be an instance of the corresponding primitive
+     * wrapper class; otherwise, it must be a type assignable to the
+     * declared return type.  If the value returned by this method is
+     * {@code null} and the interface method's return type is
+     * primitive, then a {@code NullPointerException} will be
+     * thrown by the method invocation on the proxy instance.  If the
+     * value returned by this method is otherwise not compatible with
+     * the interface method's declared return type as described above,
+     * a {@code ClassCastException} will be thrown by the method
+     * invocation on the proxy instance.
+     *
+     * @throws  Throwable the exception to throw from the method
+     * invocation on the proxy instance.  The exception's type must be
+     * assignable either to any of the exception types declared in the
+     * {@code throws} clause of the interface method or to the
+     * unchecked exception types {@code java.lang.RuntimeException}
+     * or {@code java.lang.Error}.  If a checked exception is
+     * thrown by this method that is not assignable to any of the
+     * exception types declared in the {@code throws} clause of
+     * the interface method, then an
+     * {@link UndeclaredThrowableException} containing the
+     * exception that was thrown by this method will be thrown by the
+     * method invocation on the proxy instance.
+     *
+     * @see     UndeclaredThrowableException
+     */
+    public Object invoke(Object proxy, Method method, Object[] args)
+        throws Throwable;
+}
diff --git a/java/lang/reflect/InvocationTargetException.java b/java/lang/reflect/InvocationTargetException.java
new file mode 100644
index 0000000..360d0ba
--- /dev/null
+++ b/java/lang/reflect/InvocationTargetException.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1996, 2004, 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.reflect;
+
+/**
+ * InvocationTargetException is a checked exception that wraps
+ * an exception thrown by an invoked method or constructor.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism.  The "target exception"
+ * that is provided at construction time and accessed via the
+ * {@link #getTargetException()} method is now known as the <i>cause</i>,
+ * and may be accessed via the {@link Throwable#getCause()} method,
+ * as well as the aforementioned "legacy method."
+ *
+ * @see Method
+ * @see Constructor
+ */
+public class InvocationTargetException extends ReflectiveOperationException {
+    /**
+     * Use serialVersionUID from JDK 1.1.X for interoperability
+     */
+    private static final long serialVersionUID = 4085088731926701167L;
+
+     /**
+     * This field holds the target if the
+     * InvocationTargetException(Throwable target) constructor was
+     * used to instantiate the object
+     *
+     * @serial
+     *
+     */
+    private Throwable target;
+
+    /**
+     * Constructs an {@code InvocationTargetException} with
+     * {@code null} as the target exception.
+     */
+    protected InvocationTargetException() {
+        super((Throwable)null);  // Disallow initCause
+    }
+
+    /**
+     * Constructs a InvocationTargetException with a target exception.
+     *
+     * @param target the target exception
+     */
+    public InvocationTargetException(Throwable target) {
+        super((Throwable)null);  // Disallow initCause
+        this.target = target;
+    }
+
+    /**
+     * Constructs a InvocationTargetException with a target exception
+     * and a detail message.
+     *
+     * @param target the target exception
+     * @param s      the detail message
+     */
+    public InvocationTargetException(Throwable target, String s) {
+        super(s, null);  // Disallow initCause
+        this.target = target;
+    }
+
+    /**
+     * Get the thrown target exception.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the thrown target exception (cause of this exception).
+     */
+    public Throwable getTargetException() {
+        return target;
+    }
+
+    /**
+     * Returns the cause of this exception (the thrown target exception,
+     * which may be {@code null}).
+     *
+     * @return  the cause of this exception.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return target;
+    }
+}
diff --git a/java/lang/reflect/MalformedParameterizedTypeException.java b/java/lang/reflect/MalformedParameterizedTypeException.java
new file mode 100644
index 0000000..a9efc55
--- /dev/null
+++ b/java/lang/reflect/MalformedParameterizedTypeException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003, 2008, 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.reflect;
+
+/**
+ * Thrown when a semantically malformed parameterized type is
+ * encountered by a reflective method that needs to instantiate it.
+ * For example, if the number of type arguments to a parameterized type
+ * is wrong.
+ *
+ * @since 1.5
+ */
+public class MalformedParameterizedTypeException extends RuntimeException {
+    private static final long serialVersionUID = -5696557788586220964L;
+}
diff --git a/java/lang/reflect/MalformedParametersException.java b/java/lang/reflect/MalformedParametersException.java
new file mode 100644
index 0000000..7479624
--- /dev/null
+++ b/java/lang/reflect/MalformedParametersException.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 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.reflect;
+
+/**
+ * Thrown when {@link java.lang.reflect.Executable#getParameters the
+ * java.lang.reflect package} attempts to read method parameters from
+ * a class file and determines that one or more parameters are
+ * malformed.
+ *
+ * <p>The following is a list of conditions under which this exception
+ * can be thrown:
+ * <ul>
+ * <li> The number of parameters (parameter_count) is wrong for the method
+ * <li> A constant pool index is out of bounds.
+ * <li> A constant pool index does not refer to a UTF-8 entry
+ * <li> A parameter's name is "", or contains an illegal character
+ * <li> The flags field contains an illegal flag (something other than
+ *     FINAL, SYNTHETIC, or MANDATED)
+ * </ul>
+ *
+ * See {@link java.lang.reflect.Executable#getParameters} for more
+ * information.
+ *
+ * @see java.lang.reflect.Executable#getParameters
+ * @since 1.8
+ */
+public class MalformedParametersException extends RuntimeException {
+
+    /**
+     * Version for serialization.
+     */
+    private static final long serialVersionUID = 20130919L;
+
+    /**
+     * Create a {@code MalformedParametersException} with an empty
+     * reason.
+     */
+    public MalformedParametersException() {}
+
+    /**
+     * Create a {@code MalformedParametersException}.
+     *
+     * @param reason The reason for the exception.
+     */
+    public MalformedParametersException(String reason) {
+        super(reason);
+    }
+}
diff --git a/java/lang/reflect/Member.annotated.java b/java/lang/reflect/Member.annotated.java
new file mode 100644
index 0000000..0552ce2
--- /dev/null
+++ b/java/lang/reflect/Member.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Member {
+
[email protected] public java.lang.Class<?> getDeclaringClass();
+
[email protected] public java.lang.String getName();
+
+public int getModifiers();
+
+public boolean isSynthetic();
+
+public static final int DECLARED = 1; // 0x1
+
+public static final int PUBLIC = 0; // 0x0
+}
+
diff --git a/java/lang/reflect/Member.java b/java/lang/reflect/Member.java
new file mode 100644
index 0000000..2241d45
--- /dev/null
+++ b/java/lang/reflect/Member.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1996, 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.reflect;
+
+/**
+ * Member is an interface that reflects identifying information about
+ * a single member (a field or a method) or a constructor.
+ *
+ * @see java.lang.Class
+ * @see Field
+ * @see Method
+ * @see Constructor
+ *
+ * @author Nakul Saraiya
+ */
+public
+interface Member {
+
+    /**
+     * Identifies the set of all public members of a class or interface,
+     * including inherited members.
+     */
+    public static final int PUBLIC = 0;
+
+    /**
+     * Identifies the set of declared members of a class or interface.
+     * Inherited members are not included.
+     */
+    public static final int DECLARED = 1;
+
+    /**
+     * Returns the Class object representing the class or interface
+     * that declares the member or constructor represented by this Member.
+     *
+     * @return an object representing the declaring class of the
+     * underlying member
+     */
+    public Class<?> getDeclaringClass();
+
+    /**
+     * Returns the simple name of the underlying member or constructor
+     * represented by this Member.
+     *
+     * @return the simple name of the underlying member
+     */
+    public String getName();
+
+    /**
+     * Returns the Java language modifiers for the member or
+     * constructor represented by this Member, as an integer.  The
+     * Modifier class should be used to decode the modifiers in
+     * the integer.
+     *
+     * @return the Java language modifiers for the underlying member
+     * @see Modifier
+     */
+    public int getModifiers();
+
+    /**
+     * Returns {@code true} if this member was introduced by
+     * the compiler; returns {@code false} otherwise.
+     *
+     * @return true if and only if this member was introduced by
+     * the compiler.
+     * @jls 13.1 The Form of a Binary
+     * @since 1.5
+     */
+    public boolean isSynthetic();
+}
diff --git a/java/lang/reflect/Method.annotated.java b/java/lang/reflect/Method.annotated.java
new file mode 100644
index 0000000..004a5ed
--- /dev/null
+++ b/java/lang/reflect/Method.annotated.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Method extends java.lang.reflect.Executable {
+
+Method() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getReturnType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getGenericReturnType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?>[] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Class<?>[] getExceptionTypes();
+
[email protected] public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object invoke(@libcore.util.Nullable java.lang.Object obj, [email protected] Object @libcore.util.Nullable ... args) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+
+public boolean isBridge() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isDefault() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object getDefaultValue();
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Method.java b/java/lang/reflect/Method.java
new file mode 100644
index 0000000..3da75c5
--- /dev/null
+++ b/java/lang/reflect/Method.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+import sun.reflect.CallerSensitive;
+import dalvik.annotation.optimization.FastNative;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+import libcore.reflect.Types;
+import libcore.util.EmptyArray;
+
+/**
+ * A {@code Method} provides information about, and access to, a single method
+ * on a class or interface.  The reflected method may be a class method
+ * or an instance method (including an abstract method).
+ *
+ * <p>A {@code Method} permits widening conversions to occur when matching the
+ * actual parameters to invoke with the underlying method's formal
+ * parameters, but it throws an {@code IllegalArgumentException} if a
+ * narrowing conversion would occur.
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getMethod(String, Class[])
+ * @see java.lang.Class#getDeclaredMethods()
+ * @see java.lang.Class#getDeclaredMethod(String, Class[])
+ *
+ * @author Kenneth Russell
+ * @author Nakul Saraiya
+ */
+public final class Method extends Executable  {
+    // Android-changed: Extensive modifications made throughout the class for ART.
+    // Android-changed: Many fields and methods removed / modified.
+    // Android-removed: Type annotations runtime code. Not supported on Android.
+    // Android-removed: Declared vs actual parameter annotation indexes handling.
+
+    /**
+     * Orders methods by their name, parameters and return type.
+     *
+     * @hide
+     */
+    public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
+        @Override public int compare(Method a, Method b) {
+            if (a == b) {
+                return 0;
+            }
+            int comparison = a.getName().compareTo(b.getName());
+            if (comparison == 0) {
+                comparison = a.compareMethodParametersInternal(b);
+                if (comparison == 0) {
+                    // This is necessary for methods that have covariant return types.
+                    Class<?> aReturnType = a.getReturnType();
+                    Class<?> bReturnType = b.getReturnType();
+                    if (aReturnType == bReturnType) {
+                        comparison = 0;
+                    } else {
+                        comparison = aReturnType.getName().compareTo(bReturnType.getName());
+                    }
+                }
+            }
+            return comparison;
+        }
+    };
+
+    private Method() {
+    }
+
+    @Override
+    boolean hasGenericInformation() {
+        // Android-changed: hasGenericInformation() implemented using Executable.
+        return super.hasGenericInformationInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<?> getDeclaringClass() {
+        // Android-changed: getDeclaringClass() implemented using Executable.
+        return super.getDeclaringClassInternal();
+    }
+
+    /**
+     * Returns the name of the method represented by this {@code Method}
+     * object, as a {@code String}.
+     */
+    @Override
+    public String getName() {
+        // Android-changed: getName() implemented using Executable.
+        return getMethodNameInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getModifiers() {
+        // Android-changed: getModifiers() implemented using Executable.
+        return super.getModifiersInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public TypeVariable<Method>[] getTypeParameters() {
+        // Android-changed: getTypeParameters() partly implemented using Executable.
+        GenericInfo info = getMethodOrConstructorGenericInfoInternal();
+        return (TypeVariable<Method>[]) info.formalTypeParameters.clone();
+    }
+
+    /**
+     * Returns a {@code Class} object that represents the formal return type
+     * of the method represented by this {@code Method} object.
+     *
+     * @return the return type for the method this object represents
+     */
+    public Class<?> getReturnType() {
+        // Android-changed: getReturnType() implemented using Executable.
+        return getMethodReturnTypeInternal();
+    }
+
+    /**
+     * Returns a {@code Type} object that represents the formal return
+     * type of the method represented by this {@code Method} object.
+     *
+     * <p>If the return type is a parameterized type,
+     * the {@code Type} object returned must accurately reflect
+     * the actual type parameters used in the source code.
+     *
+     * <p>If the return type is a type variable or a parameterized type, it
+     * is created. Otherwise, it is resolved.
+     *
+     * @return  a {@code Type} object that represents the formal return
+     *     type of the underlying  method
+     * @throws GenericSignatureFormatError
+     *     if the generic method signature does not conform to the format
+     *     specified in
+     *     <cite>The Java&trade; Virtual Machine Specification</cite>
+     * @throws TypeNotPresentException if the underlying method's
+     *     return type refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if the
+     *     underlying method's return typed refers to a parameterized
+     *     type that cannot be instantiated for any reason
+     * @since 1.5
+     */
+    public Type getGenericReturnType() {
+        // Android-changed: getGenericReturnType() partly implemented using Executable.
+      return Types.getType(getMethodOrConstructorGenericInfoInternal().genericReturnType);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<?>[] getParameterTypes() {
+        // Android-changed: getParameterTypes() partly implemented using Executable.
+        Class<?>[] paramTypes = super.getParameterTypesInternal();
+        if (paramTypes == null) {
+            return EmptyArray.CLASS;
+        }
+
+        return paramTypes;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.8
+     */
+    public int getParameterCount() {
+        // Android-changed: getParameterTypes() implemented using Executable.
+        return super.getParameterCountInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @throws TypeNotPresentException {@inheritDoc}
+     * @throws MalformedParameterizedTypeException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Type[] getGenericParameterTypes() {
+        return super.getGenericParameterTypes();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    // Android-changed: getExceptionTypes() implemented natively.
+    @FastNative
+    public native Class<?>[] getExceptionTypes();
+
+    /**
+     * {@inheritDoc}
+     * @throws GenericSignatureFormatError {@inheritDoc}
+     * @throws TypeNotPresentException {@inheritDoc}
+     * @throws MalformedParameterizedTypeException {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Type[] getGenericExceptionTypes() {
+        return super.getGenericExceptionTypes();
+    }
+
+    /**
+     * Compares this {@code Method} against the specified object.  Returns
+     * true if the objects are the same.  Two {@code Methods} are the same if
+     * they were declared by the same class and have the same name
+     * and formal parameter types and return type.
+     */
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof Method) {
+            Method other = (Method)obj;
+            if ((getDeclaringClass() == other.getDeclaringClass())
+                && (getName() == other.getName())) {
+                // Android-changed: Use getReturnType() instead of deleted returnType field
+                if (!getReturnType().equals(other.getReturnType()))
+                    return false;
+                // Android-changed: Use getParameterTypes() instead of deleted parameterTypes field
+                return equalParamTypes(getParameterTypes(), other.getParameterTypes());
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hashcode for this {@code Method}.  The hashcode is computed
+     * as the exclusive-or of the hashcodes for the underlying
+     * method's declaring class name and the method's name.
+     */
+    public int hashCode() {
+        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+    }
+
+    /**
+     * Returns a string describing this {@code Method}.  The string is
+     * formatted as the method access modifiers, if any, followed by
+     * the method return type, followed by a space, followed by the
+     * class declaring the method, followed by a period, followed by
+     * the method name, followed by a parenthesized, comma-separated
+     * list of the method's formal parameter types. If the method
+     * throws checked exceptions, the parameter list is followed by a
+     * space, followed by the word throws followed by a
+     * comma-separated list of the thrown exception types.
+     * For example:
+     * <pre>
+     *    public boolean java.lang.Object.equals(java.lang.Object)
+     * </pre>
+     *
+     * <p>The access modifiers are placed in canonical order as
+     * specified by "The Java Language Specification".  This is
+     * {@code public}, {@code protected} or {@code private} first,
+     * and then other modifiers in the following order:
+     * {@code abstract}, {@code default}, {@code static}, {@code final},
+     * {@code synchronized}, {@code native}, {@code strictfp}.
+     *
+     * @return a string describing this {@code Method}
+     *
+     * @jls 8.4.3 Method Modifiers
+     */
+    public String toString() {
+        // Android-changed: Use getParameterTypes() / getExceptionTypes() instead of deleted fields
+        return sharedToString(Modifier.methodModifiers(),
+                              isDefault(),
+                              getParameterTypes(),
+                              getExceptionTypes());
+    }
+
+    @Override
+    void specificToStringHeader(StringBuilder sb) {
+        sb.append(getReturnType().getTypeName()).append(' ');
+        sb.append(getDeclaringClass().getTypeName()).append('.');
+        sb.append(getName());
+    }
+
+    /**
+     * Returns a string describing this {@code Method}, including
+     * type parameters.  The string is formatted as the method access
+     * modifiers, if any, followed by an angle-bracketed
+     * comma-separated list of the method's type parameters, if any,
+     * followed by the method's generic return type, followed by a
+     * space, followed by the class declaring the method, followed by
+     * a period, followed by the method name, followed by a
+     * parenthesized, comma-separated list of the method's generic
+     * formal parameter types.
+     *
+     * If this method was declared to take a variable number of
+     * arguments, instead of denoting the last parameter as
+     * "<tt><i>Type</i>[]</tt>", it is denoted as
+     * "<tt><i>Type</i>...</tt>".
+     *
+     * A space is used to separate access modifiers from one another
+     * and from the type parameters or return type.  If there are no
+     * type parameters, the type parameter list is elided; if the type
+     * parameter list is present, a space separates the list from the
+     * class name.  If the method is declared to throw exceptions, the
+     * parameter list is followed by a space, followed by the word
+     * throws followed by a comma-separated list of the generic thrown
+     * exception types.
+     *
+     * <p>The access modifiers are placed in canonical order as
+     * specified by "The Java Language Specification".  This is
+     * {@code public}, {@code protected} or {@code private} first,
+     * and then other modifiers in the following order:
+     * {@code abstract}, {@code default}, {@code static}, {@code final},
+     * {@code synchronized}, {@code native}, {@code strictfp}.
+     *
+     * @return a string describing this {@code Method},
+     * include type parameters
+     *
+     * @since 1.5
+     *
+     * @jls 8.4.3 Method Modifiers
+     */
+    @Override
+    public String toGenericString() {
+        return sharedToGenericString(Modifier.methodModifiers(), isDefault());
+    }
+
+    @Override
+    void specificToGenericStringHeader(StringBuilder sb) {
+        Type genRetType = getGenericReturnType();
+        sb.append(genRetType.getTypeName()).append(' ');
+        sb.append(getDeclaringClass().getTypeName()).append('.');
+        sb.append(getName());
+    }
+
+    /**
+     * Invokes the underlying method represented by this {@code Method}
+     * object, on the specified object with the specified parameters.
+     * Individual parameters are automatically unwrapped to match
+     * primitive formal parameters, and both primitive and reference
+     * parameters are subject to method invocation conversions as
+     * necessary.
+     *
+     * <p>If the underlying method is static, then the specified {@code obj}
+     * argument is ignored. It may be null.
+     *
+     * <p>If the number of formal parameters required by the underlying method is
+     * 0, the supplied {@code args} array may be of length 0 or null.
+     *
+     * <p>If the underlying method is an instance method, it is invoked
+     * using dynamic method lookup as documented in The Java Language
+     * Specification, Second Edition, section 15.12.4.4; in particular,
+     * overriding based on the runtime type of the target object will occur.
+     *
+     * <p>If the underlying method is static, the class that declared
+     * the method is initialized if it has not already been initialized.
+     *
+     * <p>If the method completes normally, the value it returns is
+     * returned to the caller of invoke; if the value has a primitive
+     * type, it is first appropriately wrapped in an object. However,
+     * if the value has the type of an array of a primitive type, the
+     * elements of the array are <i>not</i> wrapped in objects; in
+     * other words, an array of primitive type is returned.  If the
+     * underlying method return type is void, the invocation returns
+     * null.
+     *
+     * @param obj  the object the underlying method is invoked from
+     * @param args the arguments used for the method call
+     * @return the result of dispatching the method represented by
+     * this object on {@code obj} with parameters
+     * {@code args}
+     *
+     * @exception IllegalAccessException    if this {@code Method} object
+     *              is enforcing Java language access control and the underlying
+     *              method is inaccessible.
+     * @exception IllegalArgumentException  if the method is an
+     *              instance method and the specified object argument
+     *              is not an instance of the class or interface
+     *              declaring the underlying method (or of a subclass
+     *              or implementor thereof); if the number of actual
+     *              and formal parameters differ; if an unwrapping
+     *              conversion for primitive arguments fails; or if,
+     *              after possible unwrapping, a parameter value
+     *              cannot be converted to the corresponding formal
+     *              parameter type by a method invocation conversion.
+     * @exception InvocationTargetException if the underlying method
+     *              throws an exception.
+     * @exception NullPointerException      if the specified object is null
+     *              and the method is an instance method.
+     * @exception ExceptionInInitializerError if the initialization
+     * provoked by this method fails.
+     */
+    @CallerSensitive
+    // Android-changed: invoke(Object, Object...) implemented natively.
+    @FastNative
+    public native Object invoke(Object obj, Object... args)
+            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+
+    /**
+     * Returns {@code true} if this method is a bridge
+     * method; returns {@code false} otherwise.
+     *
+     * @return true if and only if this method is a bridge
+     * method as defined by the Java Language Specification.
+     * @since 1.5
+     */
+    public boolean isBridge() {
+        // Android-changed: isBridge() implemented using Executable.
+        return super.isBridgeMethodInternal();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public boolean isVarArgs() {
+        return super.isVarArgs();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @jls 13.1 The Form of a Binary
+     * @since 1.5
+     */
+    @Override
+    public boolean isSynthetic() {
+        return super.isSynthetic();
+    }
+
+    /**
+     * Returns {@code true} if this method is a default
+     * method; returns {@code false} otherwise.
+     *
+     * A default method is a public non-abstract instance method, that
+     * is, a non-static method with a body, declared in an interface
+     * type.
+     *
+     * @return true if and only if this method is a default
+     * method as defined by the Java Language Specification.
+     * @since 1.8
+     */
+    public boolean isDefault() {
+        // Android-changed: isDefault() implemented using Executable.
+        return super.isDefaultMethodInternal();
+    }
+
+    /**
+     * Returns the default value for the annotation member represented by
+     * this {@code Method} instance.  If the member is of a primitive type,
+     * an instance of the corresponding wrapper type is returned. Returns
+     * null if no default is associated with the member, or if the method
+     * instance does not represent a declared member of an annotation type.
+     *
+     * @return the default value for the annotation member represented
+     *     by this {@code Method} instance.
+     * @throws TypeNotPresentException if the annotation is of type
+     *     {@link Class} and no definition can be found for the
+     *     default class value.
+     * @since  1.5
+     */
+    // Android-changed: isDefault() implemented natively.
+    @FastNative
+    public native Object getDefaultValue();
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     * @since 1.5
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return super.getAnnotation(annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    public Annotation[] getDeclaredAnnotations()  {
+        return super.getDeclaredAnnotations();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.5
+     */
+    @Override
+    public Annotation[][] getParameterAnnotations() {
+        // Android-changed: getParameterAnnotations() implemented using Executable.
+        return super.getParameterAnnotationsInternal();
+    }
+
+    // Android-added: equalNameAndParameters(Method) for Proxy support.
+    /**
+     * Returns true if this and {@code method} have the same name and the same
+     * parameters in the same order. Such methods can share implementation if
+     * one method's return types is assignable to the other.
+     *
+     * @hide needed by Proxy
+     */
+    boolean equalNameAndParameters(Method m) {
+        return equalNameAndParametersInternal(m);
+    }
+}
diff --git a/java/lang/reflect/Modifier.java b/java/lang/reflect/Modifier.java
new file mode 100644
index 0000000..28d89bb
--- /dev/null
+++ b/java/lang/reflect/Modifier.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 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.reflect;
+
+/**
+ * The Modifier class provides {@code static} methods and
+ * constants to decode class and member access modifiers.  The sets of
+ * modifiers are represented as integers with distinct bit positions
+ * representing different modifiers.  The values for the constants
+ * representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of
+ * <cite>The Java&trade; Virtual Machine Specification</cite>.
+ *
+ * @see Class#getModifiers()
+ * @see Member#getModifiers()
+ *
+ * @author Nakul Saraiya
+ * @author Kenneth Russell
+ */
+public class Modifier {
+
+    // Android-removed: ReflectionFactory bootstrapping code not used on Android.
+    /*
+    /*
+     * Bootstrapping protocol between java.lang and java.lang.reflect
+     *  packages
+     *
+    static {
+        sun.reflect.ReflectionFactory factory =
+            AccessController.doPrivileged(
+                new ReflectionFactory.GetReflectionFactoryAction());
+        factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess());
+    }
+    */
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code public} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code public} modifier; {@code false} otherwise.
+     */
+    public static boolean isPublic(int mod) {
+        return (mod & PUBLIC) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code private} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code private} modifier; {@code false} otherwise.
+     */
+    public static boolean isPrivate(int mod) {
+        return (mod & PRIVATE) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code protected} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code protected} modifier; {@code false} otherwise.
+     */
+    public static boolean isProtected(int mod) {
+        return (mod & PROTECTED) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code static} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code static} modifier; {@code false} otherwise.
+     */
+    public static boolean isStatic(int mod) {
+        return (mod & STATIC) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code final} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code final} modifier; {@code false} otherwise.
+     */
+    public static boolean isFinal(int mod) {
+        return (mod & FINAL) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code synchronized} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code synchronized} modifier; {@code false} otherwise.
+     */
+    public static boolean isSynchronized(int mod) {
+        return (mod & SYNCHRONIZED) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code volatile} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code volatile} modifier; {@code false} otherwise.
+     */
+    public static boolean isVolatile(int mod) {
+        return (mod & VOLATILE) != 0;
+    }
+
+    // Android-added: isConstructor(int) to support DEX-defined modifier flag.
+    /**
+     * Returns true if the given modifiers contain {@link Modifier#CONSTRUCTOR}.
+     * @hide
+     */
+    public static boolean isConstructor(int modifiers) {
+        return ((modifiers & Modifier.CONSTRUCTOR) != 0);
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code transient} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code transient} modifier; {@code false} otherwise.
+     */
+    public static boolean isTransient(int mod) {
+        return (mod & TRANSIENT) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code native} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code native} modifier; {@code false} otherwise.
+     */
+    public static boolean isNative(int mod) {
+        return (mod & NATIVE) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code interface} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code interface} modifier; {@code false} otherwise.
+     */
+    public static boolean isInterface(int mod) {
+        return (mod & INTERFACE) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code abstract} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code abstract} modifier; {@code false} otherwise.
+     */
+    public static boolean isAbstract(int mod) {
+        return (mod & ABSTRACT) != 0;
+    }
+
+    /**
+     * Return {@code true} if the integer argument includes the
+     * {@code strictfp} modifier, {@code false} otherwise.
+     *
+     * @param   mod a set of modifiers
+     * @return {@code true} if {@code mod} includes the
+     * {@code strictfp} modifier; {@code false} otherwise.
+     */
+    public static boolean isStrict(int mod) {
+        return (mod & STRICT) != 0;
+    }
+
+    /**
+     * Return a string describing the access modifier flags in
+     * the specified modifier. For example:
+     * <blockquote><pre>
+     *    public final synchronized strictfp
+     * </pre></blockquote>
+     * The modifier names are returned in an order consistent with the
+     * suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of
+     * <cite>The Java&trade; Language Specification</cite>.
+     * The full modifier ordering used by this method is:
+     * <blockquote> {@code
+     * public protected private abstract static final transient
+     * volatile synchronized native strictfp
+     * interface } </blockquote>
+     * The {@code interface} modifier discussed in this class is
+     * not a true modifier in the Java language and it appears after
+     * all other modifiers listed by this method.  This method may
+     * return a string of modifiers that are not valid modifiers of a
+     * Java entity; in other words, no checking is done on the
+     * possible validity of the combination of modifiers represented
+     * by the input.
+     *
+     * Note that to perform such checking for a known kind of entity,
+     * such as a constructor or method, first AND the argument of
+     * {@code toString} with the appropriate mask from a method like
+     * {@link #constructorModifiers} or {@link #methodModifiers}.
+     *
+     * @param   mod a set of modifiers
+     * @return  a string representation of the set of modifiers
+     * represented by {@code mod}
+     */
+    public static String toString(int mod) {
+        StringBuilder sb = new StringBuilder();
+        int len;
+
+        if ((mod & PUBLIC) != 0)        sb.append("public ");
+        if ((mod & PROTECTED) != 0)     sb.append("protected ");
+        if ((mod & PRIVATE) != 0)       sb.append("private ");
+
+        /* Canonical order */
+        if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
+        if ((mod & STATIC) != 0)        sb.append("static ");
+        if ((mod & FINAL) != 0)         sb.append("final ");
+        if ((mod & TRANSIENT) != 0)     sb.append("transient ");
+        if ((mod & VOLATILE) != 0)      sb.append("volatile ");
+        if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
+        if ((mod & NATIVE) != 0)        sb.append("native ");
+        if ((mod & STRICT) != 0)        sb.append("strictfp ");
+        if ((mod & INTERFACE) != 0)     sb.append("interface ");
+
+        if ((len = sb.length()) > 0)    /* trim trailing space */
+            return sb.toString().substring(0, len-1);
+        return "";
+    }
+
+    /*
+     * Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of
+     * <cite>The Java&trade; Virtual Machine Specification</cite>
+     */
+
+    /**
+     * The {@code int} value representing the {@code public}
+     * modifier.
+     */
+    public static final int PUBLIC           = 0x00000001;
+
+    /**
+     * The {@code int} value representing the {@code private}
+     * modifier.
+     */
+    public static final int PRIVATE          = 0x00000002;
+
+    /**
+     * The {@code int} value representing the {@code protected}
+     * modifier.
+     */
+    public static final int PROTECTED        = 0x00000004;
+
+    /**
+     * The {@code int} value representing the {@code static}
+     * modifier.
+     */
+    public static final int STATIC           = 0x00000008;
+
+    /**
+     * The {@code int} value representing the {@code final}
+     * modifier.
+     */
+    public static final int FINAL            = 0x00000010;
+
+    /**
+     * The {@code int} value representing the {@code synchronized}
+     * modifier.
+     */
+    public static final int SYNCHRONIZED     = 0x00000020;
+
+    /**
+     * The {@code int} value representing the {@code volatile}
+     * modifier.
+     */
+    public static final int VOLATILE         = 0x00000040;
+
+    /**
+     * The {@code int} value representing the {@code transient}
+     * modifier.
+     */
+    public static final int TRANSIENT        = 0x00000080;
+
+    /**
+     * The {@code int} value representing the {@code native}
+     * modifier.
+     */
+    public static final int NATIVE           = 0x00000100;
+
+    /**
+     * The {@code int} value representing the {@code interface}
+     * modifier.
+     */
+    public static final int INTERFACE        = 0x00000200;
+
+    /**
+     * The {@code int} value representing the {@code abstract}
+     * modifier.
+     */
+    public static final int ABSTRACT         = 0x00000400;
+
+    /**
+     * The {@code int} value representing the {@code strictfp}
+     * modifier.
+     */
+    public static final int STRICT           = 0x00000800;
+
+    // Bits not (yet) exposed in the public API either because they
+    // have different meanings for fields and methods and there is no
+    // way to distinguish between the two in this class, or because
+    // they are not Java programming language keywords
+    static final int BRIDGE    = 0x00000040;
+    static final int VARARGS   = 0x00000080;
+    // Android-changed: SYNTHETIC made public for use in tests.
+    /**
+     * @hide
+     */
+    public static final int SYNTHETIC = 0x00001000;
+    static final int ANNOTATION  = 0x00002000;
+    static final int ENUM      = 0x00004000;
+    static final int MANDATED  = 0x00008000;
+    static boolean isSynthetic(int mod) {
+      return (mod & SYNTHETIC) != 0;
+    }
+
+    static boolean isMandated(int mod) {
+      return (mod & MANDATED) != 0;
+    }
+
+    // Note on the FOO_MODIFIERS fields and fooModifiers() methods:
+    // the sets of modifiers are not guaranteed to be constants
+    // across time and Java SE releases. Therefore, it would not be
+    // appropriate to expose an external interface to this information
+    // that would allow the values to be treated as Java-level
+    // constants since the values could be constant folded and updates
+    // to the sets of modifiers missed. Thus, the fooModifiers()
+    // methods return an unchanging values for a given release, but a
+    // value that can potentially change over time.
+
+    // Android-added: CONSTRUCTOR to support DEX-defined modifier flag.
+    /**
+     * Dex addition to mark instance constructors and static class
+     * initializer methods.
+     * @hide
+     */
+    public static final int CONSTRUCTOR = 0x10000;
+
+    // Android-added: DEFAULT to support DEX-defined modifier flag.
+    /**
+     * Default methods are marked with a synthetic access flag
+     * to speed up class loading and invocation target lookup.
+     * Implies INTERFACE, not-ABSTRACT, and not-STATIC.
+     *
+     * @hide
+     */
+    public static final int DEFAULT = 0x00400000;
+
+    /**
+     * The Java source modifiers that can be applied to a class.
+     * @jls 8.1.1 Class Modifiers
+     */
+    private static final int CLASS_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
+        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.FINAL   |
+        Modifier.STRICT;
+
+    /**
+     * The Java source modifiers that can be applied to an interface.
+     * @jls 9.1.1 Interface Modifiers
+     */
+    private static final int INTERFACE_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
+        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.STRICT;
+
+
+    /**
+     * The Java source modifiers that can be applied to a constructor.
+     * @jls 8.8.3 Constructor Modifiers
+     */
+    private static final int CONSTRUCTOR_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE;
+
+    /**
+     * The Java source modifiers that can be applied to a method.
+     * @jls8.4.3  Method Modifiers
+     */
+    private static final int METHOD_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
+        Modifier.ABSTRACT       | Modifier.STATIC       | Modifier.FINAL   |
+        Modifier.SYNCHRONIZED   | Modifier.NATIVE       | Modifier.STRICT;
+
+    /**
+     * The Java source modifiers that can be applied to a field.
+     * @jls 8.3.1  Field Modifiers
+     */
+    private static final int FIELD_MODIFIERS =
+        Modifier.PUBLIC         | Modifier.PROTECTED    | Modifier.PRIVATE |
+        Modifier.STATIC         | Modifier.FINAL        | Modifier.TRANSIENT |
+        Modifier.VOLATILE;
+
+    /**
+     * The Java source modifiers that can be applied to a method or constructor parameter.
+     * @jls 8.4.1 Formal Parameters
+     */
+    private static final int PARAMETER_MODIFIERS =
+        Modifier.FINAL;
+
+    /**
+     *
+     */
+    static final int ACCESS_MODIFIERS =
+        Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a class.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a class.
+     *
+     * @jls 8.1.1 Class Modifiers
+     * @since 1.7
+     */
+    public static int classModifiers() {
+        return CLASS_MODIFIERS;
+    }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to an interface.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to an interface.
+     *
+     * @jls 9.1.1 Interface Modifiers
+     * @since 1.7
+     */
+    public static int interfaceModifiers() {
+        return INTERFACE_MODIFIERS;
+    }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a constructor.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a constructor.
+     *
+     * @jls 8.8.3 Constructor Modifiers
+     * @since 1.7
+     */
+    public static int constructorModifiers() {
+        return CONSTRUCTOR_MODIFIERS;
+    }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a method.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a method.
+     *
+     * @jls 8.4.3 Method Modifiers
+     * @since 1.7
+     */
+    public static int methodModifiers() {
+        return METHOD_MODIFIERS;
+    }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a field.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a field.
+     *
+     * @jls 8.3.1 Field Modifiers
+     * @since 1.7
+     */
+    public static int fieldModifiers() {
+        return FIELD_MODIFIERS;
+    }
+
+    /**
+     * Return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a parameter.
+     * @return an {@code int} value OR-ing together the source language
+     * modifiers that can be applied to a parameter.
+     *
+     * @jls 8.4.1 Formal Parameters
+     * @since 1.8
+     */
+    public static int parameterModifiers() {
+        return PARAMETER_MODIFIERS;
+    }
+}
diff --git a/java/lang/reflect/Parameter.annotated.java b/java/lang/reflect/Parameter.annotated.java
new file mode 100644
index 0000000..247db53
--- /dev/null
+++ b/java/lang/reflect/Parameter.annotated.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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.reflect;
+
+import java.lang.annotation.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Parameter implements java.lang.reflect.AnnotatedElement {
+
+Parameter(java.lang.String name, int modifiers, java.lang.reflect.Executable executable, int index) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean isNamePresent() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Executable getDeclaringExecutable() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getParameterizedType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public boolean isImplicit() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Parameter.java b/java/lang/reflect/Parameter.java
new file mode 100644
index 0000000..4dc32b4
--- /dev/null
+++ b/java/lang/reflect/Parameter.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.annotation.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+
+/**
+ * Information about method parameters.
+ *
+ * A {@code Parameter} provides information about method parameters,
+ * including its name and modifiers.  It also provides an alternate
+ * means of obtaining attributes for the parameter.
+ *
+ * @since 1.8
+ */
+public final class Parameter implements AnnotatedElement {
+    // Android-changed: Extensive modifications made throughout the class for ART.
+    // Android-removed: Type annotations runtime code. Not supported on Android.
+    // Android-removed: Annotation retrieval is implemented natively in ART.
+
+    private final String name;
+    private final int modifiers;
+    private final Executable executable;
+    private final int index;
+
+    /**
+     * Package-private constructor for {@code Parameter}.
+     *
+     * If method parameter data is present in the classfile, then the
+     * JVM creates {@code Parameter} objects directly.  If it is
+     * absent, however, then {@code Executable} uses this constructor
+     * to synthesize them.
+     *
+     * @param name The name of the parameter.
+     * @param modifiers The modifier flags for the parameter.
+     * @param executable The executable which defines this parameter.
+     * @param index The index of the parameter.
+     */
+    Parameter(String name,
+              int modifiers,
+              Executable executable,
+              int index) {
+        this.name = name;
+        this.modifiers = modifiers;
+        this.executable = executable;
+        this.index = index;
+    }
+
+    /**
+     * Compares based on the executable and the index.
+     *
+     * @param obj The object to compare.
+     * @return Whether or not this is equal to the argument.
+     */
+    public boolean equals(Object obj) {
+        if(obj instanceof Parameter) {
+            Parameter other = (Parameter)obj;
+            return (other.executable.equals(executable) &&
+                    other.index == index);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code based on the executable's hash code and the
+     * index.
+     *
+     * @return A hash code based on the executable's hash code.
+     */
+    public int hashCode() {
+        return executable.hashCode() ^ index;
+    }
+
+    // Android-changed: Removed references in javadoc to the class file format.
+    /**
+     * Returns true if the parameter has a name; returns false otherwise.
+     * Whether a parameter has a name is determined by compiler options
+     * and whether the parameter is synthesized.
+     *
+     * @return true if and only if the parameter has a name
+     */
+    public boolean isNamePresent() {
+        return executable.hasRealParameterData() && name != null;
+    }
+
+    /**
+     * Returns a string describing this parameter.  The format is the
+     * modifiers for the parameter, if any, in canonical order as
+     * recommended by <cite>The Java&trade; Language
+     * Specification</cite>, followed by the fully- qualified type of
+     * the parameter (excluding the last [] if the parameter is
+     * variable arity), followed by "..." if the parameter is variable
+     * arity, followed by a space, followed by the name of the
+     * parameter.
+     *
+     * @return A string representation of the parameter and associated
+     * information.
+     */
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        final Type type = getParameterizedType();
+        final String typename = type.getTypeName();
+
+        sb.append(Modifier.toString(getModifiers()));
+
+        if(0 != modifiers)
+            sb.append(' ');
+
+        if(isVarArgs())
+            sb.append(typename.replaceFirst("\\[\\]$", "..."));
+        else
+            sb.append(typename);
+
+        sb.append(' ');
+        sb.append(getName());
+
+        return sb.toString();
+    }
+
+    /**
+     * Return the {@code Executable} which declares this parameter.
+     *
+     * @return The {@code Executable} declaring this parameter.
+     */
+    public Executable getDeclaringExecutable() {
+        return executable;
+    }
+
+    /**
+     * Get the modifier flags for this the parameter represented by
+     * this {@code Parameter} object.
+     *
+     * @return The modifier flags for this parameter.
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Returns the name of the parameter.  If the parameter's name is
+     * {@linkplain #isNamePresent() present}, then this method returns
+     * the name provided by the class file. Otherwise, this method
+     * synthesizes a name of the form argN, where N is the index of
+     * the parameter in the descriptor of the method which declares
+     * the parameter.
+     *
+     * @return The name of the parameter, either provided by the class
+     *         file or synthesized if the class file does not provide
+     *         a name.
+     */
+    public String getName() {
+        // Note: empty strings as paramete names are now outlawed.
+        // The .equals("") is for compatibility with current JVM
+        // behavior.  It may be removed at some point.
+        if(name == null || name.equals(""))
+            return "arg" + index;
+        else
+            return name;
+    }
+
+    // Package-private accessor to the real name field.
+    String getRealName() {
+        return name;
+    }
+
+    /**
+     * Returns a {@code Type} object that identifies the parameterized
+     * type for the parameter represented by this {@code Parameter}
+     * object.
+     *
+     * @return a {@code Type} object identifying the parameterized
+     * type of the parameter represented by this object
+     */
+    public Type getParameterizedType() {
+        Type tmp = parameterTypeCache;
+        if (null == tmp) {
+            tmp = executable.getAllGenericParameterTypes()[index];
+            parameterTypeCache = tmp;
+        }
+
+        return tmp;
+    }
+
+    private transient volatile Type parameterTypeCache = null;
+
+    /**
+     * Returns a {@code Class} object that identifies the
+     * declared type for the parameter represented by this
+     * {@code Parameter} object.
+     *
+     * @return a {@code Class} object identifying the declared
+     * type of the parameter represented by this object
+     */
+    public Class<?> getType() {
+        Class<?> tmp = parameterClassCache;
+        if (null == tmp) {
+            tmp = executable.getParameterTypes()[index];
+            parameterClassCache = tmp;
+        }
+        return tmp;
+    }
+
+    private transient volatile Class<?> parameterClassCache = null;
+
+    /**
+     * Returns {@code true} if this parameter is implicitly declared
+     * in source code; returns {@code false} otherwise.
+     *
+     * @return true if and only if this parameter is implicitly
+     * declared as defined by <cite>The Java&trade; Language
+     * Specification</cite>.
+     */
+    public boolean isImplicit() {
+        return Modifier.isMandated(getModifiers());
+    }
+
+    /**
+     * Returns {@code true} if this parameter is neither implicitly
+     * nor explicitly declared in source code; returns {@code false}
+     * otherwise.
+     *
+     * @jls 13.1 The Form of a Binary
+     * @return true if and only if this parameter is a synthetic
+     * construct as defined by
+     * <cite>The Java&trade; Language Specification</cite>.
+     */
+    public boolean isSynthetic() {
+        return Modifier.isSynthetic(getModifiers());
+    }
+
+    /**
+     * Returns {@code true} if this parameter represents a variable
+     * argument list; returns {@code false} otherwise.
+     *
+     * @return {@code true} if an only if this parameter represents a
+     * variable argument list.
+     */
+    public boolean isVarArgs() {
+        return executable.isVarArgs() &&
+            index == executable.getParameterCount() - 1;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Objects.requireNonNull(annotationClass);
+        // Android-changed: getAnnotation(Class) Uses native code to obtain annotation information.
+        return getAnnotationNative(executable, index, annotationClass);
+    }
+    // Android-added: getAnnotation(Class) Uses native code to obtain annotation information.
+    @FastNative
+    private static native <A extends Annotation> A getAnnotationNative(
+            Executable executable, int parameterIndex, Class<A> annotationType);
+
+    /**
+     * {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     */
+    @Override
+    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+        // Android-changed: getAnnotationsByType(Class), Android uses AnnotatedElements instead.
+        return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Annotation[] getDeclaredAnnotations() {
+        return executable.getParameterAnnotations()[index];
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+        // Only annotations on classes are inherited, for all other
+        // objects getDeclaredAnnotation is the same as
+        // getAnnotation.
+        return getAnnotation(annotationClass);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    @Override
+    public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+        // Only annotations on classes are inherited, for all other
+        // objects getDeclaredAnnotations is the same as
+        // getAnnotations.
+        return getAnnotationsByType(annotationClass);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Annotation[] getAnnotations() {
+        return getDeclaredAnnotations();
+    }
+
+}
diff --git a/java/lang/reflect/ParameterizedType.annotated.java b/java/lang/reflect/ParameterizedType.annotated.java
new file mode 100644
index 0000000..1502d68
--- /dev/null
+++ b/java/lang/reflect/ParameterizedType.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface ParameterizedType extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getActualTypeArguments();
+
[email protected] public java.lang.reflect.Type getRawType();
+
[email protected] public java.lang.reflect.Type getOwnerType();
+}
diff --git a/java/lang/reflect/ParameterizedType.java b/java/lang/reflect/ParameterizedType.java
new file mode 100644
index 0000000..a1b1398
--- /dev/null
+++ b/java/lang/reflect/ParameterizedType.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+/**
+ * ParameterizedType represents a parameterized type such as
+ * Collection&lt;String&gt;.
+ *
+ * <p>A parameterized type is created the first time it is needed by a
+ * reflective method, as specified in this package. When a
+ * parameterized type p is created, the generic type declaration that
+ * p instantiates is resolved, and all type arguments of p are created
+ * recursively. See {@link java.lang.reflect.TypeVariable
+ * TypeVariable} for details on the creation process for type
+ * variables. Repeated creation of a parameterized type has no effect.
+ *
+ * <p>Instances of classes that implement this interface must implement
+ * an equals() method that equates any two instances that share the
+ * same generic type declaration and have equal type parameters.
+ *
+ * @since 1.5
+ */
+public interface ParameterizedType extends Type {
+    /**
+     * Returns an array of {@code Type} objects representing the actual type
+     * arguments to this type.
+     *
+     * <p>Note that in some cases, the returned array be empty. This can occur
+     * if this type represents a non-parameterized type nested within
+     * a parameterized type.
+     *
+     * @return an array of {@code Type} objects representing the actual type
+     *     arguments to this type
+     * @throws TypeNotPresentException if any of the
+     *     actual type arguments refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if any of the
+     *     actual type parameters refer to a parameterized type that cannot
+     *     be instantiated for any reason
+     * @since 1.5
+     */
+    Type[] getActualTypeArguments();
+
+    /**
+     * Returns the {@code Type} object representing the class or interface
+     * that declared this type.
+     *
+     * @return the {@code Type} object representing the class or interface
+     *     that declared this type
+     * @since 1.5
+     */
+    Type getRawType();
+
+    /**
+     * Returns a {@code Type} object representing the type that this type
+     * is a member of.  For example, if this type is {@code O<T>.I<S>},
+     * return a representation of {@code O<T>}.
+     *
+     * <p>If this type is a top-level type, {@code null} is returned.
+     *
+     * @return a {@code Type} object representing the type that
+     *     this type is a member of. If this type is a top-level type,
+     *     {@code null} is returned
+     * @throws TypeNotPresentException if the owner type
+     *     refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if the owner type
+     *     refers to a parameterized type that cannot be instantiated
+     *     for any reason
+     * @since 1.5
+     */
+    Type getOwnerType();
+}
diff --git a/java/lang/reflect/Proxy.annotated.java b/java/lang/reflect/Proxy.annotated.java
new file mode 100644
index 0000000..eb396c7
--- /dev/null
+++ b/java/lang/reflect/Proxy.annotated.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 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.reflect;
+
+import java.security.Permission;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy implements java.io.Serializable {
+
+protected Proxy(@libcore.util.NonNull java.lang.reflect.InvocationHandler h) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Class<?> getProxyClass(@libcore.util.Nullable java.lang.ClassLoader loader, [email protected] Class<?> @libcore.util.NonNull ... interfaces) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newProxyInstance(@libcore.util.Nullable java.lang.ClassLoader loader, [email protected] Class<?> @libcore.util.NonNull [] interfaces, @libcore.util.NonNull java.lang.reflect.InvocationHandler h) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean isProxyClass(@libcore.util.NonNull java.lang.Class<?> cl) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.reflect.InvocationHandler getInvocationHandler(@libcore.util.NonNull java.lang.Object proxy) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.reflect.InvocationHandler h;
+}
diff --git a/java/lang/reflect/Proxy.java b/java/lang/reflect/Proxy.java
new file mode 100644
index 0000000..584d568
--- /dev/null
+++ b/java/lang/reflect/Proxy.java
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 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.reflect;
+
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiFunction;
+import libcore.util.EmptyArray;
+import sun.reflect.CallerSensitive;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
+
+/**
+ * {@code Proxy} provides static methods for creating dynamic proxy
+ * classes and instances, and it is also the superclass of all
+ * dynamic proxy classes created by those methods.
+ *
+ * <p>To create a proxy for some interface {@code Foo}:
+ * <pre>
+ *     InvocationHandler handler = new MyInvocationHandler(...);
+ *     Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
+ *     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
+ *                     newInstance(handler);
+ * </pre>
+ * or more simply:
+ * <pre>
+ *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
+ *                                          new Class&lt;?&gt;[] { Foo.class },
+ *                                          handler);
+ * </pre>
+ *
+ * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
+ * class</i> below) is a class that implements a list of interfaces
+ * specified at runtime when the class is created, with behavior as
+ * described below.
+ *
+ * A <i>proxy interface</i> is such an interface that is implemented
+ * by a proxy class.
+ *
+ * A <i>proxy instance</i> is an instance of a proxy class.
+ *
+ * Each proxy instance has an associated <i>invocation handler</i>
+ * object, which implements the interface {@link InvocationHandler}.
+ * A method invocation on a proxy instance through one of its proxy
+ * interfaces will be dispatched to the {@link InvocationHandler#invoke
+ * invoke} method of the instance's invocation handler, passing the proxy
+ * instance, a {@code java.lang.reflect.Method} object identifying
+ * the method that was invoked, and an array of type {@code Object}
+ * containing the arguments.  The invocation handler processes the
+ * encoded method invocation as appropriate and the result that it
+ * returns will be returned as the result of the method invocation on
+ * the proxy instance.
+ *
+ * <p>A proxy class has the following properties:
+ *
+ * <ul>
+ * <li>Proxy classes are <em>public, final, and not abstract</em> if
+ * all proxy interfaces are public.</li>
+ *
+ * <li>Proxy classes are <em>non-public, final, and not abstract</em> if
+ * any of the proxy interfaces is non-public.</li>
+ *
+ * <li>The unqualified name of a proxy class is unspecified.  The space
+ * of class names that begin with the string {@code "$Proxy"}
+ * should be, however, reserved for proxy classes.
+ *
+ * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
+ *
+ * <li>A proxy class implements exactly the interfaces specified at its
+ * creation, in the same order.
+ *
+ * <li>If a proxy class implements a non-public interface, then it will
+ * be defined in the same package as that interface.  Otherwise, the
+ * package of a proxy class is also unspecified.  Note that package
+ * sealing will not prevent a proxy class from being successfully defined
+ * in a particular package at runtime, and neither will classes already
+ * defined by the same class loader and the same package with particular
+ * signers.
+ *
+ * <li>Since a proxy class implements all of the interfaces specified at
+ * its creation, invoking {@code getInterfaces} on its
+ * {@code Class} object will return an array containing the same
+ * list of interfaces (in the order specified at its creation), invoking
+ * {@code getMethods} on its {@code Class} object will return
+ * an array of {@code Method} objects that include all of the
+ * methods in those interfaces, and invoking {@code getMethod} will
+ * find methods in the proxy interfaces as would be expected.
+ *
+ * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
+ * return true if it is passed a proxy class-- a class returned by
+ * {@code Proxy.getProxyClass} or the class of an object returned by
+ * {@code Proxy.newProxyInstance}-- and false otherwise.
+ *
+ * <li>The {@code java.security.ProtectionDomain} of a proxy class
+ * is the same as that of system classes loaded by the bootstrap class
+ * loader, such as {@code java.lang.Object}, because the code for a
+ * proxy class is generated by trusted system code.  This protection
+ * domain will typically be granted
+ * {@code java.security.AllPermission}.
+ *
+ * <li>Each proxy class has one public constructor that takes one argument,
+ * an implementation of the interface {@link InvocationHandler}, to set
+ * the invocation handler for a proxy instance.  Rather than having to use
+ * the reflection API to access the public constructor, a proxy instance
+ * can be also be created by calling the {@link Proxy#newProxyInstance
+ * Proxy.newProxyInstance} method, which combines the actions of calling
+ * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
+ * constructor with an invocation handler.
+ * </ul>
+ *
+ * <p>A proxy instance has the following properties:
+ *
+ * <ul>
+ * <li>Given a proxy instance {@code proxy} and one of the
+ * interfaces implemented by its proxy class {@code Foo}, the
+ * following expression will return true:
+ * <pre>
+ *     {@code proxy instanceof Foo}
+ * </pre>
+ * and the following cast operation will succeed (rather than throwing
+ * a {@code ClassCastException}):
+ * <pre>
+ *     {@code (Foo) proxy}
+ * </pre>
+ *
+ * <li>Each proxy instance has an associated invocation handler, the one
+ * that was passed to its constructor.  The static
+ * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
+ * will return the invocation handler associated with the proxy instance
+ * passed as its argument.
+ *
+ * <li>An interface method invocation on a proxy instance will be
+ * encoded and dispatched to the invocation handler's {@link
+ * InvocationHandler#invoke invoke} method as described in the
+ * documentation for that method.
+ *
+ * <li>An invocation of the {@code hashCode},
+ * {@code equals}, or {@code toString} methods declared in
+ * {@code java.lang.Object} on a proxy instance will be encoded and
+ * dispatched to the invocation handler's {@code invoke} method in
+ * the same manner as interface method invocations are encoded and
+ * dispatched, as described above.  The declaring class of the
+ * {@code Method} object passed to {@code invoke} will be
+ * {@code java.lang.Object}.  Other public methods of a proxy
+ * instance inherited from {@code java.lang.Object} are not
+ * overridden by a proxy class, so invocations of those methods behave
+ * like they do for instances of {@code java.lang.Object}.
+ * </ul>
+ *
+ * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
+ *
+ * <p>When two or more interfaces of a proxy class contain a method with
+ * the same name and parameter signature, the order of the proxy class's
+ * interfaces becomes significant.  When such a <i>duplicate method</i>
+ * is invoked on a proxy instance, the {@code Method} object passed
+ * to the invocation handler will not necessarily be the one whose
+ * declaring class is assignable from the reference type of the interface
+ * that the proxy's method was invoked through.  This limitation exists
+ * because the corresponding method implementation in the generated proxy
+ * class cannot determine which interface it was invoked through.
+ * Therefore, when a duplicate method is invoked on a proxy instance,
+ * the {@code Method} object for the method in the foremost interface
+ * that contains the method (either directly or inherited through a
+ * superinterface) in the proxy class's list of interfaces is passed to
+ * the invocation handler's {@code invoke} method, regardless of the
+ * reference type through which the method invocation occurred.
+ *
+ * <p>If a proxy interface contains a method with the same name and
+ * parameter signature as the {@code hashCode}, {@code equals},
+ * or {@code toString} methods of {@code java.lang.Object},
+ * when such a method is invoked on a proxy instance, the
+ * {@code Method} object passed to the invocation handler will have
+ * {@code java.lang.Object} as its declaring class.  In other words,
+ * the public, non-final methods of {@code java.lang.Object}
+ * logically precede all of the proxy interfaces for the determination of
+ * which {@code Method} object to pass to the invocation handler.
+ *
+ * <p>Note also that when a duplicate method is dispatched to an
+ * invocation handler, the {@code invoke} method may only throw
+ * checked exception types that are assignable to one of the exception
+ * types in the {@code throws} clause of the method in <i>all</i> of
+ * the proxy interfaces that it can be invoked through.  If the
+ * {@code invoke} method throws a checked exception that is not
+ * assignable to any of the exception types declared by the method in one
+ * of the proxy interfaces that it can be invoked through, then an
+ * unchecked {@code UndeclaredThrowableException} will be thrown by
+ * the invocation on the proxy instance.  This restriction means that not
+ * all of the exception types returned by invoking
+ * {@code getExceptionTypes} on the {@code Method} object
+ * passed to the {@code invoke} method can necessarily be thrown
+ * successfully by the {@code invoke} method.
+ *
+ * @author      Peter Jones
+ * @see         InvocationHandler
+ * @since       1.3
+ */
+public class Proxy implements java.io.Serializable {
+
+    private static final long serialVersionUID = -2222568056686623797L;
+
+    /** parameter types of a proxy class constructor */
+    private static final Class<?>[] constructorParams =
+        { InvocationHandler.class };
+
+    /**
+     * a cache of proxy classes
+     */
+    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
+        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
+
+    /**
+     * the invocation handler for this proxy instance.
+     * @serial
+     */
+    protected InvocationHandler h;
+
+    /**
+     * Prohibits instantiation.
+     */
+    private Proxy() {
+    }
+
+    /**
+     * Constructs a new {@code Proxy} instance from a subclass
+     * (typically, a dynamic proxy class) with the specified value
+     * for its invocation handler.
+     *
+     * @param  h the invocation handler for this proxy instance
+     *
+     * @throws NullPointerException if the given invocation handler, {@code h},
+     *         is {@code null}.
+     */
+    protected Proxy(InvocationHandler h) {
+        Objects.requireNonNull(h);
+        this.h = h;
+    }
+
+    /**
+     * Returns the {@code java.lang.Class} object for a proxy class
+     * given a class loader and an array of interfaces.  The proxy class
+     * will be defined by the specified class loader and will implement
+     * all of the supplied interfaces.  If any of the given interfaces
+     * is non-public, the proxy class will be non-public. If a proxy class
+     * for the same permutation of interfaces has already been defined by the
+     * class loader, then the existing proxy class will be returned; otherwise,
+     * a proxy class for those interfaces will be generated dynamically
+     * and defined by the class loader.
+     *
+     * <p>There are several restrictions on the parameters that may be
+     * passed to {@code Proxy.getProxyClass}:
+     *
+     * <ul>
+     * <li>All of the {@code Class} objects in the
+     * {@code interfaces} array must represent interfaces, not
+     * classes or primitive types.
+     *
+     * <li>No two elements in the {@code interfaces} array may
+     * refer to identical {@code Class} objects.
+     *
+     * <li>All of the interface types must be visible by name through the
+     * specified class loader.  In other words, for class loader
+     * {@code cl} and every interface {@code i}, the following
+     * expression must be true:
+     * <pre>
+     *     Class.forName(i.getName(), false, cl) == i
+     * </pre>
+     *
+     * <li>All non-public interfaces must be in the same package;
+     * otherwise, it would not be possible for the proxy class to
+     * implement all of the interfaces, regardless of what package it is
+     * defined in.
+     *
+     * <li>For any set of member methods of the specified interfaces
+     * that have the same signature:
+     * <ul>
+     * <li>If the return type of any of the methods is a primitive
+     * type or void, then all of the methods must have that same
+     * return type.
+     * <li>Otherwise, one of the methods must have a return type that
+     * is assignable to all of the return types of the rest of the
+     * methods.
+     * </ul>
+     *
+     * <li>The resulting proxy class must not exceed any limits imposed
+     * on classes by the virtual machine.  For example, the VM may limit
+     * the number of interfaces that a class may implement to 65535; in
+     * that case, the size of the {@code interfaces} array must not
+     * exceed 65535.
+     * </ul>
+     *
+     * <p>If any of these restrictions are violated,
+     * {@code Proxy.getProxyClass} will throw an
+     * {@code IllegalArgumentException}.  If the {@code interfaces}
+     * array argument or any of its elements are {@code null}, a
+     * {@code NullPointerException} will be thrown.
+     *
+     * <p>Note that the order of the specified proxy interfaces is
+     * significant: two requests for a proxy class with the same combination
+     * of interfaces but in a different order will result in two distinct
+     * proxy classes.
+     *
+     * @param   loader the class loader to define the proxy class
+     * @param   interfaces the list of interfaces for the proxy class
+     *          to implement
+     * @return  a proxy class that is defined in the specified class loader
+     *          and that implements the specified interfaces
+     * @throws  IllegalArgumentException if any of the restrictions on the
+     *          parameters that may be passed to {@code getProxyClass}
+     *          are violated
+     * @throws  SecurityException if a security manager, <em>s</em>, is present
+     *          and any of the following conditions is met:
+     *          <ul>
+     *             <li> the given {@code loader} is {@code null} and
+     *             the caller's class loader is not {@code null} and the
+     *             invocation of {@link SecurityManager#checkPermission
+     *             s.checkPermission} with
+     *             {@code RuntimePermission("getClassLoader")} permission
+     *             denies access.</li>
+     *             <li> for each proxy interface, {@code intf},
+     *             the caller's class loader is not the same as or an
+     *             ancestor of the class loader for {@code intf} and
+     *             invocation of {@link SecurityManager#checkPackageAccess
+     *             s.checkPackageAccess()} denies access to {@code intf}.</li>
+     *          </ul>
+     * @throws  NullPointerException if the {@code interfaces} array
+     *          argument or any of its elements are {@code null}
+     */
+    @CallerSensitive
+    public static Class<?> getProxyClass(ClassLoader loader,
+                                         Class<?>... interfaces)
+        throws IllegalArgumentException
+    {
+        // BEGIN Android-changed: Excluded SecurityManager / permission checks.
+        /*
+        final Class<?>[] intfs = interfaces.clone();
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
+        }
+
+        return getProxyClass0(loader, intfs);
+        */
+
+        return getProxyClass0(loader, interfaces);
+        // END Android-changed: Excluded SecurityManager / permission checks.
+    }
+
+    // Android-removed: SecurityManager / permission check code.
+    /*
+    /*
+     * Check permissions required to create a Proxy class.
+     *
+     * To define a proxy class, it performs the access checks as in
+     * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
+     * 1. "getClassLoader" permission check if loader == null
+     * 2. checkPackageAccess on the interfaces it implements
+     *
+     * To get a constructor and new instance of a proxy class, it performs
+     * the package access check on the interfaces it implements
+     * as in Class.getConstructor.
+     *
+     * If an interface is non-public, the proxy class must be defined by
+     * the defining loader of the interface.  If the caller's class loader
+     * is not the same as the defining loader of the interface, the VM
+     * will throw IllegalAccessError when the generated proxy class is
+     * being defined via the defineClass0 method.
+     *
+    private static void checkProxyAccess(Class<?> caller,
+                                         ClassLoader loader,
+                                         Class<?>... interfaces)
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            ClassLoader ccl = caller.getClassLoader();
+            if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
+                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+            }
+            ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
+        }
+    }
+    */
+
+    /**
+     * Generate a proxy class.  Must call the checkProxyAccess method
+     * to perform permission checks before calling this.
+     */
+    private static Class<?> getProxyClass0(ClassLoader loader,
+                                           Class<?>... interfaces) {
+        if (interfaces.length > 65535) {
+            throw new IllegalArgumentException("interface limit exceeded");
+        }
+
+        // If the proxy class defined by the given loader implementing
+        // the given interfaces exists, this will simply return the cached copy;
+        // otherwise, it will create the proxy class via the ProxyClassFactory
+        return proxyClassCache.get(loader, interfaces);
+    }
+
+    /*
+     * a key used for proxy class with 0 implemented interfaces
+     */
+    private static final Object key0 = new Object();
+
+    /*
+     * Key1 and Key2 are optimized for the common use of dynamic proxies
+     * that implement 1 or 2 interfaces.
+     */
+
+    /*
+     * a key used for proxy class with 1 implemented interface
+     */
+    private static final class Key1 extends WeakReference<Class<?>> {
+        private final int hash;
+
+        Key1(Class<?> intf) {
+            super(intf);
+            this.hash = intf.hashCode();
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            Class<?> intf;
+            return this == obj ||
+                   obj != null &&
+                   obj.getClass() == Key1.class &&
+                   (intf = get()) != null &&
+                   intf == ((Key1) obj).get();
+        }
+    }
+
+    /*
+     * a key used for proxy class with 2 implemented interfaces
+     */
+    private static final class Key2 extends WeakReference<Class<?>> {
+        private final int hash;
+        private final WeakReference<Class<?>> ref2;
+
+        Key2(Class<?> intf1, Class<?> intf2) {
+            super(intf1);
+            hash = 31 * intf1.hashCode() + intf2.hashCode();
+            ref2 = new WeakReference<Class<?>>(intf2);
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            Class<?> intf1, intf2;
+            return this == obj ||
+                   obj != null &&
+                   obj.getClass() == Key2.class &&
+                   (intf1 = get()) != null &&
+                   intf1 == ((Key2) obj).get() &&
+                   (intf2 = ref2.get()) != null &&
+                   intf2 == ((Key2) obj).ref2.get();
+        }
+    }
+
+    /*
+     * a key used for proxy class with any number of implemented interfaces
+     * (used here for 3 or more only)
+     */
+    private static final class KeyX {
+        private final int hash;
+        private final WeakReference<Class<?>>[] refs;
+
+        @SuppressWarnings("unchecked")
+        KeyX(Class<?>[] interfaces) {
+            hash = Arrays.hashCode(interfaces);
+            refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
+            for (int i = 0; i < interfaces.length; i++) {
+                refs[i] = new WeakReference<>(interfaces[i]);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return this == obj ||
+                   obj != null &&
+                   obj.getClass() == KeyX.class &&
+                   equals(refs, ((KeyX) obj).refs);
+        }
+
+        private static boolean equals(WeakReference<Class<?>>[] refs1,
+                                      WeakReference<Class<?>>[] refs2) {
+            if (refs1.length != refs2.length) {
+                return false;
+            }
+            for (int i = 0; i < refs1.length; i++) {
+                Class<?> intf = refs1[i].get();
+                if (intf == null || intf != refs2[i].get()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * A function that maps an array of interfaces to an optimal key where
+     * Class objects representing interfaces are weakly referenced.
+     */
+    private static final class KeyFactory
+        implements BiFunction<ClassLoader, Class<?>[], Object>
+    {
+        @Override
+        public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
+            switch (interfaces.length) {
+                case 1: return new Key1(interfaces[0]); // the most frequent
+                case 2: return new Key2(interfaces[0], interfaces[1]);
+                case 0: return key0;
+                default: return new KeyX(interfaces);
+            }
+        }
+    }
+
+    // BEGIN Android-changed: How proxies are generated.
+    /**
+     * Orders methods by their name, parameters, return type and inheritance relationship.
+     *
+     * @hide
+     */
+    private static final Comparator<Method> ORDER_BY_SIGNATURE_AND_SUBTYPE = new Comparator<Method>() {
+        @Override public int compare(Method a, Method b) {
+            int comparison = Method.ORDER_BY_SIGNATURE.compare(a, b);
+            if (comparison != 0) {
+                return comparison;
+            }
+            Class<?> aClass = a.getDeclaringClass();
+            Class<?> bClass = b.getDeclaringClass();
+            if (aClass == bClass) {
+                return 0;
+            } else if (aClass.isAssignableFrom(bClass)) {
+                return 1;
+            } else if (bClass.isAssignableFrom(aClass)) {
+                return -1;
+            } else {
+                return 0;
+            }
+        }
+    };
+
+    /**
+     * A factory function that generates, defines and returns the proxy class given
+     * the ClassLoader and array of interfaces.
+     */
+    private static final class ProxyClassFactory
+        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
+    {
+        // prefix for all proxy class names
+        private static final String proxyClassNamePrefix = "$Proxy";
+
+        // next number to use for generation of unique proxy class names
+        private static final AtomicLong nextUniqueNumber = new AtomicLong();
+
+        @Override
+        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
+
+            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
+            for (Class<?> intf : interfaces) {
+                /*
+                 * Verify that the class loader resolves the name of this
+                 * interface to the same Class object.
+                 */
+                Class<?> interfaceClass = null;
+                try {
+                    interfaceClass = Class.forName(intf.getName(), false, loader);
+                } catch (ClassNotFoundException e) {
+                }
+                if (interfaceClass != intf) {
+                    throw new IllegalArgumentException(
+                        intf + " is not visible from class loader");
+                }
+                /*
+                 * Verify that the Class object actually represents an
+                 * interface.
+                 */
+                if (!interfaceClass.isInterface()) {
+                    throw new IllegalArgumentException(
+                        interfaceClass.getName() + " is not an interface");
+                }
+                /*
+                 * Verify that this interface is not a duplicate.
+                 */
+                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
+                    throw new IllegalArgumentException(
+                        "repeated interface: " + interfaceClass.getName());
+                }
+            }
+
+            String proxyPkg = null;     // package to define proxy class in
+            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
+
+            /*
+             * Record the package of a non-public proxy interface so that the
+             * proxy class will be defined in the same package.  Verify that
+             * all non-public proxy interfaces are in the same package.
+             */
+            for (Class<?> intf : interfaces) {
+                int flags = intf.getModifiers();
+                if (!Modifier.isPublic(flags)) {
+                    accessFlags = Modifier.FINAL;
+                    String name = intf.getName();
+                    int n = name.lastIndexOf('.');
+                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
+                    if (proxyPkg == null) {
+                        proxyPkg = pkg;
+                    } else if (!pkg.equals(proxyPkg)) {
+                        throw new IllegalArgumentException(
+                            "non-public interfaces from different packages");
+                    }
+                }
+            }
+
+            if (proxyPkg == null) {
+                // if no non-public proxy interfaces, use the default package.
+                proxyPkg = "";
+            }
+
+            {
+                // Android-changed: Generate the proxy directly instead of calling
+                // through to ProxyGenerator.
+                List<Method> methods = getMethods(interfaces);
+                Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
+                validateReturnTypes(methods);
+                List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
+
+                Method[] methodsArray = methods.toArray(new Method[methods.size()]);
+                Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
+
+                /*
+                 * Choose a name for the proxy class to generate.
+                 */
+                long num = nextUniqueNumber.getAndIncrement();
+                String proxyName = proxyPkg + proxyClassNamePrefix + num;
+
+                return generateProxy(proxyName, interfaces, loader, methodsArray,
+                                     exceptionsArray);
+            }
+        }
+    }
+
+    /**
+     * Remove methods that have the same name, parameters and return type. This
+     * computes the exceptions of each method; this is the intersection of the
+     * exceptions of equivalent methods.
+     *
+     * @param methods the methods to find exceptions for, ordered by name and
+     *     signature.
+     */
+    private static List<Class<?>[]> deduplicateAndGetExceptions(List<Method> methods) {
+        List<Class<?>[]> exceptions = new ArrayList<Class<?>[]>(methods.size());
+
+        for (int i = 0; i < methods.size(); ) {
+            Method method = methods.get(i);
+            Class<?>[] exceptionTypes = method.getExceptionTypes();
+
+            if (i > 0 && Method.ORDER_BY_SIGNATURE.compare(method, methods.get(i - 1)) == 0) {
+                exceptions.set(i - 1, intersectExceptions(exceptions.get(i - 1), exceptionTypes));
+                methods.remove(i);
+            } else {
+                exceptions.add(exceptionTypes);
+                i++;
+            }
+        }
+        return exceptions;
+    }
+
+    /**
+     * Returns the exceptions that are declared in both {@code aExceptions} and
+     * {@code bExceptions}. If an exception type in one array is a subtype of an
+     * exception from the other, the subtype is included in the intersection.
+     */
+    private static Class<?>[] intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions) {
+        if (aExceptions.length == 0 || bExceptions.length == 0) {
+            return EmptyArray.CLASS;
+        }
+        if (Arrays.equals(aExceptions, bExceptions)) {
+            return aExceptions;
+        }
+        Set<Class<?>> intersection = new HashSet<Class<?>>();
+        for (Class<?> a : aExceptions) {
+            for (Class<?> b : bExceptions) {
+                if (a.isAssignableFrom(b)) {
+                    intersection.add(b);
+                } else if (b.isAssignableFrom(a)) {
+                    intersection.add(a);
+                }
+            }
+        }
+        return intersection.toArray(new Class<?>[intersection.size()]);
+    }
+
+    /**
+     * Throws if any two methods in {@code methods} have the same name and
+     * parameters but incompatible return types.
+     *
+     * @param methods the methods to find exceptions for, ordered by name and
+     *     signature.
+     */
+    private static void validateReturnTypes(List<Method> methods) {
+        Method vs = null;
+        for (Method method : methods) {
+            if (vs == null || !vs.equalNameAndParameters(method)) {
+                vs = method; // this has a different name or parameters
+                continue;
+            }
+            Class<?> returnType = method.getReturnType();
+            Class<?> vsReturnType = vs.getReturnType();
+            if (returnType.isInterface() && vsReturnType.isInterface()) {
+                // all interfaces are mutually compatible
+            } else if (vsReturnType.isAssignableFrom(returnType)) {
+                vs = method; // the new return type is a subtype; use it instead
+            } else if (!returnType.isAssignableFrom(vsReturnType)) {
+                throw new IllegalArgumentException("proxied interface methods have incompatible "
+                        + "return types:\n  " + vs + "\n  " + method);
+            }
+        }
+    }
+
+    private static List<Method> getMethods(Class<?>[] interfaces) {
+        List<Method> result = new ArrayList<Method>();
+        try {
+            result.add(Object.class.getMethod("equals", Object.class));
+            result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
+            result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
+        } catch (NoSuchMethodException e) {
+            throw new AssertionError();
+        }
+
+        getMethodsRecursive(interfaces, result);
+        return result;
+    }
+
+    /**
+     * Fills {@code proxiedMethods} with the methods of {@code interfaces} and
+     * the interfaces they extend. May contain duplicates.
+     */
+    private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
+        for (Class<?> i : interfaces) {
+            getMethodsRecursive(i.getInterfaces(), methods);
+            Collections.addAll(methods, i.getDeclaredMethods());
+        }
+    }
+
+    @FastNative
+    private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
+                                                 ClassLoader loader, Method[] methods,
+                                                 Class<?>[][] exceptions);
+    // END Android-changed: How proxies are generated.
+
+
+    /**
+     * Returns an instance of a proxy class for the specified interfaces
+     * that dispatches method invocations to the specified invocation
+     * handler.
+     *
+     * <p>{@code Proxy.newProxyInstance} throws
+     * {@code IllegalArgumentException} for the same reasons that
+     * {@code Proxy.getProxyClass} does.
+     *
+     * @param   loader the class loader to define the proxy class
+     * @param   interfaces the list of interfaces for the proxy class
+     *          to implement
+     * @param   h the invocation handler to dispatch method invocations to
+     * @return  a proxy instance with the specified invocation handler of a
+     *          proxy class that is defined by the specified class loader
+     *          and that implements the specified interfaces
+     * @throws  IllegalArgumentException if any of the restrictions on the
+     *          parameters that may be passed to {@code getProxyClass}
+     *          are violated
+     * @throws  SecurityException if a security manager, <em>s</em>, is present
+     *          and any of the following conditions is met:
+     *          <ul>
+     *          <li> the given {@code loader} is {@code null} and
+     *               the caller's class loader is not {@code null} and the
+     *               invocation of {@link SecurityManager#checkPermission
+     *               s.checkPermission} with
+     *               {@code RuntimePermission("getClassLoader")} permission
+     *               denies access;</li>
+     *          <li> for each proxy interface, {@code intf},
+     *               the caller's class loader is not the same as or an
+     *               ancestor of the class loader for {@code intf} and
+     *               invocation of {@link SecurityManager#checkPackageAccess
+     *               s.checkPackageAccess()} denies access to {@code intf};</li>
+     *          <li> any of the given proxy interfaces is non-public and the
+     *               caller class is not in the same {@linkplain Package runtime package}
+     *               as the non-public interface and the invocation of
+     *               {@link SecurityManager#checkPermission s.checkPermission} with
+     *               {@code ReflectPermission("newProxyInPackage.{package name}")}
+     *               permission denies access.</li>
+     *          </ul>
+     * @throws  NullPointerException if the {@code interfaces} array
+     *          argument or any of its elements are {@code null}, or
+     *          if the invocation handler, {@code h}, is
+     *          {@code null}
+     */
+    @CallerSensitive
+    public static Object newProxyInstance(ClassLoader loader,
+                                          Class<?>[] interfaces,
+                                          InvocationHandler h)
+        throws IllegalArgumentException
+    {
+        Objects.requireNonNull(h);
+
+        final Class<?>[] intfs = interfaces.clone();
+        // Android-removed: SecurityManager calls
+        /*
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
+        }
+        */
+
+        /*
+         * Look up or generate the designated proxy class.
+         */
+        Class<?> cl = getProxyClass0(loader, intfs);
+
+        /*
+         * Invoke its constructor with the designated invocation handler.
+         */
+        try {
+            // Android-removed: SecurityManager / permission checks.
+            /*
+            if (sm != null) {
+                checkNewProxyPermission(Reflection.getCallerClass(), cl);
+            }
+            */
+
+            final Constructor<?> cons = cl.getConstructor(constructorParams);
+            final InvocationHandler ih = h;
+            if (!Modifier.isPublic(cl.getModifiers())) {
+                // BEGIN Android-removed: Excluded AccessController.doPrivileged call.
+                /*
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() {
+                        cons.setAccessible(true);
+                        return null;
+                    }
+                });
+                */
+
+                cons.setAccessible(true);
+                // END Android-removed: Excluded AccessController.doPrivileged call.
+            }
+            return cons.newInstance(new Object[]{h});
+        } catch (IllegalAccessException|InstantiationException e) {
+            throw new InternalError(e.toString(), e);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getCause();
+            if (t instanceof RuntimeException) {
+                throw (RuntimeException) t;
+            } else {
+                throw new InternalError(t.toString(), t);
+            }
+        } catch (NoSuchMethodException e) {
+            throw new InternalError(e.toString(), e);
+        }
+    }
+
+    // Android-removed: SecurityManager / permission checks.
+    /*
+    private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
+                ClassLoader ccl = caller.getClassLoader();
+                ClassLoader pcl = proxyClass.getClassLoader();
+
+                // do permission check if the caller is in a different runtime package
+                // of the proxy class
+                int n = proxyClass.getName().lastIndexOf('.');
+                String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
+
+                n = caller.getName().lastIndexOf('.');
+                String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
+
+                if (pcl != ccl || !pkg.equals(callerPkg)) {
+                    sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
+                }
+            }
+        }
+    }
+    */
+
+    /**
+     * Returns true if and only if the specified class was dynamically
+     * generated to be a proxy class using the {@code getProxyClass}
+     * method or the {@code newProxyInstance} method.
+     *
+     * <p>The reliability of this method is important for the ability
+     * to use it to make security decisions, so its implementation should
+     * not just test if the class in question extends {@code Proxy}.
+     *
+     * @param   cl the class to test
+     * @return  {@code true} if the class is a proxy class and
+     *          {@code false} otherwise
+     * @throws  NullPointerException if {@code cl} is {@code null}
+     */
+    public static boolean isProxyClass(Class<?> cl) {
+        return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
+    }
+
+    /**
+     * Returns the invocation handler for the specified proxy instance.
+     *
+     * @param   proxy the proxy instance to return the invocation handler for
+     * @return  the invocation handler for the proxy instance
+     * @throws  IllegalArgumentException if the argument is not a
+     *          proxy instance
+     * @throws  SecurityException if a security manager, <em>s</em>, is present
+     *          and the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the invocation handler
+     *          and invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the invocation
+     *          handler's class.
+     */
+    @CallerSensitive
+    public static InvocationHandler getInvocationHandler(Object proxy)
+        throws IllegalArgumentException
+    {
+        /*
+         * Verify that the object is actually a proxy instance.
+         */
+        if (!isProxyClass(proxy.getClass())) {
+            throw new IllegalArgumentException("not a proxy instance");
+        }
+
+        final Proxy p = (Proxy) proxy;
+        final InvocationHandler ih = p.h;
+        // Android-removed: SecurityManager / access checks.
+        /*
+        if (System.getSecurityManager() != null) {
+            Class<?> ihClass = ih.getClass();
+            Class<?> caller = Reflection.getCallerClass();
+            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
+                                                    ihClass.getClassLoader()))
+            {
+                ReflectUtil.checkPackageAccess(ihClass);
+            }
+        }
+        */
+
+        return ih;
+    }
+
+    // Android-added: Helper method invoke(Proxy, Method, Object[]) for ART native code.
+    private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
+        InvocationHandler h = proxy.h;
+        return h.invoke(proxy, method, args);
+    }
+}
diff --git a/java/lang/reflect/ReflectPermission.java b/java/lang/reflect/ReflectPermission.java
new file mode 100644
index 0000000..a5e5be1
--- /dev/null
+++ b/java/lang/reflect/ReflectPermission.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 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.reflect;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public final
+class ReflectPermission extends java.security.BasicPermission {
+
+    public ReflectPermission(String name) {
+        super(name);
+    }
+
+    public ReflectPermission(String name, String actions) {
+        super("", "");
+    }
+}
diff --git a/java/lang/reflect/Type.annotated.java b/java/lang/reflect/Type.annotated.java
new file mode 100644
index 0000000..f2b646b
--- /dev/null
+++ b/java/lang/reflect/Type.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Type {
+
[email protected] public default java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/reflect/Type.java b/java/lang/reflect/Type.java
new file mode 100644
index 0000000..eee7443
--- /dev/null
+++ b/java/lang/reflect/Type.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+/**
+ * Type is the common superinterface for all types in the Java
+ * programming language. These include raw types, parameterized types,
+ * array types, type variables and primitive types.
+ *
+ * @since 1.5
+ */
+public interface Type {
+    /**
+     * Returns a string describing this type, including information
+     * about any type parameters.
+     *
+     * @implSpec The default implementation calls {@code toString}.
+     *
+     * @return a string describing this type
+     * @since 1.8
+     */
+    default String getTypeName() {
+        return toString();
+    }
+}
diff --git a/java/lang/reflect/TypeVariable.annotated.java b/java/lang/reflect/TypeVariable.annotated.java
new file mode 100644
index 0000000..5654963
--- /dev/null
+++ b/java/lang/reflect/TypeVariable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getBounds();
+
[email protected] public D getGenericDeclaration();
+
[email protected] public java.lang.String getName();
+}
diff --git a/java/lang/reflect/TypeVariable.java b/java/lang/reflect/TypeVariable.java
new file mode 100644
index 0000000..4e29a94
--- /dev/null
+++ b/java/lang/reflect/TypeVariable.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2003, 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.reflect;
+
+/**
+ * TypeVariable is the common superinterface for type variables of kinds.
+ * A type variable is created the first time it is needed by a reflective
+ * method, as specified in this package.  If a type variable t is referenced
+ * by a type (i.e, class, interface or annotation type) T, and T is declared
+ * by the nth enclosing class of T (see JLS 8.1.2), then the creation of t
+ * requires the resolution (see JVMS 5) of the ith enclosing class of T,
+ * for i = 0 to n, inclusive. Creating a type variable must not cause the
+ * creation of its bounds. Repeated creation of a type variable has no effect.
+ *
+ * <p>Multiple objects may be instantiated at run-time to
+ * represent a given type variable. Even though a type variable is
+ * created only once, this does not imply any requirement to cache
+ * instances representing the type variable. However, all instances
+ * representing a type variable must be equal() to each other.
+ * As a consequence, users of type variables must not rely on the identity
+ * of instances of classes implementing this interface.
+ *
+ * @param <D> the type of generic declaration that declared the
+ * underlying type variable.
+ *
+ * @since 1.5
+ */
+// Android-changed: Removed support for type annotations at runtime.
+// Removed AnnotatedElement super-class.
+public interface TypeVariable<D extends GenericDeclaration> extends Type/*, AnnotatedElement*/ {
+    /**
+     * Returns an array of {@code Type} objects representing the
+     * upper bound(s) of this type variable.  Note that if no upper bound is
+     * explicitly declared, the upper bound is {@code Object}.
+     *
+     * <p>For each upper bound B: <ul> <li>if B is a parameterized
+     * type or a type variable, it is created, (see {@link
+     * java.lang.reflect.ParameterizedType ParameterizedType} for the
+     * details of the creation process for parameterized types).
+     * <li>Otherwise, B is resolved.  </ul>
+     *
+     * @throws TypeNotPresentException  if any of the
+     *     bounds refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if any of the
+     *     bounds refer to a parameterized type that cannot be instantiated
+     *     for any reason
+     * @return an array of {@code Type}s representing the upper
+     *     bound(s) of this type variable
+    */
+    Type[] getBounds();
+
+    /**
+     * Returns the {@code GenericDeclaration} object representing the
+     * generic declaration declared this type variable.
+     *
+     * @return the generic declaration declared for this type variable.
+     *
+     * @since 1.5
+     */
+    D getGenericDeclaration();
+
+    /**
+     * Returns the name of this type variable, as it occurs in the source code.
+     *
+     * @return the name of this type variable, as it appears in the source code
+     */
+    String getName();
+
+    // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
+    /*
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of
+     * types to denote the upper bounds of the type parameter represented by
+     * this TypeVariable. The order of the objects in the array corresponds to
+     * the order of the bounds in the declaration of the type parameter.
+     *
+     * Returns an array of length 0 if the type parameter declares no bounds.
+     *
+     * @return an array of objects representing the upper bounds of the type variable
+     * @since 1.8
+     *
+     AnnotatedType[] getAnnotatedBounds();
+    */
+}
diff --git a/java/lang/reflect/UndeclaredThrowableException.java b/java/lang/reflect/UndeclaredThrowableException.java
new file mode 100644
index 0000000..a585745
--- /dev/null
+++ b/java/lang/reflect/UndeclaredThrowableException.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999, 2006, 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.reflect;
+
+/**
+ * Thrown by a method invocation on a proxy instance if its invocation
+ * handler's {@link InvocationHandler#invoke invoke} method throws a
+ * checked exception (a {@code Throwable} that is not assignable
+ * to {@code RuntimeException} or {@code Error}) that
+ * is not assignable to any of the exception types declared in the
+ * {@code throws} clause of the method that was invoked on the
+ * proxy instance and dispatched to the invocation handler.
+ *
+ * <p>An {@code UndeclaredThrowableException} instance contains
+ * the undeclared checked exception that was thrown by the invocation
+ * handler, and it can be retrieved with the
+ * {@code getUndeclaredThrowable()} method.
+ * {@code UndeclaredThrowableException} extends
+ * {@code RuntimeException}, so it is an unchecked exception
+ * that wraps a checked exception.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to
+ * conform to the general purpose exception-chaining mechanism.  The
+ * "undeclared checked exception that was thrown by the invocation
+ * handler" that may be provided at construction time and accessed via
+ * the {@link #getUndeclaredThrowable()} method is now known as the
+ * <i>cause</i>, and may be accessed via the {@link
+ * Throwable#getCause()} method, as well as the aforementioned "legacy
+ * method."
+ *
+ * @author      Peter Jones
+ * @see         InvocationHandler
+ * @since       1.3
+ */
+public class UndeclaredThrowableException extends RuntimeException {
+    static final long serialVersionUID = 330127114055056639L;
+
+    /**
+     * the undeclared checked exception that was thrown
+     * @serial
+     */
+    private Throwable undeclaredThrowable;
+
+    /**
+     * Constructs an {@code UndeclaredThrowableException} with the
+     * specified {@code Throwable}.
+     *
+     * @param   undeclaredThrowable the undeclared checked exception
+     *          that was thrown
+     */
+    public UndeclaredThrowableException(Throwable undeclaredThrowable) {
+        super((Throwable) null);  // Disallow initCause
+        this.undeclaredThrowable = undeclaredThrowable;
+    }
+
+    /**
+     * Constructs an {@code UndeclaredThrowableException} with the
+     * specified {@code Throwable} and a detail message.
+     *
+     * @param   undeclaredThrowable the undeclared checked exception
+     *          that was thrown
+     * @param   s the detail message
+     */
+    public UndeclaredThrowableException(Throwable undeclaredThrowable,
+                                        String s)
+    {
+        super(s, null);  // Disallow initCause
+        this.undeclaredThrowable = undeclaredThrowable;
+    }
+
+    /**
+     * Returns the {@code Throwable} instance wrapped in this
+     * {@code UndeclaredThrowableException}, which may be {@code null}.
+     *
+     * <p>This method predates the general-purpose exception chaining facility.
+     * The {@link Throwable#getCause()} method is now the preferred means of
+     * obtaining this information.
+     *
+     * @return the undeclared checked exception that was thrown
+     */
+    public Throwable getUndeclaredThrowable() {
+        return undeclaredThrowable;
+    }
+
+    /**
+     * Returns the cause of this exception (the {@code Throwable}
+     * instance wrapped in this {@code UndeclaredThrowableException},
+     * which may be {@code null}).
+     *
+     * @return  the cause of this exception.
+     * @since   1.4
+     */
+    public Throwable getCause() {
+        return undeclaredThrowable;
+    }
+}
diff --git a/java/lang/reflect/WeakCache.java b/java/lang/reflect/WeakCache.java
new file mode 100644
index 0000000..4c28024
--- /dev/null
+++ b/java/lang/reflect/WeakCache.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 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.reflect;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * Cache mapping pairs of {@code (key, sub-key) -> value}. Keys and values are
+ * weakly but sub-keys are strongly referenced.  Keys are passed directly to
+ * {@link #get} method which also takes a {@code parameter}. Sub-keys are
+ * calculated from keys and parameters using the {@code subKeyFactory} function
+ * passed to the constructor. Values are calculated from keys and parameters
+ * using the {@code valueFactory} function passed to the constructor.
+ * Keys can be {@code null} and are compared by identity while sub-keys returned by
+ * {@code subKeyFactory} or values returned by {@code valueFactory}
+ * can not be null. Sub-keys are compared using their {@link #equals} method.
+ * Entries are expunged from cache lazily on each invocation to {@link #get},
+ * {@link #containsValue} or {@link #size} methods when the WeakReferences to
+ * keys are cleared. Cleared WeakReferences to individual values don't cause
+ * expunging, but such entries are logically treated as non-existent and
+ * trigger re-evaluation of {@code valueFactory} on request for their
+ * key/subKey.
+ *
+ * @author Peter Levart
+ * @param <K> type of keys
+ * @param <P> type of parameters
+ * @param <V> type of values
+ */
+final class WeakCache<K, P, V> {
+
+    private final ReferenceQueue<K> refQueue
+        = new ReferenceQueue<>();
+    // the key type is Object for supporting null key
+    private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
+        = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
+        = new ConcurrentHashMap<>();
+    private final BiFunction<K, P, ?> subKeyFactory;
+    private final BiFunction<K, P, V> valueFactory;
+
+    /**
+     * Construct an instance of {@code WeakCache}
+     *
+     * @param subKeyFactory a function mapping a pair of
+     *                      {@code (key, parameter) -> sub-key}
+     * @param valueFactory  a function mapping a pair of
+     *                      {@code (key, parameter) -> value}
+     * @throws NullPointerException if {@code subKeyFactory} or
+     *                              {@code valueFactory} is null.
+     */
+    public WeakCache(BiFunction<K, P, ?> subKeyFactory,
+                     BiFunction<K, P, V> valueFactory) {
+        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
+        this.valueFactory = Objects.requireNonNull(valueFactory);
+    }
+
+    /**
+     * Look-up the value through the cache. This always evaluates the
+     * {@code subKeyFactory} function and optionally evaluates
+     * {@code valueFactory} function if there is no entry in the cache for given
+     * pair of (key, subKey) or the entry has already been cleared.
+     *
+     * @param key       possibly null key
+     * @param parameter parameter used together with key to create sub-key and
+     *                  value (should not be null)
+     * @return the cached value (never null)
+     * @throws NullPointerException if {@code parameter} passed in or
+     *                              {@code sub-key} calculated by
+     *                              {@code subKeyFactory} or {@code value}
+     *                              calculated by {@code valueFactory} is null.
+     */
+    public V get(K key, P parameter) {
+        Objects.requireNonNull(parameter);
+
+        expungeStaleEntries();
+
+        Object cacheKey = CacheKey.valueOf(key, refQueue);
+
+        // lazily install the 2nd level valuesMap for the particular cacheKey
+        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
+        if (valuesMap == null) {
+            ConcurrentMap<Object, Supplier<V>> oldValuesMap
+                = map.putIfAbsent(cacheKey,
+                                  valuesMap = new ConcurrentHashMap<>());
+            if (oldValuesMap != null) {
+                valuesMap = oldValuesMap;
+            }
+        }
+
+        // create subKey and retrieve the possible Supplier<V> stored by that
+        // subKey from valuesMap
+        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
+        Supplier<V> supplier = valuesMap.get(subKey);
+        Factory factory = null;
+
+        while (true) {
+            if (supplier != null) {
+                // supplier might be a Factory or a CacheValue<V> instance
+                V value = supplier.get();
+                if (value != null) {
+                    return value;
+                }
+            }
+            // else no supplier in cache
+            // or a supplier that returned null (could be a cleared CacheValue
+            // or a Factory that wasn't successful in installing the CacheValue)
+
+            // lazily construct a Factory
+            if (factory == null) {
+                factory = new Factory(key, parameter, subKey, valuesMap);
+            }
+
+            if (supplier == null) {
+                supplier = valuesMap.putIfAbsent(subKey, factory);
+                if (supplier == null) {
+                    // successfully installed Factory
+                    supplier = factory;
+                }
+                // else retry with winning supplier
+            } else {
+                if (valuesMap.replace(subKey, supplier, factory)) {
+                    // successfully replaced
+                    // cleared CacheEntry / unsuccessful Factory
+                    // with our Factory
+                    supplier = factory;
+                } else {
+                    // retry with current supplier
+                    supplier = valuesMap.get(subKey);
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks whether the specified non-null value is already present in this
+     * {@code WeakCache}. The check is made using identity comparison regardless
+     * of whether value's class overrides {@link Object#equals} or not.
+     *
+     * @param value the non-null value to check
+     * @return true if given {@code value} is already cached
+     * @throws NullPointerException if value is null
+     */
+    public boolean containsValue(V value) {
+        Objects.requireNonNull(value);
+
+        expungeStaleEntries();
+        return reverseMap.containsKey(new LookupValue<>(value));
+    }
+
+    /**
+     * Returns the current number of cached entries that
+     * can decrease over time when keys/values are GC-ed.
+     */
+    public int size() {
+        expungeStaleEntries();
+        return reverseMap.size();
+    }
+
+    private void expungeStaleEntries() {
+        CacheKey<K> cacheKey;
+        while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
+            cacheKey.expungeFrom(map, reverseMap);
+        }
+    }
+
+    /**
+     * A factory {@link Supplier} that implements the lazy synchronized
+     * construction of the value and installment of it into the cache.
+     */
+    private final class Factory implements Supplier<V> {
+
+        private final K key;
+        private final P parameter;
+        private final Object subKey;
+        private final ConcurrentMap<Object, Supplier<V>> valuesMap;
+
+        Factory(K key, P parameter, Object subKey,
+                ConcurrentMap<Object, Supplier<V>> valuesMap) {
+            this.key = key;
+            this.parameter = parameter;
+            this.subKey = subKey;
+            this.valuesMap = valuesMap;
+        }
+
+        @Override
+        public synchronized V get() { // serialize access
+            // re-check
+            Supplier<V> supplier = valuesMap.get(subKey);
+            if (supplier != this) {
+                // something changed while we were waiting:
+                // might be that we were replaced by a CacheValue
+                // or were removed because of failure ->
+                // return null to signal WeakCache.get() to retry
+                // the loop
+                return null;
+            }
+            // else still us (supplier == this)
+
+            // create new value
+            V value = null;
+            try {
+                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
+            } finally {
+                if (value == null) { // remove us on failure
+                    valuesMap.remove(subKey, this);
+                }
+            }
+            // the only path to reach here is with non-null value
+            assert value != null;
+
+            // wrap value with CacheValue (WeakReference)
+            CacheValue<V> cacheValue = new CacheValue<>(value);
+
+            // try replacing us with CacheValue (this should always succeed)
+            if (valuesMap.replace(subKey, this, cacheValue)) {
+                // put also in reverseMap
+                reverseMap.put(cacheValue, Boolean.TRUE);
+            } else {
+                throw new AssertionError("Should not reach here");
+            }
+
+            // successfully replaced us with new CacheValue -> return the value
+            // wrapped by it
+            return value;
+        }
+    }
+
+    /**
+     * Common type of value suppliers that are holding a referent.
+     * The {@link #equals} and {@link #hashCode} of implementations is defined
+     * to compare the referent by identity.
+     */
+    private interface Value<V> extends Supplier<V> {}
+
+    /**
+     * An optimized {@link Value} used to look-up the value in
+     * {@link WeakCache#containsValue} method so that we are not
+     * constructing the whole {@link CacheValue} just to look-up the referent.
+     */
+    private static final class LookupValue<V> implements Value<V> {
+        private final V value;
+
+        LookupValue(V value) {
+            this.value = value;
+        }
+
+        @Override
+        public V get() {
+            return value;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(value); // compare by identity
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj == this ||
+                   obj instanceof Value &&
+                   this.value == ((Value<?>) obj).get();  // compare by identity
+        }
+    }
+
+    /**
+     * A {@link Value} that weakly references the referent.
+     */
+    private static final class CacheValue<V>
+        extends WeakReference<V> implements Value<V>
+    {
+        private final int hash;
+
+        CacheValue(V value) {
+            super(value);
+            this.hash = System.identityHashCode(value); // compare by identity
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            V value;
+            return obj == this ||
+                   obj instanceof Value &&
+                   // cleared CacheValue is only equal to itself
+                   (value = get()) != null &&
+                   value == ((Value<?>) obj).get(); // compare by identity
+        }
+    }
+
+    /**
+     * CacheKey containing a weakly referenced {@code key}. It registers
+     * itself with the {@code refQueue} so that it can be used to expunge
+     * the entry when the {@link WeakReference} is cleared.
+     */
+    private static final class CacheKey<K> extends WeakReference<K> {
+
+        // a replacement for null keys
+        private static final Object NULL_KEY = new Object();
+
+        static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
+            return key == null
+                   // null key means we can't weakly reference it,
+                   // so we use a NULL_KEY singleton as cache key
+                   ? NULL_KEY
+                   // non-null key requires wrapping with a WeakReference
+                   : new CacheKey<>(key, refQueue);
+        }
+
+        private final int hash;
+
+        private CacheKey(K key, ReferenceQueue<K> refQueue) {
+            super(key, refQueue);
+            this.hash = System.identityHashCode(key);  // compare by identity
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            K key;
+            return obj == this ||
+                   obj != null &&
+                   obj.getClass() == this.getClass() &&
+                   // cleared CacheKey is only equal to itself
+                   (key = this.get()) != null &&
+                   // compare key by identity
+                   key == ((CacheKey<K>) obj).get();
+        }
+
+        void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
+                         ConcurrentMap<?, Boolean> reverseMap) {
+            // removing just by key is always safe here because after a CacheKey
+            // is cleared and enqueue-ed it is only equal to itself
+            // (see equals method)...
+            ConcurrentMap<?, ?> valuesMap = map.remove(this);
+            // remove also from reverseMap if needed
+            if (valuesMap != null) {
+                for (Object cacheValue : valuesMap.values()) {
+                    reverseMap.remove(cacheValue);
+                }
+            }
+        }
+    }
+}
diff --git a/java/lang/reflect/WildcardType.annotated.java b/java/lang/reflect/WildcardType.annotated.java
new file mode 100644
index 0000000..c8b90a0
--- /dev/null
+++ b/java/lang/reflect/WildcardType.annotated.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface WildcardType extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getUpperBounds();
+
+public [email protected] Type @libcore.util.NonNull [] getLowerBounds();
+}
diff --git a/java/lang/reflect/WildcardType.java b/java/lang/reflect/WildcardType.java
new file mode 100644
index 0000000..aa8e824
--- /dev/null
+++ b/java/lang/reflect/WildcardType.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+/**
+ * WildcardType represents a wildcard type expression, such as
+ * {@code ?}, {@code ? extends Number}, or {@code ? super Integer}.
+ *
+ * @since 1.5
+ */
+public interface WildcardType extends Type {
+    /**
+     * Returns an array of {@code Type} objects representing the  upper
+     * bound(s) of this type variable.  Note that if no upper bound is
+     * explicitly declared, the upper bound is {@code Object}.
+     *
+     * <p>For each upper bound B :
+     * <ul>
+     *  <li>if B is a parameterized type or a type variable, it is created,
+     *  (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
+     *  for the details of the creation process for parameterized types).
+     *  <li>Otherwise, B is resolved.
+     * </ul>
+     *
+     * @return an array of Types representing the upper bound(s) of this
+     *     type variable
+     * @throws TypeNotPresentException if any of the
+     *     bounds refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if any of the
+     *     bounds refer to a parameterized type that cannot be instantiated
+     *     for any reason
+     */
+    Type[] getUpperBounds();
+
+    /**
+     * Returns an array of {@code Type} objects representing the
+     * lower bound(s) of this type variable.  Note that if no lower bound is
+     * explicitly declared, the lower bound is the type of {@code null}.
+     * In this case, a zero length array is returned.
+     *
+     * <p>For each lower bound B :
+     * <ul>
+     *   <li>if B is a parameterized type or a type variable, it is created,
+     *  (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
+     *  for the details of the creation process for parameterized types).
+     *   <li>Otherwise, B is resolved.
+     * </ul>
+     *
+     * @return an array of Types representing the lower bound(s) of this
+     *     type variable
+     * @throws TypeNotPresentException if any of the
+     *     bounds refers to a non-existent type declaration
+     * @throws MalformedParameterizedTypeException if any of the
+     *     bounds refer to a parameterized type that cannot be instantiated
+     *     for any reason
+     */
+    Type[] getLowerBounds();
+    // one or many? Up to language spec; currently only one, but this API
+    // allows for generalization.
+}
diff --git a/java/lang/reflect/package-info.java b/java/lang/reflect/package-info.java
new file mode 100644
index 0000000..258a07e
--- /dev/null
+++ b/java/lang/reflect/package-info.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1998, 2006, 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.
+ */
+
+/**
+ * Provides classes and interfaces for obtaining reflective
+ * information about classes and objects.  Reflection allows
+ * programmatic access to information about the fields, methods and
+ * constructors of loaded classes, and the use of reflected fields,
+ * methods, and constructors to operate on their underlying
+ * counterparts, within security restrictions.
+ *
+ * <p>{@code AccessibleObject} allows suppression of access checks if
+ * the necessary {@code ReflectPermission} is available.
+ *
+ * <p>{@code Array} provides static methods to dynamically create and
+ * access arrays.
+ *
+ * <p>Classes in this package, along with {@code java.lang.Class}
+ * accommodate applications such as debuggers, interpreters, object
+ * inspectors, class browsers, and services such as Object
+ * Serialization and JavaBeans that need access to either the public
+ * members of a target object (based on its runtime class) or the
+ * members declared by a given class.
+ *
+ * @since JDK1.1
+ */
+package java.lang.reflect;