/*
 * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 4533872 4985214 4985217 4993841 5017268 5017280 8298033
 * @summary Unit tests for supplementary character support (JSR-204)
 * @compile Supplementary.java
 * @run main/timeout=600 Supplementary
 */

public class Supplementary {
    private static final char MIN_HIGH = '\uD800';
    private static final char MAX_HIGH = '\uDBFF';
    private static final char MIN_LOW = MAX_HIGH + 1;
    private static final char MAX_LOW = '\uDFFF';
    private static final int MIN_CODE_POINT = 0x000000;
    private static final int MIN_SUPPLEMENTARY = 0x010000;
    private static final int MAX_SUPPLEMENTARY = 0x10ffff;

    public static void main(String[] args) {
        // Do not change the order of test method calls since there
        // are some interdependencies.

        testConstants();

        test00();

        // Store all Unicode code points, except for surrogate code
        // points, in cu[] through the loops below. Then, use the data
        // for code point/code unit conversion and other tests later.
        char[] cu = new char[(MAX_SUPPLEMENTARY+1) * 2];
        int length = test01(cu);

        String str = new String(cu, 0, length);
        cu = null;
        test02(str);
        test03(str.toCharArray());
        test04(str);
        test05(str);

        // Test for toString(int)
        test06();

        // Test unpaired surrogates
        testUnpaired();

        // Test exceptions
        testExceptions00();
        testExceptions01(str);
        testExceptions02(str.toCharArray());
    }

    static void testConstants() {
        if (Character.MIN_HIGH_SURROGATE != MIN_HIGH) {
            constantError("MIN_HIGH_SURROGATE", Character.MIN_HIGH_SURROGATE, MIN_HIGH);
        }
        if (Character.MAX_HIGH_SURROGATE != MAX_HIGH) {
            constantError("MAX_HIGH_SURROGATE", Character.MAX_HIGH_SURROGATE, MAX_HIGH);
        }
        if (Character.MIN_LOW_SURROGATE != MIN_LOW) {
            constantError("MIN_LOW_SURROGATE", Character.MIN_LOW_SURROGATE, MIN_LOW);
        }
        if (Character.MAX_LOW_SURROGATE != MAX_LOW) {
            constantError("MAX_LOW_SURROGATE", Character.MAX_LOW_SURROGATE, MAX_LOW);
        }
        if (Character.MIN_SURROGATE != MIN_HIGH) {
            constantError("MIN_SURROGATE", Character.MIN_SURROGATE, MIN_HIGH);
        }
        if (Character.MAX_SURROGATE != MAX_LOW) {
            constantError("MAX_SURROGATE", Character.MAX_SURROGATE, MAX_LOW);
        }
        if (Character.MIN_SUPPLEMENTARY_CODE_POINT != MIN_SUPPLEMENTARY) {
            constantError("MIN_SUPPLEMENTARY_CODE_POINT",
                          Character.MIN_SUPPLEMENTARY_CODE_POINT, MIN_SUPPLEMENTARY);
        }
        if (Character.MIN_CODE_POINT != MIN_CODE_POINT) {
            constantError("MIN_CODE_POINT", Character.MIN_CODE_POINT, MIN_CODE_POINT);
        }
        if (Character.MAX_CODE_POINT != MAX_SUPPLEMENTARY) {
            constantError("MAX_CODE_POINT", Character.MAX_CODE_POINT, MAX_SUPPLEMENTARY);
        }
    }

    static void constantError(String name, int value, int expectedValue) {
        throw new RuntimeException("Character." + name + " has a wrong value: got "
                                   + toHexString(value)
                                   + ", expected " + toHexString(expectedValue));
    }

