// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2006-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */

package com.ibm.icu.charset;

import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.Locale;

import com.ibm.icu.charset.UConverterSharedData.UConverterType;
import com.ibm.icu.impl.ICUBinary;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.InvalidFormatException;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;

class CharsetMBCS extends CharsetICU {

    private byte[] fromUSubstitution = null;
    UConverterSharedData sharedData = null;
    private static final int MAX_VERSION_LENGTH = 4;

    // these variables are used in getUnicodeSet() and may be changed in future
    // typedef enum UConverterSetFilter {
      static final int UCNV_SET_FILTER_NONE = 1;
      static final int UCNV_SET_FILTER_DBCS_ONLY = 2;
      static final int UCNV_SET_FILTER_2022_CN = 3;
      static final int UCNV_SET_FILTER_SJIS= 4 ;
      static final int UCNV_SET_FILTER_GR94DBCS = 5;
      static final int UCNV_SET_FILTER_HZ = 6;
      static final int UCNV_SET_FILTER_COUNT = 7;
   //  } UConverterSetFilter;

    /**
     * Fallbacks to Unicode are stored outside the normal state table and code point structures in a vector of items of
     * this type. They are sorted by offset.
     */
    final static class MBCSToUFallback {
        int offset;
        int codePoint;

        MBCSToUFallback(int off, int cp) {
            offset = off;
            codePoint = cp;
        }
    }

    /**
     * This is the MBCS part of the UConverterTable union (a runtime data structure). It keeps all the per-converter
     * data and points into the loaded mapping tables.
     */
    static final class UConverterMBCSTable {
        /* toUnicode */
        short countStates;
        byte dbcsOnlyState;
        boolean stateTableOwned;
        int countToUFallbacks;

        int stateTable[/* countStates */][/* 256 */];
        int swapLFNLStateTable[/* countStates */][/* 256 */]; /* for swaplfnl */
        char unicodeCodeUnits[/* countUnicodeResults */];
        MBCSToUFallback toUFallbacks[/* countToUFallbacks */];

        /* fromUnicode */
        char fromUnicodeTable[];  // stage1, and for MBCS_OUTPUT_1 also contains stage2
        int fromUnicodeTableInts[];  // stage1 and stage2 together as int[]
        // Exactly one of the fromUnicode(Type) tables is not null,
        // depending on the outputType.
        byte fromUnicodeBytes[];
        char fromUnicodeChars[];
        int fromUnicodeInts[];
        char swapLFNLFromUnicodeChars[]; /* for swaplfnl */
        int fromUBytesLength;
        short outputType, unicodeMask;

        /* converter name for swaplfnl */
        String swapLFNLName;

        /* extension data */
        UConverterSharedData baseSharedData;
        // int extIndexes[];
        ByteBuffer extIndexes; // create int[] view etc. as needed

        CharBuffer mbcsIndex;                     /* for fast conversion from most of BMP to MBCS (utf8Friendly data) */
        // char sbcsIndex[/* SBCS_FAST_LIMIT>>6 */]; /* for fast conversion from low BMP to SBCS (utf8Friendly data) */
        boolean utf8Friendly;                     /* for utf8Friendly data */
        char maxFastUChar;                        /* for utf8Friendly data */

        /* roundtrips */
        int asciiRoundtrips;

        UConverterMBCSTable() {
            utf8Friendly = false;
            mbcsIndex = null;
        }

        boolean hasSupplementary() {
            return (unicodeMask & UConverterConstants.HAS_SUPPLEMENTARY) != 0;
        }

        /*
         * UConverterMBCSTable(UConverterMBCSTable t) { countStates = t.countStates; dbcsOnlyState = t.dbcsOnlyState;
         * stateTableOwned = t.stateTableOwned; countToUFallbacks = t.countToUFallbacks; stateTable = t.stateTable;
         * swapLFNLStateTable = t.swapLFNLStateTable; unicodeCodeUnits = t.unicodeCodeUnits; toUFallbacks =
         * t.toUFallbacks; fromUnicodeTable = t.fromUnicodeTable; fromUnicodeBytes = t.fromUnicodeBytes;
         * swapLFNLFromUnicodeChars = t.swapLFNLFromUnicodeChars; fromUBytesLength = t.fromUBytesLength; outputType =
         * t.outputType; unicodeMask = t.unicodeMask; swapLFNLName = t.swapLFNLName; baseSharedData = t.baseSharedData;
         * extIndexes = t.extIndexes; }
         */
    }

    /* Constants used in MBCS data header */
    // enum {
        static final int MBCS_OPT_LENGTH_MASK=0x3f;
        static final int MBCS_OPT_NO_FROM_U=0x40;
        /*
         * If any of the following options bits are set,
         * then the file must be rejected.
         */
        static final int MBCS_OPT_INCOMPATIBLE_MASK=0xffc0;
        /*
         * Remove bits from this mask as more options are recognized
         * by all implementations that use this constant.
         */
        static final int MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK=0xff80;
    // };
    /* Constants for fast and UTF-8-friendly conversion. */
    // enum {
        static final int SBCS_FAST_MAX=0x0fff;               /* maximum code point with UTF-8-friendly SBCS runtime code, see makeconv SBCS_UTF8_MAX */
        static final int SBCS_FAST_LIMIT=SBCS_FAST_MAX+1;    /* =0x1000 */
        static final int MBCS_FAST_MAX=0xd7ff;               /* maximum code point with UTF-8-friendly MBCS runtime code, see makeconv MBCS_UTF8_MAX */
        static final int MBCS_FAST_LIMIT=MBCS_FAST_MAX+1;    /* =0xd800 */
    // };
    /**
     * MBCS data header. See data format description above.
     */
    final static class MBCSHeader {
        byte version[/* U_MAX_VERSION_LENGTH */];
        int countStates, countToUFallbacks, offsetToUCodeUnits, offsetFromUTable, offsetFromUBytes;
        int flags;
        int fromUBytesLength;

        /* new and required in version 5 */
        int options;

        /* new and optional in version 5; used if options&MBCS_OPT_NO_FROM_U */
        int fullStage2Length;  /* number of 32-bit units */

        MBCSHeader() {
            version = new byte[MAX_VERSION_LENGTH];
        }
    }

    public CharsetMBCS(String icuCanonicalName, String javaCanonicalName, String[] aliases, String classPath,
            ClassLoader loader) throws InvalidFormatException {
        super(icuCanonicalName, javaCanonicalName, aliases);

        /* See if the icuCanonicalName contains certain option information. */
        if (icuCanonicalName.indexOf(UConverterConstants.OPTION_SWAP_LFNL_STRING) > -1) {
            options = UConverterConstants.OPTION_SWAP_LFNL;
            icuCanonicalName = icuCanonicalName.substring(0, icuCanonicalName.indexOf(UConverterConstants.OPTION_SWAP_LFNL_STRING));
            super.icuCanonicalName = icuCanonicalName;
        }

        // now try to load the data
        sharedData = loadConverter(1, icuCanonicalName, classPath, loader);

        maxBytesPerChar = sharedData.staticData.maxBytesPerChar;
        minBytesPerChar = sharedData.staticData.minBytesPerChar;
        maxCharsPerByte = 1;
        fromUSubstitution = sharedData.staticData.subChar;
        subChar = sharedData.staticData.subChar;
        subCharLen = sharedData.staticData.subCharLen;
        subChar1 = sharedData.staticData.subChar1;
        fromUSubstitution = new byte[sharedData.staticData.subCharLen];
        System.arraycopy(sharedData.staticData.subChar, 0, fromUSubstitution, 0, sharedData.staticData.subCharLen);

        initializeConverter(options);
    }

    public CharsetMBCS(String icuCanonicalName, String javaCanonicalName, String[] aliases)
            throws InvalidFormatException {
        this(icuCanonicalName, javaCanonicalName, aliases, ICUData.ICU_BUNDLE, null);
    }

