// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

// created: 2018may04 Markus W. Scherer

package com.ibm.icu.util;

import java.util.Arrays;

/**
 * Mutable Unicode code point trie.
 * Fast map from Unicode code points (U+0000..U+10FFFF) to 32-bit integer values.
 * For details see http://site.icu-project.org/design/struct/utrie
 *
 * <p>Setting values (especially ranges) and lookup is fast.
 * The mutable trie is only somewhat space-efficient.
 * It builds a compacted, immutable {@link CodePointTrie}.
 *
 * <p>This trie can be modified while iterating over its contents.
 * For example, it is possible to merge its values with those from another
 * set of ranges (e.g., another @{link CodePointMap}):
 * Iterate over those source ranges; for each of them iterate over this trie;
 * add the source value into the value of each trie range.
 *
 * @stable ICU 63
 */
public final class MutableCodePointTrie extends CodePointMap implements Cloneable {
    /**
     * Constructs a mutable trie that initially maps each Unicode code point to the same value.
     * It uses 32-bit data values until
     * {@link #buildImmutable(com.ibm.icu.util.CodePointTrie.Type, com.ibm.icu.util.CodePointTrie.ValueWidth)}
     * is called.
     * buildImmutable() takes a valueWidth parameter which
     * determines the number of bits in the data value in the resulting {@link CodePointTrie}.
     *
     * @param initialValue the initial value that is set for all code points
     * @param errorValue the value for out-of-range code points and ill-formed UTF-8/16
     * @stable ICU 63
     */
    public MutableCodePointTrie(int initialValue, int errorValue) {
        index = new int[BMP_I_LIMIT];
        index3NullOffset = -1;
        data = new int[INITIAL_DATA_LENGTH];
        dataNullOffset = -1;
        origInitialValue = initialValue;
        this.initialValue = initialValue;
        this.errorValue = errorValue;
        highValue = initialValue;
    }

    /**
     * Clones this mutable trie.
     *
     * @return the clone
     * @stable ICU 63
     */
    @Override
    public MutableCodePointTrie clone() {
        try {
            MutableCodePointTrie builder = (MutableCodePointTrie) super.clone();
            int iCapacity = highStart <= BMP_LIMIT ? BMP_I_LIMIT : I_LIMIT;
            builder.index = new int[iCapacity];
            builder.flags = new byte[UNICODE_LIMIT >> CodePointTrie.SHIFT_3];
            for (int i = 0, iLimit = highStart >> CodePointTrie.SHIFT_3; i < iLimit; ++i) {
                builder.index[i] = index[i];
                builder.flags[i] = flags[i];
            }
            builder.index3NullOffset = index3NullOffset;
            builder.data = data.clone();
            builder.dataLength = dataLength;
            builder.dataNullOffset = dataNullOffset;
            builder.origInitialValue = origInitialValue;
            builder.initialValue = initialValue;
            builder.errorValue = errorValue;
            builder.highStart = highStart;
            builder.highValue = highValue;
            assert index16 == null;
            return builder;
        } catch (CloneNotSupportedException ignored) {
            // Unreachable: Cloning *is* supported.
            return null;
        }
    }

    /**
     * Creates a mutable trie with the same contents as the {@link CodePointMap}.
     *
     * @param map the source map or trie
     * @return the mutable trie
     * @stable ICU 63
     */
    public static MutableCodePointTrie fromCodePointMap(CodePointMap map) {
        // TODO: Consider special code branch for map instanceof CodePointTrie?
        // Use the highValue as the initialValue to reduce the highStart.
        int errorValue = map.get(-1);
        int initialValue = map.get(MAX_UNICODE);
        MutableCodePointTrie mutableTrie = new MutableCodePointTrie(initialValue, errorValue);
        CodePointMap.Range range = new CodePointMap.Range();
        int start = 0;
        while (map.getRange(start, null, range)) {
            int end = range.getEnd();
            int value = range.getValue();
            if (value != initialValue) {
                if (start == end) {
                    mutableTrie.set(start, value);
                } else {
                    mutableTrie.setRange(start, end, value);
                }
            }
            start = end + 1;
        }
        return mutableTrie;
    }