    /*
     * Test isValidCodePoint(int)
     *      isSupplementaryCodePoint(int)
     *      charCount(int)
     */
    static void test00() {
        for (int cp = -MAX_SUPPLEMENTARY; cp <= MAX_SUPPLEMENTARY*2; cp++) {
            boolean isValid = cp >= 0 && cp <= MAX_SUPPLEMENTARY;
            if (Character.isValidCodePoint(cp) != isValid) {
                throw new RuntimeException("isValidCodePoint failed with "
                                           + toHexString(cp));
            }
            boolean isSupplementary = cp >= MIN_SUPPLEMENTARY && cp <= MAX_SUPPLEMENTARY;
            if (Character.isSupplementaryCodePoint(cp) != isSupplementary) {
                throw new RuntimeException("isSupplementaryCodePoint failed with "
                                           + toHexString(cp));
            }
            int len = Character.charCount(cp);
            if (isValid) {
                if ((isSupplementary && len != 2)
                    || (!isSupplementary && len != 1)) {
                    throw new RuntimeException("wrong character length "+len+" for "
                                               + toHexString(cp));
                }
            } else if (len != 1 && len != 2) {
                throw new RuntimeException("wrong character length "+len+" for "
                                           + toHexString(cp));
            }
        }
    }

    /**
     * Test toChar(int)
     *      toChar(int, char[], int)
     *      isHighSurrogate(char)
     *      isLowSurrogate(char)
     *      isSurrogatePair(int, int)
     *
     * While testing those methods, this method generates all Unicode
     * code points (except for surrogate code points) and store them
     * in cu.
     *
     * @return the number of code units generated in cu
     */
    static int test01(char[] cu) {
        int index = 0;
        // Test toChar(int)
        //      toChar(int, char[], int)
        //      isHighSurrogate(char)
        //      isLowSurrogate(char)
        // with BMP code points
        for (int i = 0; i <= Character.MAX_VALUE; i++) {
            char[] u = Character.toChars(i);
            if (u.length != 1 || u[0] != i) {
                throw new RuntimeException("wrong toChars(int) result for BMP: "
                                           + toHexString("u", u));
            }
            int n = Character.toChars(i, cu, index);
            if (n != 1 || cu[index] != i) {
                throw new RuntimeException("wrong toChars(int, char[], int) result for BMP:"
                                           + " len=" + n
                                           + ", cu["+index+"]="+toHexString(cu[index]));
            }
            boolean isHigh = i >= MIN_HIGH && i <= MAX_HIGH;
            if (Character.isHighSurrogate((char) i) != isHigh) {
                throw new RuntimeException("wrong high-surrogate test for "
                                           + toHexString(i));
            }
            boolean isLow = i >= MIN_LOW && i <= MAX_LOW;
            if (Character.isLowSurrogate((char)i) != isLow) {
                throw new RuntimeException("wrong low-surrogate test for "
                                           + toHexString(i));
            }
            if (!isHigh && !isLow) {
                index++;
            }
        }

        // Test isSurrogatePair with all surrogate pairs
        // Test toChars(int)
        //      toChars(int, char[], int)
        // with all supplementary characters
        int supplementary = MIN_SUPPLEMENTARY;
        for (int i = Character.MAX_VALUE/2; i <= Character.MAX_VALUE; i++) {
            char hi = (char) i;
            boolean isHigh = Character.isHighSurrogate(hi);

            for (int j = Character.MAX_VALUE/2; j <= Character.MAX_VALUE; j++) {
                char lo = (char) j;
                boolean isLow = Character.isLowSurrogate(lo);
                boolean isSurrogatePair = isHigh && isLow;
                if (Character.isSurrogatePair(hi, lo) != isSurrogatePair) {
                    throw new RuntimeException("wrong surrogate pair test for hi="
                                               + toHexString(hi)
                                               + ", lo="+toHexString(lo));
                }
                if (isSurrogatePair) {
                    int cp = Character.toCodePoint(hi, lo);
                    if (cp != supplementary) {
                        throw new RuntimeException("wrong code point: got "
                                                   + toHexString(cp)
                                                   + ", expected="
                                                   + toHexString(supplementary));
                    }
                    char[] u = Character.toChars(cp);
                    if (u.length != 2 || u[0] != hi || u[1] != lo) {
                        throw new RuntimeException("wrong toChars(int) result for supplementary: "+
                                                   toHexString("u", u));
                    }
                    int n = Character.toChars(cp, cu, index);
                    if (n != 2 || cu[index] != hi || cu[index+1] != lo) {
                        throw new RuntimeException("wrong toChars(int, char[], int) result "
                                           + "for supplementary: len=" + n
                                           + ", cu["+index+"]=" + toHexString(cu[index])
                                           + ", cu["+(index+1)+"]=" + toHexString(cu[index+1]));
                    }
                    index += n;
                    supplementary++;
                }
            }
        }
        if (supplementary != MAX_SUPPLEMENTARY + 1) {
            throw new RuntimeException("wrong supplementary count (supplementary="
                                       + toHexString(supplementary)+")");
        }

        int nCodeUnits = Character.MAX_VALUE + 1 - (MAX_LOW - MIN_HIGH + 1)
                         + ((MAX_SUPPLEMENTARY - MIN_SUPPLEMENTARY + 1) * 2);
        if (index != nCodeUnits) {
            throw new RuntimeException("wrong number of code units: " + index
                                       + ", expected " + nCodeUnits);
        }
        return index;
    }

