/**
         * Encodes characters starting at the current position of the given input
         * buffer, and writes the equivalent byte sequence into the given output
         * buffer from its current position.
         * <p>
         * The buffers' position will be changed with the reading and writing
         * operation, but their limits and marks will be kept intact.
         * <p>
         * A <code>CoderResult</code> instance will be returned according to
         * following rules:
         * <ul>
         * <li>A {@link CoderResult#malformedForLength(int) malformed input} result
         * indicates that some malformed input error was encountered, and the
         * erroneous characters start at the input buffer's position and their
         * number can be got by result's {@link CoderResult#length() length}. This
         * kind of result can be returned only if the malformed action is
         * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li>
         * <li>{@link CoderResult#UNDERFLOW CoderResult.UNDERFLOW} indicates that
         * as many characters as possible in the input buffer have been encoded. If
         * there is no further input and no characters left in the input buffer then
         * this task is complete. If this is not the case then the client should
         * call this method again supplying some more input characters.</li>
         * <li>{@link CoderResult#OVERFLOW CoderResult.OVERFLOW} indicates that the
         * output buffer has been filled, while there are still some characters
         * remaining in the input buffer. This method should be invoked again with a
         * non-full output buffer.</li>
         * <li>A {@link CoderResult#unmappableForLength(int) unmappable character}
         * result indicates that some unmappable character error was encountered,
         * and the erroneous characters start at the input buffer's position and
         * their number can be got by result's {@link CoderResult#length() length}.
         * This kind of result can be returned only on
         * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li>
         * </ul>
         * <p>
         * The <code>endOfInput</code> parameter indicates if the invoker can
         * provider further input. This parameter is true if and only if the
         * characters in the current input buffer are all inputs for this encoding
         * operation. Note that it is common and won't cause an error if the invoker
         * sets false and then has no more input available, while it may cause an
         * error if the invoker always sets true in several consecutive invocations.
         * This would make the remaining input to be treated as malformed input.
         * input.
         * <p>
         * This method invokes the
         * {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} method to
         * implement the basic encode logic for a specific charset.
         *
         * @param in
         *            the input buffer.
         * @param out
         *            the output buffer.
         * @param endOfInput
         *            true if all the input characters have been provided.
         * @return a <code>CoderResult</code> instance indicating the result.
         * @throws IllegalStateException
         *             if the encoding operation has already started or no more
         *             input is needed in this encoding process.
         * @throws CoderMalfunctionError
         *             If the {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop}
         *             method threw an <code>BufferUnderflowException</code> or
         *             <code>BufferUnderflowException</code>.
         */
        public CoderResult encode(java.nio.CharBuffer inJ, java.nio.ByteBuffer outJ, bool endOfInput)
        {
            //If the previous step is encode(CharBuffer), then no more input is needed
            // thus endOfInput should not be false
            if (status == READY && finished && !endOfInput) {
                throw new java.lang.IllegalStateException();
            }

            if ((status == FLUSH) || (!endOfInput && status == END)) {
                throw new java.lang.IllegalStateException();
            }

            CoderResult result;
            while (true) {
                try {
                    result = encodeLoop(inJ, outJ);
                } catch (BufferOverflowException e) {
                    throw new CoderMalfunctionError(e);
                } catch (BufferUnderflowException e) {
                    throw new CoderMalfunctionError(e);
                }
                if (result == CoderResult.UNDERFLOW) {
                    status = endOfInput ? END : ONGOING;
                    if (endOfInput) {
                        int remaining = inJ.remaining();
                        if (remaining > 0) {
                            result = CoderResult.malformedForLength(remaining);
                        } else {
                            return result;
                        }
                    } else {
                        return result;
                    }
                } else if (result==CoderResult.OVERFLOW) {
                    status = endOfInput ? END : ONGOING;
                    return result;
                }
                CodingErrorAction action = malformAction;
                if (result.isUnmappable()) {
                    action = unmapAction;
                }
                // If the action is IGNORE or REPLACE, we should continue
                // encoding.
                if (action == CodingErrorAction.REPLACE) {
                    if (outJ.remaining() < replace.Length) {
                        return CoderResult.OVERFLOW;
                    }
                    outJ.put(replace);
                } else {
                    if (action != CodingErrorAction.IGNORE) {
                        return result;
                    }
                }
                inJ.position(inJ.position() + result.length());
            }
        }
        //throws CharacterCodingException
        /**
         * This is a facade method for the decoding operation.
         * <p>
         * This method decodes the remaining byte sequence of the given byte buffer
         * into a new character buffer. This method performs a complete decoding
         * operation, resets at first, then decodes, and flushes at last.
         * <p>
         * This method should not be invoked while another {@code decode} operation
         * is ongoing.
         *
         * @param in
         *            the input buffer.
         * @return a new <code>CharBuffer</code> containing the the characters
         *         produced by this decoding operation. The buffer's limit will be
         *         the position of the last character in the buffer, and the
         *         position will be zero.
         * @throws IllegalStateException
         *             if another decoding operation is ongoing.
         * @throws MalformedInputException
         *             if an illegal input byte sequence for this charset was
         *             encountered, and the action for malformed error is
         *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}
         * @throws UnmappableCharacterException
         *             if a legal but unmappable input byte sequence for this
         *             charset was encountered, and the action for unmappable
         *             character error is
         *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.
         *             Unmappable means the byte sequence at the input buffer's
         *             current position cannot be mapped to a Unicode character
         *             sequence.
         * @throws CharacterCodingException
         *             if another exception happened during the decode operation.
         */
        public java.nio.CharBuffer decode(java.nio.ByteBuffer inJ)
        {
            reset();
            int length = (int) (inJ.remaining() * averChars);
            java.nio.CharBuffer output = java.nio.CharBuffer.allocate(length);
            CoderResult result = null;
            while (true) {
                result = decode(inJ, output, false);
                checkCoderResult(result);
                if (result.isUnderflow()) {
                    break;
                } else if (result.isOverflow()) {
                    output = allocateMore(output);
                }
            }
            result = decode(inJ, output, true);
            checkCoderResult(result);

            while (true) {
                result = flush(output);
                checkCoderResult(result);
                if (result.isOverflow()) {
                    output = allocateMore(output);
                } else {
                    break;
                }
            }

            output.flip();
            status = FLUSH;
            return output;
        }
 protected override java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer inJ, java.nio.CharBuffer outJ)
 {
     Encoding enc = this.cs.getEncoding();
     byte[] input = new byte[inJ.remaining()];
     inJ.get(input);
     char[] output = new char[input.Length * CharsetEncoderImpl.fiveValue];
     int size = enc.GetDecoder().GetChars(input, 0, input.Length, output, 0, true);
     outJ.put(output, 0, size);
     return java.nio.charset.CoderResult.UNDERFLOW;
 }