    private void clear() {
        index3NullOffset = dataNullOffset = -1;
        dataLength = 0;
        highValue = initialValue = origInitialValue;
        highStart = 0;
        index16 = null;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 63
     */
    @Override
    public int get(int c) {
        if (c < 0 || MAX_UNICODE < c) {
            return errorValue;
        }
        if (c >= highStart) {
            return highValue;
        }
        int i = c >> CodePointTrie.SHIFT_3;
        if (flags[i] == ALL_SAME) {
            return index[i];
        } else {
            return data[index[i] + (c & CodePointTrie.SMALL_DATA_MASK)];
        }
    }

    private static final int maybeFilterValue(int value, int initialValue, int nullValue,
            ValueFilter filter) {
        if (value == initialValue) {
            value = nullValue;
        } else if (filter != null) {
            value = filter.apply(value);
        }
        return value;
    }

    /**
     * {@inheritDoc}
     *
     * <p>The trie can be modified between calls to this function.
     *
     * @stable ICU 63
     */
    @Override
    public boolean getRange(int start, CodePointTrie.ValueFilter filter,
            CodePointTrie.Range range) {
        if (start < 0 || MAX_UNICODE < start) {
            return false;
        }
        if (start >= highStart) {
            int value = highValue;
            if (filter != null) { value = filter.apply(value); }
            range.set(start, MAX_UNICODE, value);
            return true;
        }
        int nullValue = initialValue;
        if (filter != null) { nullValue = filter.apply(nullValue); }
        int c = start;
        // Initialize to make compiler happy. Real value when haveValue is true.
        int trieValue = 0, value = 0;
        boolean haveValue = false;
        int i = c >> CodePointTrie.SHIFT_3;
        do {
            if (flags[i] == ALL_SAME) {
                int trieValue2 = index[i];
                if (haveValue) {
                    if (trieValue2 != trieValue) {
                        if (filter == null ||
                                maybeFilterValue(trieValue2, initialValue, nullValue,
                                        filter) != value) {
                            range.set(start, c - 1, value);
                            return true;
                        }
                        trieValue = trieValue2;  // may or may not help
                    }
                } else {
                    trieValue = trieValue2;
                    value = maybeFilterValue(trieValue2, initialValue, nullValue, filter);
                    haveValue = true;
                }
                c = (c + CodePointTrie.SMALL_DATA_BLOCK_LENGTH) & ~CodePointTrie.SMALL_DATA_MASK;
            } else /* MIXED */ {
                int di = index[i] + (c & CodePointTrie.SMALL_DATA_MASK);
                int trieValue2 = data[di];
                if (haveValue) {
                    if (trieValue2 != trieValue) {
                        if (filter == null ||
                                maybeFilterValue(trieValue2, initialValue, nullValue,
                                        filter) != value) {
                            range.set(start, c - 1, value);
                            return true;
                        }
                        trieValue = trieValue2;  // may or may not help
                    }
                } else {
                    trieValue = trieValue2;
                    value = maybeFilterValue(trieValue2, initialValue, nullValue, filter);
                    haveValue = true;
                }
                while ((++c & CodePointTrie.SMALL_DATA_MASK) != 0) {
                    trieValue2 = data[++di];
                    if (trieValue2 != trieValue) {
                        if (filter == null ||
                                maybeFilterValue(trieValue2, initialValue, nullValue,
                                        filter) != value) {
                            range.set(start, c - 1, value);
                            return true;
                        }
                        trieValue = trieValue2;  // may or may not help
                    }
                }
            }
            ++i;
        } while (c < highStart);
        assert(haveValue);
        if (maybeFilterValue(highValue, initialValue, nullValue, filter) != value) {
            range.set(start, c - 1, value);
        } else {
            range.set(start, MAX_UNICODE, value);
        }
        return true;
    }

    private void writeBlock(int block, int value) {
        int limit = block + CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
        Arrays.fill(data, block, limit, value);
    }

    /**
     * Sets a value for a code point.
     *
     * @param c the code point
     * @param value the value
     * @stable ICU 63
     */
    public void set(int c, int value) {
        if (c < 0 || MAX_UNICODE < c) {
            throw new IllegalArgumentException("invalid code point");
        }

        ensureHighStart(c);
        int block = getDataBlock(c >> CodePointTrie.SHIFT_3);
        data[block + (c & CodePointTrie.SMALL_DATA_MASK)] = value;
    }

    private void fillBlock(int block, int start, int limit, int value) {
        Arrays.fill(data, block + start, block + limit, value);
    }

    /**
     * Sets a value for each code point [start..end].
     * Faster and more space-efficient than setting the value for each code point separately.
     *
     * @param start the first code point to get the value
     * @param end the last code point to get the value (inclusive)
     * @param value the value
     * @stable ICU 63
     */
    public void setRange(int start, int end, int value) {
        if (start < 0 || MAX_UNICODE < start || end < 0 || MAX_UNICODE < end || start > end) {
            throw new IllegalArgumentException("invalid code point range");
        }
        ensureHighStart(end);

        int limit = end + 1;
        if ((start & CodePointTrie.SMALL_DATA_MASK) != 0) {
            // Set partial block at [start..following block boundary[.
            int block = getDataBlock(start >> CodePointTrie.SHIFT_3);
            int nextStart = (start + CodePointTrie.SMALL_DATA_MASK) & ~CodePointTrie.SMALL_DATA_MASK;
            if (nextStart <= limit) {
                fillBlock(block, start & CodePointTrie.SMALL_DATA_MASK,
                          CodePointTrie.SMALL_DATA_BLOCK_LENGTH, value);
                start = nextStart;
            } else {
                fillBlock(block, start & CodePointTrie.SMALL_DATA_MASK,
                          limit & CodePointTrie.SMALL_DATA_MASK, value);
                return;
            }
        }

        // Number of positions in the last, partial block.
        int rest = limit & CodePointTrie.SMALL_DATA_MASK;

        // Round down limit to a block boundary.
        limit &= ~CodePointTrie.SMALL_DATA_MASK;

        // Iterate over all-value blocks.
        while (start < limit) {
            int i = start >> CodePointTrie.SHIFT_3;
            if (flags[i] == ALL_SAME) {
                index[i] = value;
            } else /* MIXED */ {
                fillBlock(index[i], 0, CodePointTrie.SMALL_DATA_BLOCK_LENGTH, value);
            }
            start += CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
        }

        if (rest > 0) {
            // Set partial block at [last block boundary..limit[.
            int block = getDataBlock(start >> CodePointTrie.SHIFT_3);
            fillBlock(block, 0, rest, value);
        }
    }

    /**
     * Compacts the data and builds an immutable {@link CodePointTrie} according to the parameters.
     * After this, the mutable trie will be empty.
     *
     * <p>The mutable trie stores 32-bit values until buildImmutable() is called.
     * If values shorter than 32 bits are to be stored in the immutable trie,
     * then the upper bits are discarded.
     * For example, when the mutable trie contains values 0x81, -0x7f, and 0xa581,
     * and the value width is 8 bits, then each of these is stored as 0x81
     * and the immutable trie will return that as an unsigned value.
     * (Some implementations may want to make productive temporary use of the upper bits
     * until buildImmutable() discards them.)
     *
     * <p>Not every possible set of mappings can be built into a CodePointTrie,
     * because of limitations resulting from speed and space optimizations.
     * Every Unicode assigned character can be mapped to a unique value.
     * Typical data yields data structures far smaller than the limitations.
     *
     * <p>It is possible to construct extremely unusual mappings that exceed the
     * data structure limits.
     * In such a case this function will throw an exception.
     *
     * @param type selects the trie type
     * @param valueWidth selects the number of bits in a trie data value; if smaller than 32 bits,
     *                   then the values stored in the trie will be truncated first
     *
     * @see #fromCodePointMap(CodePointMap)
     * @stable ICU 63
     */
    public CodePointTrie buildImmutable(CodePointTrie.Type type, CodePointTrie.ValueWidth valueWidth) {
        if (type == null || valueWidth == null) {
            throw new IllegalArgumentException("The type and valueWidth must be specified.");
        }

        try {
            return build(type, valueWidth);
        } finally {
            clear();
        }
    }

    private static final int MAX_UNICODE = 0x10ffff;

    private static final int UNICODE_LIMIT = 0x110000;
    private static final int BMP_LIMIT = 0x10000;
    private static final int ASCII_LIMIT = 0x80;

    private static final int I_LIMIT = UNICODE_LIMIT >> CodePointTrie.SHIFT_3;
    private static final int BMP_I_LIMIT = BMP_LIMIT >> CodePointTrie.SHIFT_3;
    private static final int ASCII_I_LIMIT = ASCII_LIMIT >> CodePointTrie.SHIFT_3;

    private static final int SMALL_DATA_BLOCKS_PER_BMP_BLOCK = (1 << (CodePointTrie.FAST_SHIFT - CodePointTrie.SHIFT_3));

    // Flag values for data blocks.
    private static final byte ALL_SAME = 0;
    private static final byte MIXED = 1;
    private static final byte SAME_AS = 2;

    /** Start with allocation of 16k data entries. */
    private static final int INITIAL_DATA_LENGTH = (1 << 14);

    /** Grow about 8x each time. */
    private static final int MEDIUM_DATA_LENGTH = (1 << 17);

    /**
     * Maximum length of the build-time data array.
     * One entry per 0x110000 code points.
     */
    private static final int MAX_DATA_LENGTH = UNICODE_LIMIT;

    // Flag values for index-3 blocks while compacting/building.
    private static final byte I3_NULL = 0;
    private static final byte I3_BMP = 1;
    private static final byte I3_16 = 2;
    private static final byte I3_18 = 3;

    private static final int INDEX_3_18BIT_BLOCK_LENGTH = CodePointTrie.INDEX_3_BLOCK_LENGTH + CodePointTrie.INDEX_3_BLOCK_LENGTH / 8;

    private int[] index;
    private int index3NullOffset;
    private int[] data;
    private int dataLength;
    private int dataNullOffset;

    private int origInitialValue;
    private int initialValue;
    private int errorValue;
    private int highStart;
    private int highValue;

    /** Temporary array while building the final data. */
    private char[] index16;
    private byte[] flags = new byte[UNICODE_LIMIT >> CodePointTrie.SHIFT_3];

    private void ensureHighStart(int c) {
        if (c >= highStart) {
            // Round up to a CodePointTrie.CP_PER_INDEX_2_ENTRY boundary to simplify compaction.
            c = (c + CodePointTrie.CP_PER_INDEX_2_ENTRY) & ~(CodePointTrie.CP_PER_INDEX_2_ENTRY - 1);
            int i = highStart >> CodePointTrie.SHIFT_3;
            int iLimit = c >> CodePointTrie.SHIFT_3;
            if (iLimit > index.length) {
                int[] newIndex = new int[I_LIMIT];
                for (int j = 0; j < i; ++j) { newIndex[j] = index[j]; }
                index = newIndex;
            }
            do {
                flags[i] = ALL_SAME;
                index[i] = initialValue;
            } while(++i < iLimit);
            highStart = c;
        }
    }

    private int allocDataBlock(int blockLength) {
        int newBlock = dataLength;
        int newTop = newBlock + blockLength;
        if (newTop > data.length) {
            int capacity;
            if (data.length < MEDIUM_DATA_LENGTH) {
                capacity = MEDIUM_DATA_LENGTH;
            } else if (data.length < MAX_DATA_LENGTH) {
                capacity = MAX_DATA_LENGTH;
            } else {
                // Should never occur.
                // Either MAX_DATA_LENGTH is incorrect,
                // or the code writes more values than should be possible.
                throw new AssertionError();
            }
            int[] newData = new int[capacity];
            for (int j = 0; j < dataLength; ++j) { newData[j] = data[j]; }
            data = newData;
        }
        dataLength = newTop;
        return newBlock;
    }

    /**
     * No error checking for illegal arguments.
     * The Java version always returns non-negative values.
     */
    private int getDataBlock(int i) {
        if (flags[i] == MIXED) {
            return index[i];
        }
        if (i < BMP_I_LIMIT) {
            int newBlock = allocDataBlock(CodePointTrie.FAST_DATA_BLOCK_LENGTH);
            int iStart = i & ~(SMALL_DATA_BLOCKS_PER_BMP_BLOCK -1);
            int iLimit = iStart + SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
            do {
                assert(flags[iStart] == ALL_SAME);
                writeBlock(newBlock, index[iStart]);
                flags[iStart] = MIXED;
                index[iStart++] = newBlock;
                newBlock += CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
            } while (iStart < iLimit);
            return index[i];
        } else {
            int newBlock = allocDataBlock(CodePointTrie.SMALL_DATA_BLOCK_LENGTH);
            if (newBlock < 0) { return newBlock; }
            writeBlock(newBlock, index[i]);
            flags[i] = MIXED;
            index[i] = newBlock;
            return newBlock;
        }
    }

    // compaction --------------------------------------------------------------

    private void maskValues(int mask) {
        initialValue &= mask;
        errorValue &= mask;
        highValue &= mask;
        int iLimit = highStart >> CodePointTrie.SHIFT_3;
        for (int i = 0; i < iLimit; ++i) {
            if (flags[i] == ALL_SAME) {
                index[i] &= mask;
            }
        }
        for (int i = 0; i < dataLength; ++i) {
            data[i] &= mask;
        }
    }

    private static boolean equalBlocks(int[] s, int si, int[] t, int ti, int length) {
        while (length > 0 && s[si] == t[ti]) {
            ++si;
            ++ti;
            --length;
        }
        return length == 0;
    }

    private static boolean equalBlocks(char[] s, int si, int[] t, int ti, int length) {
        while (length > 0 && s[si] == t[ti]) {
            ++si;
            ++ti;
            --length;
        }
        return length == 0;
    }

    private static boolean equalBlocks(char[] s, int si, char[] t, int ti, int length) {
        while (length > 0 && s[si] == t[ti]) {
            ++si;
            ++ti;
            --length;
        }
        return length == 0;
    }

    private static boolean allValuesSameAs(int[] p, int pi, int length, int value) {
        int pLimit = pi + length;
        while (pi < pLimit && p[pi] == value) { ++pi; }
        return pi == pLimit;
    }

    /** Search for an identical block. */
    private static int findSameBlock(char[] p, int pStart, int length,
            char[] q, int qStart, int blockLength) {
        // Ensure that we do not even partially get past length.
        length -= blockLength;

        while (pStart <= length) {
            if (equalBlocks(p, pStart, q, qStart, blockLength)) {
                return pStart;
            }
            ++pStart;
        }
        return -1;
    }

    private static int findAllSameBlock(int[] p, int start, int limit,
            int value, int blockLength) {
        // Ensure that we do not even partially get past limit.
        limit -= blockLength;

        for (int block = start; block <= limit; ++block) {
            if (p[block] == value) {
                for (int i = 1;; ++i) {
                    if (i == blockLength) {
                        return block;
                    }
                    if (p[block + i] != value) {
                        block += i;
                        break;
                    }
                }
            }
        }
        return -1;
    }

    /**
     * Look for maximum overlap of the beginning of the other block
     * with the previous, adjacent block.
     */
    private static int getOverlap(int[] p, int length, int[] q, int qStart, int blockLength) {
        int overlap = blockLength - 1;
        assert(overlap <= length);
        while (overlap > 0 && !equalBlocks(p, length - overlap, q, qStart, overlap)) {
            --overlap;
        }
        return overlap;
    }

    private static int getOverlap(char[] p, int length, int[] q, int qStart, int blockLength) {
        int overlap = blockLength - 1;
        assert(overlap <= length);
        while (overlap > 0 && !equalBlocks(p, length - overlap, q, qStart, overlap)) {
            --overlap;
        }
        return overlap;
    }

    private static int getOverlap(char[] p, int length, char[] q, int qStart, int blockLength) {
        int overlap = blockLength - 1;
        assert(overlap <= length);
        while (overlap > 0 && !equalBlocks(p, length - overlap, q, qStart, overlap)) {
            --overlap;
        }
        return overlap;
    }

    private static int getAllSameOverlap(int[] p, int length, int value, int blockLength) {
        int min = length - (blockLength - 1);
        int i = length;
        while (min < i && p[i - 1] == value) { --i; }
        return length - i;
    }

    private static boolean isStartOfSomeFastBlock(int dataOffset, int[] index, int fastILimit) {
        for (int i = 0; i < fastILimit; i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK) {
            if (index[i] == dataOffset) {
                return true;
            }
        }
        return false;
    }

    /**
     * Finds the start of the last range in the trie by enumerating backward.
     * Indexes for code points higher than this will be omitted.
     */
    private int findHighStart() {
        int i = highStart >> CodePointTrie.SHIFT_3;
        while (i > 0) {
            boolean match;
            if (flags[--i] == ALL_SAME) {
                match = index[i] == highValue;
            } else /* MIXED */ {
                int p = index[i];
                for (int j = 0;; ++j) {
                    if (j == CodePointTrie.SMALL_DATA_BLOCK_LENGTH) {
                        match = true;
                        break;
                    }
                    if (data[p + j] != highValue) {
                        match = false;
                        break;
                    }
                }
            }
            if (!match) {
                return (i + 1) << CodePointTrie.SHIFT_3;
            }
        }
        return 0;
    }

    private static final class AllSameBlocks {
        static final int NEW_UNIQUE = -1;
        static final int OVERFLOW = -2;

        AllSameBlocks() {
            mostRecent = -1;
        }

        int findOrAdd(int index, int count, int value) {
            if (mostRecent >= 0 && values[mostRecent] == value) {
                refCounts[mostRecent] += count;
                return indexes[mostRecent];
            }
            for (int i = 0; i < length; ++i) {
                if (values[i] == value) {
                    mostRecent = i;
                    refCounts[i] += count;
                    return indexes[i];
                }
            }
            if (length == CAPACITY) {
                return OVERFLOW;
            }
            mostRecent = length;
            indexes[length] = index;
            values[length] = value;
            refCounts[length++] = count;
            return NEW_UNIQUE;
        }

        /** Replaces the block which has the lowest reference count. */
        void add(int index, int count, int value) {
            assert(length == CAPACITY);
            int least = -1;
            int leastCount = I_LIMIT;
            for (int i = 0; i < length; ++i) {
                assert(values[i] != value);
                if (refCounts[i] < leastCount) {
                    least = i;
                    leastCount = refCounts[i];
                }
            }
            assert(least >= 0);
            mostRecent = least;
            indexes[least] = index;
            values[least] = value;
            refCounts[least] = count;
        }

        int findMostUsed() {
            if (length == 0) { return -1; }
            int max = -1;
            int maxCount = 0;
            for (int i = 0; i < length; ++i) {
                if (refCounts[i] > maxCount) {
                    max = i;
                    maxCount = refCounts[i];
                }
            }
            return indexes[max];
        }

        private static final int CAPACITY = 32;

        private int length;
        private int mostRecent;

        private int[] indexes = new int[CAPACITY];
        private int[] values = new int[CAPACITY];
        private int[] refCounts = new int[CAPACITY];
    }

    // Custom hash table for mixed-value blocks to be found anywhere in the
    // compacted data or index so far.
    private static final class MixedBlocks {
        void init(int maxLength, int newBlockLength) {
            // We store actual data indexes + 1 to reserve 0 for empty entries.
            int maxDataIndex = maxLength - newBlockLength + 1;
            int newLength;
            if (maxDataIndex <= 0xfff) {  // 4k
                newLength = 6007;
                shift = 12;
                mask = 0xfff;
            } else if (maxDataIndex <= 0x7fff) {  // 32k
                newLength = 50021;
                shift = 15;
                mask = 0x7fff;
            } else if (maxDataIndex <= 0x1ffff) {  // 128k
                newLength = 200003;
                shift = 17;
                mask = 0x1ffff;
            } else {
                // maxDataIndex up to around MAX_DATA_LENGTH, ca. 1.1M
                newLength = 1500007;
                shift = 21;
                mask = 0x1fffff;
            }
            if (table == null || newLength > table.length) {
                table = new int[newLength];
            } else {
                Arrays.fill(table, 0, newLength, 0);
            }
            length = newLength;

            blockLength = newBlockLength;
        }

        void extend(int[] data, int minStart, int prevDataLength, int newDataLength) {
            int start = prevDataLength - blockLength;
            if (start >= minStart) {
                ++start;  // Skip the last block that we added last time.
            } else {
                start = minStart;  // Begin with the first full block.
            }
            for (int end = newDataLength - blockLength; start <= end; ++start) {
                int hashCode = makeHashCode(data, start);
                addEntry(data, null, start, hashCode, start);
            }
        }

        void extend(char[] data, int minStart, int prevDataLength, int newDataLength) {
            int start = prevDataLength - blockLength;
            if (start >= minStart) {
                ++start;  // Skip the last block that we added last time.
            } else {
                start = minStart;  // Begin with the first full block.
            }
            for (int end = newDataLength - blockLength; start <= end; ++start) {
                int hashCode = makeHashCode(data, start);
                addEntry(null, data, start, hashCode, start);
            }
        }

        int findBlock(int[] data, int[] blockData, int blockStart) {
            int hashCode = makeHashCode(blockData, blockStart);
            int entryIndex = findEntry(data, null, blockData, null, blockStart, hashCode);
            if (entryIndex >= 0) {
                return (table[entryIndex] & mask) - 1;
            } else {
                return -1;
            }
        }

        int findBlock(char[] data, int[] blockData, int blockStart) {
            int hashCode = makeHashCode(blockData, blockStart);
            int entryIndex = findEntry(null, data, blockData, null, blockStart, hashCode);
            if (entryIndex >= 0) {
                return (table[entryIndex] & mask) - 1;
            } else {
                return -1;
            }
        }

        int findBlock(char[] data, char[] blockData, int blockStart) {
            int hashCode = makeHashCode(blockData, blockStart);
            int entryIndex = findEntry(null, data, null, blockData, blockStart, hashCode);
            if (entryIndex >= 0) {
                return (table[entryIndex] & mask) - 1;
            } else {
                return -1;
            }
        }

        int findAllSameBlock(int[] data, int blockValue) {
            int hashCode = makeHashCode(blockValue);
            int entryIndex = findEntry(data, blockValue, hashCode);
            if (entryIndex >= 0) {
                return (table[entryIndex] & mask) - 1;
            } else {
                return -1;
            }
        }

        private int makeHashCode(int[] blockData, int blockStart) {
            int blockLimit = blockStart + blockLength;
            int hashCode = blockData[blockStart++];
            do {
                hashCode = 37 * hashCode + blockData[blockStart++];
            } while (blockStart < blockLimit);
            return hashCode;
        }

        private int makeHashCode(char[] blockData, int blockStart) {
            int blockLimit = blockStart + blockLength;
            int hashCode = blockData[blockStart++];
            do {
                hashCode = 37 * hashCode + blockData[blockStart++];
            } while (blockStart < blockLimit);
            return hashCode;
        }

        private int makeHashCode(int blockValue) {
            int hashCode = blockValue;
            for (int i = 1; i < blockLength; ++i) {
                hashCode = 37 * hashCode + blockValue;
            }
            return hashCode;
        }

        private void addEntry(int[] data32, char[] data16, int blockStart, int hashCode, int dataIndex) {
            assert(0 <= dataIndex && dataIndex < mask);
            int entryIndex = findEntry(data32, data16, data32, data16, blockStart, hashCode);
            if (entryIndex < 0) {
                table[~entryIndex] = (hashCode << shift) | (dataIndex + 1);
            }
        }

        private int findEntry(int[] data32, char[] data16,
                int[] blockData32, char[] blockData16, int blockStart, int hashCode) {
            int shiftedHashCode = hashCode << shift;
            int initialEntryIndex = modulo(hashCode, length - 1) + 1;  // 1..length-1
            for (int entryIndex = initialEntryIndex;;) {
                int entry = table[entryIndex];
                if (entry == 0) {
                    return ~entryIndex;
                }
                if ((entry & ~mask) == shiftedHashCode) {
                    int dataIndex = (entry & mask) - 1;
                    if (data32 != null ?
                            equalBlocks(data32, dataIndex, blockData32, blockStart, blockLength) :
                            blockData32 != null ?
                                equalBlocks(data16, dataIndex, blockData32, blockStart, blockLength) :
                                equalBlocks(data16, dataIndex, blockData16, blockStart, blockLength)) {
                        return entryIndex;
                    }
                }
                entryIndex = nextIndex(initialEntryIndex, entryIndex);
            }
        }

        private int findEntry(int[] data, int blockValue, int hashCode) {
            int shiftedHashCode = hashCode << shift;
            int initialEntryIndex = modulo(hashCode, length - 1) + 1;  // 1..length-1
            for (int entryIndex = initialEntryIndex;;) {
                int entry = table[entryIndex];
                if (entry == 0) {
                    return ~entryIndex;
                }
                if ((entry & ~mask) == shiftedHashCode) {
                    int dataIndex = (entry & mask) - 1;
                    if (allValuesSameAs(data, dataIndex, blockLength, blockValue)) {
                        return entryIndex;
                    }
                }
                entryIndex = nextIndex(initialEntryIndex, entryIndex);
            }
        }

        private int nextIndex(int initialEntryIndex, int entryIndex) {
            // U_ASSERT(0 < initialEntryIndex && initialEntryIndex < length);
            return (entryIndex + initialEntryIndex) % length;
        }

        /** Ensures non-negative n % m (that is 0..m-1). */
        private int modulo(int n, int m) {
            int i = n % m;
            if (i < 0) {
                i += m;
            }
            return i;
        }

        // Hash table.
        // The length is a prime number, larger than the maximum data length.
        // The "shift" lower bits store a data index + 1.
        // The remaining upper bits store a partial hashCode of the block data values.
        private int[] table;
        private int length;
        private int shift;
        private int mask;

        private int blockLength;
    }

    private int compactWholeDataBlocks(int fastILimit, AllSameBlocks allSameBlocks) {
        // ASCII data will be stored as a linear table, even if the following code
        // does not yet count it that way.
        int newDataCapacity = ASCII_LIMIT;
        // Add room for a small data null block in case it would match the start of
        // a fast data block where dataNullOffset must not be set in that case.
        newDataCapacity += CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
        // Add room for special values (errorValue, highValue) and padding.
        newDataCapacity += 4;
        int iLimit = highStart >> CodePointTrie.SHIFT_3;
        int blockLength = CodePointTrie.FAST_DATA_BLOCK_LENGTH;
        int inc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
        for (int i = 0; i < iLimit; i += inc) {
            if (i == fastILimit) {
                blockLength = CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
                inc = 1;
            }
            int value = index[i];
            if (flags[i] == MIXED) {
                // Really mixed?
                int p = value;
                value = data[p];
                if (allValuesSameAs(data, p + 1, blockLength - 1, value)) {
                    flags[i] = ALL_SAME;
                    index[i] = value;
                    // Fall through to ALL_SAME handling.
                } else {
                    newDataCapacity += blockLength;
                    continue;
                }
            } else {
                assert(flags[i] == ALL_SAME);
                if (inc > 1) {
                    // Do all of the fast-range data block's ALL_SAME parts have the same value?
                    boolean allSame = true;
                    int next_i = i + inc;
                    for (int j = i + 1; j < next_i; ++j) {
                        assert(flags[j] == ALL_SAME);
                        if (index[j] != value) {
                            allSame = false;
                            break;
                        }
                    }
                    if (!allSame) {
                        // Turn it into a MIXED block.
                        if (getDataBlock(i) < 0) {
                            return -1;
                        }
                        newDataCapacity += blockLength;
                        continue;
                    }
                }
            }
            // Is there another ALL_SAME block with the same value?
            int other = allSameBlocks.findOrAdd(i, inc, value);
            if (other == AllSameBlocks.OVERFLOW) {
                // The fixed-size array overflowed. Slow check for a duplicate block.
                int jInc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
                for (int j = 0;; j += jInc) {
                    if (j == i) {
                        allSameBlocks.add(i, inc, value);
                        break;
                    }
                    if (j == fastILimit) {
                        jInc = 1;
                    }
                    if (flags[j] == ALL_SAME && index[j] == value) {
                        allSameBlocks.add(j, jInc + inc, value);
                        other = j;
                        break;
                        // We could keep counting blocks with the same value
                        // before we add the first one, which may improve compaction in rare cases,
                        // but it would make it slower.
                    }
                }
            }
            if (other >= 0) {
                flags[i] = SAME_AS;
                index[i] = other;
            } else {
                // New unique same-value block.
                newDataCapacity += blockLength;
            }
        }
        return newDataCapacity;
    }

    /**
     * Compacts a build-time trie.
     *
     * The compaction
     * - removes blocks that are identical with earlier ones
     * - overlaps each new non-duplicate block as much as possible with the previously-written one
     * - works with fast-range data blocks whose length is a multiple of that of
     *   higher-code-point data blocks
     *
     * It does not try to find an optimal order of writing, deduplicating, and overlapping blocks.
     */
    private int compactData(
            int fastILimit, int[] newData, int dataNullIndex, MixedBlocks mixedBlocks) {
        // The linear ASCII data has been copied into newData already.
        int newDataLength = 0;
        for (int i = 0; newDataLength < ASCII_LIMIT;
                newDataLength += CodePointTrie.FAST_DATA_BLOCK_LENGTH, i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK) {
            index[i] = newDataLength;
        }

        int blockLength = CodePointTrie.FAST_DATA_BLOCK_LENGTH;
        mixedBlocks.init(newData.length, blockLength);
        mixedBlocks.extend(newData, 0, 0, newDataLength);

        int iLimit = highStart >> CodePointTrie.SHIFT_3;
        int inc = SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
        int fastLength = 0;
        for (int i = ASCII_I_LIMIT; i < iLimit; i += inc) {
            if (i == fastILimit) {
                blockLength = CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
                inc = 1;
                fastLength = newDataLength;
                mixedBlocks.init(newData.length, blockLength);
                mixedBlocks.extend(newData, 0, 0, newDataLength);
            }
            if (flags[i] == ALL_SAME) {
                int value = index[i];
                // Find an earlier part of the data array of length blockLength
                // that is filled with this value.
                int n = mixedBlocks.findAllSameBlock(newData, value);
                // If we find a match, and the current block is the data null block,
                // and it is not a fast block but matches the start of a fast block,
                // then we need to continue looking.
                // This is because this small block is shorter than the fast block,
                // and not all of the rest of the fast block is filled with this value.
                // Otherwise trie.getRange() would detect that the fast block starts at
                // dataNullOffset and assume incorrectly that it is filled with the null value.
                while (n >= 0 && i == dataNullIndex && i >= fastILimit && n < fastLength &&
                        isStartOfSomeFastBlock(n, index, fastILimit)) {
                    n = findAllSameBlock(newData, n + 1, newDataLength, value, blockLength);
                }
                if (n >= 0) {
                    index[i] = n;
                } else {
                    n = getAllSameOverlap(newData, newDataLength, value, blockLength);
                    index[i] = newDataLength - n;
                    int prevDataLength = newDataLength;
                    while (n < blockLength) {
                        newData[newDataLength++] = value;
                        ++n;
                    }
                    mixedBlocks.extend(newData, 0, prevDataLength, newDataLength);
                }
            } else if (flags[i] == MIXED) {
                int block = index[i];
                int n = mixedBlocks.findBlock(newData, data, block);
                if (n >= 0) {
                    index[i] = n;
                } else {
                    n = getOverlap(newData, newDataLength, data, block, blockLength);
                    index[i] = newDataLength - n;
                    int prevDataLength = newDataLength;
                    while (n < blockLength) {
                        newData[newDataLength++] = data[block + n++];
                    }
                    mixedBlocks.extend(newData, 0, prevDataLength, newDataLength);
                }
            } else /* SAME_AS */ {
                int j = index[i];
                index[i] = index[j];
            }
        }

        return newDataLength;
    }

    private int compactIndex(int fastILimit, MixedBlocks mixedBlocks) {
        int fastIndexLength = fastILimit >> (CodePointTrie.FAST_SHIFT - CodePointTrie.SHIFT_3);
        if ((highStart >> CodePointTrie.FAST_SHIFT) <= fastIndexLength) {
            // Only the linear fast index, no multi-stage index tables.
            index3NullOffset = CodePointTrie.NO_INDEX3_NULL_OFFSET;
            return fastIndexLength;
        }

        // Condense the fast index table.
        // Also, does it contain an index-3 block with all dataNullOffset?
        char[] fastIndex = new char[fastIndexLength];
        int i3FirstNull = -1;
        for (int i = 0, j = 0; i < fastILimit; ++j) {
            int i3 = index[i];
            fastIndex[j] = (char)i3;
            if (i3 == dataNullOffset) {
                if (i3FirstNull < 0) {
                    i3FirstNull = j;
                } else if (index3NullOffset < 0 &&
                        (j - i3FirstNull + 1) == CodePointTrie.INDEX_3_BLOCK_LENGTH) {
                    index3NullOffset = i3FirstNull;
                }
            } else {
                i3FirstNull = -1;
            }
            // Set the index entries that compactData() skipped.
            // Needed when the multi-stage index covers the fast index range as well.
            int iNext = i + SMALL_DATA_BLOCKS_PER_BMP_BLOCK;
            while (++i < iNext) {
                i3 += CodePointTrie.SMALL_DATA_BLOCK_LENGTH;
                index[i] = i3;
            }
        }

        mixedBlocks.init(fastIndexLength, CodePointTrie.INDEX_3_BLOCK_LENGTH);
        mixedBlocks.extend(fastIndex, 0, 0, fastIndexLength);

        // Examine index-3 blocks. For each determine one of:
        // - same as the index-3 null block
        // - same as a fast-index block
        // - 16-bit indexes
        // - 18-bit indexes
        // We store this in the first flags entry for the index-3 block.
        //
        // Also determine an upper limit for the index-3 table length.
        int index3Capacity = 0;
        i3FirstNull = index3NullOffset;
        boolean hasLongI3Blocks = false;
        // If the fast index covers the whole BMP, then
        // the multi-stage index is only for supplementary code points.
        // Otherwise, the multi-stage index covers all of Unicode.
        int iStart = fastILimit < BMP_I_LIMIT ? 0 : BMP_I_LIMIT;
        int iLimit = highStart >> CodePointTrie.SHIFT_3;
        for (int i = iStart; i < iLimit;) {
            int j = i;
            int jLimit = i + CodePointTrie.INDEX_3_BLOCK_LENGTH;
            int oredI3 = 0;
            boolean isNull = true;
            do {
                int i3 = index[j];
                oredI3 |= i3;
                if (i3 != dataNullOffset) {
                    isNull = false;
                }
            } while (++j < jLimit);
            if (isNull) {
                flags[i] = I3_NULL;
                if (i3FirstNull < 0) {
                    if (oredI3 <= 0xffff) {
                        index3Capacity += CodePointTrie.INDEX_3_BLOCK_LENGTH;
                    } else {
                        index3Capacity += INDEX_3_18BIT_BLOCK_LENGTH;
                        hasLongI3Blocks = true;
                    }
                    i3FirstNull = 0;
                }
            } else {
                if (oredI3 <= 0xffff) {
                    int n = mixedBlocks.findBlock(fastIndex, index, i);
                    if (n >= 0) {
                        flags[i] = I3_BMP;
                        index[i] = n;
                    } else {
                        flags[i] = I3_16;
                        index3Capacity += CodePointTrie.INDEX_3_BLOCK_LENGTH;
                    }
                } else {
                    flags[i] = I3_18;
                    index3Capacity += INDEX_3_18BIT_BLOCK_LENGTH;
                    hasLongI3Blocks = true;
                }
            }
            i = j;
        }

        int index2Capacity = (iLimit - iStart) >> CodePointTrie.SHIFT_2_3;

        // Length of the index-1 table, rounded up.
        int index1Length = (index2Capacity + CodePointTrie.INDEX_2_MASK) >> CodePointTrie.SHIFT_1_2;

        // Index table: Fast index, index-1, index-3, index-2.
        // +1 for possible index table padding.
        int index16Capacity = fastIndexLength + index1Length + index3Capacity + index2Capacity + 1;
        index16 = Arrays.copyOf(fastIndex, index16Capacity);

        mixedBlocks.init(index16Capacity, CodePointTrie.INDEX_3_BLOCK_LENGTH);
        MixedBlocks longI3Blocks = null;
        if (hasLongI3Blocks) {
            longI3Blocks = new MixedBlocks();
            longI3Blocks.init(index16Capacity, INDEX_3_18BIT_BLOCK_LENGTH);
        }

        // Compact the index-3 table and write an uncompacted version of the index-2 table.
        char[] index2 = new char[index2Capacity];
        int i2Length = 0;
        i3FirstNull = index3NullOffset;
        int index3Start = fastIndexLength + index1Length;
        int indexLength = index3Start;
        for (int i = iStart; i < iLimit; i += CodePointTrie.INDEX_3_BLOCK_LENGTH) {
            int i3;
            byte f = flags[i];
            if (f == I3_NULL && i3FirstNull < 0) {
                // First index-3 null block. Write & overlap it like a normal block, then remember it.
                f = dataNullOffset <= 0xffff ? I3_16 : I3_18;
                i3FirstNull = 0;
            }
            if (f == I3_NULL) {
                i3 = index3NullOffset;
            } else if (f == I3_BMP) {
                i3 = index[i];
            } else if (f == I3_16) {
                int n = mixedBlocks.findBlock(index16, index, i);
                if (n >= 0) {
                    i3 = n;
                } else {
                    if (indexLength == index3Start) {
                        // No overlap at the boundary between the index-1 and index-3 tables.
                        n = 0;
                    } else {
                        n = getOverlap(index16, indexLength,
                                       index, i, CodePointTrie.INDEX_3_BLOCK_LENGTH);
                    }
                    i3 = indexLength - n;
                    int prevIndexLength = indexLength;
                    while (n < CodePointTrie.INDEX_3_BLOCK_LENGTH) {
                        index16[indexLength++] = (char)index[i + n++];
                    }
                    mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
                    if (hasLongI3Blocks) {
                        longI3Blocks.extend(index16, index3Start, prevIndexLength, indexLength);
                    }
                }
            } else {
                assert(f == I3_18);
                assert(hasLongI3Blocks);
                // Encode an index-3 block that contains one or more data indexes exceeding 16 bits.
                int j = i;
                int jLimit = i + CodePointTrie.INDEX_3_BLOCK_LENGTH;
                int k = indexLength;
                do {
                    ++k;
                    int v = index[j++];
                    int upperBits = (v & 0x30000) >> 2;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 4;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 6;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 8;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 10;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 12;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 14;
                    index16[k++] = (char)v;
                    v = index[j++];
                    upperBits |= (v & 0x30000) >> 16;
                    index16[k++] = (char)v;
                    index16[k - 9] = (char)upperBits;
                } while (j < jLimit);
                int n = longI3Blocks.findBlock(index16, index16, indexLength);
                if (n >= 0) {
                    i3 = n | 0x8000;
                } else {
                    if (indexLength == index3Start) {
                        // No overlap at the boundary between the index-1 and index-3 tables.
                        n = 0;
                    } else {
                        n = getOverlap(index16, indexLength,
                                       index16, indexLength, INDEX_3_18BIT_BLOCK_LENGTH);
                    }
                    i3 = (indexLength - n) | 0x8000;
                    int prevIndexLength = indexLength;
                    if (n > 0) {
                        int start = indexLength;
                        while (n < INDEX_3_18BIT_BLOCK_LENGTH) {
                            index16[indexLength++] = index16[start + n++];
                        }
                    } else {
                        indexLength += INDEX_3_18BIT_BLOCK_LENGTH;
                    }
                    mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
                    if (hasLongI3Blocks) {
                        longI3Blocks.extend(index16, index3Start, prevIndexLength, indexLength);
                    }
                }
            }
            if (index3NullOffset < 0 && i3FirstNull >= 0) {
                index3NullOffset = i3;
            }
            // Set the index-2 table entry.
            index2[i2Length++] = (char)i3;
        }
        assert(i2Length == index2Capacity);
        assert(indexLength <= index3Start + index3Capacity);

        if (index3NullOffset < 0) {
            index3NullOffset = CodePointTrie.NO_INDEX3_NULL_OFFSET;
        }
        if (indexLength >= (CodePointTrie.NO_INDEX3_NULL_OFFSET + CodePointTrie.INDEX_3_BLOCK_LENGTH)) {
            // The index-3 offsets exceed 15 bits, or
            // the last one cannot be distinguished from the no-null-block value.
            throw new IndexOutOfBoundsException(
                    "The trie data exceeds limitations of the data structure.");
        }

        // Compact the index-2 table and write the index-1 table.
        // assert(CodePointTrie.INDEX_2_BLOCK_LENGTH == CodePointTrie.INDEX_3_BLOCK_LENGTH) :
        //     "must re-init mixedBlocks";
        int blockLength = CodePointTrie.INDEX_2_BLOCK_LENGTH;
        int i1 = fastIndexLength;
        for (int i = 0; i < i2Length; i += blockLength) {
            int n;
            if ((i2Length - i) >= blockLength) {
                // normal block
                assert(blockLength == CodePointTrie.INDEX_2_BLOCK_LENGTH);
                n = mixedBlocks.findBlock(index16, index2, i);
            } else {
                // highStart is inside the last index-2 block. Shorten it.
                blockLength = i2Length - i;
                n = findSameBlock(index16, index3Start, indexLength,
                        index2, i, blockLength);
            }
            int i2;
            if (n >= 0) {
                i2 = n;
            } else {
                if (indexLength == index3Start) {
                    // No overlap at the boundary between the index-1 and index-3/2 tables.
                    n = 0;
                } else {
                    n = getOverlap(index16, indexLength, index2, i, blockLength);
                }
                i2 = indexLength - n;
                int prevIndexLength = indexLength;
                while (n < blockLength) {
                    index16[indexLength++] = index2[i + n++];
                }
                mixedBlocks.extend(index16, index3Start, prevIndexLength, indexLength);
            }
            // Set the index-1 table entry.
            index16[i1++] = (char)i2;
        }
        assert(i1 == index3Start);
        assert(indexLength <= index16Capacity);

        return indexLength;
    }

    private int compactTrie(int fastILimit) {
        // Find the real highStart and round it up.
        assert((highStart & (CodePointTrie.CP_PER_INDEX_2_ENTRY - 1)) == 0);
        highValue = get(MAX_UNICODE);
        int realHighStart = findHighStart();
        realHighStart = (realHighStart + (CodePointTrie.CP_PER_INDEX_2_ENTRY - 1)) &
            ~(CodePointTrie.CP_PER_INDEX_2_ENTRY - 1);
        if (realHighStart == UNICODE_LIMIT) {
            highValue = initialValue;
        }

        // We always store indexes and data values for the fast range.
        // Pin highStart to the top of that range while building.
        int fastLimit = fastILimit << CodePointTrie.SHIFT_3;
        if (realHighStart < fastLimit) {
            for (int i = (realHighStart >> CodePointTrie.SHIFT_3); i < fastILimit; ++i) {
                flags[i] = ALL_SAME;
                index[i] = highValue;
            }
            highStart = fastLimit;
        } else {
            highStart = realHighStart;
        }

        int[] asciiData = new int[ASCII_LIMIT];
        for (int i = 0; i < ASCII_LIMIT; ++i) {
            asciiData[i] = get(i);
        }

        // First we look for which data blocks have the same value repeated over the whole block,
        // deduplicate such blocks, find a good null data block (for faster enumeration),
        // and get an upper bound for the necessary data array length.
        AllSameBlocks allSameBlocks = new AllSameBlocks();
        int newDataCapacity = compactWholeDataBlocks(fastILimit, allSameBlocks);
        int[] newData = Arrays.copyOf(asciiData, newDataCapacity);

        int dataNullIndex = allSameBlocks.findMostUsed();

        MixedBlocks mixedBlocks = new MixedBlocks();
        int newDataLength = compactData(fastILimit, newData, dataNullIndex, mixedBlocks);
        assert(newDataLength <= newDataCapacity);
        data = newData;
        dataLength = newDataLength;
        if (dataLength > (0x3ffff + CodePointTrie.SMALL_DATA_BLOCK_LENGTH)) {
            // The offset of the last data block is too high to be stored in the index table.
            throw new IndexOutOfBoundsException(
                    "The trie data exceeds limitations of the data structure.");
        }

        if (dataNullIndex >= 0) {
            dataNullOffset = index[dataNullIndex];
            initialValue = data[dataNullOffset];
        } else {
            dataNullOffset = CodePointTrie.NO_DATA_NULL_OFFSET;
        }

        int indexLength = compactIndex(fastILimit, mixedBlocks);
        highStart = realHighStart;
        return indexLength;
    }

    private CodePointTrie build(CodePointTrie.Type type, CodePointTrie.ValueWidth valueWidth) {
        // The mutable trie always stores 32-bit values.
        // When we build a UCPTrie for a smaller value width, we first mask off unused bits
        // before compacting the data.
        switch (valueWidth) {
        case BITS_32:
            break;
        case BITS_16:
            maskValues(0xffff);
            break;
        case BITS_8:
            maskValues(0xff);
            break;
        default:
            // Should be unreachable.
            throw new IllegalArgumentException();
        }

        int fastLimit = type == CodePointTrie.Type.FAST ? BMP_LIMIT : CodePointTrie.SMALL_LIMIT;
        int indexLength = compactTrie(fastLimit >> CodePointTrie.SHIFT_3);

        // Ensure data table alignment: The index length must be even for uint32_t data.
        if (valueWidth == CodePointTrie.ValueWidth.BITS_32 && (indexLength & 1) != 0) {
            index16[indexLength++] = 0xffee;  // arbitrary value
        }

        // Make the total trie structure length a multiple of 4 bytes by padding the data table,
        // and store special values as the last two data values.
        int length = indexLength * 2;
        if (valueWidth == CodePointTrie.ValueWidth.BITS_16) {
            if (((indexLength ^ dataLength) & 1) != 0) {
                // padding
                data[dataLength++] = errorValue;
            }
            if (data[dataLength - 1] != errorValue || data[dataLength - 2] != highValue) {
                data[dataLength++] = highValue;
                data[dataLength++] = errorValue;
            }
            length += dataLength * 2;
        } else if (valueWidth == CodePointTrie.ValueWidth.BITS_32) {
            // 32-bit data words never need padding to a multiple of 4 bytes.
            if (data[dataLength - 1] != errorValue || data[dataLength - 2] != highValue) {
                if (data[dataLength - 1] != highValue) {
                    data[dataLength++] = highValue;
                }
                data[dataLength++] = errorValue;
            }
            length += dataLength * 4;
        } else {
            int and3 = (length + dataLength) & 3;
            if (and3 == 0 && data[dataLength - 1] == errorValue && data[dataLength - 2] == highValue) {
                // all set
            } else if(and3 == 3 && data[dataLength - 1] == highValue) {
                data[dataLength++] = errorValue;
            } else {
                while (and3 != 2) {
                    data[dataLength++] = highValue;
                    and3 = (and3 + 1) & 3;
                }
                data[dataLength++] = highValue;
                data[dataLength++] = errorValue;
            }
            length += dataLength;
        }
        assert((length & 3) == 0);

        // Fill the index and data arrays.
        char[] trieIndex;
        if (highStart <= fastLimit) {
            // Condense only the fast index from the mutable-trie index.
            trieIndex = new char[indexLength];
            for (int i = 0, j = 0; j < indexLength; i += SMALL_DATA_BLOCKS_PER_BMP_BLOCK, ++j) {
                trieIndex[j] = (char)index[i];
            }
        } else {
            if (indexLength == index16.length) {
                trieIndex = index16;
                index16 = null;
            } else {
                trieIndex = Arrays.copyOf(index16, indexLength);
            }
        }

        // Write the data array.
        switch (valueWidth) {
        case BITS_16: {
            // Write 16-bit data values.
            char[] data16 = new char[dataLength];
            for (int i = 0; i < dataLength; ++i) { data16[i] = (char)data[i]; }
            return type == CodePointTrie.Type.FAST ?
                    new CodePointTrie.Fast16(trieIndex, data16, highStart,
                            index3NullOffset, dataNullOffset) :
                    new CodePointTrie.Small16(trieIndex, data16, highStart,
                            index3NullOffset, dataNullOffset);
        }
        case BITS_32: {
            // Write 32-bit data values.
            int[] data32 = Arrays.copyOf(data, dataLength);
            return type == CodePointTrie.Type.FAST ?
                    new CodePointTrie.Fast32(trieIndex, data32, highStart,
                            index3NullOffset, dataNullOffset) :
                    new CodePointTrie.Small32(trieIndex, data32, highStart,
                            index3NullOffset, dataNullOffset);
        }
        case BITS_8: {
            // Write 8-bit data values.
            byte[] data8 = new byte[dataLength];
            for (int i = 0; i < dataLength; ++i) { data8[i] = (byte)data[i]; }
            return type == CodePointTrie.Type.FAST ?
                    new CodePointTrie.Fast8(trieIndex, data8, highStart,
                            index3NullOffset, dataNullOffset) :
                    new CodePointTrie.Small8(trieIndex, data8, highStart,
                            index3NullOffset, dataNullOffset);
        }
        default:
            // Should be unreachable.
            throw new IllegalArgumentException();
        }
    }
}