    /**
     * Test codePointAt(CharSequence, int)
     *      codePointBefore(CharSequence, int)
     */
    static void test02(CharSequence cs) {
        int cp = 0;
        int ch;
        for (int i = 0; i < cs.length(); i += Character.charCount(ch)) {
            ch = Character.codePointAt(cs, i);
            if (ch != cp) {
                throw new RuntimeException("wrong codePointAt(CharSequence, "+i+") value: got "
                                           + toHexString(ch)
                                           + ", expected "+toHexString(cp));
            }
            cp++;
            // Skip surrogates
            if (cp == MIN_HIGH) {
                cp = MAX_LOW + 1;
            }
        }

        cp--;
        for (int i = cs.length(); i > 0; i -= Character.charCount(ch)) {
            ch = Character.codePointBefore(cs, i);
            if (ch != cp) {
                throw new RuntimeException("codePointBefore(CharSequence, "+i+") returned "
                                           + toHexString(ch)
                                           + ", expected " + toHexString(cp));
            }
            cp--;
            // Skip surrogates
            if (cp == MAX_LOW) {
                cp = MIN_HIGH - 1;
            }
        }
    }

    /**
     * Test codePointAt(char[], int)
     *      codePointAt(char[], int, int)
     *      codePointBefore(char[], int)
     *      codePointBefore(char[], int, int)
     */
    static void test03(char[] a) {
        int cp = 0;
        int ch;
        for (int i = 0; i < a.length; i += Character.charCount(ch)) {
            ch = Character.codePointAt(a, i);
            if (ch != cp) {
                throw new RuntimeException("codePointAt(char[], "+i+") returned "
                                           + toHexString(ch)
                                           + ", expected "+toHexString(cp));
            }
            int x = Character.codePointAt(a, i, i+1);
            if (x != a[i]) {
                throw new RuntimeException(String.format(
                                 "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
                                 i, i+1, x, (int)a[i]));
            }
            cp++;
            // Skip surrogates
            if (cp == MIN_HIGH) {
                cp = MAX_LOW + 1;
            }
        }

        cp--;
        for (int i = a.length; i > 0; i -= Character.charCount(ch)) {
            ch = Character.codePointBefore(a, i);
            if (ch != cp) {
                throw new RuntimeException("codePointBefore(char[], "+i+") returned "
                                           + toHexString(ch)
                                           + ", expected " + toHexString(cp));
            }
            int x = Character.codePointBefore(a, i, i-1);
            if (x != a[i-1]) {
                throw new RuntimeException(String.format(
                                 "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
                                 i, i-1, x, (int)a[i-1]));
            }
            cp--;
            // Skip surrogates
            if (cp == MAX_LOW) {
                cp = MIN_HIGH - 1;
            }
        }
    }