    private UConverterSharedData loadConverter(int nestedLoads, String myName, String classPath, ClassLoader loader)
            throws InvalidFormatException {
        boolean noFromU = false;
        // Read converter data from file
        UConverterStaticData staticData = new UConverterStaticData();
        UConverterDataReader reader = null;
        try {
            String itemName = myName + '.' + UConverterSharedData.DATA_TYPE;
            String resourceName = classPath + '/' + itemName;
            ByteBuffer b;

            if (loader != null) {
                @SuppressWarnings("resource")  // Closed by getByteBufferFromInputStreamAndCloseStream().
                InputStream i = ICUData.getRequiredStream(loader, resourceName);
                b = ICUBinary.getByteBufferFromInputStreamAndCloseStream(i);
            } else if (!classPath.equals(ICUData.ICU_BUNDLE)) {
                @SuppressWarnings("resource")  // Closed by getByteBufferFromInputStreamAndCloseStream().
                InputStream i = ICUData.getRequiredStream(resourceName);
                b = ICUBinary.getByteBufferFromInputStreamAndCloseStream(i);
            } else {
                b = ICUBinary.getRequiredData(itemName);
            }
            reader = new UConverterDataReader(b);
            reader.readStaticData(staticData);
        } catch (IOException e) {
            throw new InvalidFormatException(e);
        } catch (Exception e) {
            throw new InvalidFormatException(e);
        }

        int type = staticData.conversionType;

        if (type != UConverterSharedData.UConverterType.MBCS
                || staticData.structSize != UConverterStaticData.SIZE_OF_UCONVERTER_STATIC_DATA) {
            throw new InvalidFormatException();
        }

        UConverterSharedData data = new UConverterSharedData(staticData);

        // Load data
        UConverterMBCSTable mbcsTable = data.mbcs;
        MBCSHeader header = new MBCSHeader();
        try {
            reader.readMBCSHeader(header);
        } catch (IOException e) {
            throw new InvalidFormatException();
        }

        int offset;
        // int[] extIndexesArray = null;
        String baseNameString = null;

        if (header.version[0] == 5 && header.version[1] >= 3 && (header.options & MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK) == 0) {
            noFromU = ((header.options & MBCS_OPT_NO_FROM_U) != 0);
        } else if (header.version[0] != 4) {
            throw new InvalidFormatException();
        }

        mbcsTable.outputType = (byte) header.flags;

        /* extension data, header version 4.2 and higher */
        offset = header.flags >>> 8;
        // if(offset!=0 && mbcsTable.outputType == MBCS_OUTPUT_EXT_ONLY) {
        if (mbcsTable.outputType == MBCS_OUTPUT_EXT_ONLY) {
            try {
                baseNameString = reader.readBaseTableName();
                if (offset != 0) {
                    // agljport:commment subtract 32 for sizeof(_MBCSHeader) and length of baseNameString and 1 null
                    // terminator byte all already read;
                    mbcsTable.extIndexes = reader.readExtIndexes(offset - reader.bytesReadAfterStaticData());
                }
            } catch (IOException e) {
                throw new InvalidFormatException();
            }
        }

        // agljport:add this would be unnecessary if extIndexes were memory mapped
        /*
         * if(mbcsTable.extIndexes != null) {
         *
         * try { //int nbytes = mbcsTable.extIndexes[UConverterExt.UCNV_EXT_TO_U_LENGTH]*4 +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_TO_U_UCHARS_LENGTH]*2 +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_FROM_U_LENGTH]*6 +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_FROM_U_BYTES_LENGTH] +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_FROM_U_STAGE_12_LENGTH]*2 +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_FROM_U_STAGE_3_LENGTH]*2 +
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_FROM_U_STAGE_3B_LENGTH]*4; //int nbytes =
         * mbcsTable.extIndexes[UConverterExt.UCNV_EXT_SIZE] //byte[] extTables = dataReader.readExtTables(nbytes);
         * //mbcsTable.extTables = ByteBuffer.wrap(extTables); } catch(IOException e) { System.err.println("Caught
         * IOException: " + e.getMessage()); pErrorCode[0] = UErrorCode.U_INVALID_FORMAT_ERROR; return; } }
         */
        if (mbcsTable.outputType == MBCS_OUTPUT_EXT_ONLY) {
            UConverterSharedData baseSharedData = null;
            ByteBuffer extIndexes;
            String baseName;

            /* extension-only file, load the base table and set values appropriately */
            extIndexes = mbcsTable.extIndexes;
            if (extIndexes == null) {
                /* extension-only file without extension */
                throw new InvalidFormatException();
            }

            if (nestedLoads != 1) {
                /* an extension table must not be loaded as a base table */
                throw new InvalidFormatException();
            }

            /* load the base table */
            baseName = baseNameString;
            if (baseName.equals(staticData.name)) {
                /* forbid loading this same extension-only file */
                throw new InvalidFormatException();
            }

            // agljport:fix args.size=sizeof(UConverterLoadArgs);
            baseSharedData = loadConverter(2, baseName, classPath, loader);

            if (baseSharedData.staticData.conversionType != UConverterType.MBCS
                    || baseSharedData.mbcs.baseSharedData != null) {
                // agljport:fix ucnv_unload(baseSharedData);
                throw new InvalidFormatException();
            }

            /* copy the base table data */
            // agljport:comment deep copy in C changes mbcs through local reference mbcsTable; in java we probably don't
            // need the deep copy so can just make sure mbcs and its local reference both refer to the same new object
            mbcsTable = data.mbcs = baseSharedData.mbcs;

            /* overwrite values with relevant ones for the extension converter */
            mbcsTable.baseSharedData = baseSharedData;
            mbcsTable.extIndexes = extIndexes;

            /*
             * It would be possible to share the swapLFNL data with a base converter, but the generated name would have
             * to be different, and the memory would have to be free'd only once. It is easier to just create the data
             * for the extension converter separately when it is requested.
             */
            mbcsTable.swapLFNLStateTable = null;
            mbcsTable.swapLFNLFromUnicodeChars = null;
            mbcsTable.swapLFNLName = null;

            /*
             * Set a special, runtime-only outputType if the extension converter is a DBCS version of a base converter
             * that also maps single bytes.
             */
            if (staticData.conversionType == UConverterType.DBCS
                    || (staticData.conversionType == UConverterType.MBCS && staticData.minBytesPerChar >= 2)) {

                if (baseSharedData.mbcs.outputType == MBCS_OUTPUT_2_SISO) {
                    /* the base converter is SI/SO-stateful */
                    int entry;

                    /* get the dbcs state from the state table entry for SO=0x0e */
                    entry = mbcsTable.stateTable[0][0xe];
                    if (MBCS_ENTRY_IS_FINAL(entry) && MBCS_ENTRY_FINAL_ACTION(entry) == MBCS_STATE_CHANGE_ONLY
                            && MBCS_ENTRY_FINAL_STATE(entry) != 0) {
                        mbcsTable.dbcsOnlyState = (byte) MBCS_ENTRY_FINAL_STATE(entry);

                        mbcsTable.outputType = MBCS_OUTPUT_DBCS_ONLY;
                    }
                } else if (baseSharedData.staticData.conversionType == UConverterType.MBCS
                        && baseSharedData.staticData.minBytesPerChar == 1
                        && baseSharedData.staticData.maxBytesPerChar == 2 && mbcsTable.countStates <= 127) {

                    /* non-stateful base converter, need to modify the state table */
                    int newStateTable[][/* 256 */];
                    int state[]; // this works because java 2-D array is array of references and we can have state =
                    // newStateTable[i];
                    int i, count;

                    /* allocate a new state table and copy the base state table contents */
                    count = mbcsTable.countStates;
                    newStateTable = new int[(count + 1) * 1024][256];

                    for (i = 0; i < mbcsTable.stateTable.length; ++i)
                        System.arraycopy(mbcsTable.stateTable[i], 0, newStateTable[i], 0,
                                mbcsTable.stateTable[i].length);

                    /* change all final single-byte entries to go to a new all-illegal state */
                    state = newStateTable[0];
                    for (i = 0; i < 256; ++i) {
                        if (MBCS_ENTRY_IS_FINAL(state[i])) {
                            state[i] = MBCS_ENTRY_TRANSITION(count, 0);
                        }
                    }

                    /* build the new all-illegal state */
                    state = newStateTable[count];
                    for (i = 0; i < 256; ++i) {
                        state[i] = MBCS_ENTRY_FINAL(0, MBCS_STATE_ILLEGAL, 0);
                    }
                    mbcsTable.stateTable = newStateTable;
                    mbcsTable.countStates = (byte) (count + 1);
                    mbcsTable.stateTableOwned = true;

                    mbcsTable.outputType = MBCS_OUTPUT_DBCS_ONLY;
                }
            }

            /*
             * unlike below for files with base tables, do not get the unicodeMask from the sharedData; instead, use the
             * base table's unicodeMask, which we copied in the memcpy above; this is necessary because the static data
             * unicodeMask, especially the UCNV_HAS_SUPPLEMENTARY flag, is part of the base table data
             */
        } else {
            /* conversion file with a base table; an additional extension table is optional */
            /* make sure that the output type is known */
            switch (mbcsTable.outputType) {
            case MBCS_OUTPUT_1:
            case MBCS_OUTPUT_2:
            case MBCS_OUTPUT_3:
            case MBCS_OUTPUT_4:
            case MBCS_OUTPUT_3_EUC:
            case MBCS_OUTPUT_4_EUC:
            case MBCS_OUTPUT_2_SISO:
                /* OK */
                break;
            default:
                throw new InvalidFormatException();
            }

            /*
             * converter versions 6.1 and up contain a unicodeMask that is used here to select the most efficient
             * function implementations
             */
            // agljport:fix info.size=sizeof(UDataInfo);
            // agljport:fix udata_getInfo((UDataMemory *)sharedData->dataMemory, &info);
            if (reader.dataFormatHasUnicodeMask()) {
                /* mask off possible future extensions to be safe */
                mbcsTable.unicodeMask = (short) (staticData.unicodeMask & 3);
            } else {
                /* for older versions, assume worst case: contains anything possible (prevent over-optimizations) */
                mbcsTable.unicodeMask = UConverterConstants.HAS_SUPPLEMENTARY | UConverterConstants.HAS_SURROGATES;
            }
            try {
                reader.readMBCSTable(header, mbcsTable);
            } catch (IOException e) {
                throw new InvalidFormatException();
            }

            if (offset != 0) {
                try {
                    // agljport:commment subtract 32 for sizeof(_MBCSHeader) and length of baseNameString and 1 null
                    // terminator byte all already read;
                    // int namelen = baseNameString != null? baseNameString.length() + 1: 0;
                    mbcsTable.extIndexes = reader.readExtIndexes(offset - reader.bytesReadAfterStaticData());
                } catch (IOException e) {
                    throw new InvalidFormatException();
                }
            }

            if (header.version[1] >= 3 && (mbcsTable.unicodeMask & UConverterConstants.HAS_SURROGATES) == 0 &&
                    (mbcsTable.countStates == 1 ? ((char)header.version[2] >= (SBCS_FAST_MAX>>8)) : ((char)header.version[2] >= (MBCS_FAST_MAX>>8)))) {
                mbcsTable.utf8Friendly = true;

                if (mbcsTable.countStates == 1) {
                    /*
                     * SBCS: Stage 3 is allocated in 64-entry blocks for U+0000..SBCS_FAST_MAX or higher.
                     * Build a table with indexes to each block, to be used instead of
                     * the regular stage 1/2 table.
                     */
//                    sbcsIndex = new char[SBCS_FAST_LIMIT>>6];
//                    for (int i = 0; i < (SBCS_FAST_LIMIT>>6); ++i) {
//                        mbcsTable.sbcsIndex[i] = mbcsTable.fromUnicodeTable[mbcsTable.fromUnicodeTable[i>>4]+((i<<2)&0x3c)];
//                    }
                    /* set SBCS_FAST_MAX to reflect the reach of sbcsIndex[] even if header.version[2]>(SBCS_FAST_MAX>>8) */
                    mbcsTable.maxFastUChar = SBCS_FAST_MAX;
                } else {
                    /*
                     * MBCS: Stage 3 is allocated in 64-entry blocks for U+0000..MBCS_FAST_MAX or higher.
                     * The .cnv file is prebuilt with an additional stage table with indexes to each block.
                     */
                    mbcsTable.maxFastUChar = (char)((header.version[2]<<8) | 0xff);
                }
            }
            /* calculate a bit set of 4 ASCII characters per bit that round-trip to ASCII bytes */
            {
                int asciiRoundtrips = 0xffffffff;
                for (int i = 0; i < 0x80; ++i) {
                    if (mbcsTable.stateTable[0][i] != MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_DIRECT_16, i)) {
                        asciiRoundtrips &= ~(1 << (i >> 2));
                    }
                }
                mbcsTable.asciiRoundtrips = asciiRoundtrips;
            }
            // TODO: Use asciiRoundtrips to speed up conversion, like in ICU4C.

            if (noFromU) {
                int stage1Length = (mbcsTable.unicodeMask&UConverterConstants.HAS_SUPPLEMENTARY) != 0 ? 0x440 : 0x40;
                int stage2Length = (header.offsetFromUBytes - header.offsetFromUTable)/4 - stage1Length/2;
                reconstituteData(mbcsTable, stage1Length, stage2Length, header.fullStage2Length);
            }
            if (mbcsTable.outputType == MBCS_OUTPUT_DBCS_ONLY || mbcsTable.outputType == MBCS_OUTPUT_2_SISO) {
                /*
                 * MBCS_OUTPUT_DBCS_ONLY: No SBCS mappings, therefore ASCII does not roundtrip.
                 * MBCS_OUTPUT_2_SISO: Bypass the ASCII fastpath to handle prevLength correctly.
                 */
                mbcsTable.asciiRoundtrips = 0;
            }
        }
        // TODO: Use mbcsIndex to speed up UTF-16 conversion, like in ICU4C.
        mbcsTable.mbcsIndex = null;
        return data;
    }

    private static boolean writeStage3Roundtrip(UConverterMBCSTable mbcsTable, long value, int codePoints[]) {
        char[] table;
        byte[] bytes;
        int stage2;
        int p;
        int c;
        int i, st3;

        table = mbcsTable.fromUnicodeTable;
        int[] tableInts = mbcsTable.fromUnicodeTableInts;
        bytes = mbcsTable.fromUnicodeBytes;
        char[] chars = mbcsTable.fromUnicodeChars;
        int[] ints = mbcsTable.fromUnicodeInts;

        /* for EUC outputTypes, modify the value like genmbcs.c's transformEUC() */
        switch(mbcsTable.outputType) {
        case MBCS_OUTPUT_3_EUC:
            if(value<=0xffff) {
                /* short sequences are stored directly */
                /* code set 0 or 1 */
            } else if(value<=0x8effff) {
                /* code set 2 */
                value&=0x7fff;
            } else /* first byte is 0x8f */ {
                /* code set 3 */
                value&=0xff7f;
            }
            break;
        case MBCS_OUTPUT_4_EUC:
            if(value<=0xffffff) {
                /* short sequences are stored directly */
                /* code set 0 or 1 */
            } else if(value<=0x8effffffL) {
                /* code set 2 */
                value&=0x7fffff;
            } else /* first byte is 0x8f */ {
                /* code set 3 */
                value&=0xff7fff;
            }
            break;
        default:
            break;
        }

        for(i=0; i<=0x1f; ++value, ++i) {
            c=codePoints[i];
            if(c<0) {
                continue;
            }

            /* locate the stage 2 & 3 data */
            stage2 = table[c>>10] + ((c>>4)&0x3f);
            st3 = tableInts[stage2];
            st3 = (char)(st3 * 16 + (c&0xf));

            /* write the codepage bytes into stage 3 */
            switch(mbcsTable.outputType) {
            case MBCS_OUTPUT_3:
            case MBCS_OUTPUT_4_EUC:
                p = st3*3;
                bytes[p] = (byte)(value>>16);
                bytes[p+1] = (byte)(value>>8);
                bytes[p+2] = (byte)value;
                break;
            case MBCS_OUTPUT_4:
                ints[st3] = (int)value;
                break;
            default:
                /* 2 bytes per character */
                chars[st3] = (char)value;
                break;
            }

            // Set the roundtrip flag.
            int shift = 16 + (c & 0x0F);
            tableInts[stage2] |= (1L << shift);
        }
        return true;
     }

    private static void reconstituteData(UConverterMBCSTable mbcsTable,
            int stage1Length, int stage2Length, int fullStage2Length) {
        char[] stage1 = mbcsTable.fromUnicodeTable;

        // stage2 starts with unused stage1 space.
        // Indexes into stage 2 count from the bottom of the fromUnicodeTable.
        int numStage1Ints = stage1Length / 2;  // 2 chars = 1 int
        int[] stage2 = new int[numStage1Ints + fullStage2Length];
        System.arraycopy(mbcsTable.fromUnicodeTableInts, numStage1Ints,
                stage2, (fullStage2Length - stage2Length) + numStage1Ints,
                stage2Length);
        mbcsTable.fromUnicodeTableInts = stage2;

        /* reconstitute the initial part of stage 2 from the mbcsIndex */
        {
            int stageUTF8Length=(mbcsTable.maxFastUChar+1)>>6;
            int stageUTF8Index=0;
            int st1, st2, st3, i;

            for (st1 = 0; stageUTF8Index < stageUTF8Length; ++st1) {
                st2 = stage1[st1];
                if (st2 != stage1Length/2) {
                    /* each stage 2 block has 64 entries corresponding to 16 entries in the mbcsIndex */
                    for (i = 0; i < 16; ++i) {
                        st3 = mbcsTable.mbcsIndex.get(stageUTF8Index++);
                        if (st3 != 0) {
                            /* a stage 2 entry's index is per stage 3 16-block, not per stage 3 entry */
                            st3>>=4;
                            /*
                             * 4 stage 2 entries point to 4 consecutive stage 3 16-blocks which are
                             * allocated together as a single 64-block for access from the mbcsIndex
                             */
                            stage2[st2++] = st3++;
                            stage2[st2++] = st3++;
                            stage2[st2++] = st3++;
                            stage2[st2++] = st3;
                        } else {
                            /* no stage 3 block, skip */
                            st2+=4;
                        }
                    }
                } else {
                    /* no stage 2 block, skip */
                    stageUTF8Index+=16;
                }
            }
        }

        switch (mbcsTable.outputType) {
        case CharsetMBCS.MBCS_OUTPUT_2:
        case CharsetMBCS.MBCS_OUTPUT_2_SISO:
        case CharsetMBCS.MBCS_OUTPUT_3_EUC:
            mbcsTable.fromUnicodeChars = new char[mbcsTable.fromUBytesLength / 2];
            break;
        case CharsetMBCS.MBCS_OUTPUT_3:
        case CharsetMBCS.MBCS_OUTPUT_4_EUC:
            mbcsTable.fromUnicodeBytes = new byte[mbcsTable.fromUBytesLength];
            break;
        case CharsetMBCS.MBCS_OUTPUT_4:
            mbcsTable.fromUnicodeInts = new int[mbcsTable.fromUBytesLength / 4];
            break;
        default:
            // Cannot occur, caller checked already.
            assert false;
        }

        /* reconstitute fromUnicodeBytes with roundtrips from toUnicode data */
        MBCSEnumToUnicode(mbcsTable);
    }

    /*
     * Internal function enumerating the toUnicode data of an MBCS converter.
     * Currently only used for reconstituting data for a MBCS_OPT_NO_FROM_U
     * table, but could also be used for a future getUnicodeSet() option
     * that includes reverse fallbacks (after updating this function's implementation).
     * Currently only handles roundtrip mappings.
     * Does not currently handle extensions.
     */
    private static void MBCSEnumToUnicode(UConverterMBCSTable mbcsTable) {
        /*
         * Properties for each state, to speed up the enumeration.
         * Ignorable actions are unassigned/illegal/state-change-only:
         * They do not lead to mappings.
         *
         * Bits 7..6
         * 1 direct/initial state (stateful converters have mulitple)
         * 0 non-initial state with transitions or with nonignorable result actions
         * -1 final state with only ignorable actions
         *
         * Bits 5..3
         * The lowest byte value with non-ignorable actions is
         * value<<5 (rounded down).
         *
         * Bits 2..0:
         * The highest byte value with non-ignorable actions is
         * (value<<5)&0x1f (rounded up).
         */
        byte stateProps[] = new byte[MBCS_MAX_STATE_COUNT];
        int state;

        /* recurse from state 0 and set all stateProps */
        getStateProp(mbcsTable.stateTable, stateProps, 0);

        for (state = 0; state < mbcsTable.countStates; ++state) {
            if (stateProps[state] >= 0x40) {
                /* start from each direct state */
                enumToU(mbcsTable, stateProps, state, 0, 0);
            }
        }


    }

    private static boolean enumToU(UConverterMBCSTable mbcsTable, byte stateProps[], int state, int offset, int value) {
        int[] codePoints = new int[32];
        int[] row;
        char[] unicodeCodeUnits;
        int anyCodePoints;
        int b, limit;

        row = mbcsTable.stateTable[state];
        unicodeCodeUnits = mbcsTable.unicodeCodeUnits;

        value<<=8;
        anyCodePoints = -1; /* becomes non-negative if there is a mapping */

        b = (stateProps[state]&0x38)<<2;
        if (b == 0 && stateProps[state] >= 0x40) {
            /* skip byte sequences with leading zeros because they are note stored in the fromUnicode table */
            codePoints[0] = UConverterConstants.U_SENTINEL;
            b = 1;
        }
        limit = ((stateProps[state]&7)+1)<<5;
        while (b < limit) {
            int entry = row[b];
            if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                int nextState = MBCS_ENTRY_TRANSITION_STATE(entry);
                if (stateProps[nextState] >= 0) {
                    /* recurse to a state with non-ignorable actions */
                    if (!enumToU(mbcsTable, stateProps, nextState, offset+MBCS_ENTRY_TRANSITION_OFFSET(entry), value|b)) {
                        return false;
                    }
                }
                codePoints[b&0x1f] = UConverterConstants.U_SENTINEL;
            } else {
                int c;
                int action;

                /*
                 * An if-else-if chain provides more reliable performance for
                 * the most common cases compared to a switch.
                 */
                action = MBCS_ENTRY_FINAL_ACTION(entry);
                if (action == MBCS_STATE_VALID_DIRECT_16) {
                    /* output BMP code point */
                    c = MBCS_ENTRY_FINAL_VALUE_16(entry);
                } else if (action == MBCS_STATE_VALID_16) {
                    int finalOffset = offset+MBCS_ENTRY_FINAL_VALUE_16(entry);
                    c = unicodeCodeUnits[finalOffset];
                    if (c < 0xfffe) {
                        /* output BMP code point */
                    } else {
                        c = UConverterConstants.U_SENTINEL;
                    }
                } else if (action == MBCS_STATE_VALID_16_PAIR) {
                    int finalOffset = offset+MBCS_ENTRY_FINAL_VALUE_16(entry);
                    c = unicodeCodeUnits[finalOffset++];
                    if (c < 0xd800) {
                        /* output BMP code point below 0xd800 */
                    } else if (c <= 0xdbff) {
                        /* output roundtrip or fallback supplementary code point */
                        c = ((c&0x3ff)<<10)+unicodeCodeUnits[finalOffset]+(0x10000-0xdc00);
                    } else if (c == 0xe000) {
                        /* output roundtrip BMP code point above 0xd800 or fallback BMP code point */
                        c = unicodeCodeUnits[finalOffset];
                    } else {
                        c = UConverterConstants.U_SENTINEL;
                    }
                } else if (action == MBCS_STATE_VALID_DIRECT_20) {
                    /* output supplementary code point */
                    c = MBCS_ENTRY_FINAL_VALUE(entry)+0x10000;
                } else {
                    c = UConverterConstants.U_SENTINEL;
                }

                codePoints[b&0x1f] = c;
                anyCodePoints&=c;
            }
            if (((++b)&0x1f) == 0) {
                if(anyCodePoints>=0) {
                    if(!writeStage3Roundtrip(mbcsTable, value|(b-0x20), codePoints)) {
                        return false;
                    }
                    anyCodePoints=-1;
                }
            }
        }

        return true;
    }

    /*
     * Only called if stateProps[state]==-1.
     * A recursive call may do stateProps[state]|=0x40 if this state is the target of an
     * MBCS_STATE_CHANGE_ONLY.
     */
    private static byte getStateProp(int stateTable[][], byte stateProps[], int state) {
        int[] row;
        int min, max, entry, nextState;

        row = stateTable[state];
        stateProps[state] = 0;

        /* find first non-ignorable state */
        for (min = 0;;++min) {
            entry = row[min];
            nextState = MBCS_ENTRY_STATE(entry);
            if (stateProps[nextState] == -1) {
                getStateProp(stateTable, stateProps, nextState);
            }
            if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                if (stateProps[nextState] >- 0) {
                    break;
                }
            } else if (MBCS_ENTRY_FINAL_ACTION(entry) < MBCS_STATE_UNASSIGNED) {
                break;
            }
            if (min == 0xff) {
                stateProps[state] = -0x40;  /* (byte)0xc0 */
                return stateProps[state];
            }
        }
        stateProps[state]|=(byte)((min>>5)<<3);

        /* find last non-ignorable state */
        for (max = 0xff; min < max; --max) {
            entry = row[max];
            nextState = MBCS_ENTRY_STATE(entry);
            if (stateProps[nextState] == -1) {
                getStateProp(stateTable, stateProps, nextState);
            }
            if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                if (stateProps[nextState] >- 0) {
                    break;
                }
            } else if (MBCS_ENTRY_FINAL_ACTION(entry) < MBCS_STATE_UNASSIGNED) {
                break;
            }
        }
        stateProps[state]|=(byte)(max>>5);

        /* recurse further and collect direct-state information */
        while (min <= max) {
            entry = row[min];
            nextState = MBCS_ENTRY_STATE(entry);
            if (stateProps[nextState] == -1) {
                getStateProp(stateTable, stateProps, nextState);
            }
            if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                stateProps[nextState]|=0x40;
                if (MBCS_ENTRY_FINAL_ACTION(entry) <= MBCS_STATE_FALLBACK_DIRECT_20) {
                    stateProps[state]|=0x40;
                }
            }
            ++min;
        }
        return stateProps[state];
    }

    protected void initializeConverter(int myOptions) {
        UConverterMBCSTable mbcsTable;
        ByteBuffer extIndexes;
        short outputType;
        byte maxBytesPerUChar;

        mbcsTable = sharedData.mbcs;
        outputType = mbcsTable.outputType;

        if (outputType == MBCS_OUTPUT_DBCS_ONLY) {
            /* the swaplfnl option does not apply, remove it */
            this.options = myOptions &= ~UConverterConstants.OPTION_SWAP_LFNL;
        }

        if ((myOptions & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
            /* do this because double-checked locking is broken */
            boolean isCached;

            // agljport:todo umtx_lock(NULL);
            isCached = mbcsTable.swapLFNLStateTable != null;
            // agljport:todo umtx_unlock(NULL);

            if (!isCached) {
                try {
                    if (!EBCDICSwapLFNL()) {
                        /* this option does not apply, remove it */
                        this.options = myOptions & ~UConverterConstants.OPTION_SWAP_LFNL;
                    }
                } catch (Exception e) {
                    /* something went wrong. */
                    return;
                }
            }
        }

        String lowerCaseName = icuCanonicalName.toLowerCase(Locale.ENGLISH);
        if (lowerCaseName.indexOf("gb18030") >= 0) {
            /* set a flag for GB 18030 mode, which changes the callback behavior */
            this.options |= MBCS_OPTION_GB18030;
        } else if (lowerCaseName.indexOf("keis") >= 0) {
            this.options |= MBCS_OPTION_KEIS;
        } else if (lowerCaseName.indexOf("jef") >= 0) {
            this.options |= MBCS_OPTION_JEF;
        } else if (lowerCaseName.indexOf("jips") >= 0) {
            this.options |= MBCS_OPTION_JIPS;
        }

        /* fix maxBytesPerUChar depending on outputType and options etc. */
        if (outputType == MBCS_OUTPUT_2_SISO) {
            /* changed from 3 to 4 in ICU4J only. #9205 */
            maxBytesPerChar = 4; /* SO+DBCS+SI*/
        }

        extIndexes = mbcsTable.extIndexes;
        if (extIndexes != null) {
            maxBytesPerUChar = (byte) GET_MAX_BYTES_PER_UCHAR(extIndexes);
            if (outputType == MBCS_OUTPUT_2_SISO) {
                ++maxBytesPerUChar; /* SO + multiple DBCS */
            }

            if (maxBytesPerUChar > maxBytesPerChar) {
                maxBytesPerChar = maxBytesPerUChar;
            }
        }
    }
     /* EBCDIC swap LF<->NL--------------------------------------------------------------------------------*/
     /*
      * This code modifies a standard EBCDIC<->Unicode mappling table for
      * OS/390 (z/OS) Unix System Services (Open Edition).
      * The difference is in the mapping of Line Feed and New Line control codes:
      * Standard EBDIC maps
      *
      * <U000A> \x25 |0
      * <U0085> \x15 |0
      *
      * but OS/390 USS EBCDIC swaps the control codes for LF and NL,
      * mapping
      *
      * <U000A> \x15 |0
      * <U0085> \x25 |0
      *
      * This code modifies a loaded standard EBCDIC<->Unicode mapping table
      * by copying it into allocated memory and swapping the LF and NL values.
      * It allows to support the same EBCDIC charset in both version without
      * duplicating the entire installed table.
      */
    /* standard EBCDIC codes */
    private static final short EBCDIC_LF = 0x0025;
    private static final short EBCDIC_NL = 0x0015;

    /* standard EBCDIC codes with roundtrip flag as stored in Unicode-to-single-byte tables */
    private static final short EBCDIC_RT_LF = 0x0f25;
    private static final short EBCDIC_RT_NL = 0x0f15;

    /* Unicode code points */
    private static final short U_LF = 0x000A;
    private static final short U_NL = 0x0085;

    private boolean EBCDICSwapLFNL() throws Exception {
        UConverterMBCSTable mbcsTable;

        char[] table;

        int[][] newStateTable;
        String newName;

        int stage2Entry;

        mbcsTable = sharedData.mbcs;

        table = mbcsTable.fromUnicodeTable;
        int[] tableInts = sharedData.mbcs.fromUnicodeTableInts;
        char[] chars = mbcsTable.fromUnicodeChars;
        char[] results = chars;

        /*
         * Check that this is an EBCDIC table with SBCS portion -
         * SBCS or EBCDIC with standard EBCDIC LF and NL mappings.
         *
         * If not, ignore the option. Options are always ignored if they do not apply.
         */
        if (!((mbcsTable.outputType == MBCS_OUTPUT_1 || mbcsTable.outputType == MBCS_OUTPUT_2_SISO) &&
              mbcsTable.stateTable[0][EBCDIC_LF] == MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_DIRECT_16, U_LF) &&
              mbcsTable.stateTable[0][EBCDIC_NL] == MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_DIRECT_16, U_NL))) {
            return false;
        }

        if (mbcsTable.outputType == MBCS_OUTPUT_1) {
            if (!(EBCDIC_RT_LF == MBCS_SINGLE_RESULT_FROM_U(table, results, U_LF) &&
                  EBCDIC_RT_NL == MBCS_SINGLE_RESULT_FROM_U(table, results, U_NL))) {
                return false;
            }
        } else /* MBCS_OUTPUT_2_SISO */ {
            stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, U_LF);
            if (!(MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, U_LF) &&
                  EBCDIC_LF == MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, U_LF))) {
                return false;
            }

            stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, U_NL);
            if (!(MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, U_NL) &&
                  EBCDIC_NL == MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, U_NL))) {
                return false;
            }
        }

        if (mbcsTable.fromUBytesLength > 0) {
            /*
             * We _know_ the number of bytes in the fromUnicodeBytes array
             * starting with header.version 4.1.
             */
            // sizeofFromUBytes = mbcsTable.fromUBytesLength;
        } else {
            /*
             * Otherwise:
             * There used to be code to enumerate the fromUnicode
             * trie and find the highest entry, but it was removed in ICU 3.2
             * because it was not tested and caused a low code coverage number.
             */
            throw new Exception("U_INVALID_FORMAT_ERROR");
        }

        /*
         * The table has an appropriate format.
         * Allocate and build
         * - a modified to-Unicode state table
         * - a modified from-Unicode output array
         * - a converter name string with the swap option appended
         */
