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

package java.lang;

import java.util.Arrays;
import java.util.Locale;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import jdk.internal.misc.Unsafe;
import jdk.internal.util.ArraysSupport;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;

import static java.lang.String.UTF16;

final class StringUTF16 {

    // Return a new byte array for a UTF16-coded string for len chars
    // Throw an exception if out of range
    public static byte[] newBytesFor(int len) {
        return new byte[newBytesLength(len)];
    }

    // Check the size of a UTF16-coded string
    // Throw an exception if out of range
    public static int newBytesLength(int len) {
        if (len < 0) {
            throw new NegativeArraySizeException();
        }
        if (len >= MAX_LENGTH) {
            throw new OutOfMemoryError("UTF16 String size is " + len +
                                       ", should be less than " + MAX_LENGTH);
        }
        return len << 1;
    }

    @IntrinsicCandidate
    // intrinsic performs no bounds checks
    static void putChar(byte[] val, int index, int c) {
        assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
        index <<= 1;
        val[index++] = (byte)(c >> HI_BYTE_SHIFT);
        val[index]   = (byte)(c >> LO_BYTE_SHIFT);
    }

    @IntrinsicCandidate
    // intrinsic performs no bounds checks
    static char getChar(byte[] val, int index) {
        assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
        index <<= 1;
        return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                      ((val[index]   & 0xff) << LO_BYTE_SHIFT));
    }

    public static int length(byte[] value) {
        return value.length >> 1;
    }

    private static int codePointAt(byte[] value, int index, int end, boolean checked) {
        assert index < end;
        if (checked) {
            checkIndex(index, value);
        }
        char c1 = getChar(value, index);
        if (Character.isHighSurrogate(c1) && ++index < end) {
            if (checked) {
                checkIndex(index, value);
            }
            char c2 = getChar(value, index);
            if (Character.isLowSurrogate(c2)) {
               return Character.toCodePoint(c1, c2);
            }
        }
        return c1;
    }

    public static int codePointAt(byte[] value, int index, int end) {
       return codePointAt(value, index, end, false /* unchecked */);
    }

    private static int codePointBefore(byte[] value, int index, boolean checked) {
        --index;
        if (checked) {
            checkIndex(index, value);
        }
        char c2 = getChar(value, index);
        if (Character.isLowSurrogate(c2) && index > 0) {
            --index;
            if (checked) {
                checkIndex(index, value);
            }
            char c1 = getChar(value, index);
            if (Character.isHighSurrogate(c1)) {
               return Character.toCodePoint(c1, c2);
            }
        }
        return c2;
    }

    public static int codePointBefore(byte[] value, int index) {
        return codePointBefore(value, index, false /* unchecked */);
    }

    private static int codePointCount(byte[] value, int beginIndex, int endIndex, boolean checked) {
        assert beginIndex <= endIndex;
        int count = endIndex - beginIndex;
        int i = beginIndex;
        if (checked && i < endIndex) {
            checkBoundsBeginEnd(i, endIndex, value);
        }
        for (; i < endIndex - 1; ) {
            if (Character.isHighSurrogate(getChar(value, i++)) &&
                Character.isLowSurrogate(getChar(value, i))) {
                count--;
                i++;
            }
        }
        return count;
    }

    public static int codePointCount(byte[] value, int beginIndex, int endIndex) {
        return codePointCount(value, beginIndex, endIndex, false /* unchecked */);
    }

    public static char[] toChars(byte[] value) {
        char[] dst = new char[value.length >> 1];
        getChars(value, 0, dst.length, dst, 0);
        return dst;
    }

    /**
     * {@return an encoded byte[] for the UTF16 characters in char[]}
     * No checking is done on the characters, some may or may not be latin1.
     * @param value a char array
     * @param off an offset
     * @param len a length
     */
    @IntrinsicCandidate
    public static byte[] toBytes(char[] value, int off, int len) {
        byte[] val = newBytesFor(len);
        for (int i = 0; i < len; i++) {
            putChar(val, i, value[off]);
            off++;
        }
        return val;
    }

    // Clever way to get the coder from a byte array returned from compress
    // that maybe either latin1 or UTF16-coded
    // Equivalent to (len == val.length) ? LATIN1 : UTF16
    @ForceInline
    static byte coderFromArrayLen(byte[] value, int len) {
        return (byte) ((len - value.length) >>> Integer.SIZE - 1);
    }

    /**
     * {@return Compress the char array (containing UTF16) into a compact strings byte array}
     * If all the chars are LATIN1, it returns an array with len == count,
     * otherwise, it contains UTF16 characters.
     * <p>
     * A UTF16 array is returned *only* if at least 1 non-latin1 character is present.
     * This must be true even if the input array is modified while this method is executing.
     * This is assured by copying the characters while checking for latin1.
     * If all characters are latin1, a byte array with length equals count is returned,
     * indicating all latin1 chars. The scan may be implemented as an intrinsic,
     * which returns the index of the first non-latin1 character.
     * When the first non-latin1 character is found, it switches to creating a new
     * buffer; the saved prefix of latin1 characters is copied to the new buffer;
     * and the remaining input characters are copied to the buffer.
     * The index of the known non-latin1 character is checked, if it is latin1,
     * the input has been changed. In this case, a second attempt is made to compress to
     * latin1 from the copy made in the first pass to the originally allocated latin1 buffer.
     * If it succeeds the return value is latin1, otherwise, the utf16 value is returned.
     * In this unusual case, the result is correct for the snapshot of the value.
     * The resulting string contents are unspecified if the input array is modified during this
     * operation, but it is ensured that at least 1 non-latin1 character is present in
     * the non-latin1 buffer.
     *
     * @param val   a char array
     * @param off   starting offset
     * @param count count of chars to be compressed, {@code count} > 0
     */
    @ForceInline
    public static byte[] compress(final char[] val, final int off, final int count) {
        byte[] latin1 = new byte[count];
        int ndx = compress(val, off, latin1, 0, count);
        if (ndx != count) {
            // Switch to UTF16
            byte[] utf16 = toBytes(val, off, count);
            // If the original character that was found to be non-latin1 is latin1 in the copy
            // try to make a latin1 string from the copy
            if (getChar(utf16, ndx) > 0xff
                    || compress(utf16, 0, latin1, 0, count) != count) {
                return utf16;
            }
        }
        return latin1;     // latin1 success
    }

    /**
     * {@return Compress the internal byte array (containing UTF16) into a compact strings byte array}
     * If all the chars are LATIN1, it returns an array with len == count,
     * otherwise, it contains UTF16 characters.
     * <p>
     * Refer to the description of the algorithm in {@link #compress(char[], int, int)}.
     *
     * @param val   a byte array with UTF16 coding
     * @param off   starting offset
     * @param count count of chars to be compressed, {@code count} > 0
     */
    public static byte[] compress(final byte[] val, final int off, final int count) {
        byte[] latin1 = new byte[count];
        int ndx = compress(val, off, latin1, 0, count);
        if (ndx != count) {// Switch to UTF16
            byte[] utf16 = Arrays.copyOfRange(val, off << 1, newBytesLength(off + count));
            // If the original character that was found to be non-latin1 is latin1 in the copy
            // try to make a latin1 string from the copy
            if (getChar(utf16, ndx) > 0xff
                    || compress(utf16, 0, latin1, 0, count) != count) {
                return utf16;
            }
        }
        return latin1;     // latin1 success
    }

    /**
     * {@return compress the code points into a compact strings byte array}
     * If all the chars are LATIN1, returns an array with len == count.
     * If not, a new byte array is allocated and code points converted to UTF16.
     * The algorithm is similar to that of {@link #compress(char[], int, int)}.
     * <p>
     * The resulting encoding is attempted in several steps:
     * <UL>
     *     <LI>If no non-latin1 characters are found, the encoding is latin1</LI>
     *     <LI>If an estimate of the number of characters needed to represent the codepoints is
     *         equal to the string length, they are all BMP with at least 1 UTF16 character
     *         and are copied to the result. </LI>
     *     <LI>The extractCodePoints method is called to carefully expand surrogates. </LI>
     * </UL>
     *
     * @param val   an int array of code points
     * @param off   starting offset
     * @param count length of code points to be compressed, length > 0
     */
    public static byte[] compress(final int[] val, int off, final int count) {
        // Optimistically copy all latin1 code points to the destination
        byte[] latin1 = new byte[count];
        final int end = off + count;
        for (int ndx = 0; ndx < count; ndx++, off++) {
            int cp = val[off];
            if (cp >= 0 && cp <= 0xff) {
                latin1[ndx] = (byte)cp;
            } else {
                // Pass 1: Compute precise size of char[]; see extractCodePoints for caveat
                int estSize = ndx + computeCodePointSize(val, off, end);

                // Pass 2: Switch to UTF16
                // cp = val[ndx] is at least one code point known to be UTF16
                byte[] utf16 = newBytesFor(estSize);
                if (ndx > 0) {
                    StringLatin1.inflate(latin1, 0, utf16, 0, ndx); // inflate latin1 bytes
                }

                if (estSize == count) {
                    // Based on the computed size, all remaining code points are BMP and
                    // can be copied without checking again
                    putChar(utf16, ndx, cp);        // ensure utf16 has a UTF16 char
                    off++;
                    for (int i = ndx + 1; i < count; i++, off++) {
                        putChar(utf16, i, val[off]);
                    }
                } else {
                    // Some codepoint is a surrogate pair
                    utf16 = extractCodepoints(val, off, end, utf16, ndx);

                    // The original character that was found to be UTF16 is not UTF16 in the copy
                    // Try to make a latin1 string from the copy
                    if (getChar(utf16, ndx) <= 0xff &&
                            compress(utf16, 0, latin1, 0, count) == count) {
                        return latin1;     // latin1 success
                    }
                }
                return utf16;
            }
        }
        return latin1;     // Latin1 success
    }

    // Extract code points into chars in the byte array
    //
    // Guard against possible races with the input array changing between the previous
    // computation of the required output size and storing the bmp or surrogates.
    // If a BMP code point is changed to a supplementary code point it would require 2 chars
    // in the output. Changing a supplementary char to BMP would reduce the size.
    // If the utf16 destination is not large enough, it is resized to fit the
    // remaining codepoints assuming they occupy 2 characters.
    // The destination may be copied to return exactly the final length.
    // The additional allocations and compression only occur if the input array is modified.
    private static byte[] extractCodepoints(int[] val, int off, int end, byte[] dst, int dstOff) {
        while (off < end) {
            // Compute a minimum estimate on the number of characters can be put into the dst
            // given the current codepoint and the number of remaining codepoints
            int codePoint = val[off];           // read each codepoint from val only once
            int dstLimit = dstOff
                    + Character.charCount(codePoint)
                    + (end - off - 1);
            if (dstLimit > (dst.length >> 1)) {
                // Resize to hold the remaining codepoints assuming they are all surrogates.
                // By resizing to the maximum that might be needed, only a single resize will occur.
                // dstLimit includes only a single char per codepoint, pad with an additional for each.
                int maxRemaining = dstLimit + (end - off - 1);
                dst = Arrays.copyOf(dst, newBytesLength(maxRemaining));
            }
            // Efficiently copy as many codepoints as fit within the current estimated limit
            // The dst at least enough space for the current codepoint.
            while (true) {
                if (Character.isBmpCodePoint(codePoint)) {
                    putChar(dst, dstOff++, codePoint);
                } else {
                    putChar(dst, dstOff++, Character.highSurrogate(codePoint));
                    putChar(dst, dstOff++, Character.lowSurrogate(codePoint));
                }
                off++;
                if (dstOff + 2 > dstLimit)
                    break;      // no space for another surrogate; recompute limit
                codePoint = val[off];
            }
        }
        if (dstOff != (dst.length >> 1)) {
            // Truncate to actual length; should only occur if a codepoint was racily
            // changed from a surrogate to a BMP character.
            return Arrays.copyOf(dst, newBytesLength(dstOff));
        }
        return dst;
    }

    // Compute the number of chars needed to represent the code points from off to end-1
    private static int computeCodePointSize(int[] val, int off, int end) {
        int n = end - off;
        while (off < end) {
            int codePoint = val[off++];
            if (Character.isBmpCodePoint(codePoint)) {
                continue;
            } else if (Character.isValidCodePoint(codePoint)) {
                n++;
            } else {
                throw new IllegalArgumentException(Integer.toString(codePoint));
            }
        }
        return n;
    }

    // compressedCopy char[] -> byte[]
    @IntrinsicCandidate
    public static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
        for (int i = 0; i < len; i++) {
            char c = src[srcOff];
            if (c > 0xff) {
                return i;  // return index of non-latin1 char
            }
            dst[dstOff] = (byte)c;
            srcOff++;
            dstOff++;
        }
        return len;
    }

    // compressedCopy byte[] -> byte[]
    @IntrinsicCandidate
    public static int compress(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
        // We need a range check here because 'getChar' has no checks
        checkBoundsOffCount(srcOff, len, src);
        for (int i = 0; i < len; i++) {
            char c = getChar(src, srcOff);
            if (c > 0xff) {
                return i;  // return index of non-latin1 char
            }
            dst[dstOff] = (byte)c;
            srcOff++;
            dstOff++;
        }
        return len;
    }

    // Create the UTF16 buffer for !COMPACT_STRINGS
    public static byte[] toBytes(int[] val, int index, int len) {
        final int end = index + len;
        int n = computeCodePointSize(val, index, end);

        byte[] buf = newBytesFor(n);
        return extractCodepoints(val, index, end, buf, 0);
     }

    public static byte[] toBytes(char c) {
        byte[] result = new byte[2];
        putChar(result, 0, c);
        return result;
    }

    static byte[] toBytesSupplementary(int cp) {
        byte[] result = new byte[4];
        putChar(result, 0, Character.highSurrogate(cp));
        putChar(result, 1, Character.lowSurrogate(cp));
        return result;
    }

    @IntrinsicCandidate
    public static void getChars(byte[] value, int srcBegin, int srcEnd, char[] dst, int dstBegin) {
        // We need a range check here because 'getChar' has no checks
        if (srcBegin < srcEnd) {
            checkBoundsOffCount(srcBegin, srcEnd - srcBegin, value);
        }
        for (int i = srcBegin; i < srcEnd; i++) {
            dst[dstBegin++] = getChar(value, i);
        }
    }

    /* @see java.lang.String.getBytes(int, int, byte[], int) */
    public static void getBytes(byte[] value, int srcBegin, int srcEnd, byte[] dst, int dstBegin) {
        srcBegin <<= 1;
        srcEnd <<= 1;
        for (int i = srcBegin + (1 >> LO_BYTE_SHIFT); i < srcEnd; i += 2) {
            dst[dstBegin++] = value[i];
        }
    }

    @IntrinsicCandidate
    public static int compareTo(byte[] value, byte[] other) {
        int len1 = length(value);
        int len2 = length(other);
        return compareValues(value, other, len1, len2);
    }

    /*
     * Checks the boundary and then compares the byte arrays.
     */
    public static int compareTo(byte[] value, byte[] other, int len1, int len2) {
        checkOffset(len1, value);
        checkOffset(len2, other);

        return compareValues(value, other, len1, len2);
    }

    private static int compareValues(byte[] value, byte[] other, int len1, int len2) {
        int lim = Math.min(len1, len2);
        for (int k = 0; k < lim; k++) {
            char c1 = getChar(value, k);
            char c2 = getChar(other, k);
            if (c1 != c2) {
                return c1 - c2;
            }
        }
        return len1 - len2;
    }

    @IntrinsicCandidate
    public static int compareToLatin1(byte[] value, byte[] other) {
        return -StringLatin1.compareToUTF16(other, value);
    }

    public static int compareToLatin1(byte[] value, byte[] other, int len1, int len2) {
        return -StringLatin1.compareToUTF16(other, value, len2, len1);
    }

    public static int compareToCI(byte[] value, byte[] other) {
        return compareToCIImpl(value, 0, length(value), other, 0, length(other));
    }

    private static int compareToCIImpl(byte[] value, int toffset, int tlen,
                                      byte[] other, int ooffset, int olen) {
        int tlast = toffset + tlen;
        int olast = ooffset + olen;
        assert toffset >= 0 && ooffset >= 0;
        assert tlast <= length(value);
        assert olast <= length(other);

        for (int k1 = toffset, k2 = ooffset; k1 < tlast && k2 < olast; k1++, k2++) {
            int cp1 = (int)getChar(value, k1);
            int cp2 = (int)getChar(other, k2);

            if (cp1 == cp2 || compareCodePointCI(cp1, cp2) == 0) {
                continue;
            }

            // Check for supplementary characters case
            cp1 = codePointIncluding(value, cp1, k1, toffset, tlast);
            if (cp1 < 0) {
                k1++;
                cp1 = -cp1;
            }
            cp2 = codePointIncluding(other, cp2, k2, ooffset, olast);
            if (cp2 < 0) {
                k2++;
                cp2 = -cp2;
            }

            int diff = compareCodePointCI(cp1, cp2);
            if (diff != 0) {
                return diff;
            }
        }
        return tlen - olen;
    }

    // Case insensitive comparison of two code points
    private static int compareCodePointCI(int cp1, int cp2) {
        // try converting both characters to uppercase.
        // If the results match, then the comparison scan should
        // continue.
        cp1 = Character.toUpperCase(cp1);
        cp2 = Character.toUpperCase(cp2);
        if (cp1 != cp2) {
            // Unfortunately, conversion to uppercase does not work properly
            // for the Georgian alphabet, which has strange rules about case
            // conversion.  So we need to make one last check before
            // exiting.
            cp1 = Character.toLowerCase(cp1);
            cp2 = Character.toLowerCase(cp2);
            if (cp1 != cp2) {
                return cp1 - cp2;
            }
        }
        return 0;
    }

    // Returns a code point from the code unit pointed by "index". If it is
    // not a surrogate or an unpaired surrogate, then the code unit is
    // returned as is. Otherwise, it is combined with the code unit before
    // or after, depending on the type of the surrogate at index, to make a
    // supplementary code point. The return value will be negated if the code
    // unit pointed by index is a high surrogate, and index + 1 is a low surrogate.
    private static int codePointIncluding(byte[] ba, int cp, int index, int start, int end) {
        // fast check
        if (!Character.isSurrogate((char)cp)) {
            return cp;
        }
        if (Character.isLowSurrogate((char)cp)) {
            if (index > start) {
                char c = getChar(ba, index - 1);
                if (Character.isHighSurrogate(c)) {
                    return Character.toCodePoint(c, (char)cp);
                }
            }
        } else if (index + 1 < end) { // cp == high surrogate
            char c = getChar(ba, index + 1);
            if (Character.isLowSurrogate(c)) {
                // negate the code point
                return - Character.toCodePoint((char)cp, c);
            }
        }
        return cp;
    }

    public static int compareToCI_Latin1(byte[] value, byte[] other) {
        return -StringLatin1.compareToCI_UTF16(other, value);
    }

    public static int hashCode(byte[] value) {
        return ArraysSupport.hashCodeOfUTF16(value, 0, value.length >> 1, 0);
    }

    // Caller must ensure that from- and toIndex are within bounds
    public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) {
        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            // handle most cases here (ch is a BMP code point or a
            // negative value (invalid code point))
            return indexOfChar(value, ch, fromIndex, toIndex);
        } else {
            return indexOfSupplementary(value, ch, fromIndex, toIndex);
        }
    }

    @IntrinsicCandidate
    public static int indexOf(byte[] value, byte[] str) {
        if (str.length == 0) {
            return 0;
        }
        if (value.length < str.length) {
            return -1;
        }
        return indexOfUnsafe(value, length(value), str, length(str), 0);
    }

    @IntrinsicCandidate
    public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
        checkBoundsBeginEnd(fromIndex, valueCount, value);
        checkBoundsBeginEnd(0, strCount, str);
        return indexOfUnsafe(value, valueCount, str, strCount, fromIndex);
    }


    private static int indexOfUnsafe(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
        assert fromIndex >= 0;
        assert strCount > 0;
        assert strCount <= length(str);
        assert valueCount >= strCount;
        char first = getChar(str, 0);
        int max = (valueCount - strCount);
        for (int i = fromIndex; i <= max; i++) {
            // Look for first character.
            if (getChar(value, i) != first) {
                while (++i <= max && getChar(value, i) != first);
            }
            // Found first character, now look at the rest of value
            if (i <= max) {
                int j = i + 1;
                int end = j + strCount - 1;
                for (int k = 1; j < end && getChar(value, j) == getChar(str, k); j++, k++);
                if (j == end) {
                    // Found whole string.
                    return i;
                }
            }
        }
        return -1;
    }


    /**
     * Handles indexOf Latin1 substring in UTF16 string.
     */
    @IntrinsicCandidate
    public static int indexOfLatin1(byte[] value, byte[] str) {
        if (str.length == 0) {
            return 0;
        }
        if (length(value) < str.length) {
            return -1;
        }
        return indexOfLatin1Unsafe(value, length(value), str, str.length, 0);
    }

    @IntrinsicCandidate
    public static int indexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) {
        checkBoundsBeginEnd(fromIndex, srcCount, src);
        String.checkBoundsBeginEnd(0, tgtCount, tgt.length);
        return indexOfLatin1Unsafe(src, srcCount, tgt, tgtCount, fromIndex);
    }

    public static int indexOfLatin1Unsafe(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) {
        assert fromIndex >= 0;
        assert tgtCount > 0;
        assert tgtCount <= tgt.length;
        assert srcCount >= tgtCount;
        char first = (char)(tgt[0] & 0xff);
        int max = (srcCount - tgtCount);
        for (int i = fromIndex; i <= max; i++) {
            // Look for first character.
            if (getChar(src, i) != first) {
                while (++i <= max && getChar(src, i) != first);
            }
            // Found first character, now look at the rest of v2
            if (i <= max) {
                int j = i + 1;
                int end = j + tgtCount - 1;
                for (int k = 1;
                     j < end && getChar(src, j) == (tgt[k] & 0xff);
                     j++, k++);
                if (j == end) {
                    // Found whole string.
                    return i;
                }
            }
        }
        return -1;
    }

    @IntrinsicCandidate
    private static int indexOfChar(byte[] value, int ch, int fromIndex, int max) {
        for (int i = fromIndex; i < max; i++) {
            if (getChar(value, i) == ch) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Handles (rare) calls of indexOf with a supplementary character.
     */
    private static int indexOfSupplementary(byte[] value, int ch, int fromIndex, int max) {
        if (Character.isValidCodePoint(ch)) {
            final char hi = Character.highSurrogate(ch);
            final char lo = Character.lowSurrogate(ch);
            checkBoundsBeginEnd(fromIndex, max, value);
            for (int i = fromIndex; i < max - 1; i++) {
                if (getChar(value, i) == hi && getChar(value, i + 1) == lo) {
                    return i;
                }
            }
        }
        return -1;
    }

    // srcCoder == UTF16 && tgtCoder == UTF16
    public static int lastIndexOf(byte[] src, int srcCount,
                                  byte[] tgt, int tgtCount, int fromIndex) {
        assert fromIndex >= 0;
        assert tgtCount > 0;
        assert tgtCount <= length(tgt);
        int min = tgtCount - 1;
        int i = min + fromIndex;
        int strLastIndex = tgtCount - 1;

        checkIndex(strLastIndex, tgt);
        char strLastChar = getChar(tgt, strLastIndex);

        checkIndex(i, src);

    startSearchForLastChar:
        while (true) {
            while (i >= min && getChar(src, i) != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - strLastIndex;
            int k = strLastIndex - 1;
            while (j > start) {
                if (getChar(src, j--) != getChar(tgt, k--)) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start + 1;
        }
    }

    public static int lastIndexOf(byte[] value, int ch, int fromIndex) {
        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            // handle most cases here (ch is a BMP code point or a
            // negative value (invalid code point))
            int i = Math.min(fromIndex, (value.length >> 1) - 1);
            for (; i >= 0; i--) {
                if (getChar(value, i) == ch) {
                    return i;
                }
            }
            return -1;
        } else {
            return lastIndexOfSupplementary(value, ch, fromIndex);
        }
    }

    /**
     * Handles (rare) calls of lastIndexOf with a supplementary character.
     */
    private static int lastIndexOfSupplementary(final byte[] value, int ch, int fromIndex) {
        if (Character.isValidCodePoint(ch)) {
            char hi = Character.highSurrogate(ch);
            char lo = Character.lowSurrogate(ch);
            int i = Math.min(fromIndex, (value.length >> 1) - 2);
            for (; i >= 0; i--) {
                if (getChar(value, i) == hi && getChar(value, i + 1) == lo) {
                    return i;
                }
            }
        }
        return -1;
    }

    public static String replace(byte[] value, char oldChar, char newChar) {
        int len = value.length >> 1;
        int i = -1;
        while (++i < len) {
            if (getChar(value, i) == oldChar) {
                break;
            }
        }
        if (i < len) {
            byte[] buf = new byte[value.length];
            for (int j = 0; j < i; j++) {
                putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
            }
            while (i < len) {
                char c = getChar(value, i);
                putChar(buf, i, c == oldChar ? newChar : c);
                i++;
            }
            // Check if we should try to compress to latin1
            if (String.COMPACT_STRINGS &&
                !StringLatin1.canEncode(oldChar) &&
                StringLatin1.canEncode(newChar)) {
                byte[] res = StringUTF16.compress(buf, 0, len);
                byte coder = StringUTF16.coderFromArrayLen(res, len);
                return new String(res, coder);
            }
            return new String(buf, UTF16);
        }
        return null;
    }

    public static String replace(byte[] value, int valLen, boolean valLat1,
                                 byte[] targ, int targLen, boolean targLat1,
                                 byte[] repl, int replLen, boolean replLat1)
    {
        assert targLen > 0;
        assert !valLat1 || !targLat1 || !replLat1;

        //  Possible combinations of the arguments/result encodings:
        //  +---+--------+--------+--------+-----------------------+
        //  | # | VALUE  | TARGET | REPL   | RESULT                |
        //  +===+========+========+========+=======================+
        //  | 1 | Latin1 | Latin1 |  UTF16 | null or UTF16         |
        //  +---+--------+--------+--------+-----------------------+
        //  | 2 | Latin1 |  UTF16 | Latin1 | null                  |
        //  +---+--------+--------+--------+-----------------------+
        //  | 3 | Latin1 |  UTF16 |  UTF16 | null                  |
        //  +---+--------+--------+--------+-----------------------+
        //  | 4 |  UTF16 | Latin1 | Latin1 | null or UTF16         |
        //  +---+--------+--------+--------+-----------------------+
        //  | 5 |  UTF16 | Latin1 |  UTF16 | null or UTF16         |
        //  +---+--------+--------+--------+-----------------------+
        //  | 6 |  UTF16 |  UTF16 | Latin1 | null, Latin1 or UTF16 |
        //  +---+--------+--------+--------+-----------------------+
        //  | 7 |  UTF16 |  UTF16 |  UTF16 | null or UTF16         |
        //  +---+--------+--------+--------+-----------------------+

        if (String.COMPACT_STRINGS && valLat1 && !targLat1) {
            // combinations 2 or 3
            return null; // for string to return this;
        }

        int i = (String.COMPACT_STRINGS && valLat1)
                        ? StringLatin1.indexOf(value, targ) :
                (String.COMPACT_STRINGS && targLat1)
                        ? indexOfLatin1(value, targ)
                        : indexOf(value, targ);
        if (i < 0) {
            return null; // for string to return this;
        }

        // find and store indices of substrings to replace
        int j, p = 0;
        int[] pos = new int[16];
        pos[0] = i;
        i += targLen;
        while ((j = ((String.COMPACT_STRINGS && valLat1)
                            ? StringLatin1.indexOf(value, valLen, targ, targLen, i) :
                     (String.COMPACT_STRINGS && targLat1)
                            ? indexOfLatin1(value, valLen, targ, targLen, i)
                            : indexOf(value, valLen, targ, targLen, i))) > 0)
        {
            if (++p == pos.length) {
                pos = Arrays.copyOf(pos, ArraysSupport.newLength(p, 1, p >> 1));
            }
            pos[p] = j;
            i = j + targLen;
        }

        int resultLen;
        try {
            resultLen = Math.addExact(valLen,
                    Math.multiplyExact(++p, replLen - targLen));
        } catch (ArithmeticException ignored) {
           throw new OutOfMemoryError("Required length exceeds implementation limit");
        }
        if (resultLen == 0) {
            return "";
        }

        byte[] result = newBytesFor(resultLen);
        int posFrom = 0, posTo = 0;
        for (int q = 0; q < p; ++q) {
            int nextPos = pos[q];
            if (String.COMPACT_STRINGS && valLat1) {
                while (posFrom < nextPos) {
                    char c = (char)(value[posFrom++] & 0xff);
                    putChar(result, posTo++, c);
                }
            } else {
                while (posFrom < nextPos) {
                    putChar(result, posTo++, getChar(value, posFrom++));
                }
            }
            posFrom += targLen;
            if (String.COMPACT_STRINGS && replLat1) {
                for (int k = 0; k < replLen; ++k) {
                    char c = (char)(repl[k] & 0xff);
                    putChar(result, posTo++, c);
                }
            } else {
                for (int k = 0; k < replLen; ++k) {
                    putChar(result, posTo++, getChar(repl, k));
                }
            }
        }
        if (String.COMPACT_STRINGS && valLat1) {
            while (posFrom < valLen) {
                char c = (char)(value[posFrom++] & 0xff);
                putChar(result, posTo++, c);
            }
        } else {
            while (posFrom < valLen) {
                putChar(result, posTo++, getChar(value, posFrom++));
            }
        }

        if (String.COMPACT_STRINGS && replLat1 && !targLat1) {
            // combination 6
            byte[] res = StringUTF16.compress(result, 0, resultLen);
            byte coder = StringUTF16.coderFromArrayLen(res, resultLen);
            return new String(res, coder);    // combination 6
        }
        return new String(result, UTF16);
    }

    public static boolean regionMatchesCI(byte[] value, int toffset,
                                          byte[] other, int ooffset, int len) {
        return compareToCIImpl(value, toffset, len, other, ooffset, len) == 0;
    }

    public static boolean regionMatchesCI_Latin1(byte[] value, int toffset,
                                                 byte[] other, int ooffset,
                                                 int len) {
        return StringLatin1.regionMatchesCI_UTF16(other, ooffset, value, toffset, len);
    }

    public static String toLowerCase(String str, byte[] value, Locale locale) {
        if (locale == null) {
            throw new NullPointerException();
        }
        int first;
        boolean hasSurr = false;
        final int len = value.length >> 1;

        // Now check if there are any characters that need to be changed, or are surrogate
        for (first = 0 ; first < len; first++) {
            int cp = (int)getChar(value, first);
            if (Character.isSurrogate((char)cp)) {
                hasSurr = true;
                break;
            }
            if (cp != Character.toLowerCase(cp)) {  // no need to check Character.ERROR
                break;
            }
        }
        if (first == len)
            return str;
        byte[] result = new byte[value.length];
        System.arraycopy(value, 0, result, 0, first << 1);  // Just copy the first few
                                                            // lowerCase characters.
        String lang = locale.getLanguage();
        if (lang == "tr" || lang == "az" || lang == "lt") {
            return toLowerCaseEx(str, value, result, first, locale, true);
        }
        if (hasSurr) {
            return toLowerCaseEx(str, value, result, first, locale, false);
        }
        int bits = 0;
        for (int i = first; i < len; i++) {
            int cp = (int)getChar(value, i);
            if (cp == '\u03A3' ||                       // GREEK CAPITAL LETTER SIGMA
                Character.isSurrogate((char)cp)) {
                return toLowerCaseEx(str, value, result, i, locale, false);
            }
            if (cp == '\u0130') {                       // LATIN CAPITAL LETTER I WITH DOT ABOVE
                return toLowerCaseEx(str, value, result, i, locale, true);
            }
            cp = Character.toLowerCase(cp);
            if (!Character.isBmpCodePoint(cp)) {
                return toLowerCaseEx(str, value, result, i, locale, false);
            }
            bits |= cp;
            putChar(result, i, cp);
        }
        if (bits < 0 || bits > 0xff) {
            return new String(result, UTF16);
        } else {
            return newString(result, 0, len);
        }
    }

    private static String toLowerCaseEx(String str, byte[] value,
                                        byte[] result, int first, Locale locale,
                                        boolean localeDependent) {
        assert(result.length == value.length);
        assert(first >= 0);
        int resultOffset = first;
        int length = value.length >> 1;
        int srcCount;
        for (int i = first; i < length; i += srcCount) {
            int srcChar = getChar(value, i);
            int lowerChar;
            char[] lowerCharArray;
            srcCount = 1;
            if (Character.isSurrogate((char)srcChar)) {
                srcChar = codePointAt(value, i, length);
                srcCount = Character.charCount(srcChar);
            }
            if (localeDependent ||
                srcChar == '\u03A3' ||  // GREEK CAPITAL LETTER SIGMA
                srcChar == '\u0130') {  // LATIN CAPITAL LETTER I WITH DOT ABOVE
                lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
            } else {
                lowerChar = Character.toLowerCase(srcChar);
            }
            if (Character.isBmpCodePoint(lowerChar)) {    // Character.ERROR is not a bmp
                putChar(result, resultOffset++, lowerChar);
            } else {
                if (lowerChar == Character.ERROR) {
                    lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
                } else {
                    lowerCharArray = Character.toChars(lowerChar);
                }
                /* Grow result if needed */
                int mapLen = lowerCharArray.length;
                if (mapLen > srcCount) {
                    byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
                    result = result2;
                }
                assert resultOffset >= 0;
                assert resultOffset + mapLen <= length(result);
                for (int x = 0; x < mapLen; ++x) {
                    putChar(result, resultOffset++, lowerCharArray[x]);
                }
            }
        }
        return newString(result, 0, resultOffset);
    }

    public static String toUpperCase(String str, byte[] value, Locale locale) {
        if (locale == null) {
            throw new NullPointerException();
        }
        int first;
        boolean hasSurr = false;
        final int len = value.length >> 1;

        // Now check if there are any characters that need to be changed, or are surrogate
        for (first = 0 ; first < len; first++) {
            int cp = (int)getChar(value, first);
            if (Character.isSurrogate((char)cp)) {
                hasSurr = true;
                break;
            }
            if (cp != Character.toUpperCaseEx(cp)) {   // no need to check Character.ERROR
                break;
            }
        }
        if (first == len) {
            return str;
        }
        byte[] result = new byte[value.length];
        System.arraycopy(value, 0, result, 0, first << 1); // Just copy the first few
                                                           // upperCase characters.
        String lang = locale.getLanguage();
        if (lang == "tr" || lang == "az" || lang == "lt") {
            return toUpperCaseEx(str, value, result, first, locale, true);
        }
        if (hasSurr) {
            return toUpperCaseEx(str, value, result, first, locale, false);
        }
        int bits = 0;
        for (int i = first; i < len; i++) {
            int cp = (int)getChar(value, i);
            if (Character.isSurrogate((char)cp)) {
                return toUpperCaseEx(str, value, result, i, locale, false);
            }
            cp = Character.toUpperCaseEx(cp);
            if (!Character.isBmpCodePoint(cp)) {    // Character.ERROR is not bmp
                return toUpperCaseEx(str, value, result, i, locale, false);
            }
            bits |= cp;
            putChar(result, i, cp);
        }
        if (bits < 0 || bits > 0xff) {
            return new String(result, UTF16);
        } else {
            return newString(result, 0, len);
        }
    }

    private static String toUpperCaseEx(String str, byte[] value,
                                        byte[] result, int first,
                                        Locale locale, boolean localeDependent)
    {
        assert(result.length == value.length);
        assert(first >= 0);
        int resultOffset = first;
        int length = value.length >> 1;
        int srcCount;
        for (int i = first; i < length; i += srcCount) {
            int srcChar = getChar(value, i);
            int upperChar;
            char[] upperCharArray;
            srcCount = 1;
            if (Character.isSurrogate((char)srcChar)) {
                srcChar = codePointAt(value, i, length);
                srcCount = Character.charCount(srcChar);
            }
            if (localeDependent) {
                upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
            } else {
                upperChar = Character.toUpperCaseEx(srcChar);
            }
            if (Character.isBmpCodePoint(upperChar)) {
                putChar(result, resultOffset++, upperChar);
            } else {
                if (upperChar == Character.ERROR) {
                    if (localeDependent) {
                        upperCharArray =
                            ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
                    } else {
                        upperCharArray = Character.toUpperCaseCharArray(srcChar);
                    }
                } else {
                    upperCharArray = Character.toChars(upperChar);
                }
                /* Grow result if needed */
                int mapLen = upperCharArray.length;
                if (mapLen > srcCount) {
                    byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
                    result = result2;
                }
                assert resultOffset >= 0;
                assert resultOffset + mapLen <= length(result);
                for (int x = 0; x < mapLen; ++x) {
                    putChar(result, resultOffset++, upperCharArray[x]);
                }
            }
        }
        return newString(result, 0, resultOffset);
    }

    public static String trim(byte[] value) {
        int length = value.length >> 1;
        int len = length;
        int st = 0;
        while (st < len && getChar(value, st) <= ' ') {
            st++;
        }
        while (st < len && getChar(value, len - 1) <= ' ') {
            len--;
        }
        return ((st > 0) || (len < length )) ?
            new String(Arrays.copyOfRange(value, st << 1, len << 1), UTF16) :
            null;
    }

    public static int indexOfNonWhitespace(byte[] value) {
        int length = value.length >> 1;
        int left = 0;
        while (left < length) {
            int codepoint = codePointAt(value, left, length);
            if (codepoint != ' ' && codepoint != '\t' && !Character.isWhitespace(codepoint)) {
                break;
            }
            left += Character.charCount(codepoint);
        }
        return left;
    }

    public static int lastIndexOfNonWhitespace(byte[] value) {
        int length = value.length >>> 1;
        int right = length;
        while (0 < right) {
            int codepoint = codePointBefore(value, right);
            if (codepoint != ' ' && codepoint != '\t' && !Character.isWhitespace(codepoint)) {
                break;
            }
            right -= Character.charCount(codepoint);
        }
        return right;
    }

    public static String strip(byte[] value) {
        int length = value.length >>> 1;
        int left = indexOfNonWhitespace(value);
        if (left == length) {
            return "";
        }
        int right = lastIndexOfNonWhitespace(value);
        boolean ifChanged = (left > 0) || (right < length);
        return ifChanged ? newString(value, left, right - left) : null;
    }

    public static String stripLeading(byte[] value) {
        int length = value.length >>> 1;
        int left = indexOfNonWhitespace(value);
        return (left != 0) ? newString(value, left, length - left) : null;
    }

    public static String stripTrailing(byte[] value) {
        int length = value.length >>> 1;
        int right = lastIndexOfNonWhitespace(value);
        return (right != length) ? newString(value, 0, right) : null;
    }

    private static final class LinesSpliterator implements Spliterator<String> {
        private byte[] value;
        private int index;        // current index, modified on advance/split
        private final int fence;  // one past last index

        private LinesSpliterator(byte[] value, int start, int length) {
            this.value = value;
            this.index = start;
            this.fence = start + length;
        }

        private int indexOfLineSeparator(int start) {
            for (int current = start; current < fence; current++) {
                char ch = getChar(value, current);
                if (ch == '\n' || ch == '\r') {
                    return current;
                }
            }
            return fence;
        }

        private int skipLineSeparator(int start) {
            if (start < fence) {
                if (getChar(value, start) == '\r') {
                    int next = start + 1;
                    if (next < fence && getChar(value, next) == '\n') {
                        return next + 1;
                    }
                }
                return start + 1;
            }
            return fence;
        }

        private String next() {
            int start = index;
            int end = indexOfLineSeparator(start);
            index = skipLineSeparator(end);
            return newString(value, start, end - start);
        }

        @Override
        public boolean tryAdvance(Consumer<? super String> action) {
            if (action == null) {
                throw new NullPointerException("tryAdvance action missing");
            }
            if (index != fence) {
                action.accept(next());
                return true;
            }
            return false;
        }

        @Override
        public void forEachRemaining(Consumer<? super String> action) {
            if (action == null) {
                throw new NullPointerException("forEachRemaining action missing");
            }
            while (index != fence) {
                action.accept(next());
            }
        }

        @Override
        public Spliterator<String> trySplit() {
            int half = (fence + index) >>> 1;
            int mid = skipLineSeparator(indexOfLineSeparator(half));
            if (mid < fence) {
                int start = index;
                index = mid;
                return new LinesSpliterator(value, start, mid - start);
            }
            return null;
        }

        @Override
        public long estimateSize() {
            return fence - index + 1;
        }

        @Override
        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL;
        }

        static LinesSpliterator spliterator(byte[] value) {
            return new LinesSpliterator(value, 0, value.length >>> 1);
        }
    }

    static Stream<String> lines(byte[] value) {
        return StreamSupport.stream(LinesSpliterator.spliterator(value), false);
    }

    private static void putChars(byte[] val, int index, char[] str, int off, int end) {
        while (off < end) {
            putChar(val, index++, str[off++]);
        }
    }

    public static String newString(byte[] val, int index, int len) {
        if (len == 0) {
            return "";
        }
        if (String.COMPACT_STRINGS) {
            byte[] res = StringUTF16.compress(val, index, len);
            byte coder = StringUTF16.coderFromArrayLen(res, len);
            return new String(res, coder);
        }
        int last = index + len;
        return new String(Arrays.copyOfRange(val, index << 1, last << 1), UTF16);
    }

    static class CharsSpliterator implements Spliterator.OfInt {
        private final byte[] array;
        private int index;        // current index, modified on advance/split
        private final int fence;  // one past last index
        private final int cs;

        CharsSpliterator(byte[] array, int acs) {
            this(array, 0, array.length >> 1, acs);
        }

        CharsSpliterator(byte[] array, int origin, int fence, int acs) {
            this.array = array;
            this.index = origin;
            this.fence = fence;
            this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
                      | Spliterator.SUBSIZED;
        }

        @Override
        public OfInt trySplit() {
            int lo = index, mid = (lo + fence) >>> 1;
            return (lo >= mid)
                   ? null
                   : new CharsSpliterator(array, lo, index = mid, cs);
        }

        @Override
        public void forEachRemaining(IntConsumer action) {
            byte[] a; int i, hi; // hoist accesses and checks from loop
            if (action == null)
                throw new NullPointerException();
            if (((a = array).length >> 1) >= (hi = fence) &&
                (i = index) >= 0 && i < (index = hi)) {
                do {
                    action.accept(charAt(a, i));
                } while (++i < hi);
            }
        }

        @Override
        public boolean tryAdvance(IntConsumer action) {
            if (action == null)
                throw new NullPointerException();
            int i = index;
            if (i >= 0 && i < fence) {
                action.accept(charAt(array, i));
                index++;
                return true;
            }
            return false;
        }

        @Override
        public long estimateSize() { return (long)(fence - index); }

        @Override
        public int characteristics() {
            return cs;
        }
    }

    static class CodePointsSpliterator implements Spliterator.OfInt {
        private final byte[] array;
        private int index;        // current index, modified on advance/split
        private final int fence;  // one past last index
        private final int cs;

        CodePointsSpliterator(byte[] array, int acs) {
            this(array, 0, array.length >> 1, acs);
        }

        CodePointsSpliterator(byte[] array, int origin, int fence, int acs) {
            this.array = array;
            this.index = origin;
            this.fence = fence;
            this.cs = acs | Spliterator.ORDERED;
        }

        @Override
        public OfInt trySplit() {
            int lo = index, mid = (lo + fence) >>> 1;
            if (lo >= mid)
                return null;

            int midOneLess;
            // If the mid-point intersects a surrogate pair
            if (Character.isLowSurrogate(charAt(array, mid)) &&
                Character.isHighSurrogate(charAt(array, midOneLess = (mid -1)))) {
                // If there is only one pair it cannot be split
                if (lo >= midOneLess)
                    return null;
                // Shift the mid-point to align with the surrogate pair
                return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
            }
            return new CodePointsSpliterator(array, lo, index = mid, cs);
        }

        @Override
        public void forEachRemaining(IntConsumer action) {
            byte[] a; int i, hi; // hoist accesses and checks from loop
            if (action == null)
                throw new NullPointerException();
            if (((a = array).length >> 1) >= (hi = fence) &&
                (i = index) >= 0 && i < (index = hi)) {
                do {
                    i = advance(a, i, hi, action);
                } while (i < hi);
            }
        }

        @Override
        public boolean tryAdvance(IntConsumer action) {
            if (action == null)
                throw new NullPointerException();
            if (index >= 0 && index < fence) {
                index = advance(array, index, fence, action);
                return true;
            }
            return false;
        }

        // Advance one code point from the index, i, and return the next
        // index to advance from
        private static int advance(byte[] a, int i, int hi, IntConsumer action) {
            char c1 = charAt(a, i++);
            int cp = c1;
            if (Character.isHighSurrogate(c1) && i < hi) {
                char c2 = charAt(a, i);
                if (Character.isLowSurrogate(c2)) {
                    i++;
                    cp = Character.toCodePoint(c1, c2);
                }
            }
            action.accept(cp);
            return i;
        }

        @Override
        public long estimateSize() { return (long)(fence - index); }

        @Override
        public int characteristics() {
            return cs;
        }
    }

    ////////////////////////////////////////////////////////////////

    public static void putCharSB(byte[] val, int index, int c) {
        checkIndex(index, val);
        putChar(val, index, c);
    }

    public static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) {
        checkBoundsBeginEnd(index, index + end - off, val);
        putChars(val, index, ca, off, end);
    }

    public static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) {
        checkBoundsBeginEnd(index, index + end - off, val);
        for (int i = off; i < end; i++) {
            putChar(val, index++, s.charAt(i));
        }
    }

    public static int codePointAtSB(byte[] val, int index, int end) {
        return codePointAt(val, index, end, true /* checked */);
    }

    public static int codePointBeforeSB(byte[] val, int index) {
        return codePointBefore(val, index, true /* checked */);
    }

    public static int codePointCountSB(byte[] val, int beginIndex, int endIndex) {
        return codePointCount(val, beginIndex, endIndex, true /* checked */);
    }

    public static boolean contentEquals(byte[] v1, byte[] v2, int len) {
        checkBoundsOffCount(0, len, v2);
        for (int i = 0; i < len; i++) {
            if ((char)(v1[i] & 0xff) != getChar(v2, i)) {
                return false;
            }
        }
        return true;
    }

    public static boolean contentEquals(byte[] value, CharSequence cs, int len) {
        checkOffset(len, value);
        for (int i = 0; i < len; i++) {
            if (getChar(value, i) != cs.charAt(i)) {
                return false;
            }
        }
        return true;
    }

    public static void putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4) {
        int end = i + 4;
        checkBoundsBeginEnd(i, end, value);
        putChar(value, i, c1);
        putChar(value, i + 1, c2);
        putChar(value, i + 2, c3);
        putChar(value, i + 3, c4);
    }

    public static void putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4, char c5) {
        int end = i + 5;
        checkBoundsBeginEnd(i, end, value);
        putChar(value, i, c1);
        putChar(value, i + 1, c2);
        putChar(value, i + 2, c3);
        putChar(value, i + 3, c4);
        putChar(value, i + 4, c5);
    }

    public static char charAt(byte[] value, int index) {
        checkIndex(index, value);
        return getChar(value, index);
    }

    public static void reverse(byte[] val, int count) {
        checkOffset(count, val);
        int n = count - 1;
        boolean hasSurrogates = false;
        for (int j = (n-1) >> 1; j >= 0; j--) {
            int k = n - j;
            char cj = getChar(val, j);
            char ck = getChar(val, k);
            putChar(val, j, ck);
            putChar(val, k, cj);
            if (Character.isSurrogate(cj) ||
                Character.isSurrogate(ck)) {
                hasSurrogates = true;
            }
        }
        if (hasSurrogates) {
            reverseAllValidSurrogatePairs(val, count);
        }
    }

    /** Outlined helper method for reverse() */
    private static void reverseAllValidSurrogatePairs(byte[] val, int count) {
        for (int i = 0; i < count - 1; i++) {
            char c2 = getChar(val, i);
            if (Character.isLowSurrogate(c2)) {
                char c1 = getChar(val, i + 1);
                if (Character.isHighSurrogate(c1)) {
                    putChar(val, i++, c1);
                    putChar(val, i, c2);
                }
            }
        }
    }

    // inflatedCopy byte[] -> byte[]
    public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
        // We need a range check here because 'putChar' has no checks
        checkBoundsOffCount(dstOff, len, dst);
        for (int i = 0; i < len; i++) {
            putChar(dst, dstOff++, src[srcOff++] & 0xff);
        }
    }

    // srcCoder == UTF16 && tgtCoder == LATIN1
    public static int lastIndexOfLatin1(byte[] src, int srcCount,
                                        byte[] tgt, int tgtCount, int fromIndex) {
        assert fromIndex >= 0;
        assert tgtCount > 0;
        assert tgtCount <= tgt.length;
        int min = tgtCount - 1;
        int i = min + fromIndex;
        int strLastIndex = tgtCount - 1;

        char strLastChar = (char)(tgt[strLastIndex] & 0xff);

        checkIndex(i, src);

    startSearchForLastChar:
        while (true) {
            while (i >= min && getChar(src, i) != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - strLastIndex;
            int k = strLastIndex - 1;
            while (j > start) {
                if (getChar(src, j--) != (tgt[k--] & 0xff)) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start + 1;
        }
    }

    ////////////////////////////////////////////////////////////////

    private static final int HI_BYTE_SHIFT;
    private static final int LO_BYTE_SHIFT;
    static {
        if (Unsafe.getUnsafe().isBigEndian()) {
            HI_BYTE_SHIFT = 8;
            LO_BYTE_SHIFT = 0;
        } else {
            HI_BYTE_SHIFT = 0;
            LO_BYTE_SHIFT = 8;
        }
    }

    static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;

    public static void checkIndex(int off, byte[] val) {
        String.checkIndex(off, length(val));
    }

    public static void checkOffset(int off, byte[] val) {
        String.checkOffset(off, length(val));
    }

    public static void checkBoundsBeginEnd(int begin, int end, byte[] val) {
        String.checkBoundsBeginEnd(begin, end, length(val));
    }

    public static void checkBoundsOffCount(int offset, int count, byte[] val) {
        String.checkBoundsOffCount(offset, count, length(val));
    }

}