    /**
     * Test codePointCount(CharSequence, int, int)
     *      codePointCount(char[], int, int, int, int)
     */
    static void test04(String str) {
        int length = str.length();
        char[] a = str.toCharArray();

        for (int i = 0; i <= length; i += 99, length -= 29999) {
            int n = Character.codePointCount(str, i, length);
            int m = codePointCount(str.substring(i, length));
            checkCodePointCount(str, n, m);
            n = Character.codePointCount(a, i, length - i);
            checkCodePointCount(a, n, m);
        }

        // test special cases
        length = str.length();
        int n = Character.codePointCount(str, 0, 0);
        checkCodePointCount(str, n, 0);
        n = Character.codePointCount(str, length, length);
        checkCodePointCount(str, n, 0);
        n = Character.codePointCount(a, 0, 0);
        checkCodePointCount(a, n, 0);
        n = Character.codePointCount(a, length, 0);
        checkCodePointCount(a, n, 0);
    }

    // This method assumes that Character.codePointAt() and
    // Character.charCount() work correctly.
    private static int codePointCount(CharSequence seq) {
        int n = 0, len;
        for (int i = 0; i < seq.length(); i += len) {
            int codepoint = Character.codePointAt(seq, i);
            n++;
            len = Character.charCount(codepoint);
        }
        return n;
    }

    private static void checkCodePointCount(Object data, int n, int expected) {
        String type = getType(data);
        if (n != expected) {
            throw new RuntimeException("codePointCount(" + type + "...) returned " + n
                                       + ", expected " + expected);
        }
    }

    /**
     * Test offsetByCodePoints(CharSequence, int, int)
     *      offsetByCodePoints(char[], int, int, int, int)
     *
     * This test case assumes that Character.codePointCount()s work
     * correctly.
     */
    static void test05(String str) {
        int length = str.length();
        char[] a = str.toCharArray();

        for (int i = 0; i <= length; i += 99, length -= 29999) {
            int nCodePoints = Character.codePointCount(a, i, length - i);
            int index;

            // offsetByCodePoints(CharSequence, int, int)

            int expectedHighIndex = length;
            // For forward CharSequence scan, we need to adjust the
            // expected index in case the last char in the text range
            // is a high surrogate and forms a valid supplementary
            // code point with the next char.
            if (length < a.length) {
                int cp = Character.codePointAt(a, length - 1);
                if (Character.isSupplementaryCodePoint(cp)) {
                    expectedHighIndex++;
                }
            }
            index = Character.offsetByCodePoints(str, i, nCodePoints);
            checkNewIndex(str, nCodePoints, index, expectedHighIndex);
            int expectedLowIndex = i;
            if (i > 0) {
                int cp = Character.codePointBefore(a, i + 1);
                if (Character.isSupplementaryCodePoint(cp)) {
                    expectedLowIndex--;
                }
            }
            index = Character.offsetByCodePoints(str, length, -nCodePoints);
            checkNewIndex(str, -nCodePoints, index, expectedLowIndex);

            // offsetByCodePoints(char[], int, int, int, int)

            int start = Math.max(0, i-1);
            int limit = Math.min(a.length, length+1);
            index = Character.offsetByCodePoints(a, start, limit - start,
                                                 i, nCodePoints);
            checkNewIndex(a, nCodePoints, index, expectedHighIndex);
            if (length != expectedHighIndex) {
                index = Character.offsetByCodePoints(a, start, length - start,
                                                     i, nCodePoints);
                checkNewIndex(a, nCodePoints, index, length);
            }
            index = Character.offsetByCodePoints(a, start, limit - start,
                                                 length, -nCodePoints);
            checkNewIndex(a, -nCodePoints, index, expectedLowIndex);
            if (i != expectedLowIndex) {
                index = Character.offsetByCodePoints(a, i, limit - i,
                                                     length, -nCodePoints);
                checkNewIndex(a, -nCodePoints, index, i);
            }
        }

        // test special cases for 0-length text ranges.
        length = str.length();
        int index = Character.offsetByCodePoints(str, 0, 0);
        checkNewIndex(str, 0, index, 0);
        index = Character.offsetByCodePoints(str, length, 0);
        checkNewIndex(str, 0, index, length);
        index = Character.offsetByCodePoints(a, 0, 0, 0, 0);
        checkNewIndex(a, 0, index, 0);
        index = Character.offsetByCodePoints(a, 0, length, 0, 0);
        checkNewIndex(a, 0, index, 0);
        index = Character.offsetByCodePoints(a, 0, length, length, 0);
        checkNewIndex(a, 0, index, length);
        index = Character.offsetByCodePoints(a, length, 0, length, 0);
        checkNewIndex(a, 0, index, length);
    }

