]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/UTF16.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / UTF16.java
old mode 100755 (executable)
new mode 100644 (file)
index 731a37d..03d6c7b
-//##header\r
-/**\r
- *******************************************************************************\r
- * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-\r
-package com.ibm.icu.text;\r
-\r
-import com.ibm.icu.impl.UCharacterProperty;\r
-import com.ibm.icu.impl.NormalizerImpl;\r
-\r
-/**\r
- * <p>\r
- * Standalone utility class providing UTF16 character conversions and indexing conversions.\r
- * </p>\r
- * <p>\r
- * Code that uses strings alone rarely need modification. By design, UTF-16 does not allow overlap,\r
- * so searching for strings is a safe operation. Similarly, concatenation is always safe.\r
- * Substringing is safe if the start and end are both on UTF-32 boundaries. In normal code, the\r
- * values for start and end are on those boundaries, since they arose from operations like\r
- * searching. If not, the nearest UTF-32 boundaries can be determined using <code>bounds()</code>.\r
- * </p>\r
- * <strong>Examples:</strong>\r
- * <p>\r
- * The following examples illustrate use of some of these methods.\r
- * \r
- * <pre>\r
- * // iteration forwards: Original\r
- * for (int i = 0; i &lt; s.length(); ++i) {\r
- *     char ch = s.charAt(i);\r
- *     doSomethingWith(ch);\r
- * }\r
- * \r
- * // iteration forwards: Changes for UTF-32\r
- * int ch;\r
- * for (int i = 0; i &lt; s.length(); i += UTF16.getCharCount(ch)) {\r
- *     ch = UTF16.charAt(s, i);\r
- *     doSomethingWith(ch);\r
- * }\r
- * \r
- * // iteration backwards: Original\r
- * for (int i = s.length() - 1; i &gt;= 0; --i) {\r
- *     char ch = s.charAt(i);\r
- *     doSomethingWith(ch);\r
- * }\r
- * \r
- * // iteration backwards: Changes for UTF-32\r
- * int ch;\r
- * for (int i = s.length() - 1; i &gt; 0; i -= UTF16.getCharCount(ch)) {\r
- *     ch = UTF16.charAt(s, i);\r
- *     doSomethingWith(ch);\r
- * }\r
- * </pre>\r
- * \r
- * <strong>Notes:</strong>\r
- * <ul>\r
- * <li> <strong>Naming:</strong> For clarity, High and Low surrogates are called <code>Lead</code>\r
- * and <code>Trail</code> in the API, which gives a better sense of their ordering in a string.\r
- * <code>offset16</code> and <code>offset32</code> are used to distinguish offsets to UTF-16\r
- * boundaries vs offsets to UTF-32 boundaries. <code>int char32</code> is used to contain UTF-32\r
- * characters, as opposed to <code>char16</code>, which is a UTF-16 code unit. </li>\r
- * <li> <strong>Roundtripping Offsets:</strong> You can always roundtrip from a UTF-32 offset to a\r
- * UTF-16 offset and back. Because of the difference in structure, you can roundtrip from a UTF-16\r
- * offset to a UTF-32 offset and back if and only if <code>bounds(string, offset16) != TRAIL</code>.\r
- * </li>\r
- * <li> <strong>Exceptions:</strong> The error checking will throw an exception if indices are out\r
- * of bounds. Other than than that, all methods will behave reasonably, even if unmatched surrogates\r
- * or out-of-bounds UTF-32 values are present. <code>UCharacter.isLegal()</code> can be used to\r
- * check for validity if desired. </li>\r
- * <li> <strong>Unmatched Surrogates:</strong> If the string contains unmatched surrogates, then\r
- * these are counted as one UTF-32 value. This matches their iteration behavior, which is vital. It\r
- * also matches common display practice as missing glyphs (see the Unicode Standard Section 5.4,\r
- * 5.5). </li>\r
- * <li> <strong>Optimization:</strong> The method implementations may need optimization if the\r
- * compiler doesn't fold static final methods. Since surrogate pairs will form an exceeding small\r
- * percentage of all the text in the world, the singleton case should always be optimized for. </li>\r
- * </ul>\r
- * \r
- * @author Mark Davis, with help from Markus Scherer\r
- * @stable ICU 2.1\r
- */\r
-\r
-public final class UTF16 {\r
-    // public variables ---------------------------------------------------\r
-\r
-    /**\r
-     * Value returned in <code><a href="#bounds(java.lang.String, int)">\r
-     * bounds()</a></code>.\r
-     * These values are chosen specifically so that it actually represents the position of the\r
-     * character [offset16 - (value >> 2), offset16 + (value & 3)]\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int SINGLE_CHAR_BOUNDARY = 1, LEAD_SURROGATE_BOUNDARY = 2,\r
-            TRAIL_SURROGATE_BOUNDARY = 5;\r
-\r
-    /**\r
-     * The lowest Unicode code point value.\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int CODEPOINT_MIN_VALUE = 0;\r
-\r
-    /**\r
-     * The highest Unicode code point value (scalar value) according to the Unicode Standard.\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int CODEPOINT_MAX_VALUE = 0x10ffff;\r
-\r
-    /**\r
-     * The minimum value for Supplementary code points\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int SUPPLEMENTARY_MIN_VALUE = 0x10000;\r
-\r
-    /**\r
-     * Lead surrogate minimum value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int LEAD_SURROGATE_MIN_VALUE = 0xD800;\r
-\r
-    /**\r
-     * Trail surrogate minimum value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int TRAIL_SURROGATE_MIN_VALUE = 0xDC00;\r
-\r
-    /**\r
-     * Lead surrogate maximum value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int LEAD_SURROGATE_MAX_VALUE = 0xDBFF;\r
-\r
-    /**\r
-     * Trail surrogate maximum value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int TRAIL_SURROGATE_MAX_VALUE = 0xDFFF;\r
-\r
-    /**\r
-     * Surrogate minimum value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int SURROGATE_MIN_VALUE = LEAD_SURROGATE_MIN_VALUE;\r
-\r
-    /**\r
-     * Maximum surrogate value\r
-     * \r
-     * @stable ICU 2.1\r
-     */\r
-    public static final int SURROGATE_MAX_VALUE = TRAIL_SURROGATE_MAX_VALUE;\r
-\r
-    /**\r
-     * Lead surrogate bitmask\r
-     */\r
-    private static final int LEAD_SURROGATE_BITMASK = 0xFFFFFC00;\r
-\r
-    /**\r
-     * Trail surrogate bitmask\r
-     */\r
-    private static final int TRAIL_SURROGATE_BITMASK = 0xFFFFFC00;\r
-\r
-    /**\r
-     * Surrogate bitmask\r
-     */\r
-    private static final int SURROGATE_BITMASK = 0xFFFFF800;\r
-\r
-    /**\r
-     * Lead surrogate bits\r
-     */\r
-    private static final int LEAD_SURROGATE_BITS = 0xD800;\r
-\r
-    /**\r
-     * Trail surrogate bits\r
-     */\r
-    private static final int TRAIL_SURROGATE_BITS = 0xDC00;\r
-\r
-    /**\r
-     * Surrogate bits\r
-     */\r
-    private static final int SURROGATE_BITS = 0xD800;\r
-\r
-    // constructor --------------------------------------------------------\r
-\r
-    // /CLOVER:OFF\r
-    /**\r
-     * Prevent instance from being created.\r
-     */\r
-    private UTF16() {\r
-    }\r
-\r
-    // /CLOVER:ON\r
-    // public method ------------------------------------------------------\r
-\r
-    /**\r
-     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with\r
-     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is\r
-     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">\r
-     * UCharacter.isLegal()</a></code>\r
-     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary\r
-     * character will be returned. If a complete supplementary character is not found the incomplete\r
-     * character will be returned\r
-     * \r
-     * @param source\r
-     *            array of UTF-16 chars\r
-     * @param offset16\r
-     *            UTF-16 offset to the start of the character.\r
-     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries\r
-     *         of that codepoint are the same as in <code>bounds32()</code>.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int charAt(String source, int offset16) {\r
-        char single = source.charAt(offset16);\r
-        if (single < LEAD_SURROGATE_MIN_VALUE) {\r
-            return single;\r
-        }\r
-        return _charAt(source, offset16, single);\r
-    }\r
-\r
-    private static int _charAt(String source, int offset16, char single) {\r
-        if (single > TRAIL_SURROGATE_MAX_VALUE) {\r
-            return single;\r
-        }\r
-\r
-        // Convert the UTF-16 surrogate pair if necessary.\r
-        // For simplicity in usage, and because the frequency of pairs is\r
-        // low, look both directions.\r
-\r
-        if (single <= LEAD_SURROGATE_MAX_VALUE) {\r
-            ++offset16;\r
-            if (source.length() != offset16) {\r
-                char trail = source.charAt(offset16);\r
-                if (trail >= TRAIL_SURROGATE_MIN_VALUE && trail <= TRAIL_SURROGATE_MAX_VALUE) {\r
-                    return UCharacterProperty.getRawSupplementary(single, trail);\r
-                }\r
-            }\r
-        } else {\r
-            --offset16;\r
-            if (offset16 >= 0) {\r
-                // single is a trail surrogate so\r
-                char lead = source.charAt(offset16);\r
-                if (lead >= LEAD_SURROGATE_MIN_VALUE && lead <= LEAD_SURROGATE_MAX_VALUE) {\r
-                    return UCharacterProperty.getRawSupplementary(lead, single);\r
-                }\r
-            }\r
-        }\r
-        return single; // return unmatched surrogate\r
-    }\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    /**\r
-     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with\r
-     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is\r
-     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">\r
-     * UCharacter.isLegal()</a></code>\r
-     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary\r
-     * character will be returned. If a complete supplementary character is not found the incomplete\r
-     * character will be returned\r
-     * \r
-     * @param source\r
-     *            array of UTF-16 chars\r
-     * @param offset16\r
-     *            UTF-16 offset to the start of the character.\r
-     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries\r
-     *         of that codepoint are the same as in <code>bounds32()</code>.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int charAt(CharSequence source, int offset16) {\r
-        char single = source.charAt(offset16);\r
-        if (single < UTF16.LEAD_SURROGATE_MIN_VALUE) {\r
-            return single;\r
-        }\r
-        return _charAt(source, offset16, single);\r
-    }\r
-\r
-    private static int _charAt(CharSequence source, int offset16, char single) {\r
-        if (single > UTF16.TRAIL_SURROGATE_MAX_VALUE) {\r
-            return single;\r
-        }\r
-\r
-        // Convert the UTF-16 surrogate pair if necessary.\r
-        // For simplicity in usage, and because the frequency of pairs is\r
-        // low, look both directions.\r
-\r
-        if (single <= UTF16.LEAD_SURROGATE_MAX_VALUE) {\r
-            ++offset16;\r
-            if (source.length() != offset16) {\r
-                char trail = source.charAt(offset16);\r
-                if (trail >= UTF16.TRAIL_SURROGATE_MIN_VALUE\r
-                        && trail <= UTF16.TRAIL_SURROGATE_MAX_VALUE) {\r
-                    return UCharacterProperty.getRawSupplementary(single, trail);\r
-                }\r
-            }\r
-        } else {\r
-            --offset16;\r
-            if (offset16 >= 0) {\r
-                // single is a trail surrogate so\r
-                char lead = source.charAt(offset16);\r
-                if (lead >= UTF16.LEAD_SURROGATE_MIN_VALUE\r
-                        && lead <= UTF16.LEAD_SURROGATE_MAX_VALUE) {\r
-                    return UCharacterProperty.getRawSupplementary(lead, single);\r
-                }\r
-            }\r
-        }\r
-        return single; // return unmatched surrogate\r
-    }\r
-\r
-//#endif\r
-\r
-    /**\r
-     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with\r
-     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is\r
-     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()\r
-     * </a></code>\r
-     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary\r
-     * character will be returned. If a complete supplementary character is not found the incomplete\r
-     * character will be returned\r
-     * \r
-     * @param source\r
-     *            UTF-16 chars string buffer\r
-     * @param offset16\r
-     *            UTF-16 offset to the start of the character.\r
-     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries\r
-     *         of that codepoint are the same as in <code>bounds32()</code>.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int charAt(StringBuffer source, int offset16) {\r
-        if (offset16 < 0 || offset16 >= source.length()) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        char single = source.charAt(offset16);\r
-        if (!isSurrogate(single)) {\r
-            return single;\r
-        }\r
-\r
-        // Convert the UTF-16 surrogate pair if necessary.\r
-        // For simplicity in usage, and because the frequency of pairs is\r
-        // low, look both directions.\r
-\r
-        if (single <= LEAD_SURROGATE_MAX_VALUE) {\r
-            ++offset16;\r
-            if (source.length() != offset16) {\r
-                char trail = source.charAt(offset16);\r
-                if (isTrailSurrogate(trail))\r
-                    return UCharacterProperty.getRawSupplementary(single, trail);\r
-            }\r
-        } else {\r
-            --offset16;\r
-            if (offset16 >= 0) {\r
-                // single is a trail surrogate so\r
-                char lead = source.charAt(offset16);\r
-                if (isLeadSurrogate(lead)) {\r
-                    return UCharacterProperty.getRawSupplementary(lead, single);\r
-                }\r
-            }\r
-        }\r
-        return single; // return unmatched surrogate\r
-    }\r
-\r
-    /**\r
-     * Extract a single UTF-32 value from a substring. Used when iterating forwards or backwards\r
-     * (with <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is\r
-     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()\r
-     * </a></code>\r
-     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary\r
-     * character will be returned. If a complete supplementary character is not found the incomplete\r
-     * character will be returned\r
-     * \r
-     * @param source\r
-     *            array of UTF-16 chars\r
-     * @param start\r
-     *            offset to substring in the source array for analyzing\r
-     * @param limit\r
-     *            offset to substring in the source array for analyzing\r
-     * @param offset16\r
-     *            UTF-16 offset relative to start\r
-     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries\r
-     *         of that codepoint are the same as in <code>bounds32()</code>.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is not within the range of start and limit.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int charAt(char source[], int start, int limit, int offset16) {\r
-        offset16 += start;\r
-        if (offset16 < start || offset16 >= limit) {\r
-            throw new ArrayIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        char single = source[offset16];\r
-        if (!isSurrogate(single)) {\r
-            return single;\r
-        }\r
-\r
-        // Convert the UTF-16 surrogate pair if necessary.\r
-        // For simplicity in usage, and because the frequency of pairs is\r
-        // low, look both directions.\r
-        if (single <= LEAD_SURROGATE_MAX_VALUE) {\r
-            offset16++;\r
-            if (offset16 >= limit) {\r
-                return single;\r
-            }\r
-            char trail = source[offset16];\r
-            if (isTrailSurrogate(trail)) {\r
-                return UCharacterProperty.getRawSupplementary(single, trail);\r
-            }\r
-        } else { // isTrailSurrogate(single), so\r
-            if (offset16 == start) {\r
-                return single;\r
-            }\r
-            offset16--;\r
-            char lead = source[offset16];\r
-            if (isLeadSurrogate(lead))\r
-                return UCharacterProperty.getRawSupplementary(lead, single);\r
-        }\r
-        return single; // return unmatched surrogate\r
-    }\r
-\r
-    /**\r
-     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with\r
-     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is\r
-     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()\r
-     * </a></code>\r
-     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary\r
-     * character will be returned. If a complete supplementary character is not found the incomplete\r
-     * character will be returned\r
-     * \r
-     * @param source\r
-     *            UTF-16 chars string buffer\r
-     * @param offset16\r
-     *            UTF-16 offset to the start of the character.\r
-     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries\r
-     *         of that codepoint are the same as in <code>bounds32()</code>.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int charAt(Replaceable source, int offset16) {\r
-        if (offset16 < 0 || offset16 >= source.length()) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        char single = source.charAt(offset16);\r
-        if (!isSurrogate(single)) {\r
-            return single;\r
-        }\r
-\r
-        // Convert the UTF-16 surrogate pair if necessary.\r
-        // For simplicity in usage, and because the frequency of pairs is\r
-        // low, look both directions.\r
-\r
-        if (single <= LEAD_SURROGATE_MAX_VALUE) {\r
-            ++offset16;\r
-            if (source.length() != offset16) {\r
-                char trail = source.charAt(offset16);\r
-                if (isTrailSurrogate(trail))\r
-                    return UCharacterProperty.getRawSupplementary(single, trail);\r
-            }\r
-        } else {\r
-            --offset16;\r
-            if (offset16 >= 0) {\r
-                // single is a trail surrogate so\r
-                char lead = source.charAt(offset16);\r
-                if (isLeadSurrogate(lead)) {\r
-                    return UCharacterProperty.getRawSupplementary(lead, single);\r
-                }\r
-            }\r
-        }\r
-        return single; // return unmatched surrogate\r
-    }\r
-\r
-    /**\r
-     * Determines how many chars this char32 requires. If a validity check is required, use <code>\r
-     * <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code>\r
-     * on char32 before calling.\r
-     * \r
-     * @param char32\r
-     *            the input codepoint.\r
-     * @return 2 if is in supplementary space, otherwise 1.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int getCharCount(int char32) {\r
-        if (char32 < SUPPLEMENTARY_MIN_VALUE) {\r
-            return 1;\r
-        }\r
-        return 2;\r
-    }\r
-\r
-    /**\r
-     * Returns the type of the boundaries around the char at offset16. Used for random access.\r
-     * \r
-     * @param source\r
-     *            text to analyse\r
-     * @param offset16\r
-     *            UTF-16 offset\r
-     * @return\r
-     *            <ul>\r
-     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are [offset16, offset16+1]\r
-     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds\r
-     *            are [offset16, offset16 + 2]\r
-     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the\r
-     *            bounds are [offset16 - 1, offset16 + 1]\r
-     *            </ul>\r
-     *            For bit-twiddlers, the return values for these are chosen so that the boundaries\r
-     *            can be gotten by: [offset16 - (value >> 2), offset16 + (value & 3)].\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int bounds(String source, int offset16) {\r
-        char ch = source.charAt(offset16);\r
-        if (isSurrogate(ch)) {\r
-            if (isLeadSurrogate(ch)) {\r
-                if (++offset16 < source.length() && isTrailSurrogate(source.charAt(offset16))) {\r
-                    return LEAD_SURROGATE_BOUNDARY;\r
-                }\r
-            } else {\r
-                // isTrailSurrogate(ch), so\r
-                --offset16;\r
-                if (offset16 >= 0 && isLeadSurrogate(source.charAt(offset16))) {\r
-                    return TRAIL_SURROGATE_BOUNDARY;\r
-                }\r
-            }\r
-        }\r
-        return SINGLE_CHAR_BOUNDARY;\r
-    }\r
-\r
-    /**\r
-     * Returns the type of the boundaries around the char at offset16. Used for random access.\r
-     * \r
-     * @param source\r
-     *            string buffer to analyse\r
-     * @param offset16\r
-     *            UTF16 offset\r
-     * @return\r
-     *            <ul>\r
-     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are [offset16, offset16 + 1]\r
-     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds\r
-     *            are [offset16, offset16 + 2]\r
-     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the\r
-     *            bounds are [offset16 - 1, offset16 + 1]\r
-     *            </ul>\r
-     *            For bit-twiddlers, the return values for these are chosen so that the boundaries\r
-     *            can be gotten by: [offset16 - (value >> 2), offset16 + (value & 3)].\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int bounds(StringBuffer source, int offset16) {\r
-        char ch = source.charAt(offset16);\r
-        if (isSurrogate(ch)) {\r
-            if (isLeadSurrogate(ch)) {\r
-                if (++offset16 < source.length() && isTrailSurrogate(source.charAt(offset16))) {\r
-                    return LEAD_SURROGATE_BOUNDARY;\r
-                }\r
-            } else {\r
-                // isTrailSurrogate(ch), so\r
-                --offset16;\r
-                if (offset16 >= 0 && isLeadSurrogate(source.charAt(offset16))) {\r
-                    return TRAIL_SURROGATE_BOUNDARY;\r
-                }\r
-            }\r
-        }\r
-        return SINGLE_CHAR_BOUNDARY;\r
-    }\r
-\r
-    /**\r
-     * Returns the type of the boundaries around the char at offset16. Used for random access. Note\r
-     * that the boundaries are determined with respect to the subarray, hence the char array\r
-     * {0xD800, 0xDC00} has the result SINGLE_CHAR_BOUNDARY for start = offset16 = 0 and limit = 1.\r
-     * \r
-     * @param source\r
-     *            char array to analyse\r
-     * @param start\r
-     *            offset to substring in the source array for analyzing\r
-     * @param limit\r
-     *            offset to substring in the source array for analyzing\r
-     * @param offset16\r
-     *            UTF16 offset relative to start\r
-     * @return\r
-     *            <ul>\r
-     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are\r
-     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds\r
-     *            are [offset16, offset16 + 2]\r
-     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the\r
-     *            bounds are [offset16 - 1, offset16 + 1]\r
-     *            </ul>\r
-     *            For bit-twiddlers, the boundary values for these are chosen so that the boundaries\r
-     *            can be gotten by: [offset16 - (boundvalue >> 2), offset16 + (boundvalue & 3)].\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is not within the range of start and limit.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int bounds(char source[], int start, int limit, int offset16) {\r
-        offset16 += start;\r
-        if (offset16 < start || offset16 >= limit) {\r
-            throw new ArrayIndexOutOfBoundsException(offset16);\r
-        }\r
-        char ch = source[offset16];\r
-        if (isSurrogate(ch)) {\r
-            if (isLeadSurrogate(ch)) {\r
-                ++offset16;\r
-                if (offset16 < limit && isTrailSurrogate(source[offset16])) {\r
-                    return LEAD_SURROGATE_BOUNDARY;\r
-                }\r
-            } else { // isTrailSurrogate(ch), so\r
-                --offset16;\r
-                if (offset16 >= start && isLeadSurrogate(source[offset16])) {\r
-                    return TRAIL_SURROGATE_BOUNDARY;\r
-                }\r
-            }\r
-        }\r
-        return SINGLE_CHAR_BOUNDARY;\r
-    }\r
-\r
-    /**\r
-     * Determines whether the code value is a surrogate.\r
-     * \r
-     * @param char16\r
-     *            the input character.\r
-     * @return true iff the input character is a surrogate.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static boolean isSurrogate(char char16) {\r
-        return (char16 & SURROGATE_BITMASK) == SURROGATE_BITS;\r
-    }\r
-\r
-    /**\r
-     * Determines whether the character is a trail surrogate.\r
-     * \r
-     * @param char16\r
-     *            the input character.\r
-     * @return true iff the input character is a trail surrogate.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static boolean isTrailSurrogate(char char16) {\r
-        return (char16 & TRAIL_SURROGATE_BITMASK) == TRAIL_SURROGATE_BITS;\r
-    }\r
-\r
-    /**\r
-     * Determines whether the character is a lead surrogate.\r
-     * \r
-     * @param char16\r
-     *            the input character.\r
-     * @return true iff the input character is a lead surrogate\r
-     * @stable ICU 2.1\r
-     */\r
-    public static boolean isLeadSurrogate(char char16) {\r
-        return (char16 & LEAD_SURROGATE_BITMASK) == LEAD_SURROGATE_BITS;\r
-    }\r
-\r
-    /**\r
-     * Returns the lead surrogate. If a validity check is required, use\r
-     * <code><a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32\r
-     * before calling.\r
-     * \r
-     * @param char32\r
-     *            the input character.\r
-     * @return lead surrogate if the getCharCount(ch) is 2; <br>\r
-     *         and 0 otherwise (note: 0 is not a valid lead surrogate).\r
-     * @stable ICU 2.1\r
-     */\r
-    public static char getLeadSurrogate(int char32) {\r
-        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {\r
-            return (char) (LEAD_SURROGATE_OFFSET_ + (char32 >> LEAD_SURROGATE_SHIFT_));\r
-        }\r
-        return 0;\r
-    }\r
-\r
-    /**\r
-     * Returns the trail surrogate. If a validity check is required, use\r
-     * <code><a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32\r
-     * before calling.\r
-     * \r
-     * @param char32\r
-     *            the input character.\r
-     * @return the trail surrogate if the getCharCount(ch) is 2; <br>\r
-     *         otherwise the character itself\r
-     * @stable ICU 2.1\r
-     */\r
-    public static char getTrailSurrogate(int char32) {\r
-        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {\r
-            return (char) (TRAIL_SURROGATE_MIN_VALUE + (char32 & TRAIL_SURROGATE_MASK_));\r
-        }\r
-        return (char) char32;\r
-    }\r
-\r
-    /**\r
-     * Convenience method corresponding to String.valueOf(char). Returns a one or two char string\r
-     * containing the UTF-32 value in UTF16 format. If a validity check is required, use <a\r
-     * href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32 before calling.\r
-     * \r
-     * @param char32\r
-     *            the input character.\r
-     * @return string value of char32 in UTF16 format\r
-     * @exception IllegalArgumentException\r
-     *                thrown if char32 is a invalid codepoint.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static String valueOf(int char32) {\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Illegal codepoint");\r
-        }\r
-        return toString(char32);\r
-    }\r
-\r
-    /**\r
-     * Convenience method corresponding to String.valueOf(codepoint at offset16). Returns a one or\r
-     * two char string containing the UTF-32 value in UTF16 format. If offset16 indexes a surrogate\r
-     * character, the whole supplementary codepoint will be returned. If a validity check is\r
-     * required, use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on the\r
-     * codepoint at offset16 before calling. The result returned will be a newly created String\r
-     * obtained by calling source.substring(..) with the appropriate indexes.\r
-     * \r
-     * @param source\r
-     *            the input string.\r
-     * @param offset16\r
-     *            the UTF16 index to the codepoint in source\r
-     * @return string value of char32 in UTF16 format\r
-     * @stable ICU 2.1\r
-     */\r
-    public static String valueOf(String source, int offset16) {\r
-        switch (bounds(source, offset16)) {\r
-        case LEAD_SURROGATE_BOUNDARY:\r
-            return source.substring(offset16, offset16 + 2);\r
-        case TRAIL_SURROGATE_BOUNDARY:\r
-            return source.substring(offset16 - 1, offset16 + 1);\r
-        default:\r
-            return source.substring(offset16, offset16 + 1);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Convenience method corresponding to StringBuffer.valueOf(codepoint at offset16). Returns a\r
-     * one or two char string containing the UTF-32 value in UTF16 format. If offset16 indexes a\r
-     * surrogate character, the whole supplementary codepoint will be returned. If a validity check\r
-     * is required, use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on\r
-     * the codepoint at offset16 before calling. The result returned will be a newly created String\r
-     * obtained by calling source.substring(..) with the appropriate indexes.\r
-     * \r
-     * @param source\r
-     *            the input string buffer.\r
-     * @param offset16\r
-     *            the UTF16 index to the codepoint in source\r
-     * @return string value of char32 in UTF16 format\r
-     * @stable ICU 2.1\r
-     */\r
-    public static String valueOf(StringBuffer source, int offset16) {\r
-        switch (bounds(source, offset16)) {\r
-        case LEAD_SURROGATE_BOUNDARY:\r
-            return source.substring(offset16, offset16 + 2);\r
-        case TRAIL_SURROGATE_BOUNDARY:\r
-            return source.substring(offset16 - 1, offset16 + 1);\r
-        default:\r
-            return source.substring(offset16, offset16 + 1);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Convenience method. Returns a one or two char string containing the UTF-32 value in UTF16\r
-     * format. If offset16 indexes a surrogate character, the whole supplementary codepoint will be\r
-     * returned, except when either the leading or trailing surrogate character lies out of the\r
-     * specified subarray. In the latter case, only the surrogate character within bounds will be\r
-     * returned. If a validity check is required, use <a\r
-     * href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on the codepoint at\r
-     * offset16 before calling. The result returned will be a newly created String containing the\r
-     * relevant characters.\r
-     * \r
-     * @param source\r
-     *            the input char array.\r
-     * @param start\r
-     *            start index of the subarray\r
-     * @param limit\r
-     *            end index of the subarray\r
-     * @param offset16\r
-     *            the UTF16 index to the codepoint in source relative to start\r
-     * @return string value of char32 in UTF16 format\r
-     * @stable ICU 2.1\r
-     */\r
-    public static String valueOf(char source[], int start, int limit, int offset16) {\r
-        switch (bounds(source, start, limit, offset16)) {\r
-        case LEAD_SURROGATE_BOUNDARY:\r
-            return new String(source, start + offset16, 2);\r
-        case TRAIL_SURROGATE_BOUNDARY:\r
-            return new String(source, start + offset16 - 1, 2);\r
-        }\r
-        return new String(source, start + offset16, 1);\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See\r
-     * the <a name="_top_">class description</a> for notes on roundtripping.\r
-     * \r
-     * @param source\r
-     *            the UTF-16 string\r
-     * @param offset32\r
-     *            UTF-32 offset\r
-     * @return UTF-16 offset\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset32 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findOffsetFromCodePoint(String source, int offset32) {\r
-        char ch;\r
-        int size = source.length(), result = 0, count = offset32;\r
-        if (offset32 < 0 || offset32 > size) {\r
-            throw new StringIndexOutOfBoundsException(offset32);\r
-        }\r
-        while (result < size && count > 0) {\r
-            ch = source.charAt(result);\r
-            if (isLeadSurrogate(ch) && ((result + 1) < size)\r
-                    && isTrailSurrogate(source.charAt(result + 1))) {\r
-                result++;\r
-            }\r
-\r
-            count--;\r
-            result++;\r
-        }\r
-        if (count != 0) {\r
-            throw new StringIndexOutOfBoundsException(offset32);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See\r
-     * the <a name="_top_">class description</a> for notes on roundtripping.\r
-     * \r
-     * @param source\r
-     *            the UTF-16 string buffer\r
-     * @param offset32\r
-     *            UTF-32 offset\r
-     * @return UTF-16 offset\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset32 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findOffsetFromCodePoint(StringBuffer source, int offset32) {\r
-        char ch;\r
-        int size = source.length(), result = 0, count = offset32;\r
-        if (offset32 < 0 || offset32 > size) {\r
-            throw new StringIndexOutOfBoundsException(offset32);\r
-        }\r
-        while (result < size && count > 0) {\r
-            ch = source.charAt(result);\r
-            if (isLeadSurrogate(ch) && ((result + 1) < size)\r
-                    && isTrailSurrogate(source.charAt(result + 1))) {\r
-                result++;\r
-            }\r
-\r
-            count--;\r
-            result++;\r
-        }\r
-        if (count != 0) {\r
-            throw new StringIndexOutOfBoundsException(offset32);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See\r
-     * the <a name="_top_">class description</a> for notes on roundtripping.\r
-     * \r
-     * @param source\r
-     *            the UTF-16 char array whose substring is to be analysed\r
-     * @param start\r
-     *            offset of the substring to be analysed\r
-     * @param limit\r
-     *            offset of the substring to be analysed\r
-     * @param offset32\r
-     *            UTF-32 offset relative to start\r
-     * @return UTF-16 offset relative to start\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset32 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findOffsetFromCodePoint(char source[], int start, int limit, int offset32) {\r
-        char ch;\r
-        int result = start, count = offset32;\r
-        if (offset32 > limit - start) {\r
-            throw new ArrayIndexOutOfBoundsException(offset32);\r
-        }\r
-        while (result < limit && count > 0) {\r
-            ch = source[result];\r
-            if (isLeadSurrogate(ch) && ((result + 1) < limit)\r
-                    && isTrailSurrogate(source[result + 1])) {\r
-                result++;\r
-            }\r
-\r
-            count--;\r
-            result++;\r
-        }\r
-        if (count != 0) {\r
-            throw new ArrayIndexOutOfBoundsException(offset32);\r
-        }\r
-        return result - start;\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at or after the given\r
-     * UTF-16 offset. Used for random access. See the <a name="_top_">class description</a> for\r
-     * notes on roundtripping.<br>\r
-     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset\r
-     * of the <strong>lead</strong> of the pair is returned. </i>\r
-     * <p>\r
-     * To find the UTF-32 length of a string, use:\r
-     * \r
-     * <pre>\r
-     * len32 = countCodePoint(source, source.length());\r
-     * </pre>\r
-     * \r
-     * </p>\r
-     * <p>\r
-     * \r
-     * @param source\r
-     *            text to analyse\r
-     * @param offset16\r
-     *            UTF-16 offset < source text length.\r
-     * @return UTF-32 offset\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findCodePointOffset(String source, int offset16) {\r
-        if (offset16 < 0 || offset16 > source.length()) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        int result = 0;\r
-        char ch;\r
-        boolean hadLeadSurrogate = false;\r
-\r
-        for (int i = 0; i < offset16; ++i) {\r
-            ch = source.charAt(i);\r
-            if (hadLeadSurrogate && isTrailSurrogate(ch)) {\r
-                hadLeadSurrogate = false; // count valid trail as zero\r
-            } else {\r
-                hadLeadSurrogate = isLeadSurrogate(ch);\r
-                ++result; // count others as 1\r
-            }\r
-        }\r
-\r
-        if (offset16 == source.length()) {\r
-            return result;\r
-        }\r
-\r
-        // end of source being the less significant surrogate character\r
-        // shift result back to the start of the supplementary character\r
-        if (hadLeadSurrogate && (isTrailSurrogate(source.charAt(offset16)))) {\r
-            result--;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at the given UTF-16\r
-     * offset. Used for random access. See the <a name="_top_">class description</a> for notes on\r
-     * roundtripping.<br>\r
-     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset\r
-     * of the <strong>lead</strong> of the pair is returned. </i>\r
-     * <p>\r
-     * To find the UTF-32 length of a string, use:\r
-     * \r
-     * <pre>\r
-     * len32 = countCodePoint(source);\r
-     * </pre>\r
-     * \r
-     * </p>\r
-     * <p>\r
-     * \r
-     * @param source\r
-     *            text to analyse\r
-     * @param offset16\r
-     *            UTF-16 offset < source text length.\r
-     * @return UTF-32 offset\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findCodePointOffset(StringBuffer source, int offset16) {\r
-        if (offset16 < 0 || offset16 > source.length()) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        int result = 0;\r
-        char ch;\r
-        boolean hadLeadSurrogate = false;\r
-\r
-        for (int i = 0; i < offset16; ++i) {\r
-            ch = source.charAt(i);\r
-            if (hadLeadSurrogate && isTrailSurrogate(ch)) {\r
-                hadLeadSurrogate = false; // count valid trail as zero\r
-            } else {\r
-                hadLeadSurrogate = isLeadSurrogate(ch);\r
-                ++result; // count others as 1\r
-            }\r
-        }\r
-\r
-        if (offset16 == source.length()) {\r
-            return result;\r
-        }\r
-\r
-        // end of source being the less significant surrogate character\r
-        // shift result back to the start of the supplementary character\r
-        if (hadLeadSurrogate && (isTrailSurrogate(source.charAt(offset16)))) {\r
-            result--;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at the given UTF-16\r
-     * offset. Used for random access. See the <a name="_top_">class description</a> for notes on\r
-     * roundtripping.<br>\r
-     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset\r
-     * of the <strong>lead</strong> of the pair is returned. </i>\r
-     * <p>\r
-     * To find the UTF-32 length of a substring, use:\r
-     * \r
-     * <pre>\r
-     * len32 = countCodePoint(source, start, limit);\r
-     * </pre>\r
-     * \r
-     * </p>\r
-     * <p>\r
-     * \r
-     * @param source\r
-     *            text to analyse\r
-     * @param start\r
-     *            offset of the substring\r
-     * @param limit\r
-     *            offset of the substring\r
-     * @param offset16\r
-     *            UTF-16 relative to start\r
-     * @return UTF-32 offset relative to start\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is not within the range of start and limit.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int findCodePointOffset(char source[], int start, int limit, int offset16) {\r
-        offset16 += start;\r
-        if (offset16 > limit) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-\r
-        int result = 0;\r
-        char ch;\r
-        boolean hadLeadSurrogate = false;\r
-\r
-        for (int i = start; i < offset16; ++i) {\r
-            ch = source[i];\r
-            if (hadLeadSurrogate && isTrailSurrogate(ch)) {\r
-                hadLeadSurrogate = false; // count valid trail as zero\r
-            } else {\r
-                hadLeadSurrogate = isLeadSurrogate(ch);\r
-                ++result; // count others as 1\r
-            }\r
-        }\r
-\r
-        if (offset16 == limit) {\r
-            return result;\r
-        }\r
-\r
-        // end of source being the less significant surrogate character\r
-        // shift result back to the start of the supplementary character\r
-        if (hadLeadSurrogate && (isTrailSurrogate(source[offset16]))) {\r
-            result--;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Append a single UTF-32 value to the end of a StringBuffer. If a validity check is required,\r
-     * use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32 before\r
-     * calling.\r
-     * \r
-     * @param target\r
-     *            the buffer to append to\r
-     * @param char32\r
-     *            value to append.\r
-     * @return the updated StringBuffer\r
-     * @exception IllegalArgumentException\r
-     *                thrown when char32 does not lie within the range of the Unicode codepoints\r
-     * @stable ICU 2.1\r
-     */\r
-    public static StringBuffer append(StringBuffer target, int char32) {\r
-        // Check for irregular values\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Illegal codepoint: " + Integer.toHexString(char32));\r
-        }\r
-\r
-        // Write the UTF-16 values\r
-        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {\r
-            target.append(getLeadSurrogate(char32));\r
-            target.append(getTrailSurrogate(char32));\r
-        } else {\r
-            target.append((char) char32);\r
-        }\r
-        return target;\r
-    }\r
-\r
-    /**\r
-     * Cover JDK 1.5 APIs. Append the code point to the buffer and return the buffer as a\r
-     * convenience.\r
-     * \r
-     * @param target\r
-     *            the buffer to append to\r
-     * @param cp\r
-     *            the code point to append\r
-     * @return the updated StringBuffer\r
-     * @throws IllegalArgumentException\r
-     *             if cp is not a valid code point\r
-     * @stable ICU 3.0\r
-     */\r
-    public static StringBuffer appendCodePoint(StringBuffer target, int cp) {\r
-        return append(target, cp);\r
-    }\r
-\r
-    /**\r
-     * Adds a codepoint to offset16 position of the argument char array.\r
-     * \r
-     * @param target\r
-     *            char array to be append with the new code point\r
-     * @param limit\r
-     *            UTF16 offset which the codepoint will be appended.\r
-     * @param char32\r
-     *            code point to be appended\r
-     * @return offset after char32 in the array.\r
-     * @exception IllegalArgumentException\r
-     *                thrown if there is not enough space for the append, or when char32 does not\r
-     *                lie within the range of the Unicode codepoints.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int append(char[] target, int limit, int char32) {\r
-        // Check for irregular values\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Illegal codepoint");\r
-        }\r
-        // Write the UTF-16 values\r
-        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {\r
-            target[limit++] = getLeadSurrogate(char32);\r
-            target[limit++] = getTrailSurrogate(char32);\r
-        } else {\r
-            target[limit++] = (char) char32;\r
-        }\r
-        return limit;\r
-    }\r
-\r
-    /**\r
-     * Number of codepoints in a UTF16 String\r
-     * \r
-     * @param source\r
-     *            UTF16 string\r
-     * @return number of codepoint in string\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int countCodePoint(String source) {\r
-        if (source == null || source.length() == 0) {\r
-            return 0;\r
-        }\r
-        return findCodePointOffset(source, source.length());\r
-    }\r
-\r
-    /**\r
-     * Number of codepoints in a UTF16 String buffer\r
-     * \r
-     * @param source\r
-     *            UTF16 string buffer\r
-     * @return number of codepoint in string\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int countCodePoint(StringBuffer source) {\r
-        if (source == null || source.length() == 0) {\r
-            return 0;\r
-        }\r
-        return findCodePointOffset(source, source.length());\r
-    }\r
-\r
-    /**\r
-     * Number of codepoints in a UTF16 char array substring\r
-     * \r
-     * @param source\r
-     *            UTF16 char array\r
-     * @param start\r
-     *            offset of the substring\r
-     * @param limit\r
-     *            offset of the substring\r
-     * @return number of codepoint in the substring\r
-     * @exception IndexOutOfBoundsException\r
-     *                if start and limit are not valid.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int countCodePoint(char source[], int start, int limit) {\r
-        if (source == null || source.length == 0) {\r
-            return 0;\r
-        }\r
-        return findCodePointOffset(source, start, limit, limit - start);\r
-    }\r
-\r
-    /**\r
-     * Set a code point into a UTF16 position. Adjusts target according if we are replacing a\r
-     * non-supplementary codepoint with a supplementary and vice versa.\r
-     * \r
-     * @param target\r
-     *            stringbuffer\r
-     * @param offset16\r
-     *            UTF16 position to insert into\r
-     * @param char32\r
-     *            code point\r
-     * @stable ICU 2.1\r
-     */\r
-    public static void setCharAt(StringBuffer target, int offset16, int char32) {\r
-        int count = 1;\r
-        char single = target.charAt(offset16);\r
-\r
-        if (isSurrogate(single)) {\r
-            // pairs of the surrogate with offset16 at the lead char found\r
-            if (isLeadSurrogate(single) && (target.length() > offset16 + 1)\r
-                    && isTrailSurrogate(target.charAt(offset16 + 1))) {\r
-                count++;\r
-            } else {\r
-                // pairs of the surrogate with offset16 at the trail char\r
-                // found\r
-                if (isTrailSurrogate(single) && (offset16 > 0)\r
-                        && isLeadSurrogate(target.charAt(offset16 - 1))) {\r
-                    offset16--;\r
-                    count++;\r
-                }\r
-            }\r
-        }\r
-        target.replace(offset16, offset16 + count, valueOf(char32));\r
-    }\r
-\r
-    /**\r
-     * Set a code point into a UTF16 position in a char array. Adjusts target according if we are\r
-     * replacing a non-supplementary codepoint with a supplementary and vice versa.\r
-     * \r
-     * @param target\r
-     *            char array\r
-     * @param limit\r
-     *            numbers of valid chars in target, different from target.length. limit counts the\r
-     *            number of chars in target that represents a string, not the size of array target.\r
-     * @param offset16\r
-     *            UTF16 position to insert into\r
-     * @param char32\r
-     *            code point\r
-     * @return new number of chars in target that represents a string\r
-     * @exception IndexOutOfBoundsException\r
-     *                if offset16 is out of range\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int setCharAt(char target[], int limit, int offset16, int char32) {\r
-        if (offset16 >= limit) {\r
-            throw new ArrayIndexOutOfBoundsException(offset16);\r
-        }\r
-        int count = 1;\r
-        char single = target[offset16];\r
-\r
-        if (isSurrogate(single)) {\r
-            // pairs of the surrogate with offset16 at the lead char found\r
-            if (isLeadSurrogate(single) && (target.length > offset16 + 1)\r
-                    && isTrailSurrogate(target[offset16 + 1])) {\r
-                count++;\r
-            } else {\r
-                // pairs of the surrogate with offset16 at the trail char\r
-                // found\r
-                if (isTrailSurrogate(single) && (offset16 > 0)\r
-                        && isLeadSurrogate(target[offset16 - 1])) {\r
-                    offset16--;\r
-                    count++;\r
-                }\r
-            }\r
-        }\r
-\r
-        String str = valueOf(char32);\r
-        int result = limit;\r
-        int strlength = str.length();\r
-        target[offset16] = str.charAt(0);\r
-        if (count == strlength) {\r
-            if (count == 2) {\r
-                target[offset16 + 1] = str.charAt(1);\r
-            }\r
-        } else {\r
-            // this is not exact match in space, we'll have to do some\r
-            // shifting\r
-            System.arraycopy(target, offset16 + count, target, offset16 + strlength, limit\r
-                    - (offset16 + count));\r
-            if (count < strlength) {\r
-                // char32 is a supplementary character trying to squeeze into\r
-                // a non-supplementary space\r
-                target[offset16 + 1] = str.charAt(1);\r
-                result++;\r
-                if (result < target.length) {\r
-                    target[result] = 0;\r
-                }\r
-            } else {\r
-                // char32 is a non-supplementary character trying to fill\r
-                // into a supplementary space\r
-                result--;\r
-                target[result] = 0;\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Shifts offset16 by the argument number of codepoints\r
-     * \r
-     * @param source\r
-     *            string\r
-     * @param offset16\r
-     *            UTF16 position to shift\r
-     * @param shift32\r
-     *            number of codepoints to shift\r
-     * @return new shifted offset16\r
-     * @exception IndexOutOfBoundsException\r
-     *                if the new offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int moveCodePointOffset(String source, int offset16, int shift32) {\r
-        int result = offset16;\r
-        int size = source.length();\r
-        int count;\r
-        char ch;\r
-        if (offset16 < 0 || offset16 > size) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-        if (shift32 > 0) {\r
-            if (shift32 + offset16 > size) {\r
-                throw new StringIndexOutOfBoundsException(offset16);\r
-            }\r
-            count = shift32;\r
-            while (result < size && count > 0) {\r
-                ch = source.charAt(result);\r
-                if (isLeadSurrogate(ch) && ((result + 1) < size)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    result++;\r
-                }\r
-                count--;\r
-                result++;\r
-            }\r
-        } else {\r
-            if (offset16 + shift32 < 0) {\r
-                throw new StringIndexOutOfBoundsException(offset16);\r
-            }\r
-            for (count = -shift32; count > 0; count--) {\r
-                result--;\r
-                if (result < 0) {\r
-                    break;\r
-                }\r
-                ch = source.charAt(result);\r
-                if (isTrailSurrogate(ch) && result > 0\r
-                        && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    result--;\r
-                }\r
-            }\r
-        }\r
-        if (count != 0) {\r
-            throw new StringIndexOutOfBoundsException(shift32);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Shifts offset16 by the argument number of codepoints\r
-     * \r
-     * @param source\r
-     *            string buffer\r
-     * @param offset16\r
-     *            UTF16 position to shift\r
-     * @param shift32\r
-     *            number of codepoints to shift\r
-     * @return new shifted offset16\r
-     * @exception IndexOutOfBoundsException\r
-     *                if the new offset16 is out of bounds.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int moveCodePointOffset(StringBuffer source, int offset16, int shift32) {\r
-        int result = offset16;\r
-        int size = source.length();\r
-        int count;\r
-        char ch;\r
-        if (offset16 < 0 || offset16 > size) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-        if (shift32 > 0) {\r
-            if (shift32 + offset16 > size) {\r
-                throw new StringIndexOutOfBoundsException(offset16);\r
-            }\r
-            count = shift32;\r
-            while (result < size && count > 0) {\r
-                ch = source.charAt(result);\r
-                if (isLeadSurrogate(ch) && ((result + 1) < size)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    result++;\r
-                }\r
-                count--;\r
-                result++;\r
-            }\r
-        } else {\r
-            if (offset16 + shift32 < 0) {\r
-                throw new StringIndexOutOfBoundsException(offset16);\r
-            }\r
-            for (count = -shift32; count > 0; count--) {\r
-                result--;\r
-                if (result < 0) {\r
-                    break;\r
-                }\r
-                ch = source.charAt(result);\r
-                if (isTrailSurrogate(ch) && result > 0\r
-                        && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    result--;\r
-                }\r
-            }\r
-        }\r
-        if (count != 0) {\r
-            throw new StringIndexOutOfBoundsException(shift32);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Shifts offset16 by the argument number of codepoints within a subarray.\r
-     * \r
-     * @param source\r
-     *            char array\r
-     * @param start\r
-     *            position of the subarray to be performed on\r
-     * @param limit\r
-     *            position of the subarray to be performed on\r
-     * @param offset16\r
-     *            UTF16 position to shift relative to start\r
-     * @param shift32\r
-     *            number of codepoints to shift\r
-     * @return new shifted offset16 relative to start\r
-     * @exception IndexOutOfBoundsException\r
-     *                if the new offset16 is out of bounds with respect to the subarray or the\r
-     *                subarray bounds are out of range.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int moveCodePointOffset(char source[], int start, int limit, int offset16,\r
-            int shift32) {\r
-        int size = source.length;\r
-        int count;\r
-        char ch;\r
-        int result = offset16 + start;\r
-        if (start < 0 || limit < start) {\r
-            throw new StringIndexOutOfBoundsException(start);\r
-        }\r
-        if (limit > size) {\r
-            throw new StringIndexOutOfBoundsException(limit);\r
-        }\r
-        if (offset16 < 0 || result > limit) {\r
-            throw new StringIndexOutOfBoundsException(offset16);\r
-        }\r
-        if (shift32 > 0) {\r
-            if (shift32 + result > size) {\r
-                throw new StringIndexOutOfBoundsException(result);\r
-            }\r
-            count = shift32;\r
-            while (result < limit && count > 0) {\r
-                ch = source[result];\r
-                if (isLeadSurrogate(ch) && (result + 1 < limit)\r
-                        && isTrailSurrogate(source[result + 1])) {\r
-                    result++;\r
-                }\r
-                count--;\r
-                result++;\r
-            }\r
-        } else {\r
-            if (result + shift32 < start) {\r
-                throw new StringIndexOutOfBoundsException(result);\r
-            }\r
-            for (count = -shift32; count > 0; count--) {\r
-                result--;\r
-                if (result < start) {\r
-                    break;\r
-                }\r
-                ch = source[result];\r
-                if (isTrailSurrogate(ch) && result > start && isLeadSurrogate(source[result - 1])) {\r
-                    result--;\r
-                }\r
-            }\r
-        }\r
-        if (count != 0) {\r
-            throw new StringIndexOutOfBoundsException(shift32);\r
-        }\r
-        result -= start;\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Inserts char32 codepoint into target at the argument offset16. If the offset16 is in the\r
-     * middle of a supplementary codepoint, char32 will be inserted after the supplementary\r
-     * codepoint. The length of target increases by one if codepoint is non-supplementary, 2\r
-     * otherwise.\r
-     * <p>\r
-     * The overall effect is exactly as if the argument were converted to a string by the method\r
-     * valueOf(char) and the characters in that string were then inserted into target at the\r
-     * position indicated by offset16.\r
-     * </p>\r
-     * <p>\r
-     * The offset argument must be greater than or equal to 0, and less than or equal to the length\r
-     * of source.\r
-     * \r
-     * @param target\r
-     *            string buffer to insert to\r
-     * @param offset16\r
-     *            offset which char32 will be inserted in\r
-     * @param char32\r
-     *            codepoint to be inserted\r
-     * @return a reference to target\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is invalid.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static StringBuffer insert(StringBuffer target, int offset16, int char32) {\r
-        String str = valueOf(char32);\r
-        if (offset16 != target.length() && bounds(target, offset16) == TRAIL_SURROGATE_BOUNDARY) {\r
-            offset16++;\r
-        }\r
-        target.insert(offset16, str);\r
-        return target;\r
-    }\r
-\r
-    /**\r
-     * Inserts char32 codepoint into target at the argument offset16. If the offset16 is in the\r
-     * middle of a supplementary codepoint, char32 will be inserted after the supplementary\r
-     * codepoint. Limit increases by one if codepoint is non-supplementary, 2 otherwise.\r
-     * <p>\r
-     * The overall effect is exactly as if the argument were converted to a string by the method\r
-     * valueOf(char) and the characters in that string were then inserted into target at the\r
-     * position indicated by offset16.\r
-     * </p>\r
-     * <p>\r
-     * The offset argument must be greater than or equal to 0, and less than or equal to the limit.\r
-     * \r
-     * @param target\r
-     *            char array to insert to\r
-     * @param limit\r
-     *            end index of the char array, limit <= target.length\r
-     * @param offset16\r
-     *            offset which char32 will be inserted in\r
-     * @param char32\r
-     *            codepoint to be inserted\r
-     * @return new limit size\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is invalid.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int insert(char target[], int limit, int offset16, int char32) {\r
-        String str = valueOf(char32);\r
-        if (offset16 != limit && bounds(target, 0, limit, offset16) == TRAIL_SURROGATE_BOUNDARY) {\r
-            offset16++;\r
-        }\r
-        int size = str.length();\r
-        if (limit + size > target.length) {\r
-            throw new ArrayIndexOutOfBoundsException(offset16 + size);\r
-        }\r
-        System.arraycopy(target, offset16, target, offset16 + size, limit - offset16);\r
-        target[offset16] = str.charAt(0);\r
-        if (size == 2) {\r
-            target[offset16 + 1] = str.charAt(1);\r
-        }\r
-        return limit + size;\r
-    }\r
-\r
-    /**\r
-     * Removes the codepoint at the specified position in this target (shortening target by 1\r
-     * character if the codepoint is a non-supplementary, 2 otherwise).\r
-     * \r
-     * @param target\r
-     *            string buffer to remove codepoint from\r
-     * @param offset16\r
-     *            offset which the codepoint will be removed\r
-     * @return a reference to target\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is invalid.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static StringBuffer delete(StringBuffer target, int offset16) {\r
-        int count = 1;\r
-        switch (bounds(target, offset16)) {\r
-        case LEAD_SURROGATE_BOUNDARY:\r
-            count++;\r
-            break;\r
-        case TRAIL_SURROGATE_BOUNDARY:\r
-            count++;\r
-            offset16--;\r
-            break;\r
-        }\r
-        target.delete(offset16, offset16 + count);\r
-        return target;\r
-    }\r
-\r
-    /**\r
-     * Removes the codepoint at the specified position in this target (shortening target by 1\r
-     * character if the codepoint is a non-supplementary, 2 otherwise).\r
-     * \r
-     * @param target\r
-     *            string buffer to remove codepoint from\r
-     * @param limit\r
-     *            end index of the char array, limit <= target.length\r
-     * @param offset16\r
-     *            offset which the codepoint will be removed\r
-     * @return a new limit size\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown if offset16 is invalid.\r
-     * @stable ICU 2.1\r
-     */\r
-    public static int delete(char target[], int limit, int offset16) {\r
-        int count = 1;\r
-        switch (bounds(target, 0, limit, offset16)) {\r
-        case LEAD_SURROGATE_BOUNDARY:\r
-            count++;\r
-            break;\r
-        case TRAIL_SURROGATE_BOUNDARY:\r
-            count++;\r
-            offset16--;\r
-            break;\r
-        }\r
-        System.arraycopy(target, offset16 + count, target, offset16, limit - (offset16 + count));\r
-        target[limit - count] = 0;\r
-        return limit - count;\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of\r
-     * the argument codepoint. I.e., the smallest index <code>i</code> such that\r
-     * <code>UTF16.charAt(source, i) ==\r
-     * char32</code> is true.\r
-     * <p>\r
-     * If no such character occurs in this string, then -1 is returned.\r
-     * </p>\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.indexOf("abc", 'a') returns 0<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", 0x10000) returns 3<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", 0xd800) returns -1<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param char32\r
-     *            codepoint to search for\r
-     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or\r
-     *         -1 if the codepoint does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int indexOf(String source, int char32) {\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");\r
-        }\r
-        // non-surrogate bmp\r
-        if (char32 < LEAD_SURROGATE_MIN_VALUE\r
-                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {\r
-            return source.indexOf((char) char32);\r
-        }\r
-        // surrogate\r
-        if (char32 < SUPPLEMENTARY_MIN_VALUE) {\r
-            int result = source.indexOf((char) char32);\r
-            if (result >= 0) {\r
-                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    return indexOf(source, char32, result + 1);\r
-                }\r
-                // trail surrogate\r
-                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    return indexOf(source, char32, result + 1);\r
-                }\r
-            }\r
-            return result;\r
-        }\r
-        // supplementary\r
-        String char32str = toString(char32);\r
-        return source.indexOf(char32str);\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of\r
-     * the argument string str. This method is implemented based on codepoints, hence a "lead\r
-     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str\r
-     * starts with trail surrogate character at index 0, a source with a leading a surrogate\r
-     * character before str found at in source will not have a valid match. Vice versa for lead\r
-     * surrogates that ends str. See example below.\r
-     * <p>\r
-     * If no such string str occurs in this source, then -1 is returned.\r
-     * </p>\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.indexOf("abc", "ab") returns 0<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00") returns 3<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", "\ud800") returns -1<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param str\r
-     *            UTF16 format Unicode string to search for\r
-     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or\r
-     *         -1 if the codepoint does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int indexOf(String source, String str) {\r
-        int strLength = str.length();\r
-        // non-surrogate ends\r
-        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {\r
-            return source.indexOf(str);\r
-        }\r
-\r
-        int result = source.indexOf(str);\r
-        int resultEnd = result + strLength;\r
-        if (result >= 0) {\r
-            // check last character\r
-            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)\r
-                    && isTrailSurrogate(source.charAt(resultEnd + 1))) {\r
-                return indexOf(source, str, resultEnd + 1);\r
-            }\r
-            // check first character which is a trail surrogate\r
-            if (isTrailSurrogate(str.charAt(0)) && result > 0\r
-                    && isLeadSurrogate(source.charAt(result - 1))) {\r
-                return indexOf(source, str, resultEnd + 1);\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of\r
-     * the argument codepoint. I.e., the smallest index i such that: <br>\r
-     * (UTF16.charAt(source, i) == char32 && i >= fromIndex) is true.\r
-     * <p>\r
-     * If no such character occurs in this string, then -1 is returned.\r
-     * </p>\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.indexOf("abc", 'a', 1) returns -1<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", 0x10000, 1) returns 3<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", 0xd800, 1) returns -1<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param char32\r
-     *            codepoint to search for\r
-     * @param fromIndex\r
-     *            the index to start the search from.\r
-     * @return the index of the first occurrence of the codepoint in the argument Unicode string at\r
-     *         or after fromIndex, or -1 if the codepoint does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int indexOf(String source, int char32, int fromIndex) {\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");\r
-        }\r
-        // non-surrogate bmp\r
-        if (char32 < LEAD_SURROGATE_MIN_VALUE\r
-                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {\r
-            return source.indexOf((char) char32, fromIndex);\r
-        }\r
-        // surrogate\r
-        if (char32 < SUPPLEMENTARY_MIN_VALUE) {\r
-            int result = source.indexOf((char) char32, fromIndex);\r
-            if (result >= 0) {\r
-                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    return indexOf(source, char32, result + 1);\r
-                }\r
-                // trail surrogate\r
-                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    return indexOf(source, char32, result + 1);\r
-                }\r
-            }\r
-            return result;\r
-        }\r
-        // supplementary\r
-        String char32str = toString(char32);\r
-        return source.indexOf(char32str, fromIndex);\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of\r
-     * the argument string str. This method is implemented based on codepoints, hence a "lead\r
-     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str\r
-     * starts with trail surrogate character at index 0, a source with a leading a surrogate\r
-     * character before str found at in source will not have a valid match. Vice versa for lead\r
-     * surrogates that ends str. See example below.\r
-     * <p>\r
-     * If no such string str occurs in this source, then -1 is returned.\r
-     * </p>\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.indexOf("abc", "ab", 0) returns 0<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00", 0) returns 3<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00", 2) returns 3<br>\r
-     * UTF16.indexOf("abc\ud800\udc00", "\ud800", 0) returns -1<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param str\r
-     *            UTF16 format Unicode string to search for\r
-     * @param fromIndex\r
-     *            the index to start the search from.\r
-     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or\r
-     *         -1 if the codepoint does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int indexOf(String source, String str, int fromIndex) {\r
-        int strLength = str.length();\r
-        // non-surrogate ends\r
-        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {\r
-            return source.indexOf(str, fromIndex);\r
-        }\r
-\r
-        int result = source.indexOf(str, fromIndex);\r
-        int resultEnd = result + strLength;\r
-        if (result >= 0) {\r
-            // check last character\r
-            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)\r
-                    && isTrailSurrogate(source.charAt(resultEnd))) {\r
-                return indexOf(source, str, resultEnd + 1);\r
-            }\r
-            // check first character which is a trail surrogate\r
-            if (isTrailSurrogate(str.charAt(0)) && result > 0\r
-                    && isLeadSurrogate(source.charAt(result - 1))) {\r
-                return indexOf(source, str, resultEnd + 1);\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of\r
-     * the argument codepoint. I.e., the index returned is the largest value i such that:\r
-     * UTF16.charAt(source, i) == char32 is true.\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.lastIndexOf("abc", 'a') returns 0<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000) returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", 0xd800) returns -1<br>\r
-     * </p>\r
-     * <p>\r
-     * source is searched backwards starting at the last character.\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param char32\r
-     *            codepoint to search for\r
-     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint\r
-     *         does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int lastIndexOf(String source, int char32) {\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");\r
-        }\r
-        // non-surrogate bmp\r
-        if (char32 < LEAD_SURROGATE_MIN_VALUE\r
-                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {\r
-            return source.lastIndexOf((char) char32);\r
-        }\r
-        // surrogate\r
-        if (char32 < SUPPLEMENTARY_MIN_VALUE) {\r
-            int result = source.lastIndexOf((char) char32);\r
-            if (result >= 0) {\r
-                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    return lastIndexOf(source, char32, result - 1);\r
-                }\r
-                // trail surrogate\r
-                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    return lastIndexOf(source, char32, result - 1);\r
-                }\r
-            }\r
-            return result;\r
-        }\r
-        // supplementary\r
-        String char32str = toString(char32);\r
-        return source.lastIndexOf(char32str);\r
-    }\r
-\r
-    /**\r
-     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of\r
-     * the argument string str. This method is implemented based on codepoints, hence a "lead\r
-     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str\r
-     * starts with trail surrogate character at index 0, a source with a leading a surrogate\r
-     * character before str found at in source will not have a valid match. Vice versa for lead\r
-     * surrogates that ends str. See example below.\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.lastIndexOf("abc", "a") returns 0<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00") returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800") returns -1<br>\r
-     * </p>\r
-     * <p>\r
-     * source is searched backwards starting at the last character.\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param str\r
-     *            UTF16 format Unicode string to search for\r
-     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint\r
-     *         does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int lastIndexOf(String source, String str) {\r
-        int strLength = str.length();\r
-        // non-surrogate ends\r
-        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {\r
-            return source.lastIndexOf(str);\r
-        }\r
-\r
-        int result = source.lastIndexOf(str);\r
-        if (result >= 0) {\r
-            // check last character\r
-            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)\r
-                    && isTrailSurrogate(source.charAt(result + strLength + 1))) {\r
-                return lastIndexOf(source, str, result - 1);\r
-            }\r
-            // check first character which is a trail surrogate\r
-            if (isTrailSurrogate(str.charAt(0)) && result > 0\r
-                    && isLeadSurrogate(source.charAt(result - 1))) {\r
-                return lastIndexOf(source, str, result - 1);\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * <p>\r
-     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of\r
-     * the argument codepoint, where the result is less than or equals to fromIndex.\r
-     * </p>\r
-     * <p>\r
-     * This method is implemented based on codepoints, hence a single surrogate character will not\r
-     * match a supplementary character.\r
-     * </p>\r
-     * <p>\r
-     * source is searched backwards starting at the last character starting at the specified index.\r
-     * </p>\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.lastIndexOf("abc", 'c', 2) returns 2<br>\r
-     * UTF16.lastIndexOf("abc", 'c', 1) returns -1<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000, 5) returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000, 3) returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", 0xd800) returns -1<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param char32\r
-     *            codepoint to search for\r
-     * @param fromIndex\r
-     *            the index to start the search from. There is no restriction on the value of\r
-     *            fromIndex. If it is greater than or equal to the length of this string, it has the\r
-     *            same effect as if it were equal to one less than the length of this string: this\r
-     *            entire string may be searched. If it is negative, it has the same effect as if it\r
-     *            were -1: -1 is returned.\r
-     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint\r
-     *         does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int lastIndexOf(String source, int char32, int fromIndex) {\r
-        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");\r
-        }\r
-        // non-surrogate bmp\r
-        if (char32 < LEAD_SURROGATE_MIN_VALUE\r
-                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {\r
-            return source.lastIndexOf((char) char32, fromIndex);\r
-        }\r
-        // surrogate\r
-        if (char32 < SUPPLEMENTARY_MIN_VALUE) {\r
-            int result = source.lastIndexOf((char) char32, fromIndex);\r
-            if (result >= 0) {\r
-                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)\r
-                        && isTrailSurrogate(source.charAt(result + 1))) {\r
-                    return lastIndexOf(source, char32, result - 1);\r
-                }\r
-                // trail surrogate\r
-                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {\r
-                    return lastIndexOf(source, char32, result - 1);\r
-                }\r
-            }\r
-            return result;\r
-        }\r
-        // supplementary\r
-        String char32str = toString(char32);\r
-        return source.lastIndexOf(char32str, fromIndex);\r
-    }\r
-\r
-    /**\r
-     * <p>\r
-     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of\r
-     * the argument string str, where the result is less than or equals to fromIndex.\r
-     * </p>\r
-     * <p>\r
-     * This method is implemented based on codepoints, hence a "lead surrogate character + trail\r
-     * surrogate character" is treated as one entity. Hence if the str starts with trail surrogate\r
-     * character at index 0, a source with a leading a surrogate character before str found at in\r
-     * source will not have a valid match. Vice versa for lead surrogates that ends str.\r
-     * </p>\r
-     * See example below.\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.lastIndexOf("abc", "c", 2) returns 2<br>\r
-     * UTF16.lastIndexOf("abc", "c", 1) returns -1<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00", 5) returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00", 3) returns 3<br>\r
-     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800", 4) returns -1<br>\r
-     * </p>\r
-     * <p>\r
-     * source is searched backwards starting at the last character.\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string that will be searched\r
-     * @param str\r
-     *            UTF16 format Unicode string to search for\r
-     * @param fromIndex\r
-     *            the index to start the search from. There is no restriction on the value of\r
-     *            fromIndex. If it is greater than or equal to the length of this string, it has the\r
-     *            same effect as if it were equal to one less than the length of this string: this\r
-     *            entire string may be searched. If it is negative, it has the same effect as if it\r
-     *            were -1: -1 is returned.\r
-     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint\r
-     *         does not occur.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static int lastIndexOf(String source, String str, int fromIndex) {\r
-        int strLength = str.length();\r
-        // non-surrogate ends\r
-        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {\r
-            return source.lastIndexOf(str, fromIndex);\r
-        }\r
-\r
-        int result = source.lastIndexOf(str, fromIndex);\r
-        if (result >= 0) {\r
-            // check last character\r
-            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)\r
-                    && isTrailSurrogate(source.charAt(result + strLength))) {\r
-                return lastIndexOf(source, str, result - 1);\r
-            }\r
-            // check first character which is a trail surrogate\r
-            if (isTrailSurrogate(str.charAt(0)) && result > 0\r
-                    && isLeadSurrogate(source.charAt(result - 1))) {\r
-                return lastIndexOf(source, str, result - 1);\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Returns a new UTF16 format Unicode string resulting from replacing all occurrences of\r
-     * oldChar32 in source with newChar32. If the character oldChar32 does not occur in the UTF16\r
-     * format Unicode string source, then source will be returned. Otherwise, a new String object is\r
-     * created that represents a codepoint sequence identical to the codepoint sequence represented\r
-     * by source, except that every occurrence of oldChar32 is replaced by an occurrence of\r
-     * newChar32.\r
-     * <p>\r
-     * Examples: <br>\r
-     * UTF16.replace("mesquite in your cellar", 'e', 'o');<br>\r
-     * returns "mosquito in your collar"<br>\r
-     * UTF16.replace("JonL", 'q', 'x');<br>\r
-     * returns "JonL" (no change)<br>\r
-     * UTF16.replace("Supplementary character \ud800\udc00", 0x10000, '!'); <br>\r
-     * returns "Supplementary character !"<br>\r
-     * UTF16.replace("Supplementary character \ud800\udc00", 0xd800, '!'); <br>\r
-     * returns "Supplementary character \ud800\udc00"<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string which the codepoint replacements will be based on.\r
-     * @param oldChar32\r
-     *            non-zero old codepoint to be replaced.\r
-     * @param newChar32\r
-     *            the new codepoint to replace oldChar32\r
-     * @return new String derived from source by replacing every occurrence of oldChar32 with\r
-     *         newChar32, unless when no oldChar32 is found in source then source will be returned.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static String replace(String source, int oldChar32, int newChar32) {\r
-        if (oldChar32 <= 0 || oldChar32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument oldChar32 is not a valid codepoint");\r
-        }\r
-        if (newChar32 <= 0 || newChar32 > CODEPOINT_MAX_VALUE) {\r
-            throw new IllegalArgumentException("Argument newChar32 is not a valid codepoint");\r
-        }\r
-\r
-        int index = indexOf(source, oldChar32);\r
-        if (index == -1) {\r
-            return source;\r
-        }\r
-        String newChar32Str = toString(newChar32);\r
-        int oldChar32Size = 1;\r
-        int newChar32Size = newChar32Str.length();\r
-        StringBuffer result = new StringBuffer(source);\r
-        int resultIndex = index;\r
-\r
-        if (oldChar32 >= SUPPLEMENTARY_MIN_VALUE) {\r
-            oldChar32Size = 2;\r
-        }\r
-\r
-        while (index != -1) {\r
-            int endResultIndex = resultIndex + oldChar32Size;\r
-            result.replace(resultIndex, endResultIndex, newChar32Str);\r
-            int lastEndIndex = index + oldChar32Size;\r
-            index = indexOf(source, oldChar32, lastEndIndex);\r
-            resultIndex += newChar32Size + index - lastEndIndex;\r
-        }\r
-        return result.toString();\r
-    }\r
-\r
-    /**\r
-     * Returns a new UTF16 format Unicode string resulting from replacing all occurrences of oldStr\r
-     * in source with newStr. If the string oldStr does not occur in the UTF16 format Unicode string\r
-     * source, then source will be returned. Otherwise, a new String object is created that\r
-     * represents a codepoint sequence identical to the codepoint sequence represented by source,\r
-     * except that every occurrence of oldStr is replaced by an occurrence of newStr.\r
-     * <p>\r
-     * Examples: <br>\r
-     * UTF16.replace("mesquite in your cellar", "e", "o");<br>\r
-     * returns "mosquito in your collar"<br>\r
-     * UTF16.replace("mesquite in your cellar", "mesquite", "cat");<br>\r
-     * returns "cat in your cellar"<br>\r
-     * UTF16.replace("JonL", "q", "x");<br>\r
-     * returns "JonL" (no change)<br>\r
-     * UTF16.replace("Supplementary character \ud800\udc00", "\ud800\udc00", '!'); <br>\r
-     * returns "Supplementary character !"<br>\r
-     * UTF16.replace("Supplementary character \ud800\udc00", "\ud800", '!'); <br>\r
-     * returns "Supplementary character \ud800\udc00"<br>\r
-     * </p>\r
-     * Note this method is provided as support to jdk 1.3, which does not support supplementary\r
-     * characters to its fullest.\r
-     * \r
-     * @param source\r
-     *            UTF16 format Unicode string which the replacements will be based on.\r
-     * @param oldStr\r
-     *            non-zero-length string to be replaced.\r
-     * @param newStr\r
-     *            the new string to replace oldStr\r
-     * @return new String derived from source by replacing every occurrence of oldStr with newStr.\r
-     *         When no oldStr is found in source, then source will be returned.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static String replace(String source, String oldStr, String newStr) {\r
-        int index = indexOf(source, oldStr);\r
-        if (index == -1) {\r
-            return source;\r
-        }\r
-        int oldStrSize = oldStr.length();\r
-        int newStrSize = newStr.length();\r
-        StringBuffer result = new StringBuffer(source);\r
-        int resultIndex = index;\r
-\r
-        while (index != -1) {\r
-            int endResultIndex = resultIndex + oldStrSize;\r
-            result.replace(resultIndex, endResultIndex, newStr);\r
-            int lastEndIndex = index + oldStrSize;\r
-            index = indexOf(source, oldStr, lastEndIndex);\r
-            resultIndex += newStrSize + index - lastEndIndex;\r
-        }\r
-        return result.toString();\r
-    }\r
-\r
-    /**\r
-     * Reverses a UTF16 format Unicode string and replaces source's content with it. This method\r
-     * will reverse surrogate characters correctly, instead of blindly reversing every character.\r
-     * <p>\r
-     * Examples:<br>\r
-     * UTF16.reverse(new StringBuffer( "Supplementary characters \ud800\udc00\ud801\udc01"))<br>\r
-     * returns "\ud801\udc01\ud800\udc00 sretcarahc yratnemelppuS".\r
-     * \r
-     * @param source\r
-     *            the source StringBuffer that contains UTF16 format Unicode string to be reversed\r
-     * @return a modified source with reversed UTF16 format Unicode string.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static StringBuffer reverse(StringBuffer source) {\r
-        int length = source.length();\r
-        StringBuffer result = new StringBuffer(length);\r
-        for (int i = length; i-- > 0;) {\r
-            char ch = source.charAt(i);\r
-            if (isTrailSurrogate(ch) && i > 0) {\r
-                char ch2 = source.charAt(i - 1);\r
-                if (isLeadSurrogate(ch2)) {\r
-                    result.append(ch2);\r
-                    result.append(ch);\r
-                    --i;\r
-                    continue;\r
-                }\r
-            }\r
-            result.append(ch);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Check if the string contains more Unicode code points than a certain number. This is more\r
-     * efficient than counting all code points in the entire string and comparing that number with a\r
-     * threshold. This function may not need to scan the string at all if the length is within a\r
-     * certain range, and never needs to count more than 'number + 1' code points. Logically\r
-     * equivalent to (countCodePoint(s) > number). A Unicode code point may occupy either one or two\r
-     * code units.\r
-     * \r
-     * @param source\r
-     *            The input string.\r
-     * @param number\r
-     *            The number of code points in the string is compared against the 'number'\r
-     *            parameter.\r
-     * @return boolean value for whether the string contains more Unicode code points than 'number'.\r
-     * @stable ICU 2.4\r
-     */\r
-    public static boolean hasMoreCodePointsThan(String source, int number) {\r
-        if (number < 0) {\r
-            return true;\r
-        }\r
-        if (source == null) {\r
-            return false;\r
-        }\r
-        int length = source.length();\r
-\r
-        // length >= 0 known\r
-        // source contains at least (length + 1) / 2 code points: <= 2\r
-        // chars per cp\r
-        if (((length + 1) >> 1) > number) {\r
-            return true;\r
-        }\r
-\r
-        // check if source does not even contain enough chars\r
-        int maxsupplementary = length - number;\r
-        if (maxsupplementary <= 0) {\r
-            return false;\r
-        }\r
-\r
-        // there are maxsupplementary = length - number more chars than\r
-        // asked-for code points\r
-\r
-        // count code points until they exceed and also check that there are\r
-        // no more than maxsupplementary supplementary code points (char pairs)\r
-        int start = 0;\r
-        while (true) {\r
-            if (length == 0) {\r
-                return false;\r
-            }\r
-            if (number == 0) {\r
-                return true;\r
-            }\r
-            if (isLeadSurrogate(source.charAt(start++)) && start != length\r
-                    && isTrailSurrogate(source.charAt(start))) {\r
-                start++;\r
-                if (--maxsupplementary <= 0) {\r
-                    // too many pairs - too few code points\r
-                    return false;\r
-                }\r
-            }\r
-            --number;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Check if the sub-range of char array, from argument start to limit, contains more Unicode\r
-     * code points than a certain number. This is more efficient than counting all code points in\r
-     * the entire char array range and comparing that number with a threshold. This function may not\r
-     * need to scan the char array at all if start and limit is within a certain range, and never\r
-     * needs to count more than 'number + 1' code points. Logically equivalent to\r
-     * (countCodePoint(source, start, limit) > number). A Unicode code point may occupy either one\r
-     * or two code units.\r
-     * \r
-     * @param source\r
-     *            array of UTF-16 chars\r
-     * @param start\r
-     *            offset to substring in the source array for analyzing\r
-     * @param limit\r
-     *            offset to substring in the source array for analyzing\r
-     * @param number\r
-     *            The number of code points in the string is compared against the 'number'\r
-     *            parameter.\r
-     * @return boolean value for whether the string contains more Unicode code points than 'number'.\r
-     * @exception IndexOutOfBoundsException\r
-     *                thrown when limit &lt; start\r
-     * @stable ICU 2.4\r
-     */\r
-    public static boolean hasMoreCodePointsThan(char source[], int start, int limit, int number) {\r
-        int length = limit - start;\r
-        if (length < 0 || start < 0 || limit < 0) {\r
-            throw new IndexOutOfBoundsException(\r
-                    "Start and limit indexes should be non-negative and start <= limit");\r
-        }\r
-        if (number < 0) {\r
-            return true;\r
-        }\r
-        if (source == null) {\r
-            return false;\r
-        }\r
-\r
-        // length >= 0 known\r
-        // source contains at least (length + 1) / 2 code points: <= 2\r
-        // chars per cp\r
-        if (((length + 1) >> 1) > number) {\r
-            return true;\r
-        }\r
-\r
-        // check if source does not even contain enough chars\r
-        int maxsupplementary = length - number;\r
-        if (maxsupplementary <= 0) {\r
-            return false;\r
-        }\r
-\r
-        // there are maxsupplementary = length - number more chars than\r
-        // asked-for code points\r
-\r
-        // count code points until they exceed and also check that there are\r
-        // no more than maxsupplementary supplementary code points (char pairs)\r
-        while (true) {\r
-            if (length == 0) {\r
-                return false;\r
-            }\r
-            if (number == 0) {\r
-                return true;\r
-            }\r
-            if (isLeadSurrogate(source[start++]) && start != limit\r
-                    && isTrailSurrogate(source[start])) {\r
-                start++;\r
-                if (--maxsupplementary <= 0) {\r
-                    // too many pairs - too few code points\r
-                    return false;\r
-                }\r
-            }\r
-            --number;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Check if the string buffer contains more Unicode code points than a certain number. This is\r
-     * more efficient than counting all code points in the entire string buffer and comparing that\r
-     * number with a threshold. This function may not need to scan the string buffer at all if the\r
-     * length is within a certain range, and never needs to count more than 'number + 1' code\r
-     * points. Logically equivalent to (countCodePoint(s) > number). A Unicode code point may occupy\r
-     * either one or two code units.\r
-     * \r
-     * @param source\r
-     *            The input string buffer.\r
-     * @param number\r
-     *            The number of code points in the string buffer is compared against the 'number'\r
-     *            parameter.\r
-     * @return boolean value for whether the string buffer contains more Unicode code points than\r
-     *         'number'.\r
-     * @stable ICU 2.4\r
-     */\r
-    public static boolean hasMoreCodePointsThan(StringBuffer source, int number) {\r
-        if (number < 0) {\r
-            return true;\r
-        }\r
-        if (source == null) {\r
-            return false;\r
-        }\r
-        int length = source.length();\r
-\r
-        // length >= 0 known\r
-        // source contains at least (length + 1) / 2 code points: <= 2\r
-        // chars per cp\r
-        if (((length + 1) >> 1) > number) {\r
-            return true;\r
-        }\r
-\r
-        // check if source does not even contain enough chars\r
-        int maxsupplementary = length - number;\r
-        if (maxsupplementary <= 0) {\r
-            return false;\r
-        }\r
-\r
-        // there are maxsupplementary = length - number more chars than\r
-        // asked-for code points\r
-\r
-        // count code points until they exceed and also check that there are\r
-        // no more than maxsupplementary supplementary code points (char pairs)\r
-        int start = 0;\r
-        while (true) {\r
-            if (length == 0) {\r
-                return false;\r
-            }\r
-            if (number == 0) {\r
-                return true;\r
-            }\r
-            if (isLeadSurrogate(source.charAt(start++)) && start != length\r
-                    && isTrailSurrogate(source.charAt(start))) {\r
-                start++;\r
-                if (--maxsupplementary <= 0) {\r
-                    // too many pairs - too few code points\r
-                    return false;\r
-                }\r
-            }\r
-            --number;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Cover JDK 1.5 API. Create a String from an array of codePoints.\r
-     * \r
-     * @param codePoints\r
-     *            the code array\r
-     * @param offset\r
-     *            the start of the text in the code point array\r
-     * @param count\r
-     *            the number of code points\r
-     * @return a String representing the code points between offset and count\r
-     * @throws IllegalArgumentException\r
-     *             if an invalid code point is encountered\r
-     * @throws IndexOutOfBoundsException\r
-     *             if the offset or count are out of bounds.\r
-     * @stable ICU 3.0\r
-     */\r
-    public static String newString(int[] codePoints, int offset, int count) {\r
-        if (count < 0) {\r
-            throw new IllegalArgumentException();\r
-        }\r
-        char[] chars = new char[count];\r
-        int w = 0;\r
-        for (int r = offset, e = offset + count; r < e; ++r) {\r
-            int cp = codePoints[r];\r
-            if (cp < 0 || cp > 0x10ffff) {\r
-                throw new IllegalArgumentException();\r
-            }\r
-            while (true) {\r
-                try {\r
-                    if (cp < 0x010000) {\r
-                        chars[w] = (char) cp;\r
-                        w++;\r
-                    } else {\r
-                        chars[w] = (char) (LEAD_SURROGATE_OFFSET_ + (cp >> LEAD_SURROGATE_SHIFT_));\r
-                        chars[w + 1] = (char) (TRAIL_SURROGATE_MIN_VALUE + (cp & TRAIL_SURROGATE_MASK_));\r
-                        w += 2;\r
-                    }\r
-                    break;\r
-                } catch (IndexOutOfBoundsException ex) {\r
-                    int newlen = (int) (Math.ceil((double) codePoints.length * (w + 2)\r
-                            / (r - offset + 1)));\r
-                    char[] temp = new char[newlen];\r
-                    System.arraycopy(chars, 0, temp, 0, w);\r
-                    chars = temp;\r
-                }\r
-            }\r
-        }\r
-        return new String(chars, 0, w);\r
-    }\r
-\r
-    /**\r
-     * <p>\r
-     * UTF16 string comparator class. Allows UTF16 string comparison to be done with the various\r
-     * modes\r
-     * </p>\r
-     * <ul>\r
-     * <li> Code point comparison or code unit comparison\r
-     * <li> Case sensitive comparison, case insensitive comparison or case insensitive comparison\r
-     * with special handling for character 'i'.\r
-     * </ul>\r
-     * <p>\r
-     * The code unit or code point comparison differ only when comparing supplementary code points\r
-     * (&#92;u10000..&#92;u10ffff) to BMP code points near the end of the BMP (i.e.,\r
-     * &#92;ue000..&#92;uffff). In code unit comparison, high BMP code points sort after\r
-     * supplementary code points because they are stored as pairs of surrogates which are at\r
-     * &#92;ud800..&#92;udfff.\r
-     * </p>\r
-     * \r
-     * @see #FOLD_CASE_DEFAULT\r
-     * @see #FOLD_CASE_EXCLUDE_SPECIAL_I\r
-     * @stable ICU 2.1\r
-     */\r
-    public static final class StringComparator implements java.util.Comparator {\r
-        // public constructor ------------------------------------------------\r
-\r
-        /**\r
-         * Default constructor that does code unit comparison and case sensitive comparison.\r
-         * \r
-         * @stable ICU 2.1\r
-         */\r
-        public StringComparator() {\r
-            this(false, false, FOLD_CASE_DEFAULT);\r
-        }\r
-\r
-        /**\r
-         * Constructor that does comparison based on the argument options.\r
-         * \r
-         * @param codepointcompare\r
-         *            flag to indicate true for code point comparison or false for code unit\r
-         *            comparison.\r
-         * @param ignorecase\r
-         *            false for case sensitive comparison, true for case-insensitive comparison\r
-         * @param foldcaseoption\r
-         *            FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I. This option is used only\r
-         *            when ignorecase is set to true. If ignorecase is false, this option is\r
-         *            ignored.\r
-         * @see #FOLD_CASE_DEFAULT\r
-         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I\r
-         * @throws IllegalArgumentException\r
-         *             if foldcaseoption is out of range\r
-         * @stable ICU 2.4\r
-         */\r
-        public StringComparator(boolean codepointcompare, boolean ignorecase, int foldcaseoption) {\r
-            setCodePointCompare(codepointcompare);\r
-            m_ignoreCase_ = ignorecase;\r
-            if (foldcaseoption < FOLD_CASE_DEFAULT || foldcaseoption > FOLD_CASE_EXCLUDE_SPECIAL_I) {\r
-                throw new IllegalArgumentException("Invalid fold case option");\r
-            }\r
-            m_foldCase_ = foldcaseoption;\r
-        }\r
-\r
-        // public data member ------------------------------------------------\r
-\r
-        /**\r
-         * <p>\r
-         * Option value for case folding comparison:\r
-         * </p>\r
-         * <p>\r
-         * Comparison is case insensitive, strings are folded using default mappings defined in\r
-         * Unicode data file CaseFolding.txt, before comparison.\r
-         * </p>\r
-         * \r
-         * @stable ICU 2.4\r
-         */\r
-        public static final int FOLD_CASE_DEFAULT = 0;\r
-\r
-        /**\r
-         * <p>\r
-         * Option value for case folding comparison:\r
-         * </p>\r
-         * <p>\r
-         * Comparison is case insensitive, strings are folded using modified mappings defined in\r
-         * Unicode data file CaseFolding.txt, before comparison.\r
-         * </p>\r
-         * <p>\r
-         * The modified set of mappings is provided in a Unicode data file CaseFolding.txt to handle\r
-         * dotted I and dotless i appropriately for Turkic languages (tr, az).\r
-         * </p>\r
-         * <p>\r
-         * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that are to be\r
-         * included for default mappings and excluded for the Turkic-specific mappings.\r
-         * </p>\r
-         * <p>\r
-         * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that are to be\r
-         * excluded for default mappings and included for the Turkic-specific mappings.\r
-         * </p>\r
-         * \r
-         * @stable ICU 2.4\r
-         */\r
-        public static final int FOLD_CASE_EXCLUDE_SPECIAL_I = 1;\r
-\r
-        // public methods ----------------------------------------------------\r
-\r
-        // public setters ----------------------------------------------------\r
-\r
-        /**\r
-         * Sets the comparison mode to code point compare if flag is true. Otherwise comparison mode\r
-         * is set to code unit compare\r
-         * \r
-         * @param flag\r
-         *            true for code point compare, false for code unit compare\r
-         * @stable ICU 2.4\r
-         */\r
-        public void setCodePointCompare(boolean flag) {\r
-            if (flag) {\r
-                m_codePointCompare_ = Normalizer.COMPARE_CODE_POINT_ORDER;\r
-            } else {\r
-                m_codePointCompare_ = 0;\r
-            }\r
-        }\r
-\r
-        /**\r
-         * Sets the Comparator to case-insensitive comparison mode if argument is true, otherwise\r
-         * case sensitive comparison mode if set to false.\r
-         * \r
-         * @param ignorecase\r
-         *            true for case-insitive comparison, false for case sensitive comparison\r
-         * @param foldcaseoption\r
-         *            FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I. This option is used only\r
-         *            when ignorecase is set to true. If ignorecase is false, this option is\r
-         *            ignored.\r
-         * @see #FOLD_CASE_DEFAULT\r
-         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I\r
-         * @stable ICU 2.4\r
-         */\r
-        public void setIgnoreCase(boolean ignorecase, int foldcaseoption) {\r
-            m_ignoreCase_ = ignorecase;\r
-            if (foldcaseoption < FOLD_CASE_DEFAULT || foldcaseoption > FOLD_CASE_EXCLUDE_SPECIAL_I) {\r
-                throw new IllegalArgumentException("Invalid fold case option");\r
-            }\r
-            m_foldCase_ = foldcaseoption;\r
-        }\r
-\r
-        // public getters ----------------------------------------------------\r
-\r
-        /**\r
-         * Checks if the comparison mode is code point compare.\r
-         * \r
-         * @return true for code point compare, false for code unit compare\r
-         * @stable ICU 2.4\r
-         */\r
-        public boolean getCodePointCompare() {\r
-            return m_codePointCompare_ == Normalizer.COMPARE_CODE_POINT_ORDER;\r
-        }\r
-\r
-        /**\r
-         * Checks if Comparator is in the case insensitive mode.\r
-         * \r
-         * @return true if Comparator performs case insensitive comparison, false otherwise\r
-         * @stable ICU 2.4\r
-         */\r
-        public boolean getIgnoreCase() {\r
-            return m_ignoreCase_;\r
-        }\r
-\r
-        /**\r
-         * Gets the fold case options set in Comparator to be used with case insensitive comparison.\r
-         * \r
-         * @return either FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I\r
-         * @see #FOLD_CASE_DEFAULT\r
-         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I\r
-         * @stable ICU 2.4\r
-         */\r
-        public int getIgnoreCaseOption() {\r
-            return m_foldCase_;\r
-        }\r
-\r
-        // public other methods ----------------------------------------------\r
-\r
-        /**\r
-         * Compare two strings depending on the options selected during construction.\r
-         * \r
-         * @param a\r
-         *            first source string.\r
-         * @param b\r
-         *            second source string.\r
-         * @return 0 returned if a == b. If a < b, a negative value is returned. Otherwise if a > b,\r
-         *         a positive value is returned.\r
-         * @exception ClassCastException\r
-         *                thrown when either a or b is not a String object\r
-         * @stable ICU 2.4\r
-         */\r
-        public int compare(Object a, Object b) {\r
-            String str1 = (String) a;\r
-            String str2 = (String) b;\r
-\r
-            if (str1 == str2) {\r
-                return 0;\r
-            }\r
-            if (str1 == null) {\r
-                return -1;\r
-            }\r
-            if (str2 == null) {\r
-                return 1;\r
-            }\r
-\r
-            if (m_ignoreCase_) {\r
-                return compareCaseInsensitive(str1, str2);\r
-            }\r
-            return compareCaseSensitive(str1, str2);\r
-        }\r
-\r
-        // private data member ----------------------------------------------\r
-\r
-        /**\r
-         * Code unit comparison flag. True if code unit comparison is required. False if code point\r
-         * comparison is required.\r
-         */\r
-        private int m_codePointCompare_;\r
-\r
-        /**\r
-         * Fold case comparison option.\r
-         */\r
-        private int m_foldCase_;\r
-\r
-        /**\r
-         * Flag indicator if ignore case is to be used during comparison\r
-         */\r
-        private boolean m_ignoreCase_;\r
-\r
-        /**\r
-         * Code point order offset for surrogate characters\r
-         */\r
-        private static final int CODE_POINT_COMPARE_SURROGATE_OFFSET_ = 0x2800;\r
-\r
-        // private method ---------------------------------------------------\r
-\r
-        /**\r
-         * Compares case insensitive. This is a direct port of ICU4C, to make maintainence life\r
-         * easier.\r
-         * \r
-         * @param s1\r
-         *            first string to compare\r
-         * @param s2\r
-         *            second string to compare\r
-         * @return -1 is s1 &lt; s2, 0 if equals,\r
-         */\r
-        private int compareCaseInsensitive(String s1, String s2) {\r
-            return NormalizerImpl.cmpEquivFold(s1, s2, m_foldCase_ | m_codePointCompare_\r
-                    | Normalizer.COMPARE_IGNORE_CASE);\r
-        }\r
-\r
-        /**\r
-         * Compares case sensitive. This is a direct port of ICU4C, to make maintainence life\r
-         * easier.\r
-         * \r
-         * @param s1\r
-         *            first string to compare\r
-         * @param s2\r
-         *            second string to compare\r
-         * @return -1 is s1 &lt; s2, 0 if equals,\r
-         */\r
-        private int compareCaseSensitive(String s1, String s2) {\r
-            // compare identical prefixes - they do not need to be fixed up\r
-            // limit1 = start1 + min(lenght1, length2)\r
-            int length1 = s1.length();\r
-            int length2 = s2.length();\r
-            int minlength = length1;\r
-            int result = 0;\r
-            if (length1 < length2) {\r
-                result = -1;\r
-            } else if (length1 > length2) {\r
-                result = 1;\r
-                minlength = length2;\r
-            }\r
-\r
-            char c1 = 0;\r
-            char c2 = 0;\r
-            int index = 0;\r
-            for (; index < minlength; index++) {\r
-                c1 = s1.charAt(index);\r
-                c2 = s2.charAt(index);\r
-                // check pseudo-limit\r
-                if (c1 != c2) {\r
-                    break;\r
-                }\r
-            }\r
-\r
-            if (index == minlength) {\r
-                return result;\r
-            }\r
-\r
-            boolean codepointcompare = m_codePointCompare_ == Normalizer.COMPARE_CODE_POINT_ORDER;\r
-            // if both values are in or above the surrogate range, fix them up\r
-            if (c1 >= LEAD_SURROGATE_MIN_VALUE && c2 >= LEAD_SURROGATE_MIN_VALUE\r
-                    && codepointcompare) {\r
-                // subtract 0x2800 from BMP code points to make them smaller\r
-                // than supplementary ones\r
-                if ((c1 <= LEAD_SURROGATE_MAX_VALUE && (index + 1) != length1 && isTrailSurrogate(s1.charAt(index + 1)))\r
-                        || (isTrailSurrogate(c1) && index != 0 && isLeadSurrogate(s1.charAt(index - 1)))) {\r
-                    // part of a surrogate pair, leave >=d800\r
-                } else {\r
-                    // BMP code point - may be surrogate code point - make\r
-                    // < d800\r
-                    c1 -= CODE_POINT_COMPARE_SURROGATE_OFFSET_;\r
-                }\r
-\r
-                if ((c2 <= LEAD_SURROGATE_MAX_VALUE && (index + 1) != length2 && isTrailSurrogate(s2.charAt(index + 1)))\r
-                        || (isTrailSurrogate(c2) && index != 0 && isLeadSurrogate(s2.charAt(index - 1)))) {\r
-                    // part of a surrogate pair, leave >=d800\r
-                } else {\r
-                    // BMP code point - may be surrogate code point - make <d800\r
-                    c2 -= CODE_POINT_COMPARE_SURROGATE_OFFSET_;\r
-                }\r
-            }\r
-\r
-            // now c1 and c2 are in UTF-32-compatible order\r
-            return c1 - c2;\r
-        }\r
-    }\r
-\r
-    // private data members -------------------------------------------------\r
-\r
-    /**\r
-     * Shift value for lead surrogate to form a supplementary character.\r
-     */\r
-    private static final int LEAD_SURROGATE_SHIFT_ = 10;\r
-\r
-    /**\r
-     * Mask to retrieve the significant value from a trail surrogate.\r
-     */\r
-    private static final int TRAIL_SURROGATE_MASK_ = 0x3FF;\r
-\r
-    /**\r
-     * Value that all lead surrogate starts with\r
-     */\r
-    private static final int LEAD_SURROGATE_OFFSET_ = LEAD_SURROGATE_MIN_VALUE\r
-            - (SUPPLEMENTARY_MIN_VALUE >> LEAD_SURROGATE_SHIFT_);\r
-\r
-    // private methods ------------------------------------------------------\r
-\r
-    /**\r
-     * <p>\r
-     * Converts argument code point and returns a String object representing the code point's value\r
-     * in UTF16 format.\r
-     * </p>\r
-     * <p>\r
-     * This method does not check for the validity of the codepoint, the results are not guaranteed\r
-     * if a invalid codepoint is passed as argument.\r
-     * </p>\r
-     * <p>\r
-     * The result is a string whose length is 1 for non-supplementary code points, 2 otherwise.\r
-     * </p>\r
-     * \r
-     * @param ch\r
-     *            code point\r
-     * @return string representation of the code point\r
-     */\r
-    private static String toString(int ch) {\r
-        if (ch < SUPPLEMENTARY_MIN_VALUE) {\r
-            return String.valueOf((char) ch);\r
-        }\r
-\r
-        StringBuffer result = new StringBuffer();\r
-        result.append(getLeadSurrogate(ch));\r
-        result.append(getTrailSurrogate(ch));\r
-        return result.toString();\r
-    }\r
-}\r
-// eof\r
+//##header J2SE15
+/**
+ *******************************************************************************
+ * Copyright (C) 1996-2009, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+package com.ibm.icu.text;
+
+import com.ibm.icu.impl.UCharacterProperty;
+import com.ibm.icu.impl.NormalizerImpl;
+
+/**
+ * <p>
+ * Standalone utility class providing UTF16 character conversions and indexing conversions.
+ * </p>
+ * <p>
+ * Code that uses strings alone rarely need modification. By design, UTF-16 does not allow overlap,
+ * so searching for strings is a safe operation. Similarly, concatenation is always safe.
+ * Substringing is safe if the start and end are both on UTF-32 boundaries. In normal code, the
+ * values for start and end are on those boundaries, since they arose from operations like
+ * searching. If not, the nearest UTF-32 boundaries can be determined using <code>bounds()</code>.
+ * </p>
+ * <strong>Examples:</strong>
+ * <p>
+ * The following examples illustrate use of some of these methods.
+ * 
+ * <pre>
+ * // iteration forwards: Original
+ * for (int i = 0; i &lt; s.length(); ++i) {
+ *     char ch = s.charAt(i);
+ *     doSomethingWith(ch);
+ * }
+ * 
+ * // iteration forwards: Changes for UTF-32
+ * int ch;
+ * for (int i = 0; i &lt; s.length(); i += UTF16.getCharCount(ch)) {
+ *     ch = UTF16.charAt(s, i);
+ *     doSomethingWith(ch);
+ * }
+ * 
+ * // iteration backwards: Original
+ * for (int i = s.length() - 1; i &gt;= 0; --i) {
+ *     char ch = s.charAt(i);
+ *     doSomethingWith(ch);
+ * }
+ * 
+ * // iteration backwards: Changes for UTF-32
+ * int ch;
+ * for (int i = s.length() - 1; i &gt; 0; i -= UTF16.getCharCount(ch)) {
+ *     ch = UTF16.charAt(s, i);
+ *     doSomethingWith(ch);
+ * }
+ * </pre>
+ * 
+ * <strong>Notes:</strong>
+ * <ul>
+ * <li> <strong>Naming:</strong> For clarity, High and Low surrogates are called <code>Lead</code>
+ * and <code>Trail</code> in the API, which gives a better sense of their ordering in a string.
+ * <code>offset16</code> and <code>offset32</code> are used to distinguish offsets to UTF-16
+ * boundaries vs offsets to UTF-32 boundaries. <code>int char32</code> is used to contain UTF-32
+ * characters, as opposed to <code>char16</code>, which is a UTF-16 code unit. </li>
+ * <li> <strong>Roundtripping Offsets:</strong> You can always roundtrip from a UTF-32 offset to a
+ * UTF-16 offset and back. Because of the difference in structure, you can roundtrip from a UTF-16
+ * offset to a UTF-32 offset and back if and only if <code>bounds(string, offset16) != TRAIL</code>.
+ * </li>
+ * <li> <strong>Exceptions:</strong> The error checking will throw an exception if indices are out
+ * of bounds. Other than than that, all methods will behave reasonably, even if unmatched surrogates
+ * or out-of-bounds UTF-32 values are present. <code>UCharacter.isLegal()</code> can be used to
+ * check for validity if desired. </li>
+ * <li> <strong>Unmatched Surrogates:</strong> If the string contains unmatched surrogates, then
+ * these are counted as one UTF-32 value. This matches their iteration behavior, which is vital. It
+ * also matches common display practice as missing glyphs (see the Unicode Standard Section 5.4,
+ * 5.5). </li>
+ * <li> <strong>Optimization:</strong> The method implementations may need optimization if the
+ * compiler doesn't fold static final methods. Since surrogate pairs will form an exceeding small
+ * percentage of all the text in the world, the singleton case should always be optimized for. </li>
+ * </ul>
+ * 
+ * @author Mark Davis, with help from Markus Scherer
+ * @stable ICU 2.1
+ */
+
+public final class UTF16 {
+    // public variables ---------------------------------------------------
+
+    /**
+     * Value returned in <code><a href="#bounds(java.lang.String, int)">
+     * bounds()</a></code>.
+     * These values are chosen specifically so that it actually represents the position of the
+     * character [offset16 - (value >> 2), offset16 + (value & 3)]
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int SINGLE_CHAR_BOUNDARY = 1, LEAD_SURROGATE_BOUNDARY = 2,
+            TRAIL_SURROGATE_BOUNDARY = 5;
+
+    /**
+     * The lowest Unicode code point value.
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int CODEPOINT_MIN_VALUE = 0;
+
+    /**
+     * The highest Unicode code point value (scalar value) according to the Unicode Standard.
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int CODEPOINT_MAX_VALUE = 0x10ffff;
+
+    /**
+     * The minimum value for Supplementary code points
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int SUPPLEMENTARY_MIN_VALUE = 0x10000;
+
+    /**
+     * Lead surrogate minimum value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int LEAD_SURROGATE_MIN_VALUE = 0xD800;
+
+    /**
+     * Trail surrogate minimum value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int TRAIL_SURROGATE_MIN_VALUE = 0xDC00;
+
+    /**
+     * Lead surrogate maximum value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int LEAD_SURROGATE_MAX_VALUE = 0xDBFF;
+
+    /**
+     * Trail surrogate maximum value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int TRAIL_SURROGATE_MAX_VALUE = 0xDFFF;
+
+    /**
+     * Surrogate minimum value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int SURROGATE_MIN_VALUE = LEAD_SURROGATE_MIN_VALUE;
+
+    /**
+     * Maximum surrogate value
+     * 
+     * @stable ICU 2.1
+     */
+    public static final int SURROGATE_MAX_VALUE = TRAIL_SURROGATE_MAX_VALUE;
+
+    /**
+     * Lead surrogate bitmask
+     */
+    private static final int LEAD_SURROGATE_BITMASK = 0xFFFFFC00;
+
+    /**
+     * Trail surrogate bitmask
+     */
+    private static final int TRAIL_SURROGATE_BITMASK = 0xFFFFFC00;
+
+    /**
+     * Surrogate bitmask
+     */
+    private static final int SURROGATE_BITMASK = 0xFFFFF800;
+
+    /**
+     * Lead surrogate bits
+     */
+    private static final int LEAD_SURROGATE_BITS = 0xD800;
+
+    /**
+     * Trail surrogate bits
+     */
+    private static final int TRAIL_SURROGATE_BITS = 0xDC00;
+
+    /**
+     * Surrogate bits
+     */
+    private static final int SURROGATE_BITS = 0xD800;
+
+    // constructor --------------------------------------------------------
+
+    // /CLOVER:OFF
+    /**
+     * Prevent instance from being created.
+     */
+    private UTF16() {
+    }
+
+    // /CLOVER:ON
+    // public method ------------------------------------------------------
+
+    /**
+     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with
+     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is
+     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">
+     * UCharacter.isLegal()</a></code>
+     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary
+     * character will be returned. If a complete supplementary character is not found the incomplete
+     * character will be returned
+     * 
+     * @param source
+     *            array of UTF-16 chars
+     * @param offset16
+     *            UTF-16 offset to the start of the character.
+     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries
+     *         of that codepoint are the same as in <code>bounds32()</code>.
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int charAt(String source, int offset16) {
+        char single = source.charAt(offset16);
+        if (single < LEAD_SURROGATE_MIN_VALUE) {
+            return single;
+        }
+        return _charAt(source, offset16, single);
+    }
+
+    private static int _charAt(String source, int offset16, char single) {
+        if (single > TRAIL_SURROGATE_MAX_VALUE) {
+            return single;
+        }
+
+        // Convert the UTF-16 surrogate pair if necessary.
+        // For simplicity in usage, and because the frequency of pairs is
+        // low, look both directions.
+
+        if (single <= LEAD_SURROGATE_MAX_VALUE) {
+            ++offset16;
+            if (source.length() != offset16) {
+                char trail = source.charAt(offset16);
+                if (trail >= TRAIL_SURROGATE_MIN_VALUE && trail <= TRAIL_SURROGATE_MAX_VALUE) {
+                    return UCharacterProperty.getRawSupplementary(single, trail);
+                }
+            }
+        } else {
+            --offset16;
+            if (offset16 >= 0) {
+                // single is a trail surrogate so
+                char lead = source.charAt(offset16);
+                if (lead >= LEAD_SURROGATE_MIN_VALUE && lead <= LEAD_SURROGATE_MAX_VALUE) {
+                    return UCharacterProperty.getRawSupplementary(lead, single);
+                }
+            }
+        }
+        return single; // return unmatched surrogate
+    }
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    /**
+     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with
+     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is
+     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">
+     * UCharacter.isLegal()</a></code>
+     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary
+     * character will be returned. If a complete supplementary character is not found the incomplete
+     * character will be returned
+     * 
+     * @param source
+     *            array of UTF-16 chars
+     * @param offset16
+     *            UTF-16 offset to the start of the character.
+     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries
+     *         of that codepoint are the same as in <code>bounds32()</code>.
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int charAt(CharSequence source, int offset16) {
+        char single = source.charAt(offset16);
+        if (single < UTF16.LEAD_SURROGATE_MIN_VALUE) {
+            return single;
+        }
+        return _charAt(source, offset16, single);
+    }
+
+    private static int _charAt(CharSequence source, int offset16, char single) {
+        if (single > UTF16.TRAIL_SURROGATE_MAX_VALUE) {
+            return single;
+        }
+
+        // Convert the UTF-16 surrogate pair if necessary.
+        // For simplicity in usage, and because the frequency of pairs is
+        // low, look both directions.
+
+        if (single <= UTF16.LEAD_SURROGATE_MAX_VALUE) {
+            ++offset16;
+            if (source.length() != offset16) {
+                char trail = source.charAt(offset16);
+                if (trail >= UTF16.TRAIL_SURROGATE_MIN_VALUE
+                        && trail <= UTF16.TRAIL_SURROGATE_MAX_VALUE) {
+                    return UCharacterProperty.getRawSupplementary(single, trail);
+                }
+            }
+        } else {
+            --offset16;
+            if (offset16 >= 0) {
+                // single is a trail surrogate so
+                char lead = source.charAt(offset16);
+                if (lead >= UTF16.LEAD_SURROGATE_MIN_VALUE
+                        && lead <= UTF16.LEAD_SURROGATE_MAX_VALUE) {
+                    return UCharacterProperty.getRawSupplementary(lead, single);
+                }
+            }
+        }
+        return single; // return unmatched surrogate
+    }
+
+//#endif
+
+    /**
+     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with
+     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is
+     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()
+     * </a></code>
+     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary
+     * character will be returned. If a complete supplementary character is not found the incomplete
+     * character will be returned
+     * 
+     * @param source
+     *            UTF-16 chars string buffer
+     * @param offset16
+     *            UTF-16 offset to the start of the character.
+     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries
+     *         of that codepoint are the same as in <code>bounds32()</code>.
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int charAt(StringBuffer source, int offset16) {
+        if (offset16 < 0 || offset16 >= source.length()) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+
+        char single = source.charAt(offset16);
+        if (!isSurrogate(single)) {
+            return single;
+        }
+
+        // Convert the UTF-16 surrogate pair if necessary.
+        // For simplicity in usage, and because the frequency of pairs is
+        // low, look both directions.
+
+        if (single <= LEAD_SURROGATE_MAX_VALUE) {
+            ++offset16;
+            if (source.length() != offset16) {
+                char trail = source.charAt(offset16);
+                if (isTrailSurrogate(trail))
+                    return UCharacterProperty.getRawSupplementary(single, trail);
+            }
+        } else {
+            --offset16;
+            if (offset16 >= 0) {
+                // single is a trail surrogate so
+                char lead = source.charAt(offset16);
+                if (isLeadSurrogate(lead)) {
+                    return UCharacterProperty.getRawSupplementary(lead, single);
+                }
+            }
+        }
+        return single; // return unmatched surrogate
+    }
+
+    /**
+     * Extract a single UTF-32 value from a substring. Used when iterating forwards or backwards
+     * (with <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is
+     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()
+     * </a></code>
+     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary
+     * character will be returned. If a complete supplementary character is not found the incomplete
+     * character will be returned
+     * 
+     * @param source
+     *            array of UTF-16 chars
+     * @param start
+     *            offset to substring in the source array for analyzing
+     * @param limit
+     *            offset to substring in the source array for analyzing
+     * @param offset16
+     *            UTF-16 offset relative to start
+     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries
+     *         of that codepoint are the same as in <code>bounds32()</code>.
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is not within the range of start and limit.
+     * @stable ICU 2.1
+     */
+    public static int charAt(char source[], int start, int limit, int offset16) {
+        offset16 += start;
+        if (offset16 < start || offset16 >= limit) {
+            throw new ArrayIndexOutOfBoundsException(offset16);
+        }
+
+        char single = source[offset16];
+        if (!isSurrogate(single)) {
+            return single;
+        }
+
+        // Convert the UTF-16 surrogate pair if necessary.
+        // For simplicity in usage, and because the frequency of pairs is
+        // low, look both directions.
+        if (single <= LEAD_SURROGATE_MAX_VALUE) {
+            offset16++;
+            if (offset16 >= limit) {
+                return single;
+            }
+            char trail = source[offset16];
+            if (isTrailSurrogate(trail)) {
+                return UCharacterProperty.getRawSupplementary(single, trail);
+            }
+        } else { // isTrailSurrogate(single), so
+            if (offset16 == start) {
+                return single;
+            }
+            offset16--;
+            char lead = source[offset16];
+            if (isLeadSurrogate(lead))
+                return UCharacterProperty.getRawSupplementary(lead, single);
+        }
+        return single; // return unmatched surrogate
+    }
+
+    /**
+     * Extract a single UTF-32 value from a string. Used when iterating forwards or backwards (with
+     * <code>UTF16.getCharCount()</code>, as well as random access. If a validity check is
+     * required, use <code><a href="../lang/UCharacter.html#isLegal(char)">UCharacter.isLegal()
+     * </a></code>
+     * on the return value. If the char retrieved is part of a surrogate pair, its supplementary
+     * character will be returned. If a complete supplementary character is not found the incomplete
+     * character will be returned
+     * 
+     * @param source
+     *            UTF-16 chars string buffer
+     * @param offset16
+     *            UTF-16 offset to the start of the character.
+     * @return UTF-32 value for the UTF-32 value that contains the char at offset16. The boundaries
+     *         of that codepoint are the same as in <code>bounds32()</code>.
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int charAt(Replaceable source, int offset16) {
+        if (offset16 < 0 || offset16 >= source.length()) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+
+        char single = source.charAt(offset16);
+        if (!isSurrogate(single)) {
+            return single;
+        }
+
+        // Convert the UTF-16 surrogate pair if necessary.
+        // For simplicity in usage, and because the frequency of pairs is
+        // low, look both directions.
+
+        if (single <= LEAD_SURROGATE_MAX_VALUE) {
+            ++offset16;
+            if (source.length() != offset16) {
+                char trail = source.charAt(offset16);
+                if (isTrailSurrogate(trail))
+                    return UCharacterProperty.getRawSupplementary(single, trail);
+            }
+        } else {
+            --offset16;
+            if (offset16 >= 0) {
+                // single is a trail surrogate so
+                char lead = source.charAt(offset16);
+                if (isLeadSurrogate(lead)) {
+                    return UCharacterProperty.getRawSupplementary(lead, single);
+                }
+            }
+        }
+        return single; // return unmatched surrogate
+    }
+
+    /**
+     * Determines how many chars this char32 requires. If a validity check is required, use <code>
+     * <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code>
+     * on char32 before calling.
+     * 
+     * @param char32
+     *            the input codepoint.
+     * @return 2 if is in supplementary space, otherwise 1.
+     * @stable ICU 2.1
+     */
+    public static int getCharCount(int char32) {
+        if (char32 < SUPPLEMENTARY_MIN_VALUE) {
+            return 1;
+        }
+        return 2;
+    }
+
+    /**
+     * Returns the type of the boundaries around the char at offset16. Used for random access.
+     * 
+     * @param source
+     *            text to analyse
+     * @param offset16
+     *            UTF-16 offset
+     * @return
+     *            <ul>
+     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are [offset16, offset16+1]
+     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds
+     *            are [offset16, offset16 + 2]
+     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the
+     *            bounds are [offset16 - 1, offset16 + 1]
+     *            </ul>
+     *            For bit-twiddlers, the return values for these are chosen so that the boundaries
+     *            can be gotten by: [offset16 - (value >> 2), offset16 + (value & 3)].
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int bounds(String source, int offset16) {
+        char ch = source.charAt(offset16);
+        if (isSurrogate(ch)) {
+            if (isLeadSurrogate(ch)) {
+                if (++offset16 < source.length() && isTrailSurrogate(source.charAt(offset16))) {
+                    return LEAD_SURROGATE_BOUNDARY;
+                }
+            } else {
+                // isTrailSurrogate(ch), so
+                --offset16;
+                if (offset16 >= 0 && isLeadSurrogate(source.charAt(offset16))) {
+                    return TRAIL_SURROGATE_BOUNDARY;
+                }
+            }
+        }
+        return SINGLE_CHAR_BOUNDARY;
+    }
+
+    /**
+     * Returns the type of the boundaries around the char at offset16. Used for random access.
+     * 
+     * @param source
+     *            string buffer to analyse
+     * @param offset16
+     *            UTF16 offset
+     * @return
+     *            <ul>
+     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are [offset16, offset16 + 1]
+     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds
+     *            are [offset16, offset16 + 2]
+     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the
+     *            bounds are [offset16 - 1, offset16 + 1]
+     *            </ul>
+     *            For bit-twiddlers, the return values for these are chosen so that the boundaries
+     *            can be gotten by: [offset16 - (value >> 2), offset16 + (value & 3)].
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int bounds(StringBuffer source, int offset16) {
+        char ch = source.charAt(offset16);
+        if (isSurrogate(ch)) {
+            if (isLeadSurrogate(ch)) {
+                if (++offset16 < source.length() && isTrailSurrogate(source.charAt(offset16))) {
+                    return LEAD_SURROGATE_BOUNDARY;
+                }
+            } else {
+                // isTrailSurrogate(ch), so
+                --offset16;
+                if (offset16 >= 0 && isLeadSurrogate(source.charAt(offset16))) {
+                    return TRAIL_SURROGATE_BOUNDARY;
+                }
+            }
+        }
+        return SINGLE_CHAR_BOUNDARY;
+    }
+
+    /**
+     * Returns the type of the boundaries around the char at offset16. Used for random access. Note
+     * that the boundaries are determined with respect to the subarray, hence the char array
+     * {0xD800, 0xDC00} has the result SINGLE_CHAR_BOUNDARY for start = offset16 = 0 and limit = 1.
+     * 
+     * @param source
+     *            char array to analyse
+     * @param start
+     *            offset to substring in the source array for analyzing
+     * @param limit
+     *            offset to substring in the source array for analyzing
+     * @param offset16
+     *            UTF16 offset relative to start
+     * @return
+     *            <ul>
+     *            <li> SINGLE_CHAR_BOUNDARY : a single char; the bounds are
+     *            <li> LEAD_SURROGATE_BOUNDARY : a surrogate pair starting at offset16; the bounds
+     *            are [offset16, offset16 + 2]
+     *            <li> TRAIL_SURROGATE_BOUNDARY : a surrogate pair starting at offset16 - 1; the
+     *            bounds are [offset16 - 1, offset16 + 1]
+     *            </ul>
+     *            For bit-twiddlers, the boundary values for these are chosen so that the boundaries
+     *            can be gotten by: [offset16 - (boundvalue >> 2), offset16 + (boundvalue & 3)].
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is not within the range of start and limit.
+     * @stable ICU 2.1
+     */
+    public static int bounds(char source[], int start, int limit, int offset16) {
+        offset16 += start;
+        if (offset16 < start || offset16 >= limit) {
+            throw new ArrayIndexOutOfBoundsException(offset16);
+        }
+        char ch = source[offset16];
+        if (isSurrogate(ch)) {
+            if (isLeadSurrogate(ch)) {
+                ++offset16;
+                if (offset16 < limit && isTrailSurrogate(source[offset16])) {
+                    return LEAD_SURROGATE_BOUNDARY;
+                }
+            } else { // isTrailSurrogate(ch), so
+                --offset16;
+                if (offset16 >= start && isLeadSurrogate(source[offset16])) {
+                    return TRAIL_SURROGATE_BOUNDARY;
+                }
+            }
+        }
+        return SINGLE_CHAR_BOUNDARY;
+    }
+
+    /**
+     * Determines whether the code value is a surrogate.
+     * 
+     * @param char16
+     *            the input character.
+     * @return true iff the input character is a surrogate.
+     * @stable ICU 2.1
+     */
+    public static boolean isSurrogate(char char16) {
+        return (char16 & SURROGATE_BITMASK) == SURROGATE_BITS;
+    }
+
+    /**
+     * Determines whether the character is a trail surrogate.
+     * 
+     * @param char16
+     *            the input character.
+     * @return true iff the input character is a trail surrogate.
+     * @stable ICU 2.1
+     */
+    public static boolean isTrailSurrogate(char char16) {
+        return (char16 & TRAIL_SURROGATE_BITMASK) == TRAIL_SURROGATE_BITS;
+    }
+
+    /**
+     * Determines whether the character is a lead surrogate.
+     * 
+     * @param char16
+     *            the input character.
+     * @return true iff the input character is a lead surrogate
+     * @stable ICU 2.1
+     */
+    public static boolean isLeadSurrogate(char char16) {
+        return (char16 & LEAD_SURROGATE_BITMASK) == LEAD_SURROGATE_BITS;
+    }
+
+    /**
+     * Returns the lead surrogate. If a validity check is required, use
+     * <code><a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32
+     * before calling.
+     * 
+     * @param char32
+     *            the input character.
+     * @return lead surrogate if the getCharCount(ch) is 2; <br>
+     *         and 0 otherwise (note: 0 is not a valid lead surrogate).
+     * @stable ICU 2.1
+     */
+    public static char getLeadSurrogate(int char32) {
+        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {
+            return (char) (LEAD_SURROGATE_OFFSET_ + (char32 >> LEAD_SURROGATE_SHIFT_));
+        }
+        return 0;
+    }
+
+    /**
+     * Returns the trail surrogate. If a validity check is required, use
+     * <code><a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32
+     * before calling.
+     * 
+     * @param char32
+     *            the input character.
+     * @return the trail surrogate if the getCharCount(ch) is 2; <br>
+     *         otherwise the character itself
+     * @stable ICU 2.1
+     */
+    public static char getTrailSurrogate(int char32) {
+        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {
+            return (char) (TRAIL_SURROGATE_MIN_VALUE + (char32 & TRAIL_SURROGATE_MASK_));
+        }
+        return (char) char32;
+    }
+
+    /**
+     * Convenience method corresponding to String.valueOf(char). Returns a one or two char string
+     * containing the UTF-32 value in UTF16 format. If a validity check is required, use <a
+     * href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32 before calling.
+     * 
+     * @param char32
+     *            the input character.
+     * @return string value of char32 in UTF16 format
+     * @exception IllegalArgumentException
+     *                thrown if char32 is a invalid codepoint.
+     * @stable ICU 2.1
+     */
+    public static String valueOf(int char32) {
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Illegal codepoint");
+        }
+        return toString(char32);
+    }
+
+    /**
+     * Convenience method corresponding to String.valueOf(codepoint at offset16). Returns a one or
+     * two char string containing the UTF-32 value in UTF16 format. If offset16 indexes a surrogate
+     * character, the whole supplementary codepoint will be returned. If a validity check is
+     * required, use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on the
+     * codepoint at offset16 before calling. The result returned will be a newly created String
+     * obtained by calling source.substring(..) with the appropriate indexes.
+     * 
+     * @param source
+     *            the input string.
+     * @param offset16
+     *            the UTF16 index to the codepoint in source
+     * @return string value of char32 in UTF16 format
+     * @stable ICU 2.1
+     */
+    public static String valueOf(String source, int offset16) {
+        switch (bounds(source, offset16)) {
+        case LEAD_SURROGATE_BOUNDARY:
+            return source.substring(offset16, offset16 + 2);
+        case TRAIL_SURROGATE_BOUNDARY:
+            return source.substring(offset16 - 1, offset16 + 1);
+        default:
+            return source.substring(offset16, offset16 + 1);
+        }
+    }
+
+    /**
+     * Convenience method corresponding to StringBuffer.valueOf(codepoint at offset16). Returns a
+     * one or two char string containing the UTF-32 value in UTF16 format. If offset16 indexes a
+     * surrogate character, the whole supplementary codepoint will be returned. If a validity check
+     * is required, use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on
+     * the codepoint at offset16 before calling. The result returned will be a newly created String
+     * obtained by calling source.substring(..) with the appropriate indexes.
+     * 
+     * @param source
+     *            the input string buffer.
+     * @param offset16
+     *            the UTF16 index to the codepoint in source
+     * @return string value of char32 in UTF16 format
+     * @stable ICU 2.1
+     */
+    public static String valueOf(StringBuffer source, int offset16) {
+        switch (bounds(source, offset16)) {
+        case LEAD_SURROGATE_BOUNDARY:
+            return source.substring(offset16, offset16 + 2);
+        case TRAIL_SURROGATE_BOUNDARY:
+            return source.substring(offset16 - 1, offset16 + 1);
+        default:
+            return source.substring(offset16, offset16 + 1);
+        }
+    }
+
+    /**
+     * Convenience method. Returns a one or two char string containing the UTF-32 value in UTF16
+     * format. If offset16 indexes a surrogate character, the whole supplementary codepoint will be
+     * returned, except when either the leading or trailing surrogate character lies out of the
+     * specified subarray. In the latter case, only the surrogate character within bounds will be
+     * returned. If a validity check is required, use <a
+     * href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on the codepoint at
+     * offset16 before calling. The result returned will be a newly created String containing the
+     * relevant characters.
+     * 
+     * @param source
+     *            the input char array.
+     * @param start
+     *            start index of the subarray
+     * @param limit
+     *            end index of the subarray
+     * @param offset16
+     *            the UTF16 index to the codepoint in source relative to start
+     * @return string value of char32 in UTF16 format
+     * @stable ICU 2.1
+     */
+    public static String valueOf(char source[], int start, int limit, int offset16) {
+        switch (bounds(source, start, limit, offset16)) {
+        case LEAD_SURROGATE_BOUNDARY:
+            return new String(source, start + offset16, 2);
+        case TRAIL_SURROGATE_BOUNDARY:
+            return new String(source, start + offset16 - 1, 2);
+        }
+        return new String(source, start + offset16, 1);
+    }
+
+    /**
+     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See
+     * the <a name="_top_">class description</a> for notes on roundtripping.
+     * 
+     * @param source
+     *            the UTF-16 string
+     * @param offset32
+     *            UTF-32 offset
+     * @return UTF-16 offset
+     * @exception IndexOutOfBoundsException
+     *                if offset32 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int findOffsetFromCodePoint(String source, int offset32) {
+        char ch;
+        int size = source.length(), result = 0, count = offset32;
+        if (offset32 < 0 || offset32 > size) {
+            throw new StringIndexOutOfBoundsException(offset32);
+        }
+        while (result < size && count > 0) {
+            ch = source.charAt(result);
+            if (isLeadSurrogate(ch) && ((result + 1) < size)
+                    && isTrailSurrogate(source.charAt(result + 1))) {
+                result++;
+            }
+
+            count--;
+            result++;
+        }
+        if (count != 0) {
+            throw new StringIndexOutOfBoundsException(offset32);
+        }
+        return result;
+    }
+
+    /**
+     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See
+     * the <a name="_top_">class description</a> for notes on roundtripping.
+     * 
+     * @param source
+     *            the UTF-16 string buffer
+     * @param offset32
+     *            UTF-32 offset
+     * @return UTF-16 offset
+     * @exception IndexOutOfBoundsException
+     *                if offset32 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int findOffsetFromCodePoint(StringBuffer source, int offset32) {
+        char ch;
+        int size = source.length(), result = 0, count = offset32;
+        if (offset32 < 0 || offset32 > size) {
+            throw new StringIndexOutOfBoundsException(offset32);
+        }
+        while (result < size && count > 0) {
+            ch = source.charAt(result);
+            if (isLeadSurrogate(ch) && ((result + 1) < size)
+                    && isTrailSurrogate(source.charAt(result + 1))) {
+                result++;
+            }
+
+            count--;
+            result++;
+        }
+        if (count != 0) {
+            throw new StringIndexOutOfBoundsException(offset32);
+        }
+        return result;
+    }
+
+    /**
+     * Returns the UTF-16 offset that corresponds to a UTF-32 offset. Used for random access. See
+     * the <a name="_top_">class description</a> for notes on roundtripping.
+     * 
+     * @param source
+     *            the UTF-16 char array whose substring is to be analysed
+     * @param start
+     *            offset of the substring to be analysed
+     * @param limit
+     *            offset of the substring to be analysed
+     * @param offset32
+     *            UTF-32 offset relative to start
+     * @return UTF-16 offset relative to start
+     * @exception IndexOutOfBoundsException
+     *                if offset32 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int findOffsetFromCodePoint(char source[], int start, int limit, int offset32) {
+        char ch;
+        int result = start, count = offset32;
+        if (offset32 > limit - start) {
+            throw new ArrayIndexOutOfBoundsException(offset32);
+        }
+        while (result < limit && count > 0) {
+            ch = source[result];
+            if (isLeadSurrogate(ch) && ((result + 1) < limit)
+                    && isTrailSurrogate(source[result + 1])) {
+                result++;
+            }
+
+            count--;
+            result++;
+        }
+        if (count != 0) {
+            throw new ArrayIndexOutOfBoundsException(offset32);
+        }
+        return result - start;
+    }
+
+    /**
+     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at or after the given
+     * UTF-16 offset. Used for random access. See the <a name="_top_">class description</a> for
+     * notes on roundtripping.<br>
+     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset
+     * of the <strong>lead</strong> of the pair is returned. </i>
+     * <p>
+     * To find the UTF-32 length of a string, use:
+     * 
+     * <pre>
+     * len32 = countCodePoint(source, source.length());
+     * </pre>
+     * 
+     * </p>
+     * <p>
+     * 
+     * @param source
+     *            text to analyse
+     * @param offset16
+     *            UTF-16 offset < source text length.
+     * @return UTF-32 offset
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int findCodePointOffset(String source, int offset16) {
+        if (offset16 < 0 || offset16 > source.length()) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+
+        int result = 0;
+        char ch;
+        boolean hadLeadSurrogate = false;
+
+        for (int i = 0; i < offset16; ++i) {
+            ch = source.charAt(i);
+            if (hadLeadSurrogate && isTrailSurrogate(ch)) {
+                hadLeadSurrogate = false; // count valid trail as zero
+            } else {
+                hadLeadSurrogate = isLeadSurrogate(ch);
+                ++result; // count others as 1
+            }
+        }
+
+        if (offset16 == source.length()) {
+            return result;
+        }
+
+        // end of source being the less significant surrogate character
+        // shift result back to the start of the supplementary character
+        if (hadLeadSurrogate && (isTrailSurrogate(source.charAt(offset16)))) {
+            result--;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at the given UTF-16
+     * offset. Used for random access. See the <a name="_top_">class description</a> for notes on
+     * roundtripping.<br>
+     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset
+     * of the <strong>lead</strong> of the pair is returned. </i>
+     * <p>
+     * To find the UTF-32 length of a string, use:
+     * 
+     * <pre>
+     * len32 = countCodePoint(source);
+     * </pre>
+     * 
+     * </p>
+     * <p>
+     * 
+     * @param source
+     *            text to analyse
+     * @param offset16
+     *            UTF-16 offset < source text length.
+     * @return UTF-32 offset
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int findCodePointOffset(StringBuffer source, int offset16) {
+        if (offset16 < 0 || offset16 > source.length()) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+
+        int result = 0;
+        char ch;
+        boolean hadLeadSurrogate = false;
+
+        for (int i = 0; i < offset16; ++i) {
+            ch = source.charAt(i);
+            if (hadLeadSurrogate && isTrailSurrogate(ch)) {
+                hadLeadSurrogate = false; // count valid trail as zero
+            } else {
+                hadLeadSurrogate = isLeadSurrogate(ch);
+                ++result; // count others as 1
+            }
+        }
+
+        if (offset16 == source.length()) {
+            return result;
+        }
+
+        // end of source being the less significant surrogate character
+        // shift result back to the start of the supplementary character
+        if (hadLeadSurrogate && (isTrailSurrogate(source.charAt(offset16)))) {
+            result--;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the UTF-32 offset corresponding to the first UTF-32 boundary at the given UTF-16
+     * offset. Used for random access. See the <a name="_top_">class description</a> for notes on
+     * roundtripping.<br>
+     * <i>Note: If the UTF-16 offset is into the middle of a surrogate pair, then the UTF-32 offset
+     * of the <strong>lead</strong> of the pair is returned. </i>
+     * <p>
+     * To find the UTF-32 length of a substring, use:
+     * 
+     * <pre>
+     * len32 = countCodePoint(source, start, limit);
+     * </pre>
+     * 
+     * </p>
+     * <p>
+     * 
+     * @param source
+     *            text to analyse
+     * @param start
+     *            offset of the substring
+     * @param limit
+     *            offset of the substring
+     * @param offset16
+     *            UTF-16 relative to start
+     * @return UTF-32 offset relative to start
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is not within the range of start and limit.
+     * @stable ICU 2.1
+     */
+    public static int findCodePointOffset(char source[], int start, int limit, int offset16) {
+        offset16 += start;
+        if (offset16 > limit) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+
+        int result = 0;
+        char ch;
+        boolean hadLeadSurrogate = false;
+
+        for (int i = start; i < offset16; ++i) {
+            ch = source[i];
+            if (hadLeadSurrogate && isTrailSurrogate(ch)) {
+                hadLeadSurrogate = false; // count valid trail as zero
+            } else {
+                hadLeadSurrogate = isLeadSurrogate(ch);
+                ++result; // count others as 1
+            }
+        }
+
+        if (offset16 == limit) {
+            return result;
+        }
+
+        // end of source being the less significant surrogate character
+        // shift result back to the start of the supplementary character
+        if (hadLeadSurrogate && (isTrailSurrogate(source[offset16]))) {
+            result--;
+        }
+
+        return result;
+    }
+
+    /**
+     * Append a single UTF-32 value to the end of a StringBuffer. If a validity check is required,
+     * use <a href="../lang/UCharacter.html#isLegal(char)">isLegal()</a></code> on char32 before
+     * calling.
+     * 
+     * @param target
+     *            the buffer to append to
+     * @param char32
+     *            value to append.
+     * @return the updated StringBuffer
+     * @exception IllegalArgumentException
+     *                thrown when char32 does not lie within the range of the Unicode codepoints
+     * @stable ICU 2.1
+     */
+    public static StringBuffer append(StringBuffer target, int char32) {
+        // Check for irregular values
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Illegal codepoint: " + Integer.toHexString(char32));
+        }
+
+        // Write the UTF-16 values
+        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {
+            target.append(getLeadSurrogate(char32));
+            target.append(getTrailSurrogate(char32));
+        } else {
+            target.append((char) char32);
+        }
+        return target;
+    }
+
+    /**
+     * Cover JDK 1.5 APIs. Append the code point to the buffer and return the buffer as a
+     * convenience.
+     * 
+     * @param target
+     *            the buffer to append to
+     * @param cp
+     *            the code point to append
+     * @return the updated StringBuffer
+     * @throws IllegalArgumentException
+     *             if cp is not a valid code point
+     * @stable ICU 3.0
+     */
+    public static StringBuffer appendCodePoint(StringBuffer target, int cp) {
+        return append(target, cp);
+    }
+
+    /**
+     * Adds a codepoint to offset16 position of the argument char array.
+     * 
+     * @param target
+     *            char array to be append with the new code point
+     * @param limit
+     *            UTF16 offset which the codepoint will be appended.
+     * @param char32
+     *            code point to be appended
+     * @return offset after char32 in the array.
+     * @exception IllegalArgumentException
+     *                thrown if there is not enough space for the append, or when char32 does not
+     *                lie within the range of the Unicode codepoints.
+     * @stable ICU 2.1
+     */
+    public static int append(char[] target, int limit, int char32) {
+        // Check for irregular values
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Illegal codepoint");
+        }
+        // Write the UTF-16 values
+        if (char32 >= SUPPLEMENTARY_MIN_VALUE) {
+            target[limit++] = getLeadSurrogate(char32);
+            target[limit++] = getTrailSurrogate(char32);
+        } else {
+            target[limit++] = (char) char32;
+        }
+        return limit;
+    }
+
+    /**
+     * Number of codepoints in a UTF16 String
+     * 
+     * @param source
+     *            UTF16 string
+     * @return number of codepoint in string
+     * @stable ICU 2.1
+     */
+    public static int countCodePoint(String source) {
+        if (source == null || source.length() == 0) {
+            return 0;
+        }
+        return findCodePointOffset(source, source.length());
+    }
+
+    /**
+     * Number of codepoints in a UTF16 String buffer
+     * 
+     * @param source
+     *            UTF16 string buffer
+     * @return number of codepoint in string
+     * @stable ICU 2.1
+     */
+    public static int countCodePoint(StringBuffer source) {
+        if (source == null || source.length() == 0) {
+            return 0;
+        }
+        return findCodePointOffset(source, source.length());
+    }
+
+    /**
+     * Number of codepoints in a UTF16 char array substring
+     * 
+     * @param source
+     *            UTF16 char array
+     * @param start
+     *            offset of the substring
+     * @param limit
+     *            offset of the substring
+     * @return number of codepoint in the substring
+     * @exception IndexOutOfBoundsException
+     *                if start and limit are not valid.
+     * @stable ICU 2.1
+     */
+    public static int countCodePoint(char source[], int start, int limit) {
+        if (source == null || source.length == 0) {
+            return 0;
+        }
+        return findCodePointOffset(source, start, limit, limit - start);
+    }
+
+    /**
+     * Set a code point into a UTF16 position. Adjusts target according if we are replacing a
+     * non-supplementary codepoint with a supplementary and vice versa.
+     * 
+     * @param target
+     *            stringbuffer
+     * @param offset16
+     *            UTF16 position to insert into
+     * @param char32
+     *            code point
+     * @stable ICU 2.1
+     */
+    public static void setCharAt(StringBuffer target, int offset16, int char32) {
+        int count = 1;
+        char single = target.charAt(offset16);
+
+        if (isSurrogate(single)) {
+            // pairs of the surrogate with offset16 at the lead char found
+            if (isLeadSurrogate(single) && (target.length() > offset16 + 1)
+                    && isTrailSurrogate(target.charAt(offset16 + 1))) {
+                count++;
+            } else {
+                // pairs of the surrogate with offset16 at the trail char
+                // found
+                if (isTrailSurrogate(single) && (offset16 > 0)
+                        && isLeadSurrogate(target.charAt(offset16 - 1))) {
+                    offset16--;
+                    count++;
+                }
+            }
+        }
+        target.replace(offset16, offset16 + count, valueOf(char32));
+    }
+
+    /**
+     * Set a code point into a UTF16 position in a char array. Adjusts target according if we are
+     * replacing a non-supplementary codepoint with a supplementary and vice versa.
+     * 
+     * @param target
+     *            char array
+     * @param limit
+     *            numbers of valid chars in target, different from target.length. limit counts the
+     *            number of chars in target that represents a string, not the size of array target.
+     * @param offset16
+     *            UTF16 position to insert into
+     * @param char32
+     *            code point
+     * @return new number of chars in target that represents a string
+     * @exception IndexOutOfBoundsException
+     *                if offset16 is out of range
+     * @stable ICU 2.1
+     */
+    public static int setCharAt(char target[], int limit, int offset16, int char32) {
+        if (offset16 >= limit) {
+            throw new ArrayIndexOutOfBoundsException(offset16);
+        }
+        int count = 1;
+        char single = target[offset16];
+
+        if (isSurrogate(single)) {
+            // pairs of the surrogate with offset16 at the lead char found
+            if (isLeadSurrogate(single) && (target.length > offset16 + 1)
+                    && isTrailSurrogate(target[offset16 + 1])) {
+                count++;
+            } else {
+                // pairs of the surrogate with offset16 at the trail char
+                // found
+                if (isTrailSurrogate(single) && (offset16 > 0)
+                        && isLeadSurrogate(target[offset16 - 1])) {
+                    offset16--;
+                    count++;
+                }
+            }
+        }
+
+        String str = valueOf(char32);
+        int result = limit;
+        int strlength = str.length();
+        target[offset16] = str.charAt(0);
+        if (count == strlength) {
+            if (count == 2) {
+                target[offset16 + 1] = str.charAt(1);
+            }
+        } else {
+            // this is not exact match in space, we'll have to do some
+            // shifting
+            System.arraycopy(target, offset16 + count, target, offset16 + strlength, limit
+                    - (offset16 + count));
+            if (count < strlength) {
+                // char32 is a supplementary character trying to squeeze into
+                // a non-supplementary space
+                target[offset16 + 1] = str.charAt(1);
+                result++;
+                if (result < target.length) {
+                    target[result] = 0;
+                }
+            } else {
+                // char32 is a non-supplementary character trying to fill
+                // into a supplementary space
+                result--;
+                target[result] = 0;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Shifts offset16 by the argument number of codepoints
+     * 
+     * @param source
+     *            string
+     * @param offset16
+     *            UTF16 position to shift
+     * @param shift32
+     *            number of codepoints to shift
+     * @return new shifted offset16
+     * @exception IndexOutOfBoundsException
+     *                if the new offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int moveCodePointOffset(String source, int offset16, int shift32) {
+        int result = offset16;
+        int size = source.length();
+        int count;
+        char ch;
+        if (offset16 < 0 || offset16 > size) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+        if (shift32 > 0) {
+            if (shift32 + offset16 > size) {
+                throw new StringIndexOutOfBoundsException(offset16);
+            }
+            count = shift32;
+            while (result < size && count > 0) {
+                ch = source.charAt(result);
+                if (isLeadSurrogate(ch) && ((result + 1) < size)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    result++;
+                }
+                count--;
+                result++;
+            }
+        } else {
+            if (offset16 + shift32 < 0) {
+                throw new StringIndexOutOfBoundsException(offset16);
+            }
+            for (count = -shift32; count > 0; count--) {
+                result--;
+                if (result < 0) {
+                    break;
+                }
+                ch = source.charAt(result);
+                if (isTrailSurrogate(ch) && result > 0
+                        && isLeadSurrogate(source.charAt(result - 1))) {
+                    result--;
+                }
+            }
+        }
+        if (count != 0) {
+            throw new StringIndexOutOfBoundsException(shift32);
+        }
+        return result;
+    }
+
+    /**
+     * Shifts offset16 by the argument number of codepoints
+     * 
+     * @param source
+     *            string buffer
+     * @param offset16
+     *            UTF16 position to shift
+     * @param shift32
+     *            number of codepoints to shift
+     * @return new shifted offset16
+     * @exception IndexOutOfBoundsException
+     *                if the new offset16 is out of bounds.
+     * @stable ICU 2.1
+     */
+    public static int moveCodePointOffset(StringBuffer source, int offset16, int shift32) {
+        int result = offset16;
+        int size = source.length();
+        int count;
+        char ch;
+        if (offset16 < 0 || offset16 > size) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+        if (shift32 > 0) {
+            if (shift32 + offset16 > size) {
+                throw new StringIndexOutOfBoundsException(offset16);
+            }
+            count = shift32;
+            while (result < size && count > 0) {
+                ch = source.charAt(result);
+                if (isLeadSurrogate(ch) && ((result + 1) < size)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    result++;
+                }
+                count--;
+                result++;
+            }
+        } else {
+            if (offset16 + shift32 < 0) {
+                throw new StringIndexOutOfBoundsException(offset16);
+            }
+            for (count = -shift32; count > 0; count--) {
+                result--;
+                if (result < 0) {
+                    break;
+                }
+                ch = source.charAt(result);
+                if (isTrailSurrogate(ch) && result > 0
+                        && isLeadSurrogate(source.charAt(result - 1))) {
+                    result--;
+                }
+            }
+        }
+        if (count != 0) {
+            throw new StringIndexOutOfBoundsException(shift32);
+        }
+        return result;
+    }
+
+    /**
+     * Shifts offset16 by the argument number of codepoints within a subarray.
+     * 
+     * @param source
+     *            char array
+     * @param start
+     *            position of the subarray to be performed on
+     * @param limit
+     *            position of the subarray to be performed on
+     * @param offset16
+     *            UTF16 position to shift relative to start
+     * @param shift32
+     *            number of codepoints to shift
+     * @return new shifted offset16 relative to start
+     * @exception IndexOutOfBoundsException
+     *                if the new offset16 is out of bounds with respect to the subarray or the
+     *                subarray bounds are out of range.
+     * @stable ICU 2.1
+     */
+    public static int moveCodePointOffset(char source[], int start, int limit, int offset16,
+            int shift32) {
+        int size = source.length;
+        int count;
+        char ch;
+        int result = offset16 + start;
+        if (start < 0 || limit < start) {
+            throw new StringIndexOutOfBoundsException(start);
+        }
+        if (limit > size) {
+            throw new StringIndexOutOfBoundsException(limit);
+        }
+        if (offset16 < 0 || result > limit) {
+            throw new StringIndexOutOfBoundsException(offset16);
+        }
+        if (shift32 > 0) {
+            if (shift32 + result > size) {
+                throw new StringIndexOutOfBoundsException(result);
+            }
+            count = shift32;
+            while (result < limit && count > 0) {
+                ch = source[result];
+                if (isLeadSurrogate(ch) && (result + 1 < limit)
+                        && isTrailSurrogate(source[result + 1])) {
+                    result++;
+                }
+                count--;
+                result++;
+            }
+        } else {
+            if (result + shift32 < start) {
+                throw new StringIndexOutOfBoundsException(result);
+            }
+            for (count = -shift32; count > 0; count--) {
+                result--;
+                if (result < start) {
+                    break;
+                }
+                ch = source[result];
+                if (isTrailSurrogate(ch) && result > start && isLeadSurrogate(source[result - 1])) {
+                    result--;
+                }
+            }
+        }
+        if (count != 0) {
+            throw new StringIndexOutOfBoundsException(shift32);
+        }
+        result -= start;
+        return result;
+    }
+
+    /**
+     * Inserts char32 codepoint into target at the argument offset16. If the offset16 is in the
+     * middle of a supplementary codepoint, char32 will be inserted after the supplementary
+     * codepoint. The length of target increases by one if codepoint is non-supplementary, 2
+     * otherwise.
+     * <p>
+     * The overall effect is exactly as if the argument were converted to a string by the method
+     * valueOf(char) and the characters in that string were then inserted into target at the
+     * position indicated by offset16.
+     * </p>
+     * <p>
+     * The offset argument must be greater than or equal to 0, and less than or equal to the length
+     * of source.
+     * 
+     * @param target
+     *            string buffer to insert to
+     * @param offset16
+     *            offset which char32 will be inserted in
+     * @param char32
+     *            codepoint to be inserted
+     * @return a reference to target
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is invalid.
+     * @stable ICU 2.1
+     */
+    public static StringBuffer insert(StringBuffer target, int offset16, int char32) {
+        String str = valueOf(char32);
+        if (offset16 != target.length() && bounds(target, offset16) == TRAIL_SURROGATE_BOUNDARY) {
+            offset16++;
+        }
+        target.insert(offset16, str);
+        return target;
+    }
+
+    /**
+     * Inserts char32 codepoint into target at the argument offset16. If the offset16 is in the
+     * middle of a supplementary codepoint, char32 will be inserted after the supplementary
+     * codepoint. Limit increases by one if codepoint is non-supplementary, 2 otherwise.
+     * <p>
+     * The overall effect is exactly as if the argument were converted to a string by the method
+     * valueOf(char) and the characters in that string were then inserted into target at the
+     * position indicated by offset16.
+     * </p>
+     * <p>
+     * The offset argument must be greater than or equal to 0, and less than or equal to the limit.
+     * 
+     * @param target
+     *            char array to insert to
+     * @param limit
+     *            end index of the char array, limit <= target.length
+     * @param offset16
+     *            offset which char32 will be inserted in
+     * @param char32
+     *            codepoint to be inserted
+     * @return new limit size
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is invalid.
+     * @stable ICU 2.1
+     */
+    public static int insert(char target[], int limit, int offset16, int char32) {
+        String str = valueOf(char32);
+        if (offset16 != limit && bounds(target, 0, limit, offset16) == TRAIL_SURROGATE_BOUNDARY) {
+            offset16++;
+        }
+        int size = str.length();
+        if (limit + size > target.length) {
+            throw new ArrayIndexOutOfBoundsException(offset16 + size);
+        }
+        System.arraycopy(target, offset16, target, offset16 + size, limit - offset16);
+        target[offset16] = str.charAt(0);
+        if (size == 2) {
+            target[offset16 + 1] = str.charAt(1);
+        }
+        return limit + size;
+    }
+
+    /**
+     * Removes the codepoint at the specified position in this target (shortening target by 1
+     * character if the codepoint is a non-supplementary, 2 otherwise).
+     * 
+     * @param target
+     *            string buffer to remove codepoint from
+     * @param offset16
+     *            offset which the codepoint will be removed
+     * @return a reference to target
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is invalid.
+     * @stable ICU 2.1
+     */
+    public static StringBuffer delete(StringBuffer target, int offset16) {
+        int count = 1;
+        switch (bounds(target, offset16)) {
+        case LEAD_SURROGATE_BOUNDARY:
+            count++;
+            break;
+        case TRAIL_SURROGATE_BOUNDARY:
+            count++;
+            offset16--;
+            break;
+        }
+        target.delete(offset16, offset16 + count);
+        return target;
+    }
+
+    /**
+     * Removes the codepoint at the specified position in this target (shortening target by 1
+     * character if the codepoint is a non-supplementary, 2 otherwise).
+     * 
+     * @param target
+     *            string buffer to remove codepoint from
+     * @param limit
+     *            end index of the char array, limit <= target.length
+     * @param offset16
+     *            offset which the codepoint will be removed
+     * @return a new limit size
+     * @exception IndexOutOfBoundsException
+     *                thrown if offset16 is invalid.
+     * @stable ICU 2.1
+     */
+    public static int delete(char target[], int limit, int offset16) {
+        int count = 1;
+        switch (bounds(target, 0, limit, offset16)) {
+        case LEAD_SURROGATE_BOUNDARY:
+            count++;
+            break;
+        case TRAIL_SURROGATE_BOUNDARY:
+            count++;
+            offset16--;
+            break;
+        }
+        System.arraycopy(target, offset16 + count, target, offset16, limit - (offset16 + count));
+        target[limit - count] = 0;
+        return limit - count;
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of
+     * the argument codepoint. I.e., the smallest index <code>i</code> such that
+     * <code>UTF16.charAt(source, i) ==
+     * char32</code> is true.
+     * <p>
+     * If no such character occurs in this string, then -1 is returned.
+     * </p>
+     * <p>
+     * Examples:<br>
+     * UTF16.indexOf("abc", 'a') returns 0<br>
+     * UTF16.indexOf("abc\ud800\udc00", 0x10000) returns 3<br>
+     * UTF16.indexOf("abc\ud800\udc00", 0xd800) returns -1<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param char32
+     *            codepoint to search for
+     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or
+     *         -1 if the codepoint does not occur.
+     * @stable ICU 2.6
+     */
+    public static int indexOf(String source, int char32) {
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");
+        }
+        // non-surrogate bmp
+        if (char32 < LEAD_SURROGATE_MIN_VALUE
+                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {
+            return source.indexOf((char) char32);
+        }
+        // surrogate
+        if (char32 < SUPPLEMENTARY_MIN_VALUE) {
+            int result = source.indexOf((char) char32);
+            if (result >= 0) {
+                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    return indexOf(source, char32, result + 1);
+                }
+                // trail surrogate
+                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {
+                    return indexOf(source, char32, result + 1);
+                }
+            }
+            return result;
+        }
+        // supplementary
+        String char32str = toString(char32);
+        return source.indexOf(char32str);
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of
+     * the argument string str. This method is implemented based on codepoints, hence a "lead
+     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str
+     * starts with trail surrogate character at index 0, a source with a leading a surrogate
+     * character before str found at in source will not have a valid match. Vice versa for lead
+     * surrogates that ends str. See example below.
+     * <p>
+     * If no such string str occurs in this source, then -1 is returned.
+     * </p>
+     * <p>
+     * Examples:<br>
+     * UTF16.indexOf("abc", "ab") returns 0<br>
+     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00") returns 3<br>
+     * UTF16.indexOf("abc\ud800\udc00", "\ud800") returns -1<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param str
+     *            UTF16 format Unicode string to search for
+     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or
+     *         -1 if the codepoint does not occur.
+     * @stable ICU 2.6
+     */
+    public static int indexOf(String source, String str) {
+        int strLength = str.length();
+        // non-surrogate ends
+        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {
+            return source.indexOf(str);
+        }
+
+        int result = source.indexOf(str);
+        int resultEnd = result + strLength;
+        if (result >= 0) {
+            // check last character
+            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)
+                    && isTrailSurrogate(source.charAt(resultEnd + 1))) {
+                return indexOf(source, str, resultEnd + 1);
+            }
+            // check first character which is a trail surrogate
+            if (isTrailSurrogate(str.charAt(0)) && result > 0
+                    && isLeadSurrogate(source.charAt(result - 1))) {
+                return indexOf(source, str, resultEnd + 1);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of
+     * the argument codepoint. I.e., the smallest index i such that: <br>
+     * (UTF16.charAt(source, i) == char32 && i >= fromIndex) is true.
+     * <p>
+     * If no such character occurs in this string, then -1 is returned.
+     * </p>
+     * <p>
+     * Examples:<br>
+     * UTF16.indexOf("abc", 'a', 1) returns -1<br>
+     * UTF16.indexOf("abc\ud800\udc00", 0x10000, 1) returns 3<br>
+     * UTF16.indexOf("abc\ud800\udc00", 0xd800, 1) returns -1<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param char32
+     *            codepoint to search for
+     * @param fromIndex
+     *            the index to start the search from.
+     * @return the index of the first occurrence of the codepoint in the argument Unicode string at
+     *         or after fromIndex, or -1 if the codepoint does not occur.
+     * @stable ICU 2.6
+     */
+    public static int indexOf(String source, int char32, int fromIndex) {
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");
+        }
+        // non-surrogate bmp
+        if (char32 < LEAD_SURROGATE_MIN_VALUE
+                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {
+            return source.indexOf((char) char32, fromIndex);
+        }
+        // surrogate
+        if (char32 < SUPPLEMENTARY_MIN_VALUE) {
+            int result = source.indexOf((char) char32, fromIndex);
+            if (result >= 0) {
+                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    return indexOf(source, char32, result + 1);
+                }
+                // trail surrogate
+                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {
+                    return indexOf(source, char32, result + 1);
+                }
+            }
+            return result;
+        }
+        // supplementary
+        String char32str = toString(char32);
+        return source.indexOf(char32str, fromIndex);
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the first occurrence of
+     * the argument string str. This method is implemented based on codepoints, hence a "lead
+     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str
+     * starts with trail surrogate character at index 0, a source with a leading a surrogate
+     * character before str found at in source will not have a valid match. Vice versa for lead
+     * surrogates that ends str. See example below.
+     * <p>
+     * If no such string str occurs in this source, then -1 is returned.
+     * </p>
+     * <p>
+     * Examples:<br>
+     * UTF16.indexOf("abc", "ab", 0) returns 0<br>
+     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00", 0) returns 3<br>
+     * UTF16.indexOf("abc\ud800\udc00", "\ud800\udc00", 2) returns 3<br>
+     * UTF16.indexOf("abc\ud800\udc00", "\ud800", 0) returns -1<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param str
+     *            UTF16 format Unicode string to search for
+     * @param fromIndex
+     *            the index to start the search from.
+     * @return the index of the first occurrence of the codepoint in the argument Unicode string, or
+     *         -1 if the codepoint does not occur.
+     * @stable ICU 2.6
+     */
+    public static int indexOf(String source, String str, int fromIndex) {
+        int strLength = str.length();
+        // non-surrogate ends
+        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {
+            return source.indexOf(str, fromIndex);
+        }
+
+        int result = source.indexOf(str, fromIndex);
+        int resultEnd = result + strLength;
+        if (result >= 0) {
+            // check last character
+            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)
+                    && isTrailSurrogate(source.charAt(resultEnd))) {
+                return indexOf(source, str, resultEnd + 1);
+            }
+            // check first character which is a trail surrogate
+            if (isTrailSurrogate(str.charAt(0)) && result > 0
+                    && isLeadSurrogate(source.charAt(result - 1))) {
+                return indexOf(source, str, resultEnd + 1);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of
+     * the argument codepoint. I.e., the index returned is the largest value i such that:
+     * UTF16.charAt(source, i) == char32 is true.
+     * <p>
+     * Examples:<br>
+     * UTF16.lastIndexOf("abc", 'a') returns 0<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000) returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", 0xd800) returns -1<br>
+     * </p>
+     * <p>
+     * source is searched backwards starting at the last character.
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param char32
+     *            codepoint to search for
+     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint
+     *         does not occur.
+     * @stable ICU 2.6
+     */
+    public static int lastIndexOf(String source, int char32) {
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");
+        }
+        // non-surrogate bmp
+        if (char32 < LEAD_SURROGATE_MIN_VALUE
+                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {
+            return source.lastIndexOf((char) char32);
+        }
+        // surrogate
+        if (char32 < SUPPLEMENTARY_MIN_VALUE) {
+            int result = source.lastIndexOf((char) char32);
+            if (result >= 0) {
+                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    return lastIndexOf(source, char32, result - 1);
+                }
+                // trail surrogate
+                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {
+                    return lastIndexOf(source, char32, result - 1);
+                }
+            }
+            return result;
+        }
+        // supplementary
+        String char32str = toString(char32);
+        return source.lastIndexOf(char32str);
+    }
+
+    /**
+     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of
+     * the argument string str. This method is implemented based on codepoints, hence a "lead
+     * surrogate character + trail surrogate character" is treated as one entity.e Hence if the str
+     * starts with trail surrogate character at index 0, a source with a leading a surrogate
+     * character before str found at in source will not have a valid match. Vice versa for lead
+     * surrogates that ends str. See example below.
+     * <p>
+     * Examples:<br>
+     * UTF16.lastIndexOf("abc", "a") returns 0<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00") returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800") returns -1<br>
+     * </p>
+     * <p>
+     * source is searched backwards starting at the last character.
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param str
+     *            UTF16 format Unicode string to search for
+     * @return the index of the last occurrence of the codepoint in source, or -1 if the codepoint
+     *         does not occur.
+     * @stable ICU 2.6
+     */
+    public static int lastIndexOf(String source, String str) {
+        int strLength = str.length();
+        // non-surrogate ends
+        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {
+            return source.lastIndexOf(str);
+        }
+
+        int result = source.lastIndexOf(str);
+        if (result >= 0) {
+            // check last character
+            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)
+                    && isTrailSurrogate(source.charAt(result + strLength + 1))) {
+                return lastIndexOf(source, str, result - 1);
+            }
+            // check first character which is a trail surrogate
+            if (isTrailSurrogate(str.charAt(0)) && result > 0
+                    && isLeadSurrogate(source.charAt(result - 1))) {
+                return lastIndexOf(source, str, result - 1);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of
+     * the argument codepoint, where the result is less than or equals to fromIndex.
+     * </p>
+     * <p>
+     * This method is implemented based on codepoints, hence a single surrogate character will not
+     * match a supplementary character.
+     * </p>
+     * <p>
+     * source is searched backwards starting at the last character starting at the specified index.
+     * </p>
+     * <p>
+     * Examples:<br>
+     * UTF16.lastIndexOf("abc", 'c', 2) returns 2<br>
+     * UTF16.lastIndexOf("abc", 'c', 1) returns -1<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000, 5) returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", 0x10000, 3) returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", 0xd800) returns -1<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param char32
+     *            codepoint to search for
+     * @param fromIndex
+     *            the index to start the search from. There is no restriction on the value of
+     *            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 codepoint in source, or -1 if the codepoint
+     *         does not occur.
+     * @stable ICU 2.6
+     */
+    public static int lastIndexOf(String source, int char32, int fromIndex) {
+        if (char32 < CODEPOINT_MIN_VALUE || char32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument char32 is not a valid codepoint");
+        }
+        // non-surrogate bmp
+        if (char32 < LEAD_SURROGATE_MIN_VALUE
+                || (char32 > TRAIL_SURROGATE_MAX_VALUE && char32 < SUPPLEMENTARY_MIN_VALUE)) {
+            return source.lastIndexOf((char) char32, fromIndex);
+        }
+        // surrogate
+        if (char32 < SUPPLEMENTARY_MIN_VALUE) {
+            int result = source.lastIndexOf((char) char32, fromIndex);
+            if (result >= 0) {
+                if (isLeadSurrogate((char) char32) && (result < source.length() - 1)
+                        && isTrailSurrogate(source.charAt(result + 1))) {
+                    return lastIndexOf(source, char32, result - 1);
+                }
+                // trail surrogate
+                if (result > 0 && isLeadSurrogate(source.charAt(result - 1))) {
+                    return lastIndexOf(source, char32, result - 1);
+                }
+            }
+            return result;
+        }
+        // supplementary
+        String char32str = toString(char32);
+        return source.lastIndexOf(char32str, fromIndex);
+    }
+
+    /**
+     * <p>
+     * Returns the index within the argument UTF16 format Unicode string of the last occurrence of
+     * the argument string str, where the result is less than or equals to fromIndex.
+     * </p>
+     * <p>
+     * This method is implemented based on codepoints, hence a "lead surrogate character + trail
+     * surrogate character" is treated as one entity. Hence if the str starts with trail surrogate
+     * character at index 0, a source with a leading a surrogate character before str found at in
+     * source will not have a valid match. Vice versa for lead surrogates that ends str.
+     * </p>
+     * See example below.
+     * <p>
+     * Examples:<br>
+     * UTF16.lastIndexOf("abc", "c", 2) returns 2<br>
+     * UTF16.lastIndexOf("abc", "c", 1) returns -1<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00", 5) returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800\udc00", 3) returns 3<br>
+     * UTF16.lastIndexOf("abc\ud800\udc00", "\ud800", 4) returns -1<br>
+     * </p>
+     * <p>
+     * source is searched backwards starting at the last character.
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string that will be searched
+     * @param str
+     *            UTF16 format Unicode string to search for
+     * @param fromIndex
+     *            the index to start the search from. There is no restriction on the value of
+     *            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 codepoint in source, or -1 if the codepoint
+     *         does not occur.
+     * @stable ICU 2.6
+     */
+    public static int lastIndexOf(String source, String str, int fromIndex) {
+        int strLength = str.length();
+        // non-surrogate ends
+        if (!isTrailSurrogate(str.charAt(0)) && !isLeadSurrogate(str.charAt(strLength - 1))) {
+            return source.lastIndexOf(str, fromIndex);
+        }
+
+        int result = source.lastIndexOf(str, fromIndex);
+        if (result >= 0) {
+            // check last character
+            if (isLeadSurrogate(str.charAt(strLength - 1)) && (result < source.length() - 1)
+                    && isTrailSurrogate(source.charAt(result + strLength))) {
+                return lastIndexOf(source, str, result - 1);
+            }
+            // check first character which is a trail surrogate
+            if (isTrailSurrogate(str.charAt(0)) && result > 0
+                    && isLeadSurrogate(source.charAt(result - 1))) {
+                return lastIndexOf(source, str, result - 1);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns a new UTF16 format Unicode string resulting from replacing all occurrences of
+     * oldChar32 in source with newChar32. If the character oldChar32 does not occur in the UTF16
+     * format Unicode string source, then source will be returned. Otherwise, a new String object is
+     * created that represents a codepoint sequence identical to the codepoint sequence represented
+     * by source, except that every occurrence of oldChar32 is replaced by an occurrence of
+     * newChar32.
+     * <p>
+     * Examples: <br>
+     * UTF16.replace("mesquite in your cellar", 'e', 'o');<br>
+     * returns "mosquito in your collar"<br>
+     * UTF16.replace("JonL", 'q', 'x');<br>
+     * returns "JonL" (no change)<br>
+     * UTF16.replace("Supplementary character \ud800\udc00", 0x10000, '!'); <br>
+     * returns "Supplementary character !"<br>
+     * UTF16.replace("Supplementary character \ud800\udc00", 0xd800, '!'); <br>
+     * returns "Supplementary character \ud800\udc00"<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string which the codepoint replacements will be based on.
+     * @param oldChar32
+     *            non-zero old codepoint to be replaced.
+     * @param newChar32
+     *            the new codepoint to replace oldChar32
+     * @return new String derived from source by replacing every occurrence of oldChar32 with
+     *         newChar32, unless when no oldChar32 is found in source then source will be returned.
+     * @stable ICU 2.6
+     */
+    public static String replace(String source, int oldChar32, int newChar32) {
+        if (oldChar32 <= 0 || oldChar32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument oldChar32 is not a valid codepoint");
+        }
+        if (newChar32 <= 0 || newChar32 > CODEPOINT_MAX_VALUE) {
+            throw new IllegalArgumentException("Argument newChar32 is not a valid codepoint");
+        }
+
+        int index = indexOf(source, oldChar32);
+        if (index == -1) {
+            return source;
+        }
+        String newChar32Str = toString(newChar32);
+        int oldChar32Size = 1;
+        int newChar32Size = newChar32Str.length();
+        StringBuffer result = new StringBuffer(source);
+        int resultIndex = index;
+
+        if (oldChar32 >= SUPPLEMENTARY_MIN_VALUE) {
+            oldChar32Size = 2;
+        }
+
+        while (index != -1) {
+            int endResultIndex = resultIndex + oldChar32Size;
+            result.replace(resultIndex, endResultIndex, newChar32Str);
+            int lastEndIndex = index + oldChar32Size;
+            index = indexOf(source, oldChar32, lastEndIndex);
+            resultIndex += newChar32Size + index - lastEndIndex;
+        }
+        return result.toString();
+    }
+
+    /**
+     * Returns a new UTF16 format Unicode string resulting from replacing all occurrences of oldStr
+     * in source with newStr. If the string oldStr does not occur in the UTF16 format Unicode string
+     * source, then source will be returned. Otherwise, a new String object is created that
+     * represents a codepoint sequence identical to the codepoint sequence represented by source,
+     * except that every occurrence of oldStr is replaced by an occurrence of newStr.
+     * <p>
+     * Examples: <br>
+     * UTF16.replace("mesquite in your cellar", "e", "o");<br>
+     * returns "mosquito in your collar"<br>
+     * UTF16.replace("mesquite in your cellar", "mesquite", "cat");<br>
+     * returns "cat in your cellar"<br>
+     * UTF16.replace("JonL", "q", "x");<br>
+     * returns "JonL" (no change)<br>
+     * UTF16.replace("Supplementary character \ud800\udc00", "\ud800\udc00", '!'); <br>
+     * returns "Supplementary character !"<br>
+     * UTF16.replace("Supplementary character \ud800\udc00", "\ud800", '!'); <br>
+     * returns "Supplementary character \ud800\udc00"<br>
+     * </p>
+     * Note this method is provided as support to jdk 1.3, which does not support supplementary
+     * characters to its fullest.
+     * 
+     * @param source
+     *            UTF16 format Unicode string which the replacements will be based on.
+     * @param oldStr
+     *            non-zero-length string to be replaced.
+     * @param newStr
+     *            the new string to replace oldStr
+     * @return new String derived from source by replacing every occurrence of oldStr with newStr.
+     *         When no oldStr is found in source, then source will be returned.
+     * @stable ICU 2.6
+     */
+    public static String replace(String source, String oldStr, String newStr) {
+        int index = indexOf(source, oldStr);
+        if (index == -1) {
+            return source;
+        }
+        int oldStrSize = oldStr.length();
+        int newStrSize = newStr.length();
+        StringBuffer result = new StringBuffer(source);
+        int resultIndex = index;
+
+        while (index != -1) {
+            int endResultIndex = resultIndex + oldStrSize;
+            result.replace(resultIndex, endResultIndex, newStr);
+            int lastEndIndex = index + oldStrSize;
+            index = indexOf(source, oldStr, lastEndIndex);
+            resultIndex += newStrSize + index - lastEndIndex;
+        }
+        return result.toString();
+    }
+
+    /**
+     * Reverses a UTF16 format Unicode string and replaces source's content with it. This method
+     * will reverse surrogate characters correctly, instead of blindly reversing every character.
+     * <p>
+     * Examples:<br>
+     * UTF16.reverse(new StringBuffer( "Supplementary characters \ud800\udc00\ud801\udc01"))<br>
+     * returns "\ud801\udc01\ud800\udc00 sretcarahc yratnemelppuS".
+     * 
+     * @param source
+     *            the source StringBuffer that contains UTF16 format Unicode string to be reversed
+     * @return a modified source with reversed UTF16 format Unicode string.
+     * @stable ICU 2.6
+     */
+    public static StringBuffer reverse(StringBuffer source) {
+        int length = source.length();
+        StringBuffer result = new StringBuffer(length);
+        for (int i = length; i-- > 0;) {
+            char ch = source.charAt(i);
+            if (isTrailSurrogate(ch) && i > 0) {
+                char ch2 = source.charAt(i - 1);
+                if (isLeadSurrogate(ch2)) {
+                    result.append(ch2);
+                    result.append(ch);
+                    --i;
+                    continue;
+                }
+            }
+            result.append(ch);
+        }
+        return result;
+    }
+
+    /**
+     * Check if the string contains more Unicode code points than a certain number. This is more
+     * efficient than counting all code points in the entire string and comparing that number with a
+     * threshold. This function may not need to scan the string at all if the length is within a
+     * certain range, and never needs to count more than 'number + 1' code points. Logically
+     * equivalent to (countCodePoint(s) > number). A Unicode code point may occupy either one or two
+     * code units.
+     * 
+     * @param source
+     *            The input string.
+     * @param number
+     *            The number of code points in the string is compared against the 'number'
+     *            parameter.
+     * @return boolean value for whether the string contains more Unicode code points than 'number'.
+     * @stable ICU 2.4
+     */
+    public static boolean hasMoreCodePointsThan(String source, int number) {
+        if (number < 0) {
+            return true;
+        }
+        if (source == null) {
+            return false;
+        }
+        int length = source.length();
+
+        // length >= 0 known
+        // source contains at least (length + 1) / 2 code points: <= 2
+        // chars per cp
+        if (((length + 1) >> 1) > number) {
+            return true;
+        }
+
+        // check if source does not even contain enough chars
+        int maxsupplementary = length - number;
+        if (maxsupplementary <= 0) {
+            return false;
+        }
+
+        // there are maxsupplementary = length - number more chars than
+        // asked-for code points
+
+        // count code points until they exceed and also check that there are
+        // no more than maxsupplementary supplementary code points (char pairs)
+        int start = 0;
+        while (true) {
+            if (length == 0) {
+                return false;
+            }
+            if (number == 0) {
+                return true;
+            }
+            if (isLeadSurrogate(source.charAt(start++)) && start != length
+                    && isTrailSurrogate(source.charAt(start))) {
+                start++;
+                if (--maxsupplementary <= 0) {
+                    // too many pairs - too few code points
+                    return false;
+                }
+            }
+            --number;
+        }
+    }
+
+    /**
+     * Check if the sub-range of char array, from argument start to limit, contains more Unicode
+     * code points than a certain number. This is more efficient than counting all code points in
+     * the entire char array range and comparing that number with a threshold. This function may not
+     * need to scan the char array at all if start and limit is within a certain range, and never
+     * needs to count more than 'number + 1' code points. Logically equivalent to
+     * (countCodePoint(source, start, limit) > number). A Unicode code point may occupy either one
+     * or two code units.
+     * 
+     * @param source
+     *            array of UTF-16 chars
+     * @param start
+     *            offset to substring in the source array for analyzing
+     * @param limit
+     *            offset to substring in the source array for analyzing
+     * @param number
+     *            The number of code points in the string is compared against the 'number'
+     *            parameter.
+     * @return boolean value for whether the string contains more Unicode code points than 'number'.
+     * @exception IndexOutOfBoundsException
+     *                thrown when limit &lt; start
+     * @stable ICU 2.4
+     */
+    public static boolean hasMoreCodePointsThan(char source[], int start, int limit, int number) {
+        int length = limit - start;
+        if (length < 0 || start < 0 || limit < 0) {
+            throw new IndexOutOfBoundsException(
+                    "Start and limit indexes should be non-negative and start <= limit");
+        }
+        if (number < 0) {
+            return true;
+        }
+        if (source == null) {
+            return false;
+        }
+
+        // length >= 0 known
+        // source contains at least (length + 1) / 2 code points: <= 2
+        // chars per cp
+        if (((length + 1) >> 1) > number) {
+            return true;
+        }
+
+        // check if source does not even contain enough chars
+        int maxsupplementary = length - number;
+        if (maxsupplementary <= 0) {
+            return false;
+        }
+
+        // there are maxsupplementary = length - number more chars than
+        // asked-for code points
+
+        // count code points until they exceed and also check that there are
+        // no more than maxsupplementary supplementary code points (char pairs)
+        while (true) {
+            if (length == 0) {
+                return false;
+            }
+            if (number == 0) {
+                return true;
+            }
+            if (isLeadSurrogate(source[start++]) && start != limit
+                    && isTrailSurrogate(source[start])) {
+                start++;
+                if (--maxsupplementary <= 0) {
+                    // too many pairs - too few code points
+                    return false;
+                }
+            }
+            --number;
+        }
+    }
+
+    /**
+     * Check if the string buffer contains more Unicode code points than a certain number. This is
+     * more efficient than counting all code points in the entire string buffer and comparing that
+     * number with a threshold. This function may not need to scan the string buffer at all if the
+     * length is within a certain range, and never needs to count more than 'number + 1' code
+     * points. Logically equivalent to (countCodePoint(s) > number). A Unicode code point may occupy
+     * either one or two code units.
+     * 
+     * @param source
+     *            The input string buffer.
+     * @param number
+     *            The number of code points in the string buffer is compared against the 'number'
+     *            parameter.
+     * @return boolean value for whether the string buffer contains more Unicode code points than
+     *         'number'.
+     * @stable ICU 2.4
+     */
+    public static boolean hasMoreCodePointsThan(StringBuffer source, int number) {
+        if (number < 0) {
+            return true;
+        }
+        if (source == null) {
+            return false;
+        }
+        int length = source.length();
+
+        // length >= 0 known
+        // source contains at least (length + 1) / 2 code points: <= 2
+        // chars per cp
+        if (((length + 1) >> 1) > number) {
+            return true;
+        }
+
+        // check if source does not even contain enough chars
+        int maxsupplementary = length - number;
+        if (maxsupplementary <= 0) {
+            return false;
+        }
+
+        // there are maxsupplementary = length - number more chars than
+        // asked-for code points
+
+        // count code points until they exceed and also check that there are
+        // no more than maxsupplementary supplementary code points (char pairs)
+        int start = 0;
+        while (true) {
+            if (length == 0) {
+                return false;
+            }
+            if (number == 0) {
+                return true;
+            }
+            if (isLeadSurrogate(source.charAt(start++)) && start != length
+                    && isTrailSurrogate(source.charAt(start))) {
+                start++;
+                if (--maxsupplementary <= 0) {
+                    // too many pairs - too few code points
+                    return false;
+                }
+            }
+            --number;
+        }
+    }
+
+    /**
+     * Cover JDK 1.5 API. Create a String from an array of codePoints.
+     * 
+     * @param codePoints
+     *            the code array
+     * @param offset
+     *            the start of the text in the code point array
+     * @param count
+     *            the number of code points
+     * @return a String representing the code points between offset and count
+     * @throws IllegalArgumentException
+     *             if an invalid code point is encountered
+     * @throws IndexOutOfBoundsException
+     *             if the offset or count are out of bounds.
+     * @stable ICU 3.0
+     */
+    public static String newString(int[] codePoints, int offset, int count) {
+        if (count < 0) {
+            throw new IllegalArgumentException();
+        }
+        char[] chars = new char[count];
+        int w = 0;
+        for (int r = offset, e = offset + count; r < e; ++r) {
+            int cp = codePoints[r];
+            if (cp < 0 || cp > 0x10ffff) {
+                throw new IllegalArgumentException();
+            }
+            while (true) {
+                try {
+                    if (cp < 0x010000) {
+                        chars[w] = (char) cp;
+                        w++;
+                    } else {
+                        chars[w] = (char) (LEAD_SURROGATE_OFFSET_ + (cp >> LEAD_SURROGATE_SHIFT_));
+                        chars[w + 1] = (char) (TRAIL_SURROGATE_MIN_VALUE + (cp & TRAIL_SURROGATE_MASK_));
+                        w += 2;
+                    }
+                    break;
+                } catch (IndexOutOfBoundsException ex) {
+                    int newlen = (int) (Math.ceil((double) codePoints.length * (w + 2)
+                            / (r - offset + 1)));
+                    char[] temp = new char[newlen];
+                    System.arraycopy(chars, 0, temp, 0, w);
+                    chars = temp;
+                }
+            }
+        }
+        return new String(chars, 0, w);
+    }
+
+    /**
+     * <p>
+     * UTF16 string comparator class. Allows UTF16 string comparison to be done with the various
+     * modes
+     * </p>
+     * <ul>
+     * <li> Code point comparison or code unit comparison
+     * <li> Case sensitive comparison, case insensitive comparison or case insensitive comparison
+     * with special handling for character 'i'.
+     * </ul>
+     * <p>
+     * The code unit or code point comparison differ only when comparing supplementary code points
+     * (&#92;u10000..&#92;u10ffff) to BMP code points near the end of the BMP (i.e.,
+     * &#92;ue000..&#92;uffff). In code unit comparison, high BMP code points sort after
+     * supplementary code points because they are stored as pairs of surrogates which are at
+     * &#92;ud800..&#92;udfff.
+     * </p>
+     * 
+     * @see #FOLD_CASE_DEFAULT
+     * @see #FOLD_CASE_EXCLUDE_SPECIAL_I
+     * @stable ICU 2.1
+     */
+    public static final class StringComparator implements java.util.Comparator {
+        // public constructor ------------------------------------------------
+
+        /**
+         * Default constructor that does code unit comparison and case sensitive comparison.
+         * 
+         * @stable ICU 2.1
+         */
+        public StringComparator() {
+            this(false, false, FOLD_CASE_DEFAULT);
+        }
+
+        /**
+         * Constructor that does comparison based on the argument options.
+         * 
+         * @param codepointcompare
+         *            flag to indicate true for code point comparison or false for code unit
+         *            comparison.
+         * @param ignorecase
+         *            false for case sensitive comparison, true for case-insensitive comparison
+         * @param foldcaseoption
+         *            FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I. This option is used only
+         *            when ignorecase is set to true. If ignorecase is false, this option is
+         *            ignored.
+         * @see #FOLD_CASE_DEFAULT
+         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I
+         * @throws IllegalArgumentException
+         *             if foldcaseoption is out of range
+         * @stable ICU 2.4
+         */
+        public StringComparator(boolean codepointcompare, boolean ignorecase, int foldcaseoption) {
+            setCodePointCompare(codepointcompare);
+            m_ignoreCase_ = ignorecase;
+            if (foldcaseoption < FOLD_CASE_DEFAULT || foldcaseoption > FOLD_CASE_EXCLUDE_SPECIAL_I) {
+                throw new IllegalArgumentException("Invalid fold case option");
+            }
+            m_foldCase_ = foldcaseoption;
+        }
+
+        // public data member ------------------------------------------------
+
+        /**
+         * <p>
+         * Option value for case folding comparison:
+         * </p>
+         * <p>
+         * Comparison is case insensitive, strings are folded using default mappings defined in
+         * Unicode data file CaseFolding.txt, before comparison.
+         * </p>
+         * 
+         * @stable ICU 2.4
+         */
+        public static final int FOLD_CASE_DEFAULT = 0;
+
+        /**
+         * <p>
+         * Option value for case folding comparison:
+         * </p>
+         * <p>
+         * Comparison is case insensitive, strings are folded using modified mappings defined in
+         * Unicode data file CaseFolding.txt, before comparison.
+         * </p>
+         * <p>
+         * The modified set of mappings is provided in a Unicode data file CaseFolding.txt to handle
+         * dotted I and dotless i appropriately for Turkic languages (tr, az).
+         * </p>
+         * <p>
+         * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that are to be
+         * included for default mappings and excluded for the Turkic-specific mappings.
+         * </p>
+         * <p>
+         * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that are to be
+         * excluded for default mappings and included for the Turkic-specific mappings.
+         * </p>
+         * 
+         * @stable ICU 2.4
+         */
+        public static final int FOLD_CASE_EXCLUDE_SPECIAL_I = 1;
+
+        // public methods ----------------------------------------------------
+
+        // public setters ----------------------------------------------------
+
+        /**
+         * Sets the comparison mode to code point compare if flag is true. Otherwise comparison mode
+         * is set to code unit compare
+         * 
+         * @param flag
+         *            true for code point compare, false for code unit compare
+         * @stable ICU 2.4
+         */
+        public void setCodePointCompare(boolean flag) {
+            if (flag) {
+                m_codePointCompare_ = Normalizer.COMPARE_CODE_POINT_ORDER;
+            } else {
+                m_codePointCompare_ = 0;
+            }
+        }
+
+        /**
+         * Sets the Comparator to case-insensitive comparison mode if argument is true, otherwise
+         * case sensitive comparison mode if set to false.
+         * 
+         * @param ignorecase
+         *            true for case-insitive comparison, false for case sensitive comparison
+         * @param foldcaseoption
+         *            FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I. This option is used only
+         *            when ignorecase is set to true. If ignorecase is false, this option is
+         *            ignored.
+         * @see #FOLD_CASE_DEFAULT
+         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I
+         * @stable ICU 2.4
+         */
+        public void setIgnoreCase(boolean ignorecase, int foldcaseoption) {
+            m_ignoreCase_ = ignorecase;
+            if (foldcaseoption < FOLD_CASE_DEFAULT || foldcaseoption > FOLD_CASE_EXCLUDE_SPECIAL_I) {
+                throw new IllegalArgumentException("Invalid fold case option");
+            }
+            m_foldCase_ = foldcaseoption;
+        }
+
+        // public getters ----------------------------------------------------
+
+        /**
+         * Checks if the comparison mode is code point compare.
+         * 
+         * @return true for code point compare, false for code unit compare
+         * @stable ICU 2.4
+         */
+        public boolean getCodePointCompare() {
+            return m_codePointCompare_ == Normalizer.COMPARE_CODE_POINT_ORDER;
+        }
+
+        /**
+         * Checks if Comparator is in the case insensitive mode.
+         * 
+         * @return true if Comparator performs case insensitive comparison, false otherwise
+         * @stable ICU 2.4
+         */
+        public boolean getIgnoreCase() {
+            return m_ignoreCase_;
+        }
+
+        /**
+         * Gets the fold case options set in Comparator to be used with case insensitive comparison.
+         * 
+         * @return either FOLD_CASE_DEFAULT or FOLD_CASE_EXCLUDE_SPECIAL_I
+         * @see #FOLD_CASE_DEFAULT
+         * @see #FOLD_CASE_EXCLUDE_SPECIAL_I
+         * @stable ICU 2.4
+         */
+        public int getIgnoreCaseOption() {
+            return m_foldCase_;
+        }
+
+        // public other methods ----------------------------------------------
+
+        /**
+         * Compare two strings depending on the options selected during construction.
+         * 
+         * @param a
+         *            first source string.
+         * @param b
+         *            second source string.
+         * @return 0 returned if a == b. If a < b, a negative value is returned. Otherwise if a > b,
+         *         a positive value is returned.
+         * @exception ClassCastException
+         *                thrown when either a or b is not a String object
+         * @stable ICU 2.4
+         */
+        public int compare(Object a, Object b) {
+            String str1 = (String) a;
+            String str2 = (String) b;
+
+            if (str1 == str2) {
+                return 0;
+            }
+            if (str1 == null) {
+                return -1;
+            }
+            if (str2 == null) {
+                return 1;
+            }
+
+            if (m_ignoreCase_) {
+                return compareCaseInsensitive(str1, str2);
+            }
+            return compareCaseSensitive(str1, str2);
+        }
+
+        // private data member ----------------------------------------------
+
+        /**
+         * Code unit comparison flag. True if code unit comparison is required. False if code point
+         * comparison is required.
+         */
+        private int m_codePointCompare_;
+
+        /**
+         * Fold case comparison option.
+         */
+        private int m_foldCase_;
+
+        /**
+         * Flag indicator if ignore case is to be used during comparison
+         */
+        private boolean m_ignoreCase_;
+
+        /**
+         * Code point order offset for surrogate characters
+         */
+        private static final int CODE_POINT_COMPARE_SURROGATE_OFFSET_ = 0x2800;
+
+        // private method ---------------------------------------------------
+
+        /**
+         * Compares case insensitive. This is a direct port of ICU4C, to make maintainence life
+         * easier.
+         * 
+         * @param s1
+         *            first string to compare
+         * @param s2
+         *            second string to compare
+         * @return -1 is s1 &lt; s2, 0 if equals,
+         */
+        private int compareCaseInsensitive(String s1, String s2) {
+            return NormalizerImpl.cmpEquivFold(s1, s2, m_foldCase_ | m_codePointCompare_
+                    | Normalizer.COMPARE_IGNORE_CASE);
+        }
+
+        /**
+         * Compares case sensitive. This is a direct port of ICU4C, to make maintainence life
+         * easier.
+         * 
+         * @param s1
+         *            first string to compare
+         * @param s2
+         *            second string to compare
+         * @return -1 is s1 &lt; s2, 0 if equals,
+         */
+        private int compareCaseSensitive(String s1, String s2) {
+            // compare identical prefixes - they do not need to be fixed up
+            // limit1 = start1 + min(lenght1, length2)
+            int length1 = s1.length();
+            int length2 = s2.length();
+            int minlength = length1;
+            int result = 0;
+            if (length1 < length2) {
+                result = -1;
+            } else if (length1 > length2) {
+                result = 1;
+                minlength = length2;
+            }
+
+            char c1 = 0;
+            char c2 = 0;
+            int index = 0;
+            for (; index < minlength; index++) {
+                c1 = s1.charAt(index);
+                c2 = s2.charAt(index);
+                // check pseudo-limit
+                if (c1 != c2) {
+                    break;
+                }
+            }
+
+            if (index == minlength) {
+                return result;
+            }
+
+            boolean codepointcompare = m_codePointCompare_ == Normalizer.COMPARE_CODE_POINT_ORDER;
+            // if both values are in or above the surrogate range, fix them up
+            if (c1 >= LEAD_SURROGATE_MIN_VALUE && c2 >= LEAD_SURROGATE_MIN_VALUE
+                    && codepointcompare) {
+                // subtract 0x2800 from BMP code points to make them smaller
+                // than supplementary ones
+                if ((c1 <= LEAD_SURROGATE_MAX_VALUE && (index + 1) != length1 && isTrailSurrogate(s1.charAt(index + 1)))
+                        || (isTrailSurrogate(c1) && index != 0 && isLeadSurrogate(s1.charAt(index - 1)))) {
+                    // part of a surrogate pair, leave >=d800
+                } else {
+                    // BMP code point - may be surrogate code point - make
+                    // < d800
+                    c1 -= CODE_POINT_COMPARE_SURROGATE_OFFSET_;
+                }
+
+                if ((c2 <= LEAD_SURROGATE_MAX_VALUE && (index + 1) != length2 && isTrailSurrogate(s2.charAt(index + 1)))
+                        || (isTrailSurrogate(c2) && index != 0 && isLeadSurrogate(s2.charAt(index - 1)))) {
+                    // part of a surrogate pair, leave >=d800
+                } else {
+                    // BMP code point - may be surrogate code point - make <d800
+                    c2 -= CODE_POINT_COMPARE_SURROGATE_OFFSET_;
+                }
+            }
+
+            // now c1 and c2 are in UTF-32-compatible order
+            return c1 - c2;
+        }
+    }
+
+    // private data members -------------------------------------------------
+
+    /**
+     * Shift value for lead surrogate to form a supplementary character.
+     */
+    private static final int LEAD_SURROGATE_SHIFT_ = 10;
+
+    /**
+     * Mask to retrieve the significant value from a trail surrogate.
+     */
+    private static final int TRAIL_SURROGATE_MASK_ = 0x3FF;
+
+    /**
+     * Value that all lead surrogate starts with
+     */
+    private static final int LEAD_SURROGATE_OFFSET_ = LEAD_SURROGATE_MIN_VALUE
+            - (SUPPLEMENTARY_MIN_VALUE >> LEAD_SURROGATE_SHIFT_);
+
+    // private methods ------------------------------------------------------
+
+    /**
+     * <p>
+     * Converts argument code point and returns a String object representing the code point's value
+     * in UTF16 format.
+     * </p>
+     * <p>
+     * This method does not check for the validity of the codepoint, the results are not guaranteed
+     * if a invalid codepoint is passed as argument.
+     * </p>
+     * <p>
+     * The result is a string whose length is 1 for non-supplementary code points, 2 otherwise.
+     * </p>
+     * 
+     * @param ch
+     *            code point
+     * @return string representation of the code point
+     */
+    private static String toString(int ch) {
+        if (ch < SUPPLEMENTARY_MIN_VALUE) {
+            return String.valueOf((char) ch);
+        }
+
+        StringBuffer result = new StringBuffer();
+        result.append(getLeadSurrogate(ch));
+        result.append(getTrailSurrogate(ch));
+        return result.toString();
+    }
+}
+// eof