/*
 *******************************************************************************
 * Copyright (C) 2006-2014, 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.ICUResourceBundle;
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, ICUResourceBundle.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) {
                InputStream i = ICUData.getRequiredStream(loader, resourceName);
                b = ICUBinary.getByteBufferFromInputStream(i);
            } else if (!classPath.equals(ICUData.ICU_BUNDLE)) {
                InputStream i = ICUData.getRequiredStream(resourceName);
                b = ICUBinary.getByteBufferFromInputStream(i);
            } else {
                b = ICUBinary.getRequiredData(itemName);
            }
            reader = new UConverterDataReader(b);
            reader.readStaticData(staticData);
        } catch (IOException e) {
            throw new InvalidFormatException();
        } catch (Exception e) {
            throw new InvalidFormatException();
        }

        UConverterSharedData data = null;
        int type = staticData.conversionType;

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

        data = new UConverterSharedData(1, null, false, 0);
        data.dataReader = reader;
        data.staticData = staticData;
        data.sharedDataCached = false;

        // 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;
        long temp;

        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<=0x8effffff) {
                /* 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 = (int)(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 */
            temp = (1L<<(16+(c&0xf)));
            tableInts[stage2] |= temp;
        }
        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(((int) 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);
        }

        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();
        }

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

        @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
         */
        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.
         */
        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;
            }
        }
    }

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

    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=((int) 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 );
    }
    
    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);
        }
    }

}