    /**
     * Test toString(int)
     *
     * This test case assumes that Character.toChars()/String(char[]) work
     * correctly.
     */
    static void test06() {
        for (int cp = Character.MIN_CODE_POINT; cp <= Character.MAX_CODE_POINT; cp++) {
            String result = Character.toString(cp);
            String expected = new String(Character.toChars(cp));
            if (!result.equals(expected)) {
                throw new RuntimeException("Wrong string is created. code point: " +
                    cp + ", result: " + result + ", expected: " + expected);
            }
        }
    }

    private static void checkNewIndex(Object data, int offset, int result, int expected) {
        String type = getType(data);
        String offsetType = (offset > 0) ? "positive" : (offset < 0) ? "negative" : "0";
        if (result != expected) {
            throw new RuntimeException("offsetByCodePoints(" + type + ", ...) ["
                                       + offsetType + " offset]"
                                       + " returned " + result
                                       + ", expected " + expected);
        }
    }

    // Test codePointAt(CharSequence, int)
    //      codePointBefore(CharSequence, int)
    //      codePointAt(char[], int)
    //      codePointBefore(char[], int)
    //      toChar(int)
    //      toChar(int, char[], int)
    // with unpaired surrogates
    static void testUnpaired() {
        testCodePoint("\uD800", new int[] { 0xD800 });
        testCodePoint("\uDC00", new int[] { 0xDC00 });
        testCodePoint("a\uD800", new int[] { 'a', 0xD800 });
        testCodePoint("a\uDC00", new int[] { 'a', 0xDC00 });
        testCodePoint("\uD800a", new int[] { 0xD800, 'a' });
        testCodePoint("\uDBFFa", new int[] { 0xDBFF, 'a' });
        testCodePoint("a\uD800\uD801", new int[] { 'a', 0xD800, 0xD801 });
        testCodePoint("a\uD800x\uDC00", new int[] { 'a', 0xD800, 'x', 0xDC00 });
        testCodePoint("\uDC00\uD800", new int[] { 0xDC00, 0xD800 });
        testCodePoint("\uD800\uDC00\uDC00", new int[] { 0x10000, 0xDC00 });
        testCodePoint("\uD800\uD800\uDC00", new int[] { 0xD800, 0x10000 });
        testCodePoint("\uD800\uD800\uD800\uD800\uDC00\uDC00\uDC00\uDC00",
                      new int[] { 0xD800, 0xD800, 0xD800, 0x10000, 0xDC00, 0xDC00, 0xDC00});
    }