//        size = mbcsTable.countStates * 1024 + sizeofFromUBytes + UConverterConstants.MAX_CONVERTER_NAME_LENGTH + 20;

        /* copy and modify the to-Unicode state table */
        newStateTable = new int[mbcsTable.stateTable.length][mbcsTable.stateTable[0].length];
        for (int i = 0; i < newStateTable.length; i++) {
            System.arraycopy(mbcsTable.stateTable[i], 0, newStateTable[i], 0, newStateTable[i].length);
        }

        newStateTable[0][EBCDIC_LF] = MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_DIRECT_16, U_NL);
        newStateTable[0][EBCDIC_NL] = MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_DIRECT_16, U_LF);

        /* copy and modify the from-Unicode result table */
        char[] newResults = new char[chars.length];
        System.arraycopy(chars, 0, newResults, 0, chars.length);
        /* conveniently, the table access macros work on the left side of expressions */
        if (mbcsTable.outputType == MBCS_OUTPUT_1) {
            MBCS_SINGLE_RESULT_FROM_U_SET(table, newResults, U_LF, EBCDIC_RT_NL);
            MBCS_SINGLE_RESULT_FROM_U_SET(table, newResults, U_NL, EBCDIC_RT_LF);
        } else /* MBCS_OUTPUT_2_SISO */ {
            stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, U_LF);
            MBCS_VALUE_2_FROM_STAGE_2_SET(newResults, stage2Entry, U_LF, EBCDIC_NL);

            stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, U_NL);
            MBCS_VALUE_2_FROM_STAGE_2_SET(newResults, stage2Entry, U_NL, EBCDIC_LF);
        }

        /* set the canonical converter name */
        newName = icuCanonicalName.concat(UConverterConstants.OPTION_SWAP_LFNL_STRING);

        if (mbcsTable.swapLFNLStateTable == null) {
            mbcsTable.swapLFNLStateTable = newStateTable;
            mbcsTable.swapLFNLFromUnicodeChars = newResults;
            mbcsTable.swapLFNLName = newName;
        }
        return true;
    }

    /**
     * MBCS output types for conversions from Unicode. These per-converter types determine the storage method in stage 3
     * of the lookup table, mostly how many bytes are stored per entry.
     */
    static final int MBCS_OUTPUT_1 = 0; /* 0 */
    static final int MBCS_OUTPUT_2 = MBCS_OUTPUT_1 + 1; /* 1 */
    static final int MBCS_OUTPUT_3 = MBCS_OUTPUT_2 + 1; /* 2 */
    static final int MBCS_OUTPUT_4 = MBCS_OUTPUT_3 + 1; /* 3 */
    static final int MBCS_OUTPUT_3_EUC = 8; /* 8 */
    static final int MBCS_OUTPUT_4_EUC = MBCS_OUTPUT_3_EUC + 1; /* 9 */
    static final int MBCS_OUTPUT_2_SISO = 12; /* c */
    static final int MBCS_OUTPUT_2_HZ = MBCS_OUTPUT_2_SISO + 1; /* d */
    static final int MBCS_OUTPUT_EXT_ONLY = MBCS_OUTPUT_2_HZ + 1; /* e */
    // static final int MBCS_OUTPUT_COUNT = MBCS_OUTPUT_EXT_ONLY + 1;
    static final int MBCS_OUTPUT_DBCS_ONLY = 0xdb; /* runtime-only type for DBCS-only handling of SISO tables */

    /* GB 18030 data ------------------------------------------------------------ */

    /* helper macros for linear values for GB 18030 four-byte sequences */
    private static int LINEAR_18030(int a, int b, int c, int d) {
        return ((((a & 0xff) * 10 + (b & 0xff)) * 126 + (c & 0xff)) * 10 + (d & 0xff));
    }

    private static int LINEAR_18030_BASE = LINEAR_18030(0x81, 0x30, 0x81, 0x30);

    private static int LINEAR(int x) {
        return LINEAR_18030(x >>> 24, (x >>> 16) & 0xff, (x >>> 8) & 0xff, x & 0xff);
    }

    /*
     * Some ranges of GB 18030 where both the Unicode code points and the GB four-byte sequences are contiguous and are
     * handled algorithmically by the special callback functions below. The values are start & end of Unicode & GB
     * codes.
     *
     * Note that single surrogates are not mapped by GB 18030 as of the re-released mapping tables from 2000-nov-30.
     */
    private static final int gb18030Ranges[][] = new int[/* 14 */][/* 4 */] {
            { 0x10000, 0x10FFFF, LINEAR(0x90308130), LINEAR(0xE3329A35) },
            { 0x9FA6, 0xD7FF, LINEAR(0x82358F33), LINEAR(0x8336C738) },
            { 0x0452, 0x1E3E, LINEAR(0x8130D330), LINEAR(0x8135F436) },
            { 0x1E40, 0x200F, LINEAR(0x8135F438), LINEAR(0x8136A531) },
            { 0xE865, 0xF92B, LINEAR(0x8336D030), LINEAR(0x84308534) },
            { 0x2643, 0x2E80, LINEAR(0x8137A839), LINEAR(0x8138FD38) },
            { 0xFA2A, 0xFE2F, LINEAR(0x84309C38), LINEAR(0x84318537) },
            { 0x3CE1, 0x4055, LINEAR(0x8231D438), LINEAR(0x8232AF32) },
            { 0x361B, 0x3917, LINEAR(0x8230A633), LINEAR(0x8230F237) },
            { 0x49B8, 0x4C76, LINEAR(0x8234A131), LINEAR(0x8234E733) },
            { 0x4160, 0x4336, LINEAR(0x8232C937), LINEAR(0x8232F837) },
            { 0x478E, 0x4946, LINEAR(0x8233E838), LINEAR(0x82349638) },
            { 0x44D7, 0x464B, LINEAR(0x8233A339), LINEAR(0x8233C931) },
            { 0xFFE6, 0xFFFF, LINEAR(0x8431A234), LINEAR(0x8431A439) } };

    /* bit flag for UConverter.options indicating GB 18030 special handling */
    private static final int MBCS_OPTION_GB18030 = 0x8000;

    /* bit flag for UConverter.options indicating KEIS,JEF,JIF special handling */
    private static final int MBCS_OPTION_KEIS = 0x01000;
    private static final int MBCS_OPTION_JEF = 0x02000;
    private static final int MBCS_OPTION_JIPS = 0x04000;

    private static enum SISO_Option {
        SI,
        SO
    }

    private static final byte[] KEIS_SO_CHAR = { 0x0A, 0x42 };
    private static final byte[] KEIS_SI_CHAR = { 0x0A, 0x41 };
    private static final byte JEF_SO_CHAR = 0x28;
    private static final byte JEF_SI_CHAR = 0x29;
    private static final byte[] JIPS_SO_CHAR = { 0x1A, 0x70 };
    private static final byte[] JIPS_SI_CHAR = { 0x1A, 0x71 };

    private static int getSISOBytes(SISO_Option option, int cnvOption, byte[] value) {
        int SISOLength = 0;

        switch (option) {
            case SI:
                if ((cnvOption&MBCS_OPTION_KEIS)!=0) {
                    value[0] = KEIS_SI_CHAR[0];
                    value[1] = KEIS_SI_CHAR[1];
                    SISOLength = 2;
                } else if ((cnvOption&MBCS_OPTION_JEF)!=0) {
                    value[0] = JEF_SI_CHAR;
                    SISOLength = 1;
                } else if ((cnvOption&MBCS_OPTION_JIPS)!=0) {
                    value[0] = JIPS_SI_CHAR[0];
                    value[1] = JIPS_SI_CHAR[1];
                    SISOLength = 2;
                } else {
                    value[0] = UConverterConstants.SI;
                    SISOLength = 1;
                }
                break;
            case SO:
                if ((cnvOption&MBCS_OPTION_KEIS)!=0) {
                    value[0] = KEIS_SO_CHAR[0];
                    value[1] = KEIS_SO_CHAR[1];
                    SISOLength = 2;
                } else if ((cnvOption&MBCS_OPTION_JEF)!=0) {
                    value[0] = JEF_SO_CHAR;
                    SISOLength = 1;
                } else if ((cnvOption&MBCS_OPTION_JIPS)!=0) {
                    value[0] = JIPS_SO_CHAR[0];
                    value[1] = JIPS_SO_CHAR[1];
                    SISOLength = 2;
                } else {
                    value[0] = UConverterConstants.SO;
                    SISOLength = 1;
                }
                break;
            default:
                /* Should never happen. */
                break;
        }

        return SISOLength;
    }
    // enum {
        static final int MBCS_MAX_STATE_COUNT = 128;
    // };
    /**
     * MBCS action codes for conversions to Unicode. These values are in bits 23..20 of the state table entries.
     */
    static final int MBCS_STATE_VALID_DIRECT_16 = 0;
    static final int MBCS_STATE_VALID_DIRECT_20 = MBCS_STATE_VALID_DIRECT_16 + 1;
    static final int MBCS_STATE_FALLBACK_DIRECT_16 = MBCS_STATE_VALID_DIRECT_20 + 1;
    static final int MBCS_STATE_FALLBACK_DIRECT_20 = MBCS_STATE_FALLBACK_DIRECT_16 + 1;
    static final int MBCS_STATE_VALID_16 = MBCS_STATE_FALLBACK_DIRECT_20 + 1;
    static final int MBCS_STATE_VALID_16_PAIR = MBCS_STATE_VALID_16 + 1;
    static final int MBCS_STATE_UNASSIGNED = MBCS_STATE_VALID_16_PAIR + 1;
    static final int MBCS_STATE_ILLEGAL = MBCS_STATE_UNASSIGNED + 1;
    static final int MBCS_STATE_CHANGE_ONLY = MBCS_STATE_ILLEGAL + 1;

    static int MBCS_ENTRY_SET_STATE(int entry, int state) {
        return (entry&0x80ffffff)|(state<<24L);
    }

    static int MBCS_ENTRY_STATE(int entry) {
        return (((entry)>>24)&0x7f);
    }

    /* Methods for state table entries */
    static int MBCS_ENTRY_TRANSITION(int state, int offset) {
        return (state << 24L) | offset;
    }

    static int MBCS_ENTRY_FINAL(int state, int action, int value) {
        return 0x80000000 | (state << 24L) | (action << 20L) | value;
    }

    static boolean MBCS_ENTRY_IS_TRANSITION(int entry) {
        return (entry) >= 0;
    }

    static boolean MBCS_ENTRY_IS_FINAL(int entry) {
        return (entry) < 0;
    }

    static int MBCS_ENTRY_TRANSITION_STATE(int entry) {
        return ((entry) >>> 24);
    }

    static int MBCS_ENTRY_TRANSITION_OFFSET(int entry) {
        return ((entry) & 0xffffff);
    }

    static int MBCS_ENTRY_FINAL_STATE(int entry) {
        return ((entry) >>> 24) & 0x7f;
    }

    static boolean MBCS_ENTRY_FINAL_IS_VALID_DIRECT_16(int entry) {
        return ((entry) < 0x80100000);
    }

    static int MBCS_ENTRY_FINAL_ACTION(int entry) {
        return ((entry) >>> 20) & 0xf;
    }

    static int MBCS_ENTRY_FINAL_VALUE(int entry) {
        return ((entry) & 0xfffff);
    }

    static char MBCS_ENTRY_FINAL_VALUE_16(int entry) {
        return (char) (entry);
    }

    static boolean MBCS_IS_ASCII_ROUNDTRIP(int b, long asciiRoundtrips) {
        return (((asciiRoundtrips) & (1<<((b)>>2)))!=0);
    }

    /**
     * This macro version of _MBCSSingleSimpleGetNextUChar() gets a code point from a byte. It works for single-byte,
     * single-state codepages that only map to and from BMP code points, and it always returns fallback values.
     */
    static char MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(UConverterMBCSTable mbcs, final int b) {
        assert 0 <= b && b <= 0xff;
        return MBCS_ENTRY_FINAL_VALUE_16(mbcs.stateTable[0][b]);
    }

    /* single-byte fromUnicode: get the 16-bit result word */
    static char MBCS_SINGLE_RESULT_FROM_U(char[] table, char[] results, int c) {
        int i1 = table[c >>> 10] + ((c >>> 4) & 0x3f);
        int i = table[i1] + (c & 0xf);
        return results[i];
    }

    /* single-byte fromUnicode: set the 16-bit result word with newValue*/
    static void MBCS_SINGLE_RESULT_FROM_U_SET(char[] table, char[] results, int c, int newValue) {
        int i1 = table[c >>> 10] + ((c >>> 4) & 0x3f);
        int i = table[i1] + (c & 0xf);
        results[i] = (char) newValue;
    }

    /* multi-byte fromUnicode: get the 32-bit stage 2 entry */
    static int MBCS_STAGE_2_FROM_U(char[] table, int[] tableInts, int c) {
        int i = table[(c) >>> 10] + ((c >>> 4) & 0x3f);
        return tableInts[i];
    }

    private static boolean MBCS_FROM_U_IS_ROUNDTRIP(int stage2Entry, int c) {
        return (((stage2Entry) & (1 << (16 + ((c) & 0xf)))) != 0);
    }

    static char MBCS_VALUE_2_FROM_STAGE_2(char[] chars, int stage2Entry, int c) {
        int i = 16 * (stage2Entry & UConverterConstants.UNSIGNED_SHORT_MASK) + (c & 0xf);
        return chars[i];
    }

    static void MBCS_VALUE_2_FROM_STAGE_2_SET(char[] chars, int stage2Entry, int c, int newValue) {
        int i = 16 * (stage2Entry & UConverterConstants.UNSIGNED_SHORT_MASK) + (c & 0xf);
        chars[i] = (char) newValue;
    }

    private static int MBCS_VALUE_4_FROM_STAGE_2(int[] ints, int stage2Entry, int c) {
        int i = 16 * (stage2Entry & UConverterConstants.UNSIGNED_SHORT_MASK) + (c & 0xf);
        return ints[i];
    }

    static int MBCS_POINTER_3_FROM_STAGE_2(byte[] bytes, int stage2Entry, int c) {
        return ((16 * (stage2Entry & UConverterConstants.UNSIGNED_SHORT_MASK) + ((c) & 0xf)) * 3);
    }

    // ------------UConverterExt-------------------------------------------------------

    static final int EXT_INDEXES_LENGTH = 0; /* 0 */

    static final int EXT_TO_U_INDEX = EXT_INDEXES_LENGTH + 1; /* 1 */
    static final int EXT_TO_U_LENGTH = EXT_TO_U_INDEX + 1;
    static final int EXT_TO_U_UCHARS_INDEX = EXT_TO_U_LENGTH + 1;
    static final int EXT_TO_U_UCHARS_LENGTH = EXT_TO_U_UCHARS_INDEX + 1;

    static final int EXT_FROM_U_UCHARS_INDEX = EXT_TO_U_UCHARS_LENGTH + 1; /* 5 */
    static final int EXT_FROM_U_VALUES_INDEX = EXT_FROM_U_UCHARS_INDEX + 1;
    static final int EXT_FROM_U_LENGTH = EXT_FROM_U_VALUES_INDEX + 1;
    static final int EXT_FROM_U_BYTES_INDEX = EXT_FROM_U_LENGTH + 1;
    static final int EXT_FROM_U_BYTES_LENGTH = EXT_FROM_U_BYTES_INDEX + 1;

    static final int EXT_FROM_U_STAGE_12_INDEX = EXT_FROM_U_BYTES_LENGTH + 1; /* 10 */
    static final int EXT_FROM_U_STAGE_1_LENGTH = EXT_FROM_U_STAGE_12_INDEX + 1;
    static final int EXT_FROM_U_STAGE_12_LENGTH = EXT_FROM_U_STAGE_1_LENGTH + 1;
    static final int EXT_FROM_U_STAGE_3_INDEX = EXT_FROM_U_STAGE_12_LENGTH + 1;
    static final int EXT_FROM_U_STAGE_3_LENGTH = EXT_FROM_U_STAGE_3_INDEX + 1;
    static final int EXT_FROM_U_STAGE_3B_INDEX = EXT_FROM_U_STAGE_3_LENGTH + 1;
    static final int EXT_FROM_U_STAGE_3B_LENGTH = EXT_FROM_U_STAGE_3B_INDEX + 1;

    private static final int EXT_COUNT_BYTES = EXT_FROM_U_STAGE_3B_LENGTH + 1; /* 17 */
    // private static final int EXT_COUNT_UCHARS = EXT_COUNT_BYTES + 1;
    // private static final int EXT_FLAGS = EXT_COUNT_UCHARS + 1;
    //
    // private static final int EXT_RESERVED_INDEX = EXT_FLAGS + 1; /* 20, moves with additional indexes */
    //
    // private static final int EXT_SIZE=31;
    // private static final int EXT_INDEXES_MIN_LENGTH=32;

    static final int EXT_FROM_U_MAX_DIRECT_LENGTH = 3;

    /* toUnicode helpers -------------------------------------------------------- */

    private static final int TO_U_BYTE_SHIFT = 24;
    private static final int TO_U_VALUE_MASK = 0xffffff;
    private static final int TO_U_MIN_CODE_POINT = 0x1f0000;
    private static final int TO_U_MAX_CODE_POINT = 0x2fffff;
    private static final int TO_U_ROUNDTRIP_FLAG = (1 << 23);
    private static final int TO_U_INDEX_MASK = 0x3ffff;
    private static final int TO_U_LENGTH_SHIFT = 18;
    private static final int TO_U_LENGTH_OFFSET = 12;

    /* maximum number of indexed UChars */
    static final int MAX_UCHARS = 19;

    static int TO_U_GET_BYTE(int word) {
        return word >>> TO_U_BYTE_SHIFT;
    }

    static int TO_U_GET_VALUE(int word) {
        return word & TO_U_VALUE_MASK;
    }

    static boolean TO_U_IS_ROUNDTRIP(int value) {
        return (value & TO_U_ROUNDTRIP_FLAG) != 0;
    }

    static boolean TO_U_IS_PARTIAL(int value) {
        return 0 <= value && value < TO_U_MIN_CODE_POINT;
    }

    static int TO_U_GET_PARTIAL_INDEX(int value) {
        return value;
    }

    static int TO_U_MASK_ROUNDTRIP(int value) {
        return value & ~TO_U_ROUNDTRIP_FLAG;
    }

    private static int TO_U_MAKE_WORD(byte b, int value) {
        // TO_U_BYTE_SHIFT == 24: safe to just shift the signed byte-as-int.
        return (b << TO_U_BYTE_SHIFT) | value;
    }

    /* use after masking off the roundtrip flag */
    static boolean TO_U_IS_CODE_POINT(int value) {
        assert value >= 0;
        return value <= TO_U_MAX_CODE_POINT;
    }

    static int TO_U_GET_CODE_POINT(int value) {
        assert value >= 0;
        return value - TO_U_MIN_CODE_POINT;
    }

    private static int TO_U_GET_INDEX(int value) {
        return value & TO_U_INDEX_MASK;
    }

    private static int TO_U_GET_LENGTH(int value) {
        return (value >>> TO_U_LENGTH_SHIFT) - TO_U_LENGTH_OFFSET;
    }

    /* fromUnicode helpers ------------------------------------------------------ */

    /* most trie constants are shared with ucnvmbcs.h */
    private static final int STAGE_2_LEFT_SHIFT = 2;

    // private static final int STAGE_3_GRANULARITY = 4;

    /* trie access, returns the stage 3 value=index to stage 3b; s1Index=c>>10 */
    static int FROM_U(CharBuffer stage12, CharBuffer stage3, int s1Index, int c) {
        return stage3.get((stage12.get((stage12.get(s1Index) + ((c >>> 4) & 0x3f))) << STAGE_2_LEFT_SHIFT)
                + (c & 0xf));
    }

    private static final int FROM_U_LENGTH_SHIFT = 24;
    private static final int FROM_U_ROUNDTRIP_FLAG = 1 << 31;
    static final int FROM_U_RESERVED_MASK = 0x60000000;
    private static final int FROM_U_DATA_MASK = 0xffffff;

    /* special value for "no mapping" to <subchar1> (impossible roundtrip to 0 bytes, value 01) */
    static final int FROM_U_SUBCHAR1 = 0x80000001;

    /* at most 3 bytes in the lower part of the value */
    private static final int FROM_U_MAX_DIRECT_LENGTH = 3;

    /* maximum number of indexed bytes */
    static final int MAX_BYTES = 0x1f;

    static boolean FROM_U_IS_PARTIAL(int value) {
        return (value >>> FROM_U_LENGTH_SHIFT) == 0;
    }

    static int FROM_U_GET_PARTIAL_INDEX(int value) {
        return value;
    }

    static boolean FROM_U_IS_ROUNDTRIP(int value) {
        return (value & FROM_U_ROUNDTRIP_FLAG) != 0;
    }

    private static int FROM_U_MASK_ROUNDTRIP(int value) {
        return value & ~FROM_U_ROUNDTRIP_FLAG;
    }

    /* use after masking off the roundtrip flag */
    static int FROM_U_GET_LENGTH(int value) {
        return (value >>> FROM_U_LENGTH_SHIFT) & MAX_BYTES;
    }

    /* get bytes or bytes index */
    static int FROM_U_GET_DATA(int value) {
        return value & FROM_U_DATA_MASK;
    }

    /* get the pointer to an extension array from indexes[index] */
    static Buffer ARRAY(ByteBuffer indexes, int index, Class<?> itemType) {
        int oldpos = indexes.position();
        Buffer b;

        // TODO: It is very inefficient to create Buffer objects for each array access.
        // We should create an inner class Extensions (or sibling class CharsetMBCSExtensions)
        // which has buffers for the arrays, together with the code that works with them.
        indexes.position(indexes.getInt(index << 2));
        if (itemType == int.class)
            b = indexes.asIntBuffer();
        else if (itemType == char.class)
            b = indexes.asCharBuffer();
        else if (itemType == short.class)
            b = indexes.asShortBuffer();
        else
            // default or (itemType == byte.class)
            b = indexes.slice();
        indexes.position(oldpos);
        return b;
    }

    private static int GET_MAX_BYTES_PER_UCHAR(ByteBuffer indexes) {
        indexes.position(0);
        return indexes.getInt(EXT_COUNT_BYTES) & 0xff;
    }

    /*
     * @return index of the UChar, if found; else <0
     */
    static int findFromU(CharBuffer fromUSection, int length, char u) {
        int i, start, limit;

        /* binary search */
        start = 0;
        limit = length;
        for (;;) {
            i = limit - start;
            if (i <= 1) {
                break; /* done */
            }
            /* start<limit-1 */

            if (i <= 4) {
                /* linear search for the last part */
                if (u <= fromUSection.get(fromUSection.position() + start)) {
                    break;
                }
                if (++start < limit && u <= fromUSection.get(fromUSection.position() + start)) {
                    break;
                }
                if (++start < limit && u <= fromUSection.get(fromUSection.position() + start)) {
                    break;
                }
                /* always break at start==limit-1 */
                ++start;
                break;
            }

            i = (start + limit) / 2;
            if (u < fromUSection.get(fromUSection.position() + i)) {
                limit = i;
            } else {
                start = i;
            }
        }

        /* did we really find it? */
        if (start < limit && u == fromUSection.get(fromUSection.position() + start)) {
            return start;
        } else {
            return -1; /* not found */
        }
    }

    /*
     * @return lookup value for the byte, if found; else 0
     */
    static int findToU(IntBuffer toUSection, int length, short byt) {
        long word0, word;
        int i, start, limit;

        /* check the input byte against the lowest and highest section bytes */
        // agljport:comment instead of receiving a start position parameter for toUSection we'll rely on its position
        // property
        start = TO_U_GET_BYTE(toUSection.get(toUSection.position()));
        limit = TO_U_GET_BYTE(toUSection.get(toUSection.position() + length - 1));
        if (byt < start || limit < byt) {
            return 0; /* the byte is out of range */
        }

        if (length == ((limit - start) + 1)) {
            /* direct access on a linear array */
            return TO_U_GET_VALUE(toUSection.get(toUSection.position() + byt - start)); /* could be 0 */
        }

        /* word0 is suitable for <=toUSection[] comparison, word for <toUSection[] */
        word0 = TO_U_MAKE_WORD((byte) byt, 0) & UConverterConstants.UNSIGNED_INT_MASK;

        /*
         * Shift byte once instead of each section word and add 0xffffff. We will compare the shifted/added byte
         * (bbffffff) against section words which have byte values in the same bit position. If and only if byte bb <
         * section byte ss then bbffffff<ssvvvvvv for all v=0..f so we need not mask off the lower 24 bits of each
         * section word.
         */
        word = word0 | TO_U_VALUE_MASK;

        /* binary search */
        start = 0;
        limit = length;
        for (;;) {
            i = limit - start;
            if (i <= 1) {
                break; /* done */
            }
            /* start<limit-1 */

            if (i <= 4) {
                /* linear search for the last part */
                if (word0 <= (toUSection.get(toUSection.position() + start) & UConverterConstants.UNSIGNED_INT_MASK)) {
                    break;
                }
                if (++start < limit
                        && word0 <= (toUSection.get(toUSection.position() + start) & UConverterConstants.UNSIGNED_INT_MASK)) {
                    break;
                }
                if (++start < limit
                        && word0 <= (toUSection.get(toUSection.position() + start) & UConverterConstants.UNSIGNED_INT_MASK)) {
                    break;
                }
                /* always break at start==limit-1 */
                ++start;
                break;
            }

            i = (start + limit) / 2;
            if (word < (toUSection.get(toUSection.position() + i) & UConverterConstants.UNSIGNED_INT_MASK)) {
                limit = i;
            } else {
                start = i;
            }
        }

        /* did we really find it? */
        if (start < limit) {
            word = (toUSection.get(toUSection.position() + start) & UConverterConstants.UNSIGNED_INT_MASK);
            if (byt == TO_U_GET_BYTE((int)word)) {
                return TO_U_GET_VALUE((int) word); /* never 0 */
            }
        }
        return 0; /* not found */
    }

    /*
     * TRUE if not an SI/SO stateful converter, or if the match length fits with the current converter state
     */
    static boolean TO_U_VERIFY_SISO_MATCH(byte sisoState, int match) {
        return sisoState < 0 || (sisoState == 0) == (match == 1);
    }

    /*
     * get the SI/SO toU state (state 0 is for SBCS, 1 for DBCS), or 1 for DBCS-only, or -1 if the converter is not
     * SI/SO stateful
     *
     * Note: For SI/SO stateful converters getting here, cnv->mode==0 is equivalent to firstLength==1.
     */
    private static int SISO_STATE(UConverterSharedData sharedData, int mode) {
        return sharedData.mbcs.outputType == MBCS_OUTPUT_2_SISO ? (byte) mode
                : sharedData.mbcs.outputType == MBCS_OUTPUT_DBCS_ONLY ? 1 : -1;
    }

    class CharsetDecoderMBCS extends CharsetDecoderICU {

        CharsetDecoderMBCS(CharsetICU cs) {
            super(cs);
        }

        @Override
        protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
        /* Just call cnvMBCSToUnicodeWithOffsets() to remove duplicate code. */
            return cnvMBCSToUnicodeWithOffsets(source, target, offsets, flush);
        }

        /*
         * continue partial match with new input never called for simple, single-character conversion
         */
        private CoderResult continueMatchToU(ByteBuffer source, CharBuffer target, IntBuffer offsets, int srcIndex,
                boolean flush) {
            CoderResult cr = CoderResult.UNDERFLOW;

            int[] value = new int[1];
            int match, length;

            match = matchToU((byte) SISO_STATE(sharedData, mode), preToUArray, preToUBegin, preToULength, source,
                    value, isToUUseFallback(), flush);

            if (match > 0) {
                if (match >= preToULength) {
                    /* advance src pointer for the consumed input */
                    source.position(source.position() + match - preToULength);
                    preToULength = 0;
                } else {
                    /* the match did not use all of preToU[] - keep the rest for replay */
                    length = preToULength - match;
                    System.arraycopy(preToUArray, preToUBegin + match, preToUArray, preToUBegin, length);
                    preToULength = (byte) -length;
                }

                /* write result */
                cr = writeToU(value[0], target, offsets, srcIndex);
            } else if (match < 0) {
                /* save state for partial match */
                int j, sArrayIndex;

                /* just _append_ the newly consumed input to preToU[] */
                sArrayIndex = source.position();
                match = -match;
                for (j = preToULength; j < match; ++j) {
                    preToUArray[j] = source.get(sArrayIndex++);
                }
                source.position(sArrayIndex); /* same as *src=srcLimit; because we reached the end of input */
                preToULength = (byte) match;
            } else /* match==0 */{
                /*
                 * no match
                 *
                 * We need to split the previous input into two parts:
                 *
                 * 1. The first codepage character is unmappable - that's how we got into trying the extension data in
                 * the first place. We need to move it from the preToU buffer to the error buffer, set an error code,
                 * and prepare the rest of the previous input for 2.
                 *
                 * 2. The rest of the previous input must be converted once we come back from the callback for the first
                 * character. At that time, we have to try again from scratch to convert these input characters. The
                 * replay will be handled by the ucnv.c conversion code.
                 */

                /* move the first codepage character to the error field */
                System.arraycopy(preToUArray, preToUBegin, toUBytesArray, toUBytesBegin, preToUFirstLength);
                toULength = preToUFirstLength;

                /* move the rest up inside the buffer */
                length = preToULength - preToUFirstLength;
                if (length > 0) {
                    System.arraycopy(preToUArray, preToUBegin + preToUFirstLength, preToUArray, preToUBegin, length);
                }

                /* mark preToU for replay */
                preToULength = (byte) -length;

                /* set the error code for unassigned */
                cr = CoderResult.unmappableForLength(preToUFirstLength);
            }
            return cr;
        }

        /*
         * this works like matchFromU() except - the first character is in pre - no trie is used - the returned
         * matchLength is not offset by 2
         */
        private int matchToU(byte sisoState, byte[] preArray, int preArrayBegin, int preLength, ByteBuffer source,
                int[] pMatchValue, boolean isUseFallback, boolean flush) {
            ByteBuffer cx = sharedData.mbcs.extIndexes;
            IntBuffer toUTable, toUSection;

            int value, matchValue, srcLength = 0;
            int i, j, index, length, matchLength;
            short b;

            if (cx == null || cx.asIntBuffer().get(EXT_TO_U_LENGTH) <= 0) {
                return 0; /* no extension data, no match */
            }

            /* initialize */
            toUTable = (IntBuffer) ARRAY(cx, EXT_TO_U_INDEX, int.class);
            index = 0;

            matchValue = 0;
            i = j = matchLength = 0;
            if (source != null) {
                srcLength = source.remaining();
            }

            if (sisoState == 0) {
                /* SBCS state of an SI/SO stateful converter, look at only exactly 1 byte */
                if (preLength > 1) {
                    return 0; /* no match of a DBCS sequence in SBCS mode */
                } else if (preLength == 1) {
                    srcLength = 0;
                } else /* preLength==0 */{
                    if (srcLength > 1) {
                        srcLength = 1;
                    }
                }
                flush = true;
            }

            /* we must not remember fallback matches when not using fallbacks */

            /* match input units until there is a full match or the input is consumed */
            for (;;) {
                /* go to the next section */
                int oldpos = toUTable.position();
                toUSection = ((IntBuffer) toUTable.position(index)).slice();
                toUTable.position(oldpos);

                /* read first pair of the section */
                value = toUSection.get();
                length = TO_U_GET_BYTE(value);
                value = TO_U_GET_VALUE(value);
                if (value != 0 && (TO_U_IS_ROUNDTRIP(value) || isToUUseFallback(isUseFallback))
                        && TO_U_VERIFY_SISO_MATCH(sisoState, i + j)) {
                    /* remember longest match so far */
                    matchValue = value;
                    matchLength = i + j;
                }

                /* match pre[] then src[] */
                if (i < preLength) {
                    b = (short) (preArray[preArrayBegin + i++] & UConverterConstants.UNSIGNED_BYTE_MASK);
                } else if (j < srcLength) {
                    b = (short) (source.get(source.position() + j++) & UConverterConstants.UNSIGNED_BYTE_MASK);
                } else {
                    /* all input consumed, partial match */
                    if (flush || (length = (i + j)) > MAX_BYTES) {
                        /*
                         * end of the entire input stream, stop with the longest match so far or: partial match must not
                         * be longer than UCNV_EXT_MAX_BYTES because it must fit into state buffers
                         */
                        break;
                    } else {
                        /* continue with more input next time */
                        return -length;
                    }
                }

                /* search for the current UChar */
                value = findToU(toUSection, length, b);
                if (value == 0) {
                    /* no match here, stop with the longest match so far */
                    break;
                } else {
                    if (TO_U_IS_PARTIAL(value)) {
                        /* partial match, continue */
                        index = TO_U_GET_PARTIAL_INDEX(value);
                    } else {
                        if ((TO_U_IS_ROUNDTRIP(value) || isToUUseFallback(isUseFallback)) && TO_U_VERIFY_SISO_MATCH(sisoState, i + j)) {
                            /* full match, stop with result */
                            matchValue = value;
                            matchLength = i + j;
                        } else {
                            /* full match on fallback not taken, stop with the longest match so far */
                        }
                        break;
                    }
                }
            }

            if (matchLength == 0) {
                /* no match at all */
                return 0;
            }

            /* return result */
            pMatchValue[0] = TO_U_MASK_ROUNDTRIP(matchValue);
            return matchLength;
        }

        private CoderResult writeToU(int value, CharBuffer target, IntBuffer offsets, int srcIndex) {
            ByteBuffer cx = sharedData.mbcs.extIndexes;
            /* output the result */
            if (TO_U_IS_CODE_POINT(value)) {
                /* output a single code point */
                return toUWriteCodePoint(TO_U_GET_CODE_POINT(value), target, offsets, srcIndex);
            } else {
                /* output a string - with correct data we have resultLength>0 */

                char[] a = new char[TO_U_GET_LENGTH(value)];
                CharBuffer cb = ((CharBuffer) ARRAY(cx, EXT_TO_U_UCHARS_INDEX, char.class));
                cb.position(TO_U_GET_INDEX(value));
                cb.get(a, 0, a.length);
                return toUWriteUChars(this, a, 0, a.length, target, offsets, srcIndex);
            }
        }

        private CoderResult toUWriteCodePoint(int c, CharBuffer target, IntBuffer offsets, int sourceIndex) {
            CoderResult cr = CoderResult.UNDERFLOW;
            int tBeginIndex = target.position();

            if (target.hasRemaining()) {
                if (c <= 0xffff) {
                    target.put((char) c);
                    c = UConverterConstants.U_SENTINEL;
                } else /* c is a supplementary code point */{
                    target.put(UTF16.getLeadSurrogate(c));
                    c = UTF16.getTrailSurrogate(c);
                    if (target.hasRemaining()) {
                        target.put((char) c);
                        c = UConverterConstants.U_SENTINEL;
                    }
                }

                /* write offsets */
                if (offsets != null) {
                    offsets.put(sourceIndex);
                    if ((tBeginIndex + 1) < target.position()) {
                        offsets.put(sourceIndex);
                    }
                }
            }

            /* write overflow from c */
            if (c >= 0) {
                charErrorBufferLength = UTF16.append(charErrorBufferArray, 0, c);
                cr = CoderResult.OVERFLOW;
            }

            return cr;
        }

        /*
         * Input sequence: cnv->toUBytes[0..length[ @return if(U_FAILURE) return the length (toULength, byteIndex) for
         * the input else return 0 after output has been written to the target
         */
        private int toU(int length, ByteBuffer source, CharBuffer target, IntBuffer offsets, int sourceIndex,
                boolean flush, CoderResult[] cr) {
            // ByteBuffer cx;

            if (sharedData.mbcs.extIndexes != null
                    && initialMatchToU(length, source, target, offsets, sourceIndex, flush, cr)) {
                return 0; /* an extension mapping handled the input */
            }

            /* GB 18030 */
            if (length == 4 && (options & MBCS_OPTION_GB18030) != 0) {
                int[] range;
                int linear;
                int i;

                linear = LINEAR_18030(toUBytesArray[0], toUBytesArray[1], toUBytesArray[2], toUBytesArray[3]);
                for (i = 0; i < gb18030Ranges.length; ++i) {
                    range = gb18030Ranges[i];
                    if (range[2] <= linear && linear <= range[3]) {
                        /* found the sequence, output the Unicode code point for it */
                        cr[0] = CoderResult.UNDERFLOW;

                        /* add the linear difference between the input and start sequences to the start code point */
                        linear = range[0] + (linear - range[2]);

                        /* output this code point */
                        cr[0] = toUWriteCodePoint(linear, target, offsets, sourceIndex);

                        return 0;
                    }
                }
            }

            /* no mapping */
            cr[0] = CoderResult.unmappableForLength(length);
            return length;
        }

        /*
         * target<targetLimit; set error code for overflow
         */
        private boolean initialMatchToU(int firstLength, ByteBuffer source, CharBuffer target, IntBuffer offsets,
                int srcIndex, boolean flush, CoderResult[] cr) {
            int[] value = new int[1];
            int match = 0;

            /* try to match */
            match = matchToU((byte) SISO_STATE(sharedData, mode), toUBytesArray, toUBytesBegin, firstLength, source,
                    value, isToUUseFallback(), flush);
            if (match > 0) {
                /* advance src pointer for the consumed input */
                source.position(source.position() + match - firstLength);

                /* write result to target */
                cr[0] = writeToU(value[0], target, offsets, srcIndex);
                return true;
            } else if (match < 0) {
                /* save state for partial match */
                byte[] sArray;
                int sArrayIndex;
                int j;

                /* copy the first code point */
                sArray = toUBytesArray;
                sArrayIndex = toUBytesBegin;
                preToUFirstLength = (byte) firstLength;
                for (j = 0; j < firstLength; ++j) {
                    preToUArray[j] = sArray[sArrayIndex++];
                }

                /* now copy the newly consumed input */
                sArrayIndex = source.position();
                match = -match;
                for (; j < match; ++j) {
                    preToUArray[j] = source.get(sArrayIndex++);
                }
                source.position(sArrayIndex);
                preToULength = (byte) match;
                return true;
            } else /* match==0 no match */{
                return false;
            }
        }

        private int simpleMatchToU(ByteBuffer source, boolean useFallback) {
            int[] value = new int[1];
            int match;

            if (source.remaining() <= 0) {
                return 0xffff;
            }

            /* try to match */
            byte[] sourceArray;
            int sourcePosition, sourceLimit;
            if (source.isReadOnly()) {
                // source.array() would throw an exception
                sourcePosition = source.position();  // relative to source.array()
                sourceArray = new byte[Math.min(source.remaining(), EXT_MAX_BYTES)];
                source.get(sourceArray).position(sourcePosition);
                sourcePosition = 0;  // relative to sourceArray
                sourceLimit = sourceArray.length;
            } else {
                sourceArray = source.array();
                sourcePosition = source.position();
                sourceLimit = source.limit();
            }
            match = matchToU((byte) -1, sourceArray, sourcePosition, sourceLimit, null, value, useFallback, true);

            if (match == source.remaining()) {
                /* write result for simple, single-character conversion */
                if (TO_U_IS_CODE_POINT(value[0])) {
                    return TO_U_GET_CODE_POINT(value[0]);
                }
            }

            /*
             * return no match because - match>0 && value points to string: simple conversion cannot handle multiple
             * code points - match>0 && match!=length: not all input consumed, forbidden for this function - match==0:
             * no match found in the first place - match<0: partial match, not supported for simple conversion (and
             * flush==TRUE)
             */
            return 0xfffe;
        }

        CoderResult cnvMBCSToUnicodeWithOffsets(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex, sourceArrayIndexStart;
            int stateTable[][/* 256 */];
            char[] unicodeCodeUnits;

            int offset;
            byte state;
            int byteIndex;
            byte[] bytes;

            int sourceIndex, nextSourceIndex;

            int entry = 0;
            char c;
            byte action;

            if (preToULength > 0) {
                /*
                 * pass sourceIndex=-1 because we continue from an earlier buffer in the future, this may change with
                 * continuous offsets
                 */
                cr[0] = continueMatchToU(source, target, offsets, -1, flush);

                if (cr[0].isError() || preToULength < 0) {
                    return cr[0];
                }
            }

            if (sharedData.mbcs.countStates == 1) {
                if (!sharedData.mbcs.hasSupplementary()) {
                    cr[0] = cnvMBCSSingleToBMPWithOffsets(source, target, offsets, flush);
                } else {
                    cr[0] = cnvMBCSSingleToUnicodeWithOffsets(source, target, offsets, flush);
                }
                return cr[0];
            }

            /* set up the local pointers */
            sourceArrayIndex = sourceArrayIndexStart = source.position();

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                stateTable = sharedData.mbcs.swapLFNLStateTable;
            } else {
                stateTable = sharedData.mbcs.stateTable;
            }
            unicodeCodeUnits = sharedData.mbcs.unicodeCodeUnits;

            /* get the converter state from UConverter */
            offset = toUnicodeStatus;
            byteIndex = toULength;
            bytes = toUBytesArray;

            /*
             * if we are in the SBCS state for a DBCS-only converter, then load the DBCS state from the MBCS data
             * (dbcsOnlyState==0 if it is not a DBCS-only converter)
             */
            state = (byte)mode;
            if (state == 0) {
                state = sharedData.mbcs.dbcsOnlyState;
            }

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = byteIndex == 0 ? 0 : -1;
            nextSourceIndex = 0;

            /* conversion loop */
            while (sourceArrayIndex < source.limit()) {
                /*
                 * This following test is to see if available input would overflow the output. It does not catch output
                 * of more than one code unit that overflows as a result of a surrogate pair or callback output from the
                 * last source byte. Therefore, those situations also test for overflows and will then break the loop,
                 * too.
                 */
                if (!target.hasRemaining()) {
                    /* target is full */
                    cr[0] = CoderResult.OVERFLOW;
                    break;
                }

                if (byteIndex == 0) {
                    /* optimized loop for 1/2-byte input and BMP output */
                    // agljport:todo see ucnvmbcs.c for deleted block
                    do {
                        entry = stateTable[state][source.get(sourceArrayIndex)&UConverterConstants.UNSIGNED_BYTE_MASK];
                        if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                            state = (byte)MBCS_ENTRY_TRANSITION_STATE(entry);
                            offset = MBCS_ENTRY_TRANSITION_OFFSET(entry);
                            ++sourceArrayIndex;
                            if (sourceArrayIndex < source.limit()
                                    && MBCS_ENTRY_IS_FINAL(entry = stateTable[state][source.get(sourceArrayIndex)&UConverterConstants.UNSIGNED_BYTE_MASK])
                                    && MBCS_ENTRY_FINAL_ACTION(entry) == MBCS_STATE_VALID_16
                                    && (c = unicodeCodeUnits[offset + MBCS_ENTRY_FINAL_VALUE_16(entry)]) < 0xfffe) {
                                ++sourceArrayIndex;
                                target.put(c);
                                if (offsets != null) {
                                    offsets.put(sourceIndex);
                                    sourceIndex = (nextSourceIndex += 2);
                                }
                                state = (byte)MBCS_ENTRY_FINAL_STATE(entry); /* typically 0 */
                                offset = 0;
                            } else {
                                /* set the state and leave the optimized loop */
                                ++nextSourceIndex;
                                bytes[0] = source.get(sourceArrayIndex - 1);
                                byteIndex = 1;
                                break;
                            }
                        } else {
                            if (MBCS_ENTRY_FINAL_IS_VALID_DIRECT_16(entry)) {
                                /* output BMP code point */
                                ++sourceArrayIndex;
                                target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                                if (offsets != null) {
                                    offsets.put(sourceIndex);
                                    sourceIndex = ++nextSourceIndex;
                                }
                                state = (byte)MBCS_ENTRY_FINAL_STATE(entry); /* typically 0 */
                            } else {
                                /* leave the optimized loop */
                                break;
                            }
                        }
                    } while (sourceArrayIndex < source.limit() && target.hasRemaining());
                    /*
                     * these tests and break statements could be put inside the loop if C had "break outerLoop" like
                     * Java
                     */
                    if (sourceArrayIndex >= source.limit()) {
                        break;
                    }
                    if (!target.hasRemaining()) {
                        /* target is full */
                        cr[0] = CoderResult.OVERFLOW;
                        break;
                    }

                    ++nextSourceIndex;
                    bytes[byteIndex++] = source.get(sourceArrayIndex++);
                } else /* byteIndex>0 */{
                    ++nextSourceIndex;
                    entry = stateTable[state][(bytes[byteIndex++] = source.get(sourceArrayIndex++))
                            & UConverterConstants.UNSIGNED_BYTE_MASK];
                }

                if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                    state = (byte)MBCS_ENTRY_TRANSITION_STATE(entry);
                    offset += MBCS_ENTRY_TRANSITION_OFFSET(entry);
                    continue;
                }

                /* save the previous state for proper extension mapping with SI/SO-stateful converters */
                mode = state;

                /* set the next state early so that we can reuse the entry variable */
                state = (byte)MBCS_ENTRY_FINAL_STATE(entry); /* typically 0 */

                /*
                 * An if-else-if chain provides more reliable performance for the most common cases compared to a
                 * switch.
                 */
                action = (byte)MBCS_ENTRY_FINAL_ACTION(entry);
                if (action == MBCS_STATE_VALID_16) {
                    offset += MBCS_ENTRY_FINAL_VALUE_16(entry);
                    c = unicodeCodeUnits[offset];
                    if (c < 0xfffe) {
                        /* output BMP code point */
                        target.put(c);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        byteIndex = 0;
                    } else if (c == 0xfffe) {
                        if (isFallbackUsed() && (entry = getFallback(sharedData.mbcs, offset)) != 0xfffe) {
                            /* output fallback BMP code point */
                            target.put((char)entry);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                            }
                            byteIndex = 0;
                        }
                    } else {
                        /* callback(illegal) */
                        cr[0] = CoderResult.malformedForLength(byteIndex);
                    }
                } else if (action == MBCS_STATE_VALID_DIRECT_16) {
                    /* output BMP code point */
                    target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                    if (offsets != null) {
                        offsets.put(sourceIndex);
                    }
                    byteIndex = 0;
                } else if (action == MBCS_STATE_VALID_16_PAIR) {
                    offset += MBCS_ENTRY_FINAL_VALUE_16(entry);
                    c = unicodeCodeUnits[offset++];
                    if (c < 0xd800) {
                        /* output BMP code point below 0xd800 */
                        target.put(c);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        byteIndex = 0;
                    } else if (isFallbackUsed() ? c <= 0xdfff : c <= 0xdbff) {
                        /* output roundtrip or fallback surrogate pair */
                        target.put((char)(c & 0xdbff));
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        byteIndex = 0;
                        if (target.hasRemaining()) {
                            target.put(unicodeCodeUnits[offset]);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                            }
                        } else {
                            /* target overflow */
                            charErrorBufferArray[0] = unicodeCodeUnits[offset];
                            charErrorBufferLength = 1;
                            cr[0] = CoderResult.OVERFLOW;

                            offset = 0;
                            break;
                        }
                    } else if (isFallbackUsed() ? (c & 0xfffe) == 0xe000 : c == 0xe000) {
                        /* output roundtrip BMP code point above 0xd800 or fallback BMP code point */
                        target.put(unicodeCodeUnits[offset]);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        byteIndex = 0;
                    } else if (c == 0xffff) {
                        /* callback(illegal) */
                        cr[0] = CoderResult.malformedForLength(byteIndex);
                    }
                } else if (action == MBCS_STATE_VALID_DIRECT_20
                        || (action == MBCS_STATE_FALLBACK_DIRECT_20 && isFallbackUsed())) {
                    entry = MBCS_ENTRY_FINAL_VALUE(entry);
                    /* output surrogate pair */
                    target.put((char)(0xd800 | (char)(entry >> 10)));
                    if (offsets != null) {
                        offsets.put(sourceIndex);
                    }
                    byteIndex = 0;
                    c = (char)(0xdc00 | (char)(entry & 0x3ff));
                    if (target.hasRemaining()) {
                        target.put(c);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                    } else {
                        /* target overflow */
                        charErrorBufferArray[0] = c;
                        charErrorBufferLength = 1;
                        cr[0] = CoderResult.OVERFLOW;

                        offset = 0;
                        break;
                    }
                } else if (action == MBCS_STATE_CHANGE_ONLY) {
                    /*
                     * This serves as a state change without any output. It is useful for reading simple stateful
                     * encodings, for example using just Shift-In/Shift-Out codes. The 21 unused bits may later be used
                     * for more sophisticated state transitions.
                     */
                    if (sharedData.mbcs.dbcsOnlyState == 0) {
                        byteIndex = 0;
                    } else {
                        /* SI/SO are illegal for DBCS-only conversion */
                        state = (byte)(mode); /* restore the previous state */

                        /* callback(illegal) */
                        cr[0] = CoderResult.malformedForLength(byteIndex);
                    }
                } else if (action == MBCS_STATE_FALLBACK_DIRECT_16) {
                    if (isFallbackUsed()) {
                        /* output BMP code point */
                        target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        byteIndex = 0;
                    }
                } else if (action == MBCS_STATE_UNASSIGNED) {
                    /* just fall through */
                } else if (action == MBCS_STATE_ILLEGAL) {
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(byteIndex);
                } else {
                    /* reserved, must never occur */
                    byteIndex = 0;
                }

                /* end of action codes: prepare for a new character */
                offset = 0;

                if (byteIndex == 0) {
                    sourceIndex = nextSourceIndex;
                } else if (cr[0].isError()) {
                    /* callback(illegal) */
                    if (byteIndex > 1) {
                        /*
                         * Ticket 5691: consistent illegal sequences:
                         * - We include at least the first byte in the illegal sequence.
                         * - If any of the non-initial bytes could be the start of a character,
                         *   we stop the illegal sequence before the first one of those.
                         */
                        boolean isDBCSOnly = (sharedData.mbcs.dbcsOnlyState != 0);
                        byte i;
                        for (i = 1; i < byteIndex && !isSingleOrLead(stateTable, state, isDBCSOnly, (short)(bytes[i] & UConverterConstants.UNSIGNED_BYTE_MASK)); i++) {}
                        if (i < byteIndex) {
                            byte backOutDistance = (byte)(byteIndex - i);
                            int bytesFromThisBuffer = sourceArrayIndex - sourceArrayIndexStart;
                            byteIndex = i; /* length of reported illegal byte sequence */
                            if (backOutDistance <= bytesFromThisBuffer) {
                                sourceArrayIndex -= backOutDistance;
                            } else {
                                /* Back out bytes from the previous buffer: Need to replay them. */
                                this.preToULength = (byte)(bytesFromThisBuffer - backOutDistance);
                                /* preToULength is negative! */
                                for (int n = 0; n < -this.preToULength; n++) {
                                    this.preToUArray[n] = bytes[i+n];
                                }
                                sourceArrayIndex = sourceArrayIndexStart;
                            }
                        }
                    }
                    break;
                } else /* unassigned sequences indicated with byteIndex>0 */{
                    /* try an extension mapping */
                    int sourceBeginIndex = sourceArrayIndex;
                    source.position(sourceArrayIndex);
                    byteIndex = toU(byteIndex, source, target, offsets, sourceIndex, flush, cr);
                    sourceArrayIndex = source.position();
                    sourceIndex = nextSourceIndex += (sourceArrayIndex - sourceBeginIndex);

                    if (cr[0].isError() || cr[0].isOverflow()) {
                        /* not mappable or buffer overflow */
                        break;
                    }
                }
            }

            /* set the converter state back into UConverter */
            toUnicodeStatus = offset;
            mode = state;
            toULength = byteIndex;

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }
        /*
         * This version of cnvMBCSSingleToUnicodeWithOffsets() is optimized for single-byte, single-state codepages that
         * only map to and from the BMP. In addition to single-byte optimizations, the offset calculations become much
         * easier.
         */
        private CoderResult cnvMBCSSingleToBMPWithOffsets(ByteBuffer source, CharBuffer target, IntBuffer offsets,
                boolean flush) {
            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex, lastSource;
            int targetCapacity, length;
            int[][] stateTable;

            int sourceIndex;

            int entry;
            byte action;

            /* set up the local pointers */
            sourceArrayIndex = source.position();
            targetCapacity = target.remaining();

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                stateTable = sharedData.mbcs.swapLFNLStateTable;
            } else {
                stateTable = sharedData.mbcs.stateTable;
            }

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = 0;
            lastSource = sourceArrayIndex;

            /*
             * since the conversion here is 1:1 UChar:uint8_t, we need only one counter for the minimum of the
             * sourceLength and targetCapacity
             */
            length = source.remaining();
            if (length < targetCapacity) {
                targetCapacity = length;
            }

            /* conversion loop */
            while (targetCapacity > 0 && sourceArrayIndex < source.limit()) {
                entry = stateTable[0][source.get(sourceArrayIndex++) & UConverterConstants.UNSIGNED_BYTE_MASK];
                /* MBCS_ENTRY_IS_FINAL(entry) */

                /* test the most common case first */
                if (MBCS_ENTRY_FINAL_IS_VALID_DIRECT_16(entry)) {
                    /* output BMP code point */
                    target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                    --targetCapacity;
                    continue;
                }

                /*
                 * An if-else-if chain provides more reliable performance for the most common cases compared to a
                 * switch.
                 */
                action = (byte) (MBCS_ENTRY_FINAL_ACTION(entry));
                if (action == MBCS_STATE_FALLBACK_DIRECT_16) {
                    if (isFallbackUsed()) {
                        /* output BMP code point */
                        target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                        --targetCapacity;
                        continue;
                    }
                } else if (action == MBCS_STATE_UNASSIGNED) {
                    /* just fall through */
                } else if (action == MBCS_STATE_ILLEGAL) {
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(sourceArrayIndex - lastSource);
                } else {
                    /* reserved, must never occur */
                    continue;
                }

                /* set offsets since the start or the last extension */
                if (offsets != null) {
                    int count = sourceArrayIndex - lastSource;

                    /* predecrement: do not set the offset for the callback-causing character */
                    while (--count > 0) {
                        offsets.put(sourceIndex++);
                    }
                    /* offset and sourceIndex are now set for the current character */
                }

                if (cr[0].isError()) {
                    /* callback(illegal) */
                    break;
                } else /* unassigned sequences indicated with byteIndex>0 */{
                    /* try an extension mapping */
                    lastSource = sourceArrayIndex;
                    toUBytesArray[0] = source.get(sourceArrayIndex - 1);
                    source.position(sourceArrayIndex);
                    toULength = toU((byte) 1, source, target, offsets, sourceIndex, flush, cr);
                    sourceArrayIndex = source.position();
                    sourceIndex += 1 + (sourceArrayIndex - lastSource);

                    if (cr[0].isError()) {
                        /* not mappable or buffer overflow */
                        break;
                    }

                    /* recalculate the targetCapacity after an extension mapping */
                    targetCapacity = target.remaining();
                    length = source.remaining();
                    if (length < targetCapacity) {
                        targetCapacity = length;
                    }
                }
            }

            if (!cr[0].isError() && sourceArrayIndex < source.limit() && !target.hasRemaining()) {
                /* target is full */
                cr[0] = CoderResult.OVERFLOW;
            }

            /* set offsets since the start or the last callback */
            if (offsets != null) {
                int count = sourceArrayIndex - lastSource;
                while (count > 0) {
                    offsets.put(sourceIndex++);
                    --count;
                }
            }

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }

        /* This version of cnvMBCSToUnicodeWithOffsets() is optimized for single-byte, single-state codepages. */
        private CoderResult cnvMBCSSingleToUnicodeWithOffsets(ByteBuffer source, CharBuffer target, IntBuffer offsets,
                boolean flush) {
            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex;
            int[][] stateTable;

            int sourceIndex;

            int entry;
            char c;
            byte action;

            /* set up the local pointers */
            sourceArrayIndex = source.position();

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                stateTable = sharedData.mbcs.swapLFNLStateTable;
            } else {
                stateTable = sharedData.mbcs.stateTable;
            }

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = 0;

            /* conversion loop */
            while (sourceArrayIndex < source.limit()) {
                /*
                 * This following test is to see if available input would overflow the output. It does not catch output
                 * of more than one code unit that overflows as a result of a surrogate pair or callback output from the
                 * last source byte. Therefore, those situations also test for overflows and will then break the loop,
                 * too.
                 */
                if (!target.hasRemaining()) {
                    /* target is full */
                    cr[0] = CoderResult.OVERFLOW;
                    break;
                }

                entry = stateTable[0][source.get(sourceArrayIndex++) & UConverterConstants.UNSIGNED_BYTE_MASK];
                /* MBCS_ENTRY_IS_FINAL(entry) */

                /* test the most common case first */
                if (MBCS_ENTRY_FINAL_IS_VALID_DIRECT_16(entry)) {
                    /* output BMP code point */
                    target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                    if (offsets != null) {
                        offsets.put(sourceIndex);
                    }

                    /* normal end of action codes: prepare for a new character */
                    ++sourceIndex;
                    continue;
                }

                /*
                 * An if-else-if chain provides more reliable performance for the most common cases compared to a
                 * switch.
                 */
                action = (byte) (MBCS_ENTRY_FINAL_ACTION(entry));
                if (action == MBCS_STATE_VALID_DIRECT_20
                        || (action == MBCS_STATE_FALLBACK_DIRECT_20 && isFallbackUsed())) {

                    entry = MBCS_ENTRY_FINAL_VALUE(entry);
                    /* output surrogate pair */
                    target.put((char) (0xd800 | (char) (entry >>> 10)));
                    if (offsets != null) {
                        offsets.put(sourceIndex);
                    }
                    c = (char) (0xdc00 | (char) (entry & 0x3ff));
                    if (target.hasRemaining()) {
                        target.put(c);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                    } else {
                        /* target overflow */
                        charErrorBufferArray[0] = c;
                        charErrorBufferLength = 1;
                        cr[0] = CoderResult.OVERFLOW;
                        break;
                    }

                    ++sourceIndex;
                    continue;
                } else if (action == MBCS_STATE_FALLBACK_DIRECT_16) {
                    if (isFallbackUsed()) {
                        /* output BMP code point */
                        target.put(MBCS_ENTRY_FINAL_VALUE_16(entry));
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }

                        ++sourceIndex;
                        continue;
                    }
                } else if (action == MBCS_STATE_UNASSIGNED) {
                    /* just fall through */
                } else if (action == MBCS_STATE_ILLEGAL) {
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(1);
                } else {
                    /* reserved, must never occur */
                    ++sourceIndex;
                    continue;
                }

                if (cr[0].isError()) {
                    /* callback(illegal) */
                    break;
                } else /* unassigned sequences indicated with byteIndex>0 */{
                    /* try an extension mapping */
                    int sourceBeginIndex = sourceArrayIndex;
                    toUBytesArray[0] = source.get(sourceArrayIndex - 1);
                    source.position(sourceArrayIndex);
                    toULength = toU((byte) 1, source, target, offsets, sourceIndex, flush, cr);
                    sourceArrayIndex = source.position();
                    sourceIndex += 1 + (sourceArrayIndex - sourceBeginIndex);

                    if (cr[0].isError()) {
                        /* not mappable or buffer overflow */
                        break;
                    }
                }
            }

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }

        private int getFallback(UConverterMBCSTable mbcsTable, int offset) {
            MBCSToUFallback[] toUFallbacks;
            int i, start, limit;

            limit = mbcsTable.countToUFallbacks;
            if (limit > 0) {
                /* do a binary search for the fallback mapping */
                toUFallbacks = mbcsTable.toUFallbacks;
                start = 0;
                while (start < limit - 1) {
                    i = (start + limit) >>> 1;
                    if (offset < toUFallbacks[i].offset) {
                        limit = i;
                    } else {
                        start = i;
                    }
                }

                /* did we really find it? */
                if (offset == toUFallbacks[start].offset) {
                    return toUFallbacks[start].codePoint;
                }
            }

            return 0xfffe;
        }

        /**
         * This is a simple version of _MBCSGetNextUChar() that is used by other converter implementations. It only
         * returns an "assigned" result if it consumes the entire input. It does not use state from the converter, nor
         * error codes. It does not handle the EBCDIC swaplfnl option (set in UConverter). It handles conversion
         * extensions but not GB 18030.
         *
         * @return U+fffe unassigned U+ffff illegal otherwise the Unicode code point
         */
        int simpleGetNextUChar(ByteBuffer source, boolean useFallback) {

            // #if 0
            // /*
            // * Code disabled 2002dec09 (ICU 2.4) because it is not currently used in ICU. markus
            // * TODO In future releases, verify that this function is never called for SBCS
            // * conversions, i.e., that sharedData->mbcs.countStates==1 is still true.
            // * Removal improves code coverage.
            // */
            // /* use optimized function if possible */
            // if(sharedData->mbcs.countStates==1) {
            // if(length==1) {
            // return ucnv_MBCSSingleSimpleGetNextUChar(sharedData, (uint8_t)*source, useFallback);
            // } else {
            // return 0xffff; /* illegal: more than a single byte for an SBCS converter */
            // }
            // }
            // #endif

            /* set up the local pointers */
            int[][] stateTable = sharedData.mbcs.stateTable;
            char[] unicodeCodeUnits = sharedData.mbcs.unicodeCodeUnits;

            /* converter state */
            int offset = 0;
            int state = sharedData.mbcs.dbcsOnlyState;

            int action;
            int entry;
            int c;
            int i = source.position();
            int length = source.limit() - i;

            /* conversion loop */
            while (true) {
                // entry=stateTable[state][(uint8_t)source[i++]];
                entry = stateTable[state][source.get(i++) & UConverterConstants.UNSIGNED_BYTE_MASK];

                if (MBCS_ENTRY_IS_TRANSITION(entry)) {
                    state = MBCS_ENTRY_TRANSITION_STATE(entry);
                    offset += MBCS_ENTRY_TRANSITION_OFFSET(entry);

                    if (i == source.limit()) {
                        return 0xffff; /* truncated character */
                    }
                } else {
                    /*
                     * An if-else-if chain provides more reliable performance for the most common cases compared to a
                     * switch.
                     */
                    action = MBCS_ENTRY_FINAL_ACTION(entry);
                    if (action == MBCS_STATE_VALID_16) {
                        offset += MBCS_ENTRY_FINAL_VALUE_16(entry);
                        c = unicodeCodeUnits[offset];
                        if (c != 0xfffe) {
                            /* done */
                        } else if (isToUUseFallback()) {
                            c = getFallback(sharedData.mbcs, offset);
                        }
                        /* else done with 0xfffe */
                    } else if (action == MBCS_STATE_VALID_DIRECT_16) {
                        // /* output BMP code point */
                        c = MBCS_ENTRY_FINAL_VALUE_16(entry);
                    } else if (action == MBCS_STATE_VALID_16_PAIR) {
                        offset += MBCS_ENTRY_FINAL_VALUE_16(entry);
                        c = unicodeCodeUnits[offset++];
                        if (c < 0xd800) {
                            /* output BMP code point below 0xd800 */
                        } else if (isToUUseFallback() ? c <= 0xdfff : c <= 0xdbff) {
                            /* output roundtrip or fallback supplementary code point */
                            c = (((c & 0x3ff) << 10) + unicodeCodeUnits[offset] + (0x10000 - 0xdc00));
                        } else if (isToUUseFallback() ? (c & 0xfffe) == 0xe000 : c == 0xe000) {
                            /* output roundtrip BMP code point above 0xd800 or fallback BMP code point */
                            c = unicodeCodeUnits[offset];
                        } else if (c == 0xffff) {
                            return 0xffff;
                        } else {
                            c = 0xfffe;
                        }
                    } else if (action == MBCS_STATE_VALID_DIRECT_20) {
                        /* output supplementary code point */
                        c = 0x10000 + MBCS_ENTRY_FINAL_VALUE(entry);
                    } else if (action == MBCS_STATE_FALLBACK_DIRECT_16) {
                        if (!isToUUseFallback(useFallback)) {
                            c = 0xfffe;
                        } else {
                            /* output BMP code point */
                            c = MBCS_ENTRY_FINAL_VALUE_16(entry);
                        }
                    } else if (action == MBCS_STATE_FALLBACK_DIRECT_20) {
                        if (!isToUUseFallback(useFallback)) {
                            c = 0xfffe;
                        } else {
                            /* output supplementary code point */
                            c = 0x10000 + MBCS_ENTRY_FINAL_VALUE(entry);
                        }
                    } else if (action == MBCS_STATE_UNASSIGNED) {
                        c = 0xfffe;
                    } else {
                        /*
                         * forbid MBCS_STATE_CHANGE_ONLY for this function, and MBCS_STATE_ILLEGAL and reserved action
                         * codes
                         */
                        return 0xffff;
                    }
                    break;
                }
            }

            if (i != source.limit()) {
                /* illegal for this function: not all input consumed */
                return 0xffff;
            }

            if (c == 0xfffe) {
                /* try an extension mapping */
                if (sharedData.mbcs.extIndexes != null) {
                    /* Increase the limit for proper handling. Used in LMBCS. */
                    if (source.limit() > i + length) {
                        source.limit(i + length);
                    }
                    return simpleMatchToU(source, useFallback);
                }
            }

            return c;
        }
        private boolean hasValidTrailBytes(int[][] stateTable, short state) {
            int[] row = stateTable[state];
            int b, entry;
            /* First test for final entries in this state for some commonly valid byte values. */
            entry = row[0xa1];
            if (!MBCS_ENTRY_IS_TRANSITION(entry) && MBCS_ENTRY_FINAL_ACTION(entry) != MBCS_STATE_ILLEGAL) {
                return true;
            }
            entry = row[0x41];
            if (!MBCS_ENTRY_IS_TRANSITION(entry) && MBCS_ENTRY_FINAL_ACTION(entry) != MBCS_STATE_ILLEGAL) {
                return true;
            }
            /* Then test for final entries in this state. */
            for (b = 0; b <= 0xff; b++) {
                entry = row[b];
                if (!MBCS_ENTRY_IS_TRANSITION(entry) && MBCS_ENTRY_FINAL_ACTION(entry) != MBCS_STATE_ILLEGAL) {
                    return true;
                }
            }
            /* Then recurse for transition entries. */
            for (b = 0; b <= 0xff; b++) {
                entry = row[b];
                if (MBCS_ENTRY_IS_TRANSITION(entry) &&
                        hasValidTrailBytes(stateTable, (short)MBCS_ENTRY_TRANSITION_STATE(entry))) {
                    return true;
                }
            }
            return false;
        }

        private boolean isSingleOrLead(int[][] stateTable, int state, boolean isDBCSOnly, int b) {
            int[] row = stateTable[state];
            int entry = row[b];
            if (MBCS_ENTRY_IS_TRANSITION(entry)) { /* lead byte */
                return hasValidTrailBytes(stateTable, (short)MBCS_ENTRY_TRANSITION_STATE(entry));
            } else {
                int action = MBCS_ENTRY_FINAL_ACTION(entry);
                if (action == MBCS_STATE_CHANGE_ONLY && isDBCSOnly) {
                    return false;   /* SI/SO are illegal for DBCS-only conversion */
                } else {
                    return (action != MBCS_STATE_ILLEGAL);
                }
            }
        }


    }

    class CharsetEncoderMBCS extends CharsetEncoderICU {
        private boolean allowReplacementChanges = false;

        CharsetEncoderMBCS(CharsetICU cs) {
            super(cs, fromUSubstitution);
            allowReplacementChanges = true; // allow changes in implReplaceWith
            implReset();
        }

        @Override
        protected void implReset() {
            super.implReset();
            preFromUFirstCP = UConverterConstants.U_SENTINEL;
        }

        @Override
        @SuppressWarnings("fallthrough")
        protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult[] cr = { CoderResult.UNDERFLOW };
            // if (!source.hasRemaining() && fromUChar32 == 0)
            // return cr[0];

            int sourceArrayIndex;
            char[] table;
            byte[] pArray, bytes;
            char[] chars;
            int[] ints;
            int pArrayIndex, outputType, c;
            int prevSourceIndex, sourceIndex, nextSourceIndex;
            int stage2Entry = 0, value = 0, length = 0, prevLength;
            short uniMask;
            // long asciiRoundtrips;

            byte[] si_value = new byte[2];
            byte[] so_value = new byte[2];
            int si_value_length = 0, so_value_length = 0;

            boolean gotoUnassigned = false;

            try {

                if (!flush && preFromUFirstCP >= 0) {
                    /*
                     * pass sourceIndex=-1 because we continue from an earlier buffer in the future, this may change
                     * with continuous offsets
                     */
                    cr[0] = continueMatchFromU(source, target, offsets, flush, -1);

                    if (cr[0].isError() || preFromULength < 0) {
                        return cr[0];
                    }
                }

                /* use optimized function if possible */
                outputType = sharedData.mbcs.outputType;
                uniMask = sharedData.mbcs.unicodeMask;
                if (outputType == MBCS_OUTPUT_1 && (uniMask & UConverterConstants.HAS_SURROGATES) == 0) {
                    if ((uniMask & UConverterConstants.HAS_SUPPLEMENTARY) == 0) {
                        cr[0] = cnvMBCSSingleFromBMPWithOffsets(source, target, offsets, flush);
                    } else {
                        cr[0] = cnvMBCSSingleFromUnicodeWithOffsets(source, target, offsets, flush);
                    }
                    return cr[0];
                } else if (outputType == MBCS_OUTPUT_2) {
                    cr[0] = cnvMBCSDoubleFromUnicodeWithOffsets(source, target, offsets, flush);
                    return cr[0];
                }

                table = sharedData.mbcs.fromUnicodeTable;
                int[] tableInts = sharedData.mbcs.fromUnicodeTableInts;
                sourceArrayIndex = source.position();

                bytes = sharedData.mbcs.fromUnicodeBytes;
                ints = sharedData.mbcs.fromUnicodeInts;
                if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                    chars = sharedData.mbcs.swapLFNLFromUnicodeChars;
                } else {
                    chars = sharedData.mbcs.fromUnicodeChars;
                }

                // asciiRoundtrips = sharedData.mbcs.asciiRoundtrips;

                /* get the converter state from UConverter */
                c = fromUChar32;

                if (outputType == MBCS_OUTPUT_2_SISO) {
                    prevLength = fromUnicodeStatus;
                    if (prevLength == 0) {
                        /* set the real value */
                        prevLength = 1;
                    }
                } else {
                    /* prevent fromUnicodeStatus from being set to something non-0 */
                    prevLength = 0;
                }

                /* sourceIndex=-1 if the current character began in the previous buffer */
                prevSourceIndex = -1;
                sourceIndex = c == 0 ? 0 : -1;
                nextSourceIndex = 0;

                /* Get the SI/SO character for the converter */
                si_value_length = getSISOBytes(SISO_Option.SI, options, si_value);
                so_value_length = getSISOBytes(SISO_Option.SO, options, so_value);

                /* conversion loop */
                /*
                 * This is another piece of ugly code: A goto into the loop if the converter state contains a first
                 * surrogate from the previous function call. It saves me to check in each loop iteration a check of
                 * if(c==0) and duplicating the trail-surrogate-handling code in the else branch of that check. I could
                 * not find any other way to get around this other than using a function call for the conversion and
                 * callback, which would be even more inefficient.
                 *
                 * Markus Scherer 2000-jul-19
                 */
                boolean doloop = true;
                boolean doread = true;
                if (c != 0 && target.hasRemaining()) {
                    if (UTF16.isLeadSurrogate((char) c) && (uniMask & UConverterConstants.HAS_SURROGATES) == 0) {
                        // c is a lead surrogate, read another input
                        SideEffects x = new SideEffects(c, sourceArrayIndex, sourceIndex, nextSourceIndex,
                                prevSourceIndex, prevLength);
                        doloop = getTrail(source, target, uniMask, x, flush, cr);
                        doread = x.doread;
                        c = x.c;
                        sourceArrayIndex = x.sourceArrayIndex;
                        sourceIndex = x.sourceIndex;
                        nextSourceIndex = x.nextSourceIndex;
                        prevSourceIndex = x.prevSourceIndex;
                        prevLength = x.prevLength;
                    } else {
                        // c is not a lead surrogate, do not read another input
                        doread = false;
                    }
                }

                if (doloop) {
                    while (!doread || sourceArrayIndex < source.limit()) {
                        /*
                         * This following test is to see if available input would overflow the output. It does not catch
                         * output of more than one byte that overflows as a result of a multi-byte character or callback
                         * output from the last source character. Therefore, those situations also test for overflows
                         * and will then break the loop, too.
                         */
                        if (target.hasRemaining()) {
                            /*
                             * Get a correct Unicode code point: a single UChar for a BMP code point or a matched
                             * surrogate pair for a "supplementary code point".
                             */

                            if (doread) {
                                // doread might be false only on the first looping

                                c = source.get(sourceArrayIndex++);
                                ++nextSourceIndex;

                                /*
                                 * This also tests if the codepage maps single surrogates. If it does, then surrogates
                                 * are not paired but mapped separately. Note that in this case unmatched surrogates are
                                 * not detected.
                                 */
                                if (UTF16.isSurrogate((char) c)
                                        && (uniMask & UConverterConstants.HAS_SURROGATES) == 0) {
                                    if (UTF16.isLeadSurrogate((char) c)) {
                                        // getTrail:
                                        SideEffects x = new SideEffects(c, sourceArrayIndex, sourceIndex,
                                                nextSourceIndex, prevSourceIndex, prevLength);
                                        doloop = getTrail(source, target, uniMask, x, flush, cr);
                                        c = x.c;
                                        sourceArrayIndex = x.sourceArrayIndex;
                                        sourceIndex = x.sourceIndex;
                                        nextSourceIndex = x.nextSourceIndex;
                                        prevSourceIndex = x.prevSourceIndex;

                                        if (x.doread) {
                                            if (doloop)
                                                continue;
                                            else
                                                break;
                                        }
                                    } else {
                                        /* this is an unmatched trail code unit (2nd surrogate) */
                                        /* callback(illegal) */
                                        cr[0] = CoderResult.malformedForLength(1);
                                        break;
                                    }
                                }
                            } else {
                                doread = true;
                            }
                            /* convert the Unicode code point in c into codepage bytes */

                            /*
                             * The basic lookup is a triple-stage compact array (trie) lookup. For details see the
                             * beginning of this file.
                             *
                             * Single-byte codepages are handled with a different data structure by _MBCSSingle...
                             * functions.
                             *
                             * The result consists of a 32-bit value from stage 2 and a pointer to as many bytes as are
                             * stored per character. The pointer points to the character's bytes in stage 3. Bits 15..0
                             * of the stage 2 entry contain the stage 3 index for that pointer, while bits 31..16 are
                             * flags for which of the 16 characters in the block are roundtrip-assigned.
                             *
                             * For 2-byte and 4-byte codepages, the bytes are stored as uint16_t respectively as
                             * uint32_t, in the platform encoding. For 3-byte codepages, the bytes are always stored in
                             * big-endian order.
                             *
                             * For EUC encodings that use only either 0x8e or 0x8f as the first byte of their longest
                             * byte sequences, the first two bytes in this third stage indicate with their 7th bits
                             * whether these bytes are to be written directly or actually need to be preceeded by one of
                             * the two Single-Shift codes. With this, the third stage stores one byte fewer per
                             * character than the actual maximum length of EUC byte sequences.
                             *
                             * Other than that, leading zero bytes are removed and the other bytes output. A single zero
                             * byte may be output if the "assigned" bit in stage 2 was on. The data structure does not
                             * support zero byte output as a fallback, and also does not allow output of leading zeros.
                             */
                            stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, c);

                            /* get the bytes and the length for the output */
                            switch (outputType) {
                            /* This is handled above with the method cnvMBCSDoubleFromUnicodeWithOffsets() */
                            /* case MBCS_OUTPUT_2:
                                value = MBCS_VALUE_2_FROM_STAGE_2(bytes, stage2Entry, c);
                                if ((value & UConverterConstants.UNSIGNED_INT_MASK) <= 0xff) {
                                    length = 1;
                                } else {
                                    length = 2;
                                }
                                break; */
                            case MBCS_OUTPUT_2_SISO:
                                /* 1/2-byte stateful with Shift-In/Shift-Out */
                                /*
                                 * Save the old state in the converter object right here, then change the local
                                 * prevLength state variable if necessary. Then, if this character turns out to be
                                 * unassigned or a fallback that is not taken, the callback code must not save the new
                                 * state in the converter because the new state is for a character that is not output.
                                 * However, the callback must still restore the state from the converter in case the
                                 * callback function changed it for its output.
                                 */
                                fromUnicodeStatus = prevLength; /* save the old state */
                                value = MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, c);
                                if (value <= 0xff) {
                                    if (value == 0 && MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, c) == false) {
                                        /* no mapping, leave value==0 */
                                        length = 0;
                                    } else if (prevLength <= 1) {
                                        length = 1;
                                    } else {
                                        /* change from double-byte mode to single-byte */
                                        if (si_value_length == 1) {
                                            value|=si_value[0]<<8;
                                            length = 2;
                                        } else if (si_value_length == 2) {
                                            value|=si_value[1]<<8;
                                            value|=si_value[0]<<16;
                                            length = 3;
                                        }
                                        prevLength = 1;
                                    }
                                } else {
                                    if (prevLength == 2) {
                                        length = 2;
                                    } else {
                                        /* change from single-byte mode to double-byte */
                                        if (so_value_length == 1) {
                                            value|=so_value[0]<<16;
                                            length = 3;
                                        } else if (so_value_length == 2) {
                                            value|=so_value[1]<<16;
                                            value|=so_value[0]<<24;
                                            length = 4;
                                        }
                                        prevLength = 2;
                                    }
                                }
                                break;
                            case MBCS_OUTPUT_DBCS_ONLY:
                                /* table with single-byte results, but only DBCS mappings used */
                                value = MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, c);
                                if (value <= 0xff) {
                                    /* no mapping or SBCS result, not taken for DBCS-only */
                                    value = stage2Entry = 0; /* stage2Entry=0 to reset roundtrip flags */
                                    length = 0;
                                } else {
                                    length = 2;
                                }
                                break;
                            case MBCS_OUTPUT_3:
                                pArray = bytes;
                                pArrayIndex = MBCS_POINTER_3_FROM_STAGE_2(bytes, stage2Entry, c);
                                value = ((pArray[pArrayIndex] & UConverterConstants.UNSIGNED_BYTE_MASK) << 16)
                                        | ((pArray[pArrayIndex + 1] & UConverterConstants.UNSIGNED_BYTE_MASK) << 8)
                                        | (pArray[pArrayIndex + 2] & UConverterConstants.UNSIGNED_BYTE_MASK);
                                if (value <= 0xff) {
                                    length = 1;
                                } else if (value <= 0xffff) {
                                    length = 2;
                                } else {
                                    length = 3;
                                }
                                break;
                            case MBCS_OUTPUT_4:
                                value = MBCS_VALUE_4_FROM_STAGE_2(ints, stage2Entry, c);
                                if (value < 0) {
                                    // Half of the 4-byte values look negative in a signed int.
                                    length = 4;
                                } else if (value <= 0xff) {
                                    length = 1;
                                } else if (value <= 0xffff) {
                                    length = 2;
                                } else if (value <= 0xffffff) {
                                    length = 3;
                                } else {
                                    length = 4;
                                }
                                break;
                            case MBCS_OUTPUT_3_EUC:
                                value = MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, c);
                                /* EUC 16-bit fixed-length representation */
                                if (value <= 0xff) {
                                    length = 1;
                                } else if ((value & 0x8000) == 0) {
                                    value |= 0x8e8000;
                                    length = 3;
                                } else if ((value & 0x80) == 0) {
                                    value |= 0x8f0080;
                                    length = 3;
                                } else {
                                    length = 2;
                                }
                                break;
                            case MBCS_OUTPUT_4_EUC:
                                pArray = bytes;
                                pArrayIndex = MBCS_POINTER_3_FROM_STAGE_2(bytes, stage2Entry, c);
                                value = ((pArray[pArrayIndex] & UConverterConstants.UNSIGNED_BYTE_MASK) << 16)
                                        | ((pArray[pArrayIndex + 1] & UConverterConstants.UNSIGNED_BYTE_MASK) << 8)
                                        | (pArray[pArrayIndex + 2] & UConverterConstants.UNSIGNED_BYTE_MASK);
                                /* EUC 16-bit fixed-length representation applied to the first two bytes */
                                if (value <= 0xff) {
                                    length = 1;
                                } else if (value <= 0xffff) {
                                    length = 2;
                                } else if ((value & 0x800000) == 0) {
                                    value |= 0x8e800000;
                                    length = 4;
                                } else if ((value & 0x8000) == 0) {
                                    value |= 0x8f008000;
                                    length = 4;
                                } else {
                                    length = 3;
                                }
                                break;
                            default:
                                /* must not occur */
                                /*
                                 * To avoid compiler warnings that value & length may be used without having been
                                 * initialized, we set them here. In reality, this is unreachable code. Not having a
                                 * default branch also causes warnings with some compilers.
                                 */
                                value = stage2Entry = 0; /* stage2Entry=0 to reset roundtrip flags */
                                length = 0;
                                break;
                            }

                            /* is this code point assigned, or do we use fallbacks? */
                            if (gotoUnassigned || (!(MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, c) || (isFromUUseFallback(c) && value != 0)))) {
                                gotoUnassigned = false;
                                /*
                                 * We allow a 0 byte output if the "assigned" bit is set for this entry. There is no way
                                 * with this data structure for fallback output to be a zero byte.
                                 */

                                // unassigned:
                                SideEffects x = new SideEffects(c, sourceArrayIndex, sourceIndex, nextSourceIndex,
                                        prevSourceIndex, prevLength);
                                doloop = unassigned(source, target, offsets, x, flush, cr);
                                c = x.c;
                                sourceArrayIndex = x.sourceArrayIndex;
                                sourceIndex = x.sourceIndex;
                                nextSourceIndex = x.nextSourceIndex;
                                prevSourceIndex = x.prevSourceIndex;
                                prevLength = x.prevLength;
                                if (doloop)
                                    continue;
                                else
                                    break;
                            }

                            /* write the output character bytes from value and length */
                            /* from the first if in the loop we know that targetCapacity>0 */
                            if (length <= target.remaining()) {
                                switch (length) {
                                /* each branch falls through to the next one */
                                case 4:
                                    target.put((byte) (value >>> 24));
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                case 3:
                                    target.put((byte) (value >>> 16));
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                case 2:
                                    target.put((byte) (value >>> 8));
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                case 1:
                                    target.put((byte) value);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                default:
                                    /* will never occur */
                                    break;
                                }
                            } else {
                                int errorBufferArrayIndex;

                                /*
                                 * We actually do this backwards here: In order to save an intermediate variable, we
                                 * output first to the overflow buffer what does not fit into the regular target.
                                 */
                                /* we know that 1<=targetCapacity<length<=4 */
                                length -= target.remaining();

                                errorBufferArrayIndex = 0;
                                switch (length) {
                                /* each branch falls through to the next one */
                                case 3:
                                    errorBuffer[errorBufferArrayIndex++] = (byte) (value >>> 16);
                                case 2:
                                    errorBuffer[errorBufferArrayIndex++] = (byte) (value >>> 8);
                                case 1:
                                    errorBuffer[errorBufferArrayIndex] = (byte) value;
                                default:
                                    /* will never occur */
                                    break;
                                }
                                errorBufferLength = (byte) length;

                                /* now output what fits into the regular target */
                                value >>>= 8 * length; /* length was reduced by targetCapacity */
                                switch (target.remaining()) {
                                /* each branch falls through to the next one */
                                case 3:
                                    target.put((byte) (value >>> 16));
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                case 2:
                                    target.put((byte) (value >>> 8));
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                case 1:
                                    target.put((byte) value);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                    }
                                default:
                                    /* will never occur */
                                    break;
                                }

                                /* target overflow */
                                cr[0] = CoderResult.OVERFLOW;
                                c = 0;
                                break;
                            }

                            /* normal end of conversion: prepare for a new character */
                            c = 0;
                            if (offsets != null) {
                                prevSourceIndex = sourceIndex;
                                sourceIndex = nextSourceIndex;
                            }
                            continue;
                        } else {
                            /* target is full */
                            cr[0] = CoderResult.OVERFLOW;
                            break;
                        }
                    }
                }

                /*
                 * the end of the input stream and detection of truncated input are handled by the framework, but for
                 * EBCDIC_STATEFUL conversion we need to emit an SI at the very end
                 *
                 * conditions: successful EBCDIC_STATEFUL in DBCS mode end of input and no truncated input
                 */
                if (outputType == MBCS_OUTPUT_2_SISO && prevLength == 2 && flush && sourceArrayIndex >= source.limit()
                        && c == 0) {

                    /* EBCDIC_STATEFUL ending with DBCS: emit an SI to return the output stream to SBCS */
                    if (target.hasRemaining()) {
                        target.put(si_value[0]);
                        if (si_value_length == 2) {
                            if (target.remaining() > 0) {
                                target.put(si_value[1]);
                            } else {
                                errorBuffer[0] = si_value[1];
                                errorBufferLength = 1;
                                cr[0] = CoderResult.OVERFLOW;
                            }
                        }
                        if (offsets != null) {
                            /* set the last source character's index (sourceIndex points at sourceLimit now) */
                            offsets.put(prevSourceIndex);
                        }
                    } else {
                        /* target is full */
                        errorBuffer[0] = si_value[0];
                        if (si_value_length == 2) {
                            errorBuffer[1] = si_value[1];
                        }
                        errorBufferLength = si_value_length;
                        cr[0] = CoderResult.OVERFLOW;
                    }
                    prevLength = 1; /* we switched into SBCS */
                }

                /* set the converter state back into UConverter */
                fromUChar32 = c;
                fromUnicodeStatus = prevLength;

                source.position(sourceArrayIndex);
            } catch (BufferOverflowException ex) {
                cr[0] = CoderResult.OVERFLOW;
            }

            return cr[0];
        }

        /*
         * This is another simple conversion function for internal use by other conversion implementations. It does not
         * use the converter state nor call callbacks. It does not handle the EBCDIC swaplfnl option (set in
         * UConverter). It handles conversion extensions but not GB 18030.
         *
         * It converts one single Unicode code point into codepage bytes, encoded as one 32-bit value. The function
         * returns the number of bytes in *pValue: 1..4 the number of bytes in *pValue 0 unassigned (*pValue undefined)
         * -1 illegal (currently not used, *pValue undefined)
         *
         * *pValue will contain the resulting bytes with the last byte in bits 7..0, the second to last byte in bits
         * 15..8, etc. Currently, the function assumes but does not check that 0<=c<=0x10ffff.
         */
        int fromUChar32(int c, int[] pValue, boolean isUseFallback) {
            // #if 0
            // /* #if 0 because this is not currently used in ICU - reduce code, increase code coverage */
            // const uint8_t *p;
            // #endif

            char[] table;
            int stage2Entry;
            int value;
            int length;
            int p;

            /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
            if (c <= 0xffff || sharedData.mbcs.hasSupplementary()) {
                table = sharedData.mbcs.fromUnicodeTable;

                /* convert the Unicode code point in c into codepage bytes (same as in _MBCSFromUnicodeWithOffsets) */
                if (sharedData.mbcs.outputType == MBCS_OUTPUT_1) {
                    value = MBCS_SINGLE_RESULT_FROM_U(table, sharedData.mbcs.fromUnicodeChars, c);
                    /* is this code point assigned, or do we use fallbacks? */
                    if (isUseFallback ? value >= 0x800 : value >= 0xc00) {
                        pValue[0] = value & 0xff;
                        return 1;
                    }
                } else /* outputType!=MBCS_OUTPUT_1 */{
                    int[] tableInts = sharedData.mbcs.fromUnicodeTableInts;
                    stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, c);

                    /* get the bytes and the length for the output */
                    switch (sharedData.mbcs.outputType) {
                    case MBCS_OUTPUT_2:
                        value = MBCS_VALUE_2_FROM_STAGE_2(sharedData.mbcs.fromUnicodeChars, stage2Entry, c);
                        if (value <= 0xff) {
                            length = 1;
                        } else {
                            length = 2;
                        }
                        break;
                    // #if 0
                    // /* #if 0 because this is not currently used in ICU - reduce code, increase code coverage */
                    // case MBCS_OUTPUT_DBCS_ONLY:
                    // /* table with single-byte results, but only DBCS mappings used */
                    // value=MBCS_VALUE_2_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
                    // if(value<=0xff) {
                    // /* no mapping or SBCS result, not taken for DBCS-only */
                    // value=stage2Entry=0; /* stage2Entry=0 to reset roundtrip flags */
                    // length=0;
                    // } else {
                    // length=2;
                    // }
                    // break;
                    case MBCS_OUTPUT_3:
                        byte[] bytes = sharedData.mbcs.fromUnicodeBytes;
                        p = CharsetMBCS.MBCS_POINTER_3_FROM_STAGE_2(bytes, stage2Entry, c);
                        value = ((bytes[p] & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) |
                            ((bytes[p+1] & UConverterConstants.UNSIGNED_BYTE_MASK)<<8) |
                            (bytes[p+2] & UConverterConstants.UNSIGNED_BYTE_MASK);
                        if (value <= 0xff) {
                            length = 1;
                        } else if (value <= 0xffff) {
                            length = 2;
                        } else {
                            length = 3;
                        }
                        break;
                    // case MBCS_OUTPUT_4:
                    // value=MBCS_VALUE_4_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
                    // if(value<=0xff) {
                    // length=1;
                    // } else if(value<=0xffff) {
                    // length=2;
                    // } else if(value<=0xffffff) {
                    // length=3;
                    // } else {
                    // length=4;
                    // }
                    // break;
                    // case MBCS_OUTPUT_3_EUC:
                    // value=MBCS_VALUE_2_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
                    // /* EUC 16-bit fixed-length representation */
                    // if(value<=0xff) {
                    // length=1;
                    // } else if((value&0x8000)==0) {
                    // value|=0x8e8000;
                    // length=3;
                    // } else if((value&0x80)==0) {
                    // value|=0x8f0080;
                    // length=3;
                    // } else {
                    // length=2;
                    // }
                    // break;
                    // case MBCS_OUTPUT_4_EUC:
                    // p=MBCS_POINTER_3_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
                    // value=((uint32_t)*p<<16)|((uint32_t)p[1]<<8)|p[2];
                    // /* EUC 16-bit fixed-length representation applied to the first two bytes */
                    // if(value<=0xff) {
                    // length=1;
                    // } else if(value<=0xffff) {
                    // length=2;
                    // } else if((value&0x800000)==0) {
                    // value|=0x8e800000;
                    // length=4;
                    // } else if((value&0x8000)==0) {
                    // value|=0x8f008000;
                    // length=4;
                    // } else {
                    // length=3;
                    // }
                    // break;
                    // #endif
                    default:
                        /* must not occur */
                        return -1;
                    }

                    /* is this code point assigned, or do we use fallbacks? */
                    if (MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, c)
                            || (CharsetEncoderICU.isFromUUseFallback(isUseFallback, c) && value != 0)) {
                        /*
                         * We allow a 0 byte output if the "assigned" bit is set for this entry. There is no way with
                         * this data structure for fallback output to be a zero byte.
                         */
                        /* assigned */
                        pValue[0] = value;
                        return length;
                    }
                }
            }

            if (sharedData.mbcs.extIndexes != null) {
                length = simpleMatchFromU(c, pValue, isUseFallback);
                return length >= 0 ? length : -length; /* return abs(length); */
            }

            /* unassigned */
            return 0;
        }

        /*
         * continue partial match with new input, requires cnv->preFromUFirstCP>=0 never called for simple,
         * single-character conversion
         */
        private CoderResult continueMatchFromU(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush,
                int srcIndex) {
            CoderResult cr = CoderResult.UNDERFLOW;
            int[] value = new int[1];
            int match;

            match = matchFromU(preFromUFirstCP, preFromUArray, preFromUBegin, preFromULength, source, value, useFallback, flush);
            if (match >= 2) {
                match -= 2; /* remove 2 for the initial code point */

                if (match >= preFromULength) {
                    /* advance src pointer for the consumed input */
                    source.position(source.position() + match - preFromULength);
                    preFromULength = 0;
                } else {
                    /* the match did not use all of preFromU[] - keep the rest for replay */
                    int length = preFromULength - match;
                    System.arraycopy(preFromUArray, preFromUBegin + match, preFromUArray, preFromUBegin, length);
                    preFromULength = (byte) -length;
                }

                /* finish the partial match */
                preFromUFirstCP = UConverterConstants.U_SENTINEL;

                /* write result */
                writeFromU(value[0], target, offsets, srcIndex);
            } else if (match < 0) {
                /* save state for partial match */
                int sArrayIndex;
                int j;

                /* just _append_ the newly consumed input to preFromU[] */
                sArrayIndex = source.position();
                match = -match - 2; /* remove 2 for the initial code point */
                for (j = preFromULength; j < match; ++j) {
                    preFromUArray[j] = source.get(sArrayIndex++);
                }
                source.position(sArrayIndex); /* same as *src=srcLimit; because we reached the end of input */
                preFromULength = (byte) match;
            } else { /* match==0 or 1 */
                /*
                 * no match
                 *
                 * We need to split the previous input into two parts:
                 *
                 * 1. The first code point is unmappable - that's how we got into trying the extension data in the first
                 * place. We need to move it from the preFromU buffer to the error buffer, set an error code, and
                 * prepare the rest of the previous input for 2.
                 *
                 * 2. The rest of the previous input must be converted once we come back from the callback for the first
                 * code point. At that time, we have to try again from scratch to convert these input characters. The
                 * replay will be handled by the ucnv.c conversion code.
                 */

                if (match == 1) {
                    /* matched, no mapping but request for <subchar1> */
                    useSubChar1 = true;
                }

                /* move the first code point to the error field */
                fromUChar32 = preFromUFirstCP;
                preFromUFirstCP = UConverterConstants.U_SENTINEL;

                /* mark preFromU for replay */
                preFromULength = (byte) -preFromULength;

                /* set the error code for unassigned */
                // TODO: figure out what the unmappable length really should be
                cr = CoderResult.unmappableForLength(1);
            }
            return cr;
        }

        /**
         * @param cx
         *            pointer to extension data; if NULL, returns 0
         * @param firstCP
         *            the first code point before all the other UChars
         * @param pre
         *            UChars that must match; !initialMatch: partial match with them
         * @param preLength
         *            length of pre, >=0
         * @param src
         *            UChars that can be used to complete a match
         * @param srcLength
         *            length of src, >=0
         * @param pMatchValue
         *            [out] output result value for the match from the data structure
         * @param useFallback
         *            "use fallback" flag, usually from cnv->useFallback
         * @param flush
         *            TRUE if the end of the input stream is reached
         * @return >1: matched, return value=total match length (number of input units matched) 1: matched, no mapping
         *         but request for <subchar1> (only for the first code point) 0: no match <0: partial match, return
         *         value=negative total match length (partial matches are never returned for flush==TRUE) (partial
         *         matches are never returned as being longer than UCNV_EXT_MAX_UCHARS) the matchLength is 2 if only
         *         firstCP matched, and >2 if firstCP and further code units matched
         */
        // static int32_t ucnv_extMatchFromU(const int32_t *cx, UChar32 firstCP, const UChar *pre, int32_t preLength,
        // const UChar *src, int32_t srcLength, uint32_t *pMatchValue, UBool useFallback, UBool flush)
        private int matchFromU(int firstCP, char[] preArray, int preArrayBegin, int preLength, CharBuffer source,
                int[] pMatchValue, boolean isUseFallback, boolean flush) {
            ByteBuffer cx = sharedData.mbcs.extIndexes;

            CharBuffer stage12, stage3;
            IntBuffer stage3b;

            CharBuffer fromUTableUChars, fromUSectionUChars;
            IntBuffer fromUTableValues, fromUSectionValues;

            int value, matchValue;
            int i, j, index, length, matchLength;
            char c;

            if (cx == null) {
                return 0; /* no extension data, no match */
            }

            /* trie lookup of firstCP */
            index = firstCP >>> 10; /* stage 1 index */
            if (index >= cx.asIntBuffer().get(EXT_FROM_U_STAGE_1_LENGTH)) {
                return 0; /* the first code point is outside the trie */
            }

            stage12 = (CharBuffer) ARRAY(cx, EXT_FROM_U_STAGE_12_INDEX, char.class);
            stage3 = (CharBuffer) ARRAY(cx, EXT_FROM_U_STAGE_3_INDEX, char.class);
            index = FROM_U(stage12, stage3, index, firstCP);

            stage3b = (IntBuffer) ARRAY(cx, EXT_FROM_U_STAGE_3B_INDEX, int.class);
            value = stage3b.get(stage3b.position() + index);
            if (value == 0) {
                return 0;
            }

            if (TO_U_IS_PARTIAL(value)) {
                /* partial match, enter the loop below */
                index = FROM_U_GET_PARTIAL_INDEX(value);

                /* initialize */
                fromUTableUChars = (CharBuffer) ARRAY(cx, EXT_FROM_U_UCHARS_INDEX, char.class);
                fromUTableValues = (IntBuffer) ARRAY(cx, EXT_FROM_U_VALUES_INDEX, int.class);

                matchValue = 0;
                i = j = matchLength = 0;

                /* we must not remember fallback matches when not using fallbacks */

                /* match input units until there is a full match or the input is consumed */
                for (;;) {
                    /* go to the next section */
                    int oldpos = fromUTableUChars.position();
                    fromUSectionUChars = ((CharBuffer) fromUTableUChars.position(index)).slice();
                    fromUTableUChars.position(oldpos);
                    oldpos = fromUTableValues.position();
                    fromUSectionValues = ((IntBuffer) fromUTableValues.position(index)).slice();
                    fromUTableValues.position(oldpos);

                    /* read first pair of the section */
                    length = fromUSectionUChars.get();
                    value = fromUSectionValues.get();
                    if (value != 0 && (FROM_U_IS_ROUNDTRIP(value) || isFromUUseFallback(isUseFallback, firstCP))) {
                        /* remember longest match so far */
                        matchValue = value;
                        matchLength = 2 + i + j;
                    }

                    /* match pre[] then src[] */
                    if (i < preLength) {
                        c = preArray[preArrayBegin + i++];
                    } else if (source != null && j < source.remaining()) {
                        c = source.get(source.position() + j++);
                    } else {
                        /* all input consumed, partial match */
                        if (flush || (length = (i + j)) > MAX_UCHARS) {
                            /*
                             * end of the entire input stream, stop with the longest match so far or: partial match must
                             * not be longer than UCNV_EXT_MAX_UCHARS because it must fit into state buffers
                             */
                            break;
                        } else {
                            /* continue with more input next time */
                            return -(2 + length);
                        }
                    }

                    /* search for the current UChar */
                    index = findFromU(fromUSectionUChars, length, c);
                    if (index < 0) {
                        /* no match here, stop with the longest match so far */
                        break;
                    } else {
                        value = fromUSectionValues.get(fromUSectionValues.position() + index);
                        if (FROM_U_IS_PARTIAL(value)) {
                            /* partial match, continue */
                            index = FROM_U_GET_PARTIAL_INDEX(value);
                        } else {
                            if (FROM_U_IS_ROUNDTRIP(value) || isFromUUseFallback(isUseFallback, firstCP)) {
                                /* full match, stop with result */
                                matchValue = value;
                                matchLength = 2 + i + j;
                            } else {
                                /* full match on fallback not taken, stop with the longest match so far */
                            }
                            break;
                        }
                    }
                }

                if (matchLength == 0) {
                    /* no match at all */
                    return 0;
                }
            } else /* result from firstCP trie lookup */{
                if (FROM_U_IS_ROUNDTRIP(value) || isFromUUseFallback(isUseFallback, firstCP)) {
                    /* full match, stop with result */
                    matchValue = value;
                    matchLength = 2;
                } else {
                    /* fallback not taken */
                    return 0;
                }
            }

            if ((matchValue & FROM_U_RESERVED_MASK) != 0) {
                /* do not interpret values with reserved bits used, for forward compatibility */
                return 0;
            }

            /* return result */
            if (matchValue == FROM_U_SUBCHAR1) {
                return 1; /* assert matchLength==2 */
            }

            pMatchValue[0] = FROM_U_MASK_ROUNDTRIP(matchValue);
            return matchLength;
        }

        private int simpleMatchFromU(int cp, int[] pValue, boolean isUseFallback) {
            int[] value = new int[1];
            int match; // signed

            /* try to match */
            match = matchFromU(cp, null, 0, 0, null, value, isUseFallback, true);
            if (match >= 2) {
                /* write result for simple, single-character conversion */
                int length;
                boolean isRoundtrip;

                isRoundtrip = FROM_U_IS_ROUNDTRIP(value[0]);
                length = FROM_U_GET_LENGTH(value[0]);
                value[0] = FROM_U_GET_DATA(value[0]);

                if (length <= EXT_FROM_U_MAX_DIRECT_LENGTH) {
                    pValue[0] = value[0];
                    return isRoundtrip ? length : -length;
                    // #if 0 /* not currently used */
                    // } else if(length==4) {
                    // /* de-serialize a 4-byte result */
                    // const uint8_t *result=UCNV_EXT_ARRAY(cx, UCNV_EXT_FROM_U_BYTES_INDEX, uint8_t)+value;
                    // *pValue=
                    // ((uint32_t)result[0]<<24)|
                    // ((uint32_t)result[1]<<16)|
                    // ((uint32_t)result[2]<<8)|
                    // result[3];
                    // return isRoundtrip ? 4 : -4;
                    // #endif
                }
            }

            /*
             * return no match because - match>1 && resultLength>4: result too long for simple conversion - match==1: no
             * match found, <subchar1> preferred - match==0: no match found in the first place - match<0: partial
             * match, not supported for simple conversion (and flush==TRUE)
             */
            return 0;
        }

        @SuppressWarnings("fallthrough")
        private CoderResult writeFromU(int value, ByteBuffer target, IntBuffer offsets, int srcIndex) {
            ByteBuffer cx = sharedData.mbcs.extIndexes;

            byte bufferArray[] = new byte[1 + MAX_BYTES];
            int bufferArrayIndex = 0;
            byte[] resultArray;
            int resultArrayIndex;
            int length, prevLength;

            length = FROM_U_GET_LENGTH(value);
            value = FROM_U_GET_DATA(value);

            /* output the result */
            if (length <= FROM_U_MAX_DIRECT_LENGTH) {
                /*
                 * Generate a byte array and then write it below. This is not the fastest possible way, but it should be
                 * ok for extension mappings, and it is much simpler. Offset and overflow handling are only done once
                 * this way.
                 */
                int p = bufferArrayIndex + 1; /* reserve buffer[0] for shiftByte below */
                switch (length) {
                case 3:
                    bufferArray[p++] = (byte) (value >>> 16);
                case 2:
                    bufferArray[p++] = (byte) (value >>> 8);
                case 1:
                    bufferArray[p++] = (byte) value;
                default:
                    break; /* will never occur */
                }
                resultArray = bufferArray;
                resultArrayIndex = bufferArrayIndex + 1;
            } else {
                byte[] slice = new byte[length];

                ByteBuffer bb = ((ByteBuffer) ARRAY(cx, EXT_FROM_U_BYTES_INDEX, byte.class));
                bb.position(value);
                bb.get(slice, 0, slice.length);

                resultArray = slice;
                resultArrayIndex = 0;
            }

            /* with correct data we have length>0 */

            if ((prevLength = fromUnicodeStatus) != 0) {
                /* handle SI/SO stateful output */
                byte shiftByte;

                if (prevLength > 1 && length == 1) {
                    /* change from double-byte mode to single-byte */
                    shiftByte = (byte) UConverterConstants.SI;
                    fromUnicodeStatus = 1;
                } else if (prevLength == 1 && length > 1) {
                    /* change from single-byte mode to double-byte */
                    shiftByte = (byte) UConverterConstants.SO;
                    fromUnicodeStatus = 2;
                } else {
                    shiftByte = 0;
                }

                if (shiftByte != 0) {
                    /* prepend the shift byte to the result bytes */
                    bufferArray[0] = shiftByte;
                    if (resultArray != bufferArray || resultArrayIndex != bufferArrayIndex + 1) {
                        System.arraycopy(resultArray, resultArrayIndex, bufferArray, bufferArrayIndex + 1, length);
                    }
                    resultArray = bufferArray;
                    resultArrayIndex = bufferArrayIndex;
                    ++length;
                }
            }

            return fromUWriteBytes(this, resultArray, resultArrayIndex, length, target, offsets, srcIndex);
        }

        /*
         * @return if(U_FAILURE) return the code point for cnv->fromUChar32 else return 0 after output has been written
         * to the target
         */
        private int fromU(int cp, CharBuffer source, ByteBuffer target, IntBuffer offsets, int sourceIndex,
                int length, boolean flush, CoderResult[] cr) {
            // ByteBuffer cx;

            useSubChar1 = false;

            if (sharedData.mbcs.extIndexes != null
                    && initialMatchFromU(cp, source, target, offsets, sourceIndex, flush, cr)) {
                return 0; /* an extension mapping handled the input */
            }

            /* GB 18030 */
            if ((options & MBCS_OPTION_GB18030) != 0) {
                int[] range;
                int i;

                for (i = 0; i < gb18030Ranges.length; ++i) {
                    range = gb18030Ranges[i];
                    if (range[0] <= cp && cp <= range[1]) {
                        /* found the Unicode code point, output the four-byte sequence for it */
                        int linear;
                        byte bytes[] = new byte[4];

                        /* get the linear value of the first GB 18030 code in this range */
                        linear = range[2] - LINEAR_18030_BASE;

                        /* add the offset from the beginning of the range */
                        linear += (cp - range[0]);

                        bytes[3] = (byte) (0x30 + linear % 10);
                        linear /= 10;
                        bytes[2] = (byte) (0x81 + linear % 126);
                        linear /= 126;
                        bytes[1] = (byte) (0x30 + linear % 10);
                        linear /= 10;
                        bytes[0] = (byte) (0x81 + linear);

                        /* output this sequence */
                        cr[0] = fromUWriteBytes(this, bytes, 0, 4, target, offsets, sourceIndex);
                        return 0;
                    }
                }
            }

            /* no mapping */
            cr[0] = CoderResult.unmappableForLength(length);
            return cp;
        }

        /*
         * target<targetLimit; set error code for overflow
         */
        private boolean initialMatchFromU(int cp, CharBuffer source, ByteBuffer target, IntBuffer offsets,
                int srcIndex, boolean flush, CoderResult[] cr) {
            int[] value = new int[1];
            int match;

            /* try to match */
            match = matchFromU(cp, null, 0, 0, source, value, useFallback, flush);

            /* reject a match if the result is a single byte for DBCS-only */
            if (match >= 2
                    && !(FROM_U_GET_LENGTH(value[0]) == 1 && sharedData.mbcs.outputType == MBCS_OUTPUT_DBCS_ONLY)) {
                /* advance src pointer for the consumed input */
                source.position(source.position() + match - 2); /* remove 2 for the initial code point */

                /* write result to target */
                cr[0] = writeFromU(value[0], target, offsets, srcIndex);
                return true;
            } else if (match < 0) {
                /* save state for partial match */
                int sArrayIndex;
                int j;

                /* copy the first code point */
                preFromUFirstCP = cp;

                /* now copy the newly consumed input */
                sArrayIndex = source.position();
                match = -match - 2; /* remove 2 for the initial code point */
                for (j = 0; j < match; ++j) {
                    preFromUArray[j] = source.get(sArrayIndex++);
                }
                source.position(sArrayIndex); /* same as *src=srcLimit; because we reached the end of input */
                preFromULength = (byte) match;
                return true;
            } else if (match == 1) {
                /* matched, no mapping but request for <subchar1> */
                useSubChar1 = true;
                return false;
            } else /* match==0 no match */{
                return false;
            }
        }

        CoderResult cnvMBCSFromUnicodeWithOffsets(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
            // Just call encodeLoop to remove duplicate code.
            return encodeLoop(source, target, offsets, flush);
        }

        /*
         * This version of ucnv_MBCSFromUnicode() is optimized for single-byte codepages that map only to and from the
         * BMP. In addition to single-byte/state optimizations, the offset calculations become much easier.
         */
        private CoderResult cnvMBCSSingleFromBMPWithOffsets(CharBuffer source, ByteBuffer target, IntBuffer offsets,
                boolean flush) {

            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex, lastSource;
            int targetCapacity, length;
            char[] table;
            char[] results;

            int c, sourceIndex;
            char value, minValue;

            /* set up the local pointers */
            sourceArrayIndex = source.position();
            targetCapacity = target.remaining();
            table = sharedData.mbcs.fromUnicodeTable;

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                results = sharedData.mbcs.swapLFNLFromUnicodeChars;
            } else {
                results = sharedData.mbcs.fromUnicodeChars;
            }

            if (useFallback) {
                /* use all roundtrip and fallback results */
                minValue = 0x800;
            } else {
                /* use only roundtrips and fallbacks from private-use characters */
                minValue = 0xc00;
            }

            /* get the converter state from UConverter */
            c = fromUChar32;

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = c == 0 ? 0 : -1;
            lastSource = sourceArrayIndex;

            /*
             * since the conversion here is 1:1 UChar:uint8_t, we need only one counter for the minimum of the
             * sourceLength and targetCapacity
             */
            length = source.limit() - sourceArrayIndex;
            if (length < targetCapacity) {
                targetCapacity = length;
            }

            boolean doloop = true;
            if (c != 0 && targetCapacity > 0) {
                SideEffectsSingleBMP x = new SideEffectsSingleBMP(c, sourceArrayIndex);
                doloop = getTrailSingleBMP(source, x, cr);
                c = x.c;
                sourceArrayIndex = x.sourceArrayIndex;
            }

            if (doloop) {
                while (targetCapacity > 0) {
                    /*
                     * Get a correct Unicode code point: a single UChar for a BMP code point or a matched surrogate pair
                     * for a "supplementary code point".
                     */
                    c = source.get(sourceArrayIndex++);
                    /*
                     * Do not immediately check for single surrogates: Assume that they are unassigned and check for
                     * them in that case. This speeds up the conversion of assigned characters.
                     */
                    /* convert the Unicode code point in c into codepage bytes */
                    value = MBCS_SINGLE_RESULT_FROM_U(table, results, c);

                    /* is this code point assigned, or do we use fallbacks? */
                    if (value >= minValue) {
                        /* assigned, write the output character bytes from value and length */
                        /* length==1 */
                        /* this is easy because we know that there is enough space */
                        target.put((byte) value);
                        --targetCapacity;

                        /* normal end of conversion: prepare for a new character */
                        c = 0;
                        continue;
                    } else if (!UTF16.isSurrogate((char) c)) {
                        /* normal, unassigned BMP character */
                    } else if (UTF16.isLeadSurrogate((char) c)) {
                        // getTrail:
                        SideEffectsSingleBMP x = new SideEffectsSingleBMP(c, sourceArrayIndex);
                        doloop = getTrailSingleBMP(source, x, cr);
                        c = x.c;
                        sourceArrayIndex = x.sourceArrayIndex;
                        if (!doloop)
                            break;
                    } else {
                        /* this is an unmatched trail code unit (2nd surrogate) */
                        /* callback(illegal) */
                        cr[0] = CoderResult.malformedForLength(1);
                        break;
                    }

                    /* c does not have a mapping */

                    /* get the number of code units for c to correctly advance sourceIndex */
                    length = UTF16.getCharCount(c);

                    /* set offsets since the start or the last extension */
                    if (offsets != null) {
                        int count = sourceArrayIndex - lastSource;

                        /* do not set the offset for this character */
                        count -= length;

                        while (count > 0) {
                            offsets.put(sourceIndex++);
                            --count;
                        }
                        /* offsets and sourceIndex are now set for the current character */
                    }

                    /* try an extension mapping */
                    lastSource = sourceArrayIndex;
                    source.position(sourceArrayIndex);
                    c = fromU(c, source, target, offsets, sourceIndex, length, flush, cr);
                    sourceArrayIndex = source.position();
                    sourceIndex += length + (sourceArrayIndex - lastSource);
                    lastSource = sourceArrayIndex;

                    if (cr[0].isError()) {
                        /* not mappable or buffer overflow */
                        break;
                    } else {
                        /* a mapping was written to the target, continue */

                        /* recalculate the targetCapacity after an extension mapping */
                        targetCapacity = target.remaining();
                        length = source.limit() - sourceArrayIndex;
                        if (length < targetCapacity) {
                            targetCapacity = length;
                        }
                    }
                }
            }

            if (sourceArrayIndex < source.limit() && !target.hasRemaining()) {
                /* target is full */
                cr[0] = CoderResult.OVERFLOW;
            }

            /* set offsets since the start or the last callback */
            if (offsets != null) {
                int count = sourceArrayIndex - lastSource;
                while (count > 0) {
                    offsets.put(sourceIndex++);
                    --count;
                }
            }

            /* set the converter state back into UConverter */
            fromUChar32 = c;

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }

        /* This version of ucnv_MBCSFromUnicodeWithOffsets() is optimized for single-byte codepages. */
        private CoderResult cnvMBCSSingleFromUnicodeWithOffsets(CharBuffer source, ByteBuffer target,
                IntBuffer offsets, boolean flush) {

            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex;

            char[] table;
            char[] results;

            int c;
            int sourceIndex, nextSourceIndex;

            char value, minValue;

            /* set up the local pointers */
            short uniMask;
            sourceArrayIndex = source.position();

            table = sharedData.mbcs.fromUnicodeTable;

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                results = sharedData.mbcs.swapLFNLFromUnicodeChars;
            } else {
                results = sharedData.mbcs.fromUnicodeChars;
            }

            if (useFallback) {
                /* use all roundtrip and fallback results */
                minValue = 0x800;
            } else {
                /* use only roundtrips and fallbacks from private-use characters */
                minValue = 0xc00;
            }
            // agljport:comment hasSupplementary only used in getTrail block which now simply repeats the mask operation
            uniMask = sharedData.mbcs.unicodeMask;

            /* get the converter state from UConverter */
            c = fromUChar32;

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = c == 0 ? 0 : -1;
            nextSourceIndex = 0;

            boolean doloop = true;
            boolean doread = true;
            if (c != 0 && target.hasRemaining()) {
                if (UTF16.isLeadSurrogate((char) c)) {
                    SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex, nextSourceIndex);
                    doloop = getTrailDouble(source, target, uniMask, x, flush, cr);
                    doread = x.doread;
                    c = x.c;
                    sourceArrayIndex = x.sourceArrayIndex;
                    sourceIndex = x.sourceIndex;
                    nextSourceIndex = x.nextSourceIndex;
                } else {
                    doread = false;
                }
            }

            if (doloop) {
                while (!doread || sourceArrayIndex < source.limit()) {
                    /*
                     * This following test is to see if available input would overflow the output. It does not catch
                     * output of more than one byte that overflows as a result of a multi-byte character or callback
                     * output from the last source character. Therefore, those situations also test for overflows and
                     * will then break the loop, too.
                     */
                    if (target.hasRemaining()) {
                        /*
                         * Get a correct Unicode code point: a single UChar for a BMP code point or a matched surrogate
                         * pair for a "supplementary code point".
                         */

                        if (doread) {
                            c = source.get(sourceArrayIndex++);
                            ++nextSourceIndex;
                            if (UTF16.isSurrogate((char) c)) {
                                if (UTF16.isLeadSurrogate((char) c)) {
                                    // getTrail:
                                    SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex,
                                            nextSourceIndex);
                                    doloop = getTrailDouble(source, target, uniMask, x, flush, cr);
                                    c = x.c;
                                    sourceArrayIndex = x.sourceArrayIndex;
                                    sourceIndex = x.sourceIndex;
                                    nextSourceIndex = x.nextSourceIndex;
                                    if (x.doread) {
                                        if (doloop)
                                            continue;
                                        else
                                            break;
                                    }
                                } else {
                                    /* this is an unmatched trail code unit (2nd surrogate) */
                                    /* callback(illegal) */
                                    cr[0] = CoderResult.malformedForLength(1);
                                    break;
                                }
                            }
                        } else {
                            doread = true;
                        }

                        /* convert the Unicode code point in c into codepage bytes */
                        value = MBCS_SINGLE_RESULT_FROM_U(table, results, c);

                        /* is this code point assigned, or do we use fallbacks? */
                        if (value >= minValue) {
                            /* assigned, write the output character bytes from value and length */
                            /* length==1 */
                            /* this is easy because we know that there is enough space */
                            target.put((byte) value);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                            }

                            /* normal end of conversion: prepare for a new character */
                            c = 0;
                            sourceIndex = nextSourceIndex;
                        } else { /* unassigned */
                            /* try an extension mapping */
                            SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex,
                                    nextSourceIndex);
                            doloop = unassignedDouble(source, target, x, flush, cr);
                            c = x.c;
                            sourceArrayIndex = x.sourceArrayIndex;
                            sourceIndex = x.sourceIndex;
                            nextSourceIndex = x.nextSourceIndex;
                            if (!doloop)
                                break;
                        }
                    } else {
                        /* target is full */
                        cr[0] = CoderResult.OVERFLOW;
                        break;
                    }
                }
            }

            /* set the converter state back into UConverter */
            fromUChar32 = c;

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }

        /* This version of ucnv_MBCSFromUnicodeWithOffsets() is optimized for double-byte codepages. */
        private CoderResult cnvMBCSDoubleFromUnicodeWithOffsets(CharBuffer source, ByteBuffer target,
                IntBuffer offsets, boolean flush) {
            CoderResult[] cr = { CoderResult.UNDERFLOW };

            int sourceArrayIndex;

            char[] table;
            char[] chars;

            int c, sourceIndex, nextSourceIndex;

            int stage2Entry;
            int value;
            int length;
            short uniMask;

            /* use optimized function if possible */
            uniMask = sharedData.mbcs.unicodeMask;

            /* set up the local pointers */
            sourceArrayIndex = source.position();

            table = sharedData.mbcs.fromUnicodeTable;
            int[] tableInts = sharedData.mbcs.fromUnicodeTableInts;

            if ((options & UConverterConstants.OPTION_SWAP_LFNL) != 0) {
                chars = sharedData.mbcs.swapLFNLFromUnicodeChars;
            } else {
                chars = sharedData.mbcs.fromUnicodeChars;
            }

            /* get the converter state from UConverter */
            c = fromUChar32;

            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex = c == 0 ? 0 : -1;
            nextSourceIndex = 0;

            /* conversion loop */
            boolean doloop = true;
            boolean doread = true;
            if (c != 0 && target.hasRemaining()) {
                if (UTF16.isLeadSurrogate((char) c)) {
                    SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex, nextSourceIndex);
                    doloop = getTrailDouble(source, target, uniMask, x, flush, cr);
                    doread = x.doread;
                    c = x.c;
                    sourceArrayIndex = x.sourceArrayIndex;
                    sourceIndex = x.sourceIndex;
                    nextSourceIndex = x.nextSourceIndex;
                } else {
                    doread = false;
                }
            }

            if (doloop) {
                while (!doread || sourceArrayIndex < source.limit()) {
                    /*
                     * This following test is to see if available input would overflow the output. It does not catch
                     * output of more than one byte that overflows as a result of a multi-byte character or callback
                     * output from the last source character. Therefore, those situations also test for overflows and
                     * will then break the loop, too.
                     */
                    if (target.hasRemaining()) {
                        if (doread) {
                            /*
                             * Get a correct Unicode code point: a single UChar for a BMP code point or a matched
                             * surrogate pair for a "supplementary code point".
                             */
                            c = source.get(sourceArrayIndex++);
                            ++nextSourceIndex;
                            /*
                             * This also tests if the codepage maps single surrogates. If it does, then surrogates are
                             * not paired but mapped separately. Note that in this case unmatched surrogates are not
                             * detected.
                             */
                            if (UTF16.isSurrogate((char) c) && (uniMask & UConverterConstants.HAS_SURROGATES) == 0) {
                                if (UTF16.isLeadSurrogate((char) c)) {
                                    // getTrail:
                                    SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex,
                                            nextSourceIndex);
                                    doloop = getTrailDouble(source, target, uniMask, x, flush, cr);
                                    c = x.c;
                                    sourceArrayIndex = x.sourceArrayIndex;
                                    sourceIndex = x.sourceIndex;
                                    nextSourceIndex = x.nextSourceIndex;

                                    if (x.doread) {
                                        if (doloop)
                                            continue;
                                        else
                                            break;
                                    }
                                } else {
                                    /* this is an unmatched trail code unit (2nd surrogate) */
                                    /* callback(illegal) */
                                    cr[0] = CoderResult.malformedForLength(1);
                                    break;
                                }
                            }
                        } else {
                            doread = true;
                        }

                        /* convert the Unicode code point in c into codepage bytes */
                        stage2Entry = MBCS_STAGE_2_FROM_U(table, tableInts, c);

                        /* get the bytes and the length for the output */
                        /* MBCS_OUTPUT_2 */
                        value = MBCS_VALUE_2_FROM_STAGE_2(chars, stage2Entry, c);
                        if (value <= 0xff) {
                            length = 1;
                        } else {
                            length = 2;
                        }

                        /* is this code point assigned, or do we use fallbacks? */
                        if (!(MBCS_FROM_U_IS_ROUNDTRIP(stage2Entry, c) || (isFromUUseFallback(c) && value != 0))) {
                            /*
                             * We allow a 0 byte output if the "assigned" bit is set for this entry. There is no way
                             * with this data structure for fallback output to be a zero byte.
                             */

                            // unassigned:
                            SideEffectsDouble x = new SideEffectsDouble(c, sourceArrayIndex, sourceIndex,
                                    nextSourceIndex);

                            doloop = unassignedDouble(source, target, x, flush, cr);
                            c = x.c;
                            sourceArrayIndex = x.sourceArrayIndex;
                            sourceIndex = x.sourceIndex;
                            nextSourceIndex = x.nextSourceIndex;
                            if (doloop)
                                continue;
                            else
                                break;
                        }

                        /* write the output character bytes from value and length */
                        /* from the first if in the loop we know that targetCapacity>0 */
                        if (length == 1) {
                            /* this is easy because we know that there is enough space */
                            target.put((byte) value);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                            }
                        } else /* length==2 */{
                            target.put((byte) (value >>> 8));
                            if (2 <= target.remaining()) {
                                target.put((byte) value);
                                if (offsets != null) {
                                    offsets.put(sourceIndex);
                                    offsets.put(sourceIndex);
                                }
                            } else {
                                if (offsets != null) {
                                    offsets.put(sourceIndex);
                                }
                                errorBuffer[0] = (byte) value;
                                errorBufferLength = 1;

                                /* target overflow */
                                cr[0] = CoderResult.OVERFLOW;
                                c = 0;
                                break;
                            }
                        }

                        /* normal end of conversion: prepare for a new character */
                        c = 0;
                        sourceIndex = nextSourceIndex;
                        continue;
                    } else {
                        /* target is full */
                        cr[0] = CoderResult.OVERFLOW;
                        break;
                    }
                }
            }

            /* set the converter state back into UConverter */
            fromUChar32 = c;

            /* write back the updated pointers */
            source.position(sourceArrayIndex);

            return cr[0];
        }

        private final class SideEffectsSingleBMP {
            int c, sourceArrayIndex;

            SideEffectsSingleBMP(int c_, int sourceArrayIndex_) {
                c = c_;
                sourceArrayIndex = sourceArrayIndex_;
            }
        }

        // function made out of block labeled getTrail in ucnv_MBCSSingleFromUnicodeWithOffsets
        // assumes input c is lead surrogate
        private final boolean getTrailSingleBMP(CharBuffer source, SideEffectsSingleBMP x, CoderResult[] cr) {
            if (x.sourceArrayIndex < source.limit()) {
                /* test the following code unit */
                char trail = source.get(x.sourceArrayIndex);
                if (UTF16.isTrailSurrogate(trail)) {
                    ++x.sourceArrayIndex;
                    x.c = UCharacter.getCodePoint((char) x.c, trail);
                    /* this codepage does not map supplementary code points */
                    /* callback(unassigned) */
                    cr[0] = CoderResult.unmappableForLength(2);
                    return false;
                } else {
                    /* this is an unmatched lead code unit (1st surrogate) */
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(1);
                    return false;
                }
            } else {
                /* no more input */
                return false;
            }
            // return true;
        }

        private final class SideEffects {
            int c, sourceArrayIndex, sourceIndex, nextSourceIndex, prevSourceIndex, prevLength;
            boolean doread = true;

            SideEffects(int c_, int sourceArrayIndex_, int sourceIndex_, int nextSourceIndex_, int prevSourceIndex_,
                    int prevLength_) {
                c = c_;
                sourceArrayIndex = sourceArrayIndex_;
                sourceIndex = sourceIndex_;
                nextSourceIndex = nextSourceIndex_;
                prevSourceIndex = prevSourceIndex_;
                prevLength = prevLength_;
            }
        }

        // function made out of block labeled getTrail in ucnv_MBCSFromUnicodeWithOffsets
        // assumes input c is lead surrogate
        private final boolean getTrail(CharBuffer source, ByteBuffer target, int uniMask, SideEffects x,
                boolean flush, CoderResult[] cr) {
            if (x.sourceArrayIndex < source.limit()) {
                /* test the following code unit */
                char trail = source.get(x.sourceArrayIndex);
                if (UTF16.isTrailSurrogate(trail)) {
                    ++x.sourceArrayIndex;
                    ++x.nextSourceIndex;
                    /* convert this supplementary code point */
                    x.c = UCharacter.getCodePoint((char) x.c, trail);
                    if ((uniMask & UConverterConstants.HAS_SUPPLEMENTARY) == 0) {
                        /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
                        fromUnicodeStatus = x.prevLength; /* save the old state */
                        /* callback(unassigned) */
                        x.doread = true;
                        return unassigned(source, target, null, x, flush, cr);
                    } else {
                        x.doread = false;
                        return true;
                    }
                } else {
                    /* this is an unmatched lead code unit (1st surrogate) */
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(1);
                    return false;
                }
            } else {
                /* no more input */
                return false;
            }
        }

        // function made out of block labeled unassigned in ucnv_MBCSFromUnicodeWithOffsets
        private final boolean unassigned(CharBuffer source, ByteBuffer target, IntBuffer offsets, SideEffects x,
                boolean flush, CoderResult[] cr) {
            /* try an extension mapping */
            int sourceBegin = x.sourceArrayIndex;
            source.position(x.sourceArrayIndex);
            x.c = fromU(x.c, source, target, null, x.sourceIndex, x.nextSourceIndex, flush, cr);
            x.sourceArrayIndex = source.position();
            x.nextSourceIndex += x.sourceArrayIndex - sourceBegin;
            x.prevLength = fromUnicodeStatus;

            if (cr[0].isError()) {
                /* not mappable or buffer overflow */
                return false;
            } else {
                /* a mapping was written to the target, continue */

                /* recalculate the targetCapacity after an extension mapping */
                // x.targetCapacity=pArgs.targetLimit-x.targetArrayIndex;
                /* normal end of conversion: prepare for a new character */
                if (offsets != null) {
                    x.prevSourceIndex = x.sourceIndex;
                    x.sourceIndex = x.nextSourceIndex;
                }
                return true;
            }
        }

        private final class SideEffectsDouble {
            int c, sourceArrayIndex, sourceIndex, nextSourceIndex;
            boolean doread = true;

            SideEffectsDouble(int c_, int sourceArrayIndex_, int sourceIndex_, int nextSourceIndex_) {
                c = c_;
                sourceArrayIndex = sourceArrayIndex_;
                sourceIndex = sourceIndex_;
                nextSourceIndex = nextSourceIndex_;
            }
        }

        // function made out of block labeled getTrail in ucnv_MBCSDoubleFromUnicodeWithOffsets
        // assumes input c is lead surrogate
        private final boolean getTrailDouble(CharBuffer source, ByteBuffer target, int uniMask,
                SideEffectsDouble x, boolean flush, CoderResult[] cr) {
            if (x.sourceArrayIndex < source.limit()) {
                /* test the following code unit */
                char trail = source.get(x.sourceArrayIndex);
                if (UTF16.isTrailSurrogate(trail)) {
                    ++x.sourceArrayIndex;
                    ++x.nextSourceIndex;
                    /* convert this supplementary code point */
                    x.c = UCharacter.getCodePoint((char) x.c, trail);
                    if ((uniMask & UConverterConstants.HAS_SUPPLEMENTARY) == 0) {
                        /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
                        /* callback(unassigned) */
                        x.doread = true;
                        return unassignedDouble(source, target, x, flush, cr);
                    } else {
                        x.doread = false;
                        return true;
                    }
                } else {
                    /* this is an unmatched lead code unit (1st surrogate) */
                    /* callback(illegal) */
                    cr[0] = CoderResult.malformedForLength(1);
                    return false;
                }
            } else {
                /* no more input */
                return false;
            }
        }

        // function made out of block labeled unassigned in ucnv_MBCSDoubleFromUnicodeWithOffsets
        private final boolean unassignedDouble(CharBuffer source, ByteBuffer target, SideEffectsDouble x,
                boolean flush, CoderResult[] cr) {
            /* try an extension mapping */
            int sourceBegin = x.sourceArrayIndex;
            source.position(x.sourceArrayIndex);
            x.c = fromU(x.c, source, target, null, x.sourceIndex, x.nextSourceIndex, flush, cr);
            x.sourceArrayIndex = source.position();
            x.nextSourceIndex += x.sourceArrayIndex - sourceBegin;

            if (cr[0].isError()) {
                /* not mappable or buffer overflow */
                return false;
            } else {
                /* a mapping was written to the target, continue */

                /* recalculate the targetCapacity after an extension mapping */
                // x.targetCapacity=pArgs.targetLimit-x.targetArrayIndex;
                /* normal end of conversion: prepare for a new character */
                x.sourceIndex = x.nextSourceIndex;
                return true;
            }
        }

        /**
         * Overrides super class method
         *
         * @param encoder
         * @param source
         * @param target
         * @param offsets
         * @return
         */
        @Override
        protected CoderResult cbFromUWriteSub(CharsetEncoderICU encoder, CharBuffer source, ByteBuffer target,
                IntBuffer offsets) {
            CharsetMBCS cs = (CharsetMBCS) encoder.charset();
            byte[] subchar;
            int length;

            if (cs.subChar1 != 0
                    && (cs.sharedData.mbcs.extIndexes != null ? encoder.useSubChar1
                            : (encoder.invalidUCharBuffer[0] <= 0xff))) {
                /*
                 * select subChar1 if it is set (not 0) and the unmappable Unicode code point is up to U+00ff (IBM MBCS
                 * behavior)
                 */
                subchar = new byte[] { cs.subChar1 };
                length = 1;
            } else {
                /* select subChar in all other cases */
                subchar = cs.subChar;
                length = cs.subCharLen;
            }

            /* reset the selector for the next code point */
            encoder.useSubChar1 = false;

            if (cs.sharedData.mbcs.outputType == MBCS_OUTPUT_2_SISO) {
                byte[] buffer = new byte[4];
                int i = 0;

                /* fromUnicodeStatus contains prevLength */
                switch (length) {
                case 1:
                    if (encoder.fromUnicodeStatus == 2) {
                        /* DBCS mode and SBCS sub char: change to SBCS */
                        encoder.fromUnicodeStatus = 1;
                        buffer[i++] = UConverterConstants.SI;
                    }
                    buffer[i++] = subchar[0];
                    break;
                case 2:
                    if (encoder.fromUnicodeStatus <= 1) {
                        /* SBCS mode and DBCS sub char: change to DBCS */
                        encoder.fromUnicodeStatus = 2;
                        buffer[i++] = UConverterConstants.SO;
                    }
                    buffer[i++] = subchar[0];
                    buffer[i++] = subchar[1];
                    break;
                default:
                    throw new IllegalArgumentException();
                }

                subchar = buffer;
                length = i;
            }
            return CharsetEncoderICU.fromUWriteBytes(encoder, subchar, 0, length, target, offsets, source.position());
        }

        /**
         * Gets called whenever CharsetEncoder.replaceWith gets called. allowReplacementChanges only allows subChar and
         * subChar1 to be modified outside construction (since replaceWith is called once during construction).
         *
         * @param replacement
         *            The replacement for subchar.
         */
        @Override
        protected void implReplaceWith(byte[] replacement) {
            if (allowReplacementChanges) {
                CharsetMBCS cs = (CharsetMBCS) this.charset();

                System.arraycopy(replacement, 0, cs.subChar, 0, replacement.length);
                cs.subCharLen = (byte) replacement.length;
                cs.subChar1 = 0;
            }
        }
    }

    @Override
    public CharsetDecoder newDecoder() {
        return new CharsetDecoderMBCS(this);
    }

    @Override
    public CharsetEncoder newEncoder() {
        return new CharsetEncoderMBCS(this);
    }

    @SuppressWarnings("fallthrough")
    void MBCSGetFilteredUnicodeSetForUnicode(UConverterSharedData data, UnicodeSet setFillIn, int which, int filter){
        UConverterMBCSTable mbcsTable;
        char[] table;
        char st1,maxStage1, st2;
        int st3;
        int c ;

        mbcsTable = data.mbcs;
        table = mbcsTable.fromUnicodeTable;
        if(mbcsTable.hasSupplementary()){
            maxStage1 = 0x440;
        }
        else{
            maxStage1 = 0x40;
        }
        c=0; /* keep track of current code point while enumerating */

        if(mbcsTable.outputType==MBCS_OUTPUT_1){
            char stage2, stage3;
            char minValue;
            char[] results = mbcsTable.fromUnicodeChars;

            if(which==ROUNDTRIP_SET) {
                /* use only roundtrips */
                minValue=0xf00;
            } else {
                /* use all roundtrip and fallback results */
                minValue=0x800;
            }
            for(st1=0;st1<maxStage1;++st1){
                st2 = table[st1];
                if(st2>maxStage1){
                    stage2 = st2;
                    for(st2=0; st2<64; ++st2){
                        st3 = table[stage2 + st2];
                        if(st3!=0){
                            /*read the stage 3 block */
                            stage3 = (char)st3;
                            do {
                                if(results[stage3++]>=minValue){
                                     setFillIn.add(c);
                                }
                            }while((++c&0xf) !=0);
                          } else {
                            c+= 16; /*empty stage 2 block */
                        }
                    }
                } else {
                    c+=1024; /* empty stage 2 block */
                }
            }
        } else {
            int[] tableInts = mbcsTable.fromUnicodeTableInts;
            int stage2,stage3;
            byte[] bytes;
            int st3Multiplier;
            int value;
            boolean useFallBack;
            bytes = mbcsTable.fromUnicodeBytes;
            char[] chars = mbcsTable.fromUnicodeChars;
            int[] ints = mbcsTable.fromUnicodeInts;
            useFallBack = (which == ROUNDTRIP_AND_FALLBACK_SET);
            switch(mbcsTable.outputType) {
            case MBCS_OUTPUT_3:
            case MBCS_OUTPUT_4_EUC:
                st3Multiplier = 3;
                break;
            case MBCS_OUTPUT_4:
                st3Multiplier =4;
                break;
            default:
                st3Multiplier =2;
                break;
            }

            for(st1=0;st1<maxStage1;++st1){
                st2 = table[st1];
                if(st2>(maxStage1>>1)){
                    stage2 =  st2 ;
                    for(st2=0;st2<64;++st2){
                        /*read the stage 3 block */
                        st3 = tableInts[stage2 + st2];
                        if(st3!=0){
                        //if((st3=table[stage2+st2])!=0){
                            stage3 = st3Multiplier*16*(st3&UConverterConstants.UNSIGNED_SHORT_MASK);

                            /* get the roundtrip flags for the stage 3 block */
                            st3>>>=16;
                            switch(filter) {
                            case UCNV_SET_FILTER_NONE:
                                do {
                                   if((st3&1)!=0){
                                        setFillIn.add(c);
                                   }else if (useFallBack) {
                                        int b =0;
                                        switch(st3Multiplier) {
                                        case 4:
                                            b = ints[stage3 / 4];
                                            break;
                                        case 3:
                                            b |= bytes[stage3] | bytes[stage3 + 1] | bytes[stage3 + 2];
                                            break;
                                        case 2:
                                            b = chars[stage3 / 2];
                                            break;
                                        default:
                                            break;
                                        }
                                        stage3+=st3Multiplier;
                                        if(b!=0) {
                                            setFillIn.add(c);
                                        }
                                    }
                                    st3>>=1;
                                }while((++c&0xf)!=0);
                                break;
                            case UCNV_SET_FILTER_DBCS_ONLY:
                                /* Ignore single bytes results (<0x100). */
                                do {
                                    if(((st3&1) != 0 || useFallBack) && chars[stage3 / 2] >= 0x100){
                                        setFillIn.add(c);
                                    }
                                    st3>>=1;
                                    stage3+=2;
                                }while((++c&0xf) != 0);
                               break;
                            case UCNV_SET_FILTER_2022_CN :
                                /* only add code points that map to CNS 11643 planes 1&2 for non-EXT ISO-2202-CN. */
                                do {
                                    if(((st3&1) != 0 || useFallBack) &&
                                            ((value= (UConverterConstants.UNSIGNED_BYTE_MASK & bytes[stage3]))==0x81 || value==0x82) ){
                                        setFillIn.add(c);
                                    }
                                    st3>>=1;
                                    stage3+=3;
                                }while((++c&0xf)!=0);
                                break;
                            case UCNV_SET_FILTER_SJIS:
                                /* only add code points that map tp Shift-JIS codes corrosponding to JIS X 0280. */
                                do{
                                    if(((st3&1) != 0 || useFallBack) && (value=chars[stage3 / 2])>=0x8140 && value<=0xeffc){
                                        setFillIn.add(c);
                                    }
                                    st3>>=1;
                                    stage3+=2;
                                }while((++c&0xf)!=0);
                                break;
                            case UCNV_SET_FILTER_GR94DBCS:
                                /* only add code points that maps to ISO 2022 GR 94 DBCS codes*/
                                do {
                                    if(((st3&1) != 0 || useFallBack) &&
                                            (UConverterConstants.UNSIGNED_SHORT_MASK & ((value=chars[stage3 / 2])- 0xa1a1))<=(0xfefe - 0xa1a1) &&
                                            (UConverterConstants.UNSIGNED_BYTE_MASK & (value - 0xa1)) <= (0xfe - 0xa1)){
                                        setFillIn.add(c);
                                    }
                                    st3>>=1;
                                    stage3+=2;
                                }while((++c&0xf)!=0);
                                break;
                            case UCNV_SET_FILTER_HZ:
                                /*Only add code points that are suitable for HZ DBCS*/
                                do {
                                    if( ((st3&1) != 0 || useFallBack) &&
                                            (UConverterConstants.UNSIGNED_SHORT_MASK & ((value=chars[stage3 / 2])-0xa1a1))<=(0xfdfe - 0xa1a1) &&
                                            (UConverterConstants.UNSIGNED_BYTE_MASK & (value - 0xa1)) <= (0xfe - 0xa1)){
                                        setFillIn.add(c);
                                    }
                                    st3>>=1;
                                    stage3+=2;
                                }while((++c&0xf) != 0);
                                break;
                            default:
                                return;
                            }
                        } else {
                            c+=16; /* empty stage 3 block */
                        }
                    }
                } else {
                    c+=1024; /*empty stage2 block */
                }
            }
        }
        extGetUnicodeSet(setFillIn, which, filter, data);
    }

    static void extGetUnicodeSetString(ByteBuffer cx,UnicodeSet setFillIn, boolean useFallback,
        int minLength, int c, char s[],int length,int sectionIndex){
        CharBuffer fromUSectionUChar;
        IntBuffer fromUSectionValues;
        fromUSectionUChar = (CharBuffer)ARRAY(cx, EXT_FROM_U_UCHARS_INDEX,char.class );
        fromUSectionValues = (IntBuffer)ARRAY(cx, EXT_FROM_U_VALUES_INDEX,int.class );
        int fromUSectionUCharIndex = fromUSectionUChar.position()+sectionIndex;
        int fromUSectionValuesIndex = fromUSectionValues.position()+sectionIndex;
        int value, i, count;

        /* read first pair of the section */
       count = fromUSectionUChar.get(fromUSectionUCharIndex++);
       value = fromUSectionValues.get(fromUSectionValuesIndex++);
       if(value!=0 && (FROM_U_IS_ROUNDTRIP(value) || useFallback) && FROM_U_GET_LENGTH(value)>=minLength) {
           if(c>=0){
               setFillIn.add(c);
           } else {
               StringBuilder normalizedStringBuilder = new StringBuilder();
               for(int j=0; j<length;j++){
                   normalizedStringBuilder.append(s[j]);
               }
               String normalizedString = normalizedStringBuilder.toString();
               for(int j=0;j<length;j++){
                   setFillIn.add(normalizedString);
               }
             }
       }

       for(i=0; i<count; ++i){
           s[length] = fromUSectionUChar.get(fromUSectionUCharIndex + i);
           value = fromUSectionValues.get(fromUSectionValuesIndex + i);

           if(value==0) {
               /* no mapping, do nothing */
           } else if (FROM_U_IS_PARTIAL(value)) {
               extGetUnicodeSetString( cx, setFillIn, useFallback, minLength, UConverterConstants.U_SENTINEL, s, length+1,
                       FROM_U_GET_PARTIAL_INDEX(value));
           } else if ((useFallback ? (value&FROM_U_RESERVED_MASK)==0:((value&(FROM_U_ROUNDTRIP_FLAG|FROM_U_RESERVED_MASK))==FROM_U_ROUNDTRIP_FLAG))
                   && FROM_U_GET_LENGTH(value)>=minLength) {
               StringBuilder normalizedStringBuilder = new StringBuilder(); // String for composite characters
               for(int j=0; j<(length+1);j++){
                   normalizedStringBuilder.append(s[j]);
               }
             setFillIn.add(normalizedStringBuilder.toString());
           }
       }

    }


    static void extGetUnicodeSet(UnicodeSet setFillIn, int which, int filter, UConverterSharedData Data){
        int st1, stage1Length, st2, st3, minLength;
        int ps2, ps3;

        CharBuffer stage12, stage3;
        int value, length;
        IntBuffer stage3b;
        boolean useFallback;
        char s[] = new char[MAX_UCHARS];
        int c;
        ByteBuffer cx = Data.mbcs.extIndexes;
        if(cx == null){
            return;
        }
        stage12 = (CharBuffer)ARRAY(cx, EXT_FROM_U_STAGE_12_INDEX,char.class );
        stage3 = (CharBuffer)ARRAY(cx, EXT_FROM_U_STAGE_3_INDEX,char.class );
        stage3b = (IntBuffer)ARRAY(cx, EXT_FROM_U_STAGE_3B_INDEX,int.class );

        stage1Length = cx.asIntBuffer().get(EXT_FROM_U_STAGE_1_LENGTH);
        useFallback = (which==ROUNDTRIP_AND_FALLBACK_SET);

        c = 0;
        if(filter == UCNV_SET_FILTER_2022_CN) {
            minLength = 3;
        } else if (Data.mbcs.outputType == MBCS_OUTPUT_DBCS_ONLY || filter != UCNV_SET_FILTER_NONE) {
            /* DBCS-only, ignore single-byte results */
            minLength = 2;
        } else {
            minLength = 1;
        }

        for(st1=0; st1< stage1Length; ++st1){
            st2 = stage12.get(st1);
            if(st2>stage1Length) {
                ps2 = st2;
                for(st2=0;st2<64;++st2){
                    st3=(stage12.get(ps2+st2))<<STAGE_2_LEFT_SHIFT;
                    if(st3!= 0){
                        ps3 = st3;
                        do {
                            value = stage3b.get(stage3.get(ps3++));
                            if(value==0){
                                /* no mapping do nothing */
                            }else if (FROM_U_IS_PARTIAL(value)){
                                length = 0;
                                length=UTF16.append(s, length, c);
                                extGetUnicodeSetString(cx,setFillIn,useFallback,minLength,c,s,length,FROM_U_GET_PARTIAL_INDEX(value));
                            } else if ((useFallback ?  (value&FROM_U_RESERVED_MASK)==0 :((value&(FROM_U_ROUNDTRIP_FLAG|FROM_U_RESERVED_MASK))== FROM_U_ROUNDTRIP_FLAG)) &&
                                    FROM_U_GET_LENGTH(value)>=minLength){

                                switch(filter) {
                                case UCNV_SET_FILTER_2022_CN:
                                    if(!(FROM_U_GET_LENGTH(value)==3 && FROM_U_GET_DATA(value)<=0x82ffff)){
                                        continue;
                                    }
                                    break;
                                case UCNV_SET_FILTER_SJIS:
                                    if(!(FROM_U_GET_LENGTH(value)==2 && (value=FROM_U_GET_DATA(value))>=0x8140 && value<=0xeffc)){
                                        continue;
                                    }
                                    break;
                                case UCNV_SET_FILTER_GR94DBCS:
                                    if(!(FROM_U_GET_LENGTH(value)==2 && ((value=FROM_U_GET_DATA(value)) - 0xa1a1)<=(0xfefe - 0xa1a1)
                                            && (UConverterConstants.UNSIGNED_BYTE_MASK & (value - 0xa1))<= (0xfe - 0xa1))){
                                        continue;
                                    }
                                    break;
                                case UCNV_SET_FILTER_HZ:
                                    if(!(FROM_U_GET_LENGTH(value)==2 && ((value=FROM_U_GET_DATA(value)) - 0xa1a1)<=(0xfdfe - 0xa1a1)
                                            && (UConverterConstants.UNSIGNED_BYTE_MASK & (value - 0xa1))<= (0xfe - 0xa1))){
                                        continue;
                                    }
                                    break;
                                default:
                                    /*
                                     * UCNV_SET_FILTER_NONE,
                                     * or UCNV_SET_FILTER_DBCS_ONLY which is handled via minLength
                                     */
                                    break;
                                }
                                setFillIn.add(c);

                            }
                        }while((++c&0xf) != 0);

                    } else {
                        c+=16;   /* emplty stage3 block */
                    }
                }
            } else {
                c+=1024;  /* empty stage 2 block*/
            }
        }
    }

    void MBCSGetUnicodeSetForUnicode(UConverterSharedData data, UnicodeSet setFillIn, int which){
        MBCSGetFilteredUnicodeSetForUnicode(data, setFillIn, which,
                this.sharedData.mbcs.outputType==MBCS_OUTPUT_DBCS_ONLY ? UCNV_SET_FILTER_DBCS_ONLY : UCNV_SET_FILTER_NONE );
    }

    @Override
    void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
        if((options & MBCS_OPTION_GB18030)!=0){
            setFillIn.add(0, 0xd7ff);
            setFillIn.add(0xe000, 0x10ffff);
        }
        else {
            this.MBCSGetUnicodeSetForUnicode(sharedData, setFillIn, which);
        }
    }

}