    static void testCodePoint(String str, int[] codepoints) {
        int c;
        // Test Character.codePointAt/Before(CharSequence, int)
        int j = 0;
        for (int i = 0; i < str.length(); i += Character.charCount(c)) {
            c = Character.codePointAt(str, i);
            if (c != codepoints[j++]) {
                throw new RuntimeException("codePointAt(CharSequence, " + i + ") returned "
                                           + toHexString(c)
                                           + ", expected " + toHexString(codepoints[j-1]));
            }
        }
        if (j != codepoints.length) {
            throw new RuntimeException("j != codepoints.length after codePointAt(CharSequence, int)"
                                       + " (j=" + j + ")"
                                       + ", expected: " + codepoints.length);
        }

        j = codepoints.length;
        for (int i = str.length(); i > 0 ; i -= Character.charCount(c)) {
            c = Character.codePointBefore(str, i);
            if (c != codepoints[--j]) {
                throw new RuntimeException("codePointBefore(CharSequence, " + i + ") returned "
                                           + toHexString(c)
                                           + ", expected " + toHexString(codepoints[j]));
            }
        }
        if (j != 0) {
            throw new RuntimeException("j != 0 after codePointBefore(CharSequence, int)"
                                       + " (j=" + j + ")");
        }

        // Test Character.codePointAt/Before(char[], int)
        char[] a = str.toCharArray();
        j = 0;
        for (int i = 0; i < a.length; i += Character.charCount(c)) {
            c = Character.codePointAt(a, i);
            if (c != codepoints[j++]) {
                throw new RuntimeException("codePointAt(char[], " + i + ") returned "
                                           + toHexString(c)
                                           + ", expected " + toHexString(codepoints[j-1]));
            }
        }
        if (j != codepoints.length) {
            throw new RuntimeException("j != codepoints.length after codePointAt(char[], int)"
                                       + " (j=" + j + ")"
                                       + ", expected: " + codepoints.length);
        }

        j = codepoints.length;
        for (int i = a.length; i > 0 ; i -= Character.charCount(c)) {
            c = Character.codePointBefore(a, i);
            if (c != codepoints[--j]) {
                throw new RuntimeException("codePointBefore(char[], " + i + ") returned "
                                           + toHexString(c)
                                           + ", expected " + toHexString(codepoints[j]));
            }
        }
        if (j != 0) {
            throw new RuntimeException("j != 0 after codePointBefore(char[], int)"
                                       + " (j=" + j + ")");
        }

        // Test toChar(int)
        j = 0;
        for (int i = 0; i < codepoints.length; i++) {
            a = Character.toChars(codepoints[i]);
            for (int k = 0; k < a.length; k++) {
                if (str.charAt(j++) != a[k]) {
                    throw new RuntimeException("toChars(int) returned " + toHexString("result", a)
                                               + " from codepoint=" + toHexString(codepoints[i]));
                }
            }
        }

        // Test toChars(int, char[], int)
        a = new char[codepoints.length * 2];
        j = 0;
        for (int i = 0; i < codepoints.length; i++) {
            int n = Character.toChars(codepoints[i], a, j);
            j += n;
        }
        String s = new String(a, 0, j);
        if (!str.equals(s)) {
            throw new RuntimeException("toChars(int, char[], int) returned "
                                       + toHexString("dst", s.toCharArray())
                                       + ", expected " + toHexString("data", str.toCharArray()));
        }
    }

    // Test toChar(int)
    //      toChar(int, char[], int)
    //      toString(int)
    // for exceptions
    static void testExceptions00() {
        callToChars1(-1, IllegalArgumentException.class);
        callToChars1(MAX_SUPPLEMENTARY + 1, IllegalArgumentException.class);

        callToChars3(MAX_SUPPLEMENTARY, null, 0, NullPointerException.class);
        callToChars3(-MIN_SUPPLEMENTARY,    new char[2], 0, IllegalArgumentException.class);
        callToChars3(MAX_SUPPLEMENTARY + 1, new char[2], 0, IllegalArgumentException.class);
        callToChars3('A', new char[0],  0, IndexOutOfBoundsException.class);
        callToChars3('A', new char[1], -1, IndexOutOfBoundsException.class);
        callToChars3('A', new char[1],  1, IndexOutOfBoundsException.class);
        callToChars3(MIN_SUPPLEMENTARY, new char[0],  0, IndexOutOfBoundsException.class);
        callToChars3(MIN_SUPPLEMENTARY, new char[1],  0, IndexOutOfBoundsException.class);
        callToChars3(MIN_SUPPLEMENTARY, new char[2], -1, IndexOutOfBoundsException.class);
        callToChars3(MIN_SUPPLEMENTARY, new char[2],  1, IndexOutOfBoundsException.class);

        callToString(Character.MIN_CODE_POINT - 1, IllegalArgumentException.class);
        callToString(Character.MAX_CODE_POINT + 1, IllegalArgumentException.class);
    }

    static final boolean At = true, Before = false;

    /**
     * Test codePointAt(CharSequence, int)
     *      codePointBefore(CharSequence, int)
     *      codePointCount(CharSequence, int, int)
     *      offsetByCodePoints(CharSequence, int, int)
     * for exceptions
     */
    static void testExceptions01(CharSequence cs) {
        CharSequence nullSeq = null;
        // codePointAt
        callCodePoint(At, nullSeq, 0, NullPointerException.class);
        callCodePoint(At, cs, -1, IndexOutOfBoundsException.class);
        callCodePoint(At, cs, cs.length(), IndexOutOfBoundsException.class);
        callCodePoint(At, cs, cs.length()*3, IndexOutOfBoundsException.class);

        // codePointBefore
        callCodePoint(Before, nullSeq, 0, NullPointerException.class);
        callCodePoint(Before, cs, -1, IndexOutOfBoundsException.class);
        callCodePoint(Before, cs, 0, IndexOutOfBoundsException.class);
        callCodePoint(Before, cs, cs.length()+1, IndexOutOfBoundsException.class);

        // codePointCount
        callCodePointCount(nullSeq, 0, 0, NullPointerException.class);
        callCodePointCount(cs, -1, 1, IndexOutOfBoundsException.class);
        callCodePointCount(cs, 0, cs.length()+1, IndexOutOfBoundsException.class);
        callCodePointCount(cs, 3, 1, IndexOutOfBoundsException.class);

        // offsetByCodePoints
        callOffsetByCodePoints(nullSeq, 0, 0, NullPointerException.class);
        callOffsetByCodePoints(cs, -1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, cs.length()+1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, 0, cs.length()*2, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, cs.length(), 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, 0, -1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, cs.length(), -cs.length()*2,
                               IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, cs.length(), Integer.MIN_VALUE,
                               IndexOutOfBoundsException.class);
        callOffsetByCodePoints(cs, 0, Integer.MAX_VALUE, IndexOutOfBoundsException.class);
    }

    /**
     * Test codePointAt(char[], int)
     *      codePointAt(char[], int, int)
     *      codePointBefore(char[], int)
     *      codePointBefore(char[], int, int)
     *      codePointCount(char[], int, int)
     *      offsetByCodePoints(char[], int, int, int, int)
     * for exceptions
     */
    static void testExceptions02(char[] a) {
        char[] nullArray = null;
        callCodePoint(At, nullArray, 0, NullPointerException.class);
        callCodePoint(At, a, -1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, a.length, IndexOutOfBoundsException.class);
        callCodePoint(At, a, a.length*3, IndexOutOfBoundsException.class);
        callCodePoint(Before, nullArray, 0, NullPointerException.class);
        callCodePoint(Before, a, -1, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, 0, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, a.length+1, IndexOutOfBoundsException.class);

        // tests for the methods with limit
        callCodePoint(At, nullArray, 0, 1, NullPointerException.class);
        callCodePoint(At, a, 0, -1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, 0, 0, IndexOutOfBoundsException.class);
        callCodePoint(At, a, 0, a.length+1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, 2, 1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, -1, 1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, a.length, 1, IndexOutOfBoundsException.class);
        callCodePoint(At, a, a.length*3, 1, IndexOutOfBoundsException.class);
        callCodePoint(Before, nullArray, 1, 0, NullPointerException.class);
        callCodePoint(Before, a, 2, -1, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, 2, 2, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, 2, 3, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, 2, a.length, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, -1, -1, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, 0, 0, IndexOutOfBoundsException.class);
        callCodePoint(Before, a, a.length+1, a.length-1, IndexOutOfBoundsException.class);

        // codePointCount
        callCodePointCount(nullArray, 0, 0, NullPointerException.class);
        callCodePointCount(a, -1, 1, IndexOutOfBoundsException.class);
        callCodePointCount(a, 0, -1, IndexOutOfBoundsException.class);
        callCodePointCount(a, 0, a.length+1, IndexOutOfBoundsException.class);
        callCodePointCount(a, 1, a.length, IndexOutOfBoundsException.class);
        callCodePointCount(a, a.length, 1, IndexOutOfBoundsException.class);
        callCodePointCount(a, a.length+1, -1, IndexOutOfBoundsException.class);

        // offsetByCodePoints
        callOffsetByCodePoints(nullArray, 0, 0, 0, 0,  NullPointerException.class);
        callOffsetByCodePoints(a, -1, a.length, 1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length+1, 1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 10, a.length, 1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 10, a.length-10, 1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 10, 10, 21, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 20, -10, 15, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 10, 10, 15, 20, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 10, 10, 15, -20, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, -1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, a.length+1, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, 0, a.length*2, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, a.length, 1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, 0, -1, IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, a.length, -a.length*2,
                               IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, a.length, Integer.MIN_VALUE,
                               IndexOutOfBoundsException.class);
        callOffsetByCodePoints(a, 0, a.length, 0, Integer.MAX_VALUE,
                               IndexOutOfBoundsException.class);
    }

    /**
     * Test the 1-arg toChars(int) for exceptions
     */
    private static void callToChars1(int codePoint, Class expectedException) {
        try {
            char[] a = Character.toChars(codePoint);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("toChars(int) didn't throw " + expectedException.getName());
    }

    /**
     * Test the 3-arg toChars(int, char[], int) for exceptions
     */
    private static void callToChars3(int codePoint, char[] dst, int index,
                                     Class expectedException) {
        try {
            int n = Character.toChars(codePoint, dst, index);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("toChars(int,char[],int) didn't throw "
                                   + expectedException.getName());
    }

    private static void callCodePoint(boolean isAt, CharSequence cs, int index,
                                      Class expectedException) {
        try {
            int c = isAt ? Character.codePointAt(cs, index)
                         : Character.codePointBefore(cs, index);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
                                   + " didn't throw " + expectedException.getName());
    }

    private static void callCodePoint(boolean isAt, char[] a, int index,
                                      Class expectedException) {
        try {
            int c = isAt ? Character.codePointAt(a, index)
                         : Character.codePointBefore(a, index);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
                                   + " didn't throw " + expectedException.getName());
    }

    private static void callCodePoint(boolean isAt, char[] a, int index, int limit,
                                      Class<? extends Exception> expectedException) {
        try {
            int c = isAt ? Character.codePointAt(a, index, limit)
                         : Character.codePointBefore(a, index, limit);
        } catch (Exception e) {
            if (expectedException == e.getClass()) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
                                   + " didn't throw " + expectedException.getName());
    }

    private static void callCodePointCount(Object data, int beginIndex, int endIndex,
                                           Class expectedException) {
        String type = getType(data);
        try {
            int n = (data instanceof CharSequence) ?
                  Character.codePointCount((CharSequence) data, beginIndex, endIndex)
                : Character.codePointCount((char[]) data, beginIndex, endIndex);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("codePointCount(" + type + "...) didn't throw "
                                   + expectedException.getName());
    }

    private static void callOffsetByCodePoints(CharSequence seq, int index, int offset,
                                               Class expectedException) {
        try {
            int n = Character.offsetByCodePoints(seq, index, offset);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("offsetCodePointCounts(CharSequnce...) didn't throw "
                                   + expectedException.getName());
    }


    private static void callOffsetByCodePoints(char[] a, int start, int count,
                                               int index, int offset,
                                               Class expectedException) {
        try {
            int n = Character.offsetByCodePoints(a, start, count, index, offset);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("offsetCodePointCounts(char[]...) didn't throw "
                                   + expectedException.getName());
    }

    private static void callToString(int codePoint, Class expectedException) {
        try {
            String s = Character.toString(codePoint);
        } catch (Exception e) {
            if (expectedException.isInstance(e)) {
                return;
            }
            throw new RuntimeException("Unspecified exception", e);
        }
        throw new RuntimeException("toString(int) didn't throw "
                                   + expectedException.getName());
    }

    private static String getType(Object data) {
        return (data instanceof CharSequence) ? "CharSequence" : "char[]";
    }

    private static String toHexString(int c) {
        return "0x" + Integer.toHexString(c);
    }

    private static String toHexString(String name, char[] a) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < a.length; i++) {
            if (i > 0) {
                sb.append(", ");
            }
            sb.append(name).append('[').append(i).append("]=");
            sb.append(toHexString(a[i]));
        }
        return sb.toString();
    }
}
