/*
 *******************************************************************************
 * Copyright (C) 2007-2011, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.charset;

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 com.ibm.icu.text.UnicodeSet;

/**
 * @author Michael Ow
 *
 */
class CharsetUTF7 extends CharsetICU {
    private final String IMAP_NAME="IMAP-mailbox-name";
    private boolean useIMAP;
    protected byte[] fromUSubstitution=new byte[]{0x3F};
   
    public CharsetUTF7(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
        super(icuCanonicalName, javaCanonicalName, aliases);
        maxBytesPerChar=4; /* max 3 bytes per code unit from UTF-7 (base64) */
        minBytesPerChar=1;
        maxCharsPerByte=1;
        
        useIMAP=false;
        
        if (icuCanonicalName.equals(IMAP_NAME)) {
            useIMAP=true;
        }
    }
    
    //private static boolean inSetD(char c) {
    //    return (
    //            (char)(c - 97) < 26 || (char)(c - 65) < 26 || /* letters */
    //            (char)(c - 48) < 10 ||                        /* digits */
    //            (char)(c - 39) < 3 ||                          /* ' () */
    //            (char)(c - 44) < 4 ||                          /* ,-./ */
    //            (c==58) || (c==63)            /* :? */
    //            );
    //}
    
    //private static boolean inSetO(char c) {
    //    return (
    //            (char)(c - 33) < 6 ||                           /* !"#$%& */
    //            (char)(c - 59) < 4 ||                           /* ;<=> */
    //            (char)(c - 93) < 4 ||                           /* ]^_` */
    //            (char)(c - 123) < 3 ||                         /* {|} */
    //            (c==58) || (c==63)             /* *@[ */
    //            );
    //}
    
    private static boolean isCRLFTAB(char c) {
        return (
                (c==13) || (c==10) || (c==9)
                );
    }
    
    //private static boolean isCRLFSPTAB(char c) {
    //   return (
    //            (c==32) || (c==13) || (c==10) || (c==9)
    //            );
    //}
    
    private static final byte PLUS=43;
    private static final byte MINUS=45;
    private static final byte BACKSLASH=92;
    //private static final byte TILDE=126;
    private static final byte AMPERSAND=0x26;
    private static final byte COMMA=0x2c;
    private static final byte SLASH=0x2f;
    
    // legal byte values: all US-ASCII graphic characters 0x20..0x7e
    private static boolean isLegal(char c, boolean useIMAP) {
        if (useIMAP) {
            return (
                    (0x20 <= c) && (c <= 0x7e)
                    );
        } else {
            return (
                    ((char)(c - 32) < 94 && (c != BACKSLASH)) || isCRLFTAB(c)
                    );
        }
    }
    
    // directly encode all of printable ASCII 0x20..0x7e except '&' 0x26
    private static boolean inSetDIMAP(char c) {
        return (
                (isLegal(c, true) && c != AMPERSAND)
                );
    }
    
    private static byte TO_BASE64_IMAP(int n) {
        return (n < 63 ? TO_BASE_64[n] : COMMA);
    }
    
    private static byte FROM_BASE64_IMAP(char c) {
        return (c==COMMA ? 63 : c==SLASH ? -1 : FROM_BASE_64[c]);
    }
    
    /* encode directly sets D and O and CR LF SP TAB */
    private static final byte ENCODE_DIRECTLY_MAXIMUM[] =
    {
     /*0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f*/
        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
    };
    
    /* encode directly set D and CR LF SP TAB but not set O */
    private static final byte ENCODE_DIRECTLY_RESTRICTED[] =
    {
     /*0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f*/
        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        
        1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
        
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
        
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
    };
    
    private static final byte TO_BASE_64[] =
    {
       /* A-Z */
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
       /* a-z */
       97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
       110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
       /* 0-9 */
       48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
       /* +/ */
       43, 47
    };
    
    private static final byte FROM_BASE_64[] =
    {
       /* C0 controls, -1 for legal ones (CR LF TAB), -3 for illegal ones */
       -3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,
       -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
       /* general punctuation with + and / and a special value (-2) for - */
       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -2, -1, 63,
       /* digits */
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
       /* A-Z */
       -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
       15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -3, -1, -1, -1,       
       /* a-z*/
       -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
       41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -3, -3
    };
    
    class CharsetDecoderUTF7 extends CharsetDecoderICU {
        public CharsetDecoderUTF7(CharsetICU cs) {
            super(cs);
            implReset();
        }
    
        protected void implReset() {
            super.implReset();
            toUnicodeStatus=(toUnicodeStatus & 0xf0000000) | 0x1000000;
        }
        
        protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) { 
            CoderResult cr=CoderResult.UNDERFLOW;
            byte base64Value;
            byte base64Counter;
            byte inDirectMode;
            char bits;
            int byteIndex;
            int sourceIndex, nextSourceIndex;
            
            int length;
            
            char b;
            char c;
            
            int sourceArrayIndex=source.position();
            
            //get the state of the machine state
            {
            int status=toUnicodeStatus;
            inDirectMode=(byte)((status >> 24) & 1);
            base64Counter=(byte)(status >> 16);
            bits=(char)status;
            }
            byteIndex=toULength;
            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex=byteIndex==0 ? 0 : -1;
            nextSourceIndex=0;            
            
            directMode:  while (true) {
                if (inDirectMode==1) {
                    /* 
                     * In Direct Mode, most US-ASCII characters are encoded directly, i.e.,
                     * with their US-ASCII byte values.
                     * Backslash and Tilde and most control characters are not alled in UTF-7.
                     * A plus sign starts Unicode (or "escape") Mode.
                     * An ampersand starts Unicode Mode for IMAP.
                     * 
                     * In Direct Mode, only the sourceIndex is used.
                     */
                    byteIndex=0;
                    length=source.remaining();
                    //targetCapacity=target.remaining();
                    //Commented out because length of source may be larger than target when it comes to bytes 
                    /*if (useIMAP && length > targetCapacity) {
                        length=targetCapacity;
                    }*/
                    while (length > 0) {
                        b=(char)(source.get());
                        sourceArrayIndex++;
                        if (!isLegal(b, useIMAP)) {
                            toUBytesArray[0]=(byte)b;
                            byteIndex=1;
                            cr=CoderResult.malformedForLength(sourceArrayIndex);
                            break;
                        } else if ((!useIMAP && b!=PLUS) || (useIMAP && b!=AMPERSAND)) {
                            // write directly encoded character
                            if (target.hasRemaining()) { // Check to make sure that there is room in target.
                                target.put(b);
                                if (offsets!= null) {
                                    offsets.put(sourceIndex++);
                                }
                            } else {  // Get out and set the CoderResult.
                                charErrorBufferArray[charErrorBufferLength++] = b;
                                cr = CoderResult.OVERFLOW;
                                break;
                            }
                        } else { /* PLUS or (AMPERSAND in IMAP)*/
                            /* switch to Unicode mode */
                            nextSourceIndex=++sourceIndex;
                            inDirectMode=0;
                            byteIndex=0;
                            bits=0;
                            base64Counter=-1;
                            continue directMode;
                        }
                        --length;
                    }//end of while
                    if (source.hasRemaining() && target.position() >= target.limit()) {
                        /* target is full */
                        cr=CoderResult.OVERFLOW;
                    }
                    break directMode;
                } else { /* Unicode Mode*/
                    /* 
                     * In Unicode Mode, UTF-16BE is base64-encoded.
                     * The base64 sequence ends with any character that is not in the base64 alphabet.
                     * A terminating minus sign is consumed.
                     * 
                     * In Unicode Mode, the sourceIndex has the index to the start of the current
                     * base64 bytes, while nextSourceIndex is precisely parallel to source,
                     * keeping the index to the following byte.
                     */
                    while(source.hasRemaining()) {
                        if (target.hasRemaining()) {
                            b=(char)source.get();
                            sourceArrayIndex++;
                            toUBytesArray[byteIndex++]=(byte)b;
                            base64Value = -3; /* initialize as illegal */
                            if ((!useIMAP && (b>=126 || (base64Value=FROM_BASE_64[b])==-3 || base64Value==-1)) || (useIMAP && b>0x7e)) {
                                /* either
                                 * base64Value==-1 for any legal character except base64 and minus sign, or
                                 * base64Value==-3 for illegal characters:
                                 * 1. In either case, leave Unicode mode.
                                 * 2.1. If we ended with an incomplete UChar or none after the +, then
                                 *      generate an error for the preceding erroneous sequence and deal with
                                 *      the current (possibly illegal) character next time through.
                                 * 2.2. Else the current char comes after a complete UChar, which was already
                                 *      pushed to the output buf, so:
                                 * 2.2.1. If the current char is legal, just save it for processing next time.
                                 *        It may be for example, a plus which we need to deal with in direct mode.
                                 * 2.2.2. Else if the current char is illegal, we might as well deal with it here.
                                 */
                                inDirectMode=1;
                                
                                if(base64Counter==-1) {
                                    /* illegal: + immediately followed by something other than base64 or minus sign */
                                    /* include the plus sign in the reported sequence, but not the subsequent char */
                                    source.position(source.position() -1);
                                    toUBytesArray[0]=PLUS;
                                    byteIndex=1;
                                    cr=CoderResult.malformedForLength(sourceArrayIndex);
                                    break directMode;
                                } else if(bits!=0) {
                                    /* bits are illegally left over, a UChar is incomplete */
                                    /* don't include current char (legal or illegal) in error seq */
                                    source.position(source.position() -1);
                                    --byteIndex;
                                    cr=CoderResult.malformedForLength(sourceArrayIndex);
                                    break directMode;
                                } else {
                                    /* previous UChar was complete */
                                    if(base64Value==-3) {
                                        /* current character is illegal, deal with it here */
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        break directMode;
                                    } else {
                                        /* un-read the current character in case it is a plus sign */
                                        source.position(source.position() -1);
                                        sourceIndex=nextSourceIndex-1;
                                        continue directMode;
                                    }
                                }
                            } else if ((!useIMAP && (base64Value=FROM_BASE_64[b])>=0) || (useIMAP && (base64Value=FROM_BASE64_IMAP(b))>=0)) {
                                /* collect base64 bytes */
                                switch (base64Counter) {
                                case -1: /* -1 is immediately after the + */
                                case 0:
                                    bits=(char)base64Value;
                                    base64Counter=1;
                                    break;
                                case 1:
                                case 3:
                                case 4:
                                case 6:
                                    bits=(char)((bits<<6) | base64Value);
                                    ++base64Counter;
                                    break;
                                case 2:
                                    c=(char)((bits<<4) | (base64Value>>2));
                                    if (useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex - 1;
                                    }
                                    toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
                                    byteIndex=1;
                                    bits=(char)(base64Value&3);
                                    base64Counter=3;
                                    break;
                                case 5:
                                    c=(char)((bits<<2) | (base64Value>>4));
                                    if(useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex - 1;
                                    }
                                    toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
                                    byteIndex=1;
                                    bits=(char)(base64Value&15);
                                    base64Counter=6;
                                    break;
                                case 7:
                                    c=(char)((bits<<6) | base64Value);
                                    if (useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex;
                                    }
                                    byteIndex=0;
                                    bits=0;
                                    base64Counter=0;
                                    break;
                                //default:                  
                                    /* will never occur */
                                    //break;                                                           
                                }//end of switch
                            } else if (!useIMAP || (useIMAP && base64Value==-2)) {
                                /* minus sign terminates the base64 sequence */
                                inDirectMode=1;
                                if (base64Counter==-1) {
                                    /* +- i.e. a minus immediately following a plus */
                                    target.put(useIMAP ? (char)AMPERSAND : (char)PLUS);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex - 1);
                                    }
                                } else {
                                    /* absorb the minus and leave the Unicode Mode */
                                    if (bits!=0 || (useIMAP && base64Counter!=0 && base64Counter!=3 && base64Counter!=6)) {
                                        /*bits are illegally left over, a unicode character is incomplete */
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        break;
                                    }
                                }
                                sourceIndex=nextSourceIndex;
                                continue directMode;
                            } else if (useIMAP) { 
                                if (base64Counter==-1) {
                                    // illegal: & immediately followed by something other than base64 or minus sign
                                    // include the ampersand in the reported sequence
                                    --sourceIndex;
                                    toUBytesArray[0]=AMPERSAND;
                                    toUBytesArray[1]=(byte)b;
                                    byteIndex=2;
                                }
                                /* base64Value==-3 for illegal characters */
                                /* illegal */
                                inDirectMode=1;
                                cr=CoderResult.malformedForLength(sourceArrayIndex);
                                break;
                            }
                        } else {
                            /* target is full */
                            cr=CoderResult.OVERFLOW;
                            break;
                        }
                    } //end of while
                    break directMode;
                }
            }//end of direct mode label
            if (useIMAP) {
                if (!cr.isError() && inDirectMode==0 && flush && byteIndex==0 && !source.hasRemaining()) {
                    if (base64Counter==-1) {
                        /* & at the very end of the input */
                        /* make the ampersand the reported sequence */
                        toUBytesArray[0]=AMPERSAND;
                        byteIndex=1;
                    }
                    /* else if (base64Counter!=-1) byteIndex remains 0 because ther is no particular byte sequence */
                    inDirectMode=1;
                    cr=CoderResult.malformedForLength(sourceIndex);
                }
                
            } else {
                if (!cr.isError() && flush && !source.hasRemaining() && bits  ==0) {
                    /*
                     * if we are in Unicode Mode, then the byteIndex might not be 0,
                     * but that is ok if bits -- 0
                     * -> we set byteIndex=0 at the end of the stream to avoid a truncated error 
                     * (not true for IMAP-mailbox-name where we must end in direct mode)
                     */
                    if (!cr.isOverflow()) {
                        byteIndex=0;
                    }
                }
            }
            /* set the converter state */
            toUnicodeStatus=(inDirectMode<<24 | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | (int)bits);
            toULength=byteIndex;
   
            return cr;
        }
    }
    
    class CharsetEncoderUTF7 extends CharsetEncoderICU {
        public CharsetEncoderUTF7(CharsetICU cs) {
            super(cs, fromUSubstitution);
            implReset();
        }
        
        protected void implReset() {
            super.implReset();
            fromUnicodeStatus=(fromUnicodeStatus & 0xf0000000) | 0x1000000;
        }
        
        protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult cr=CoderResult.UNDERFLOW;
            byte inDirectMode;
            byte encodeDirectly[];
            int status;
            
            int length, targetCapacity, sourceIndex;
            
            byte base64Counter;
            char bits;
            char c;
            char b;
            /* get the state machine state */
            {
                status=fromUnicodeStatus;
                encodeDirectly=(((long)status) < 0x10000000) ? ENCODE_DIRECTLY_MAXIMUM : ENCODE_DIRECTLY_RESTRICTED;
                inDirectMode=(byte)((status >> 24) & 1);
                base64Counter=(byte)(status >> 16);
                bits=(char)((byte)status);
            }
            /* UTF-7 always encodes UTF-16 code units, therefore we need only a simple sourceIndex */
            sourceIndex=0;
            
            directMode: while(true) {
            if(inDirectMode==1) {
                length=source.remaining();
                targetCapacity=target.remaining();
                if(length > targetCapacity) {
                    length=targetCapacity;
                }
                while (length > 0) {
                    c=source.get();
                    /* UTF7: currently always encode CR LF SP TAB directly */
                    /* IMAP: encode 0x20..0x7e except '&' directly */
                    if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && inSetDIMAP(c))) {
                        /* encode directly */
                        target.put((byte)c);
                        if (offsets != null) {
                            offsets.put(sourceIndex++);
                        }
                    } else if ((!useIMAP && c==PLUS) || (useIMAP && c==AMPERSAND)) {
                        /* IMAP: output &- for & */
                        /* UTF-7: output +- for + */
                        target.put(useIMAP ? AMPERSAND : PLUS);
                        if (target.hasRemaining()) {
                            target.put(MINUS);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                                offsets.put(sourceIndex++);
                            }
                            /* realign length and targetCapacity */
                            continue directMode;
                        } else {
                            if (offsets != null) {
                                offsets.put(sourceIndex++);
                            }
                            errorBuffer[0]=MINUS;
                            errorBufferLength=1;
                            cr=CoderResult.OVERFLOW;
                            break;
                        }
                    } else {
                        /* un-read this character and switch to unicode mode */
                        source.position(source.position() - 1);
                        target.put(useIMAP ? AMPERSAND : PLUS);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        inDirectMode=0;
                        base64Counter=0;
                        continue directMode;
                    }
                    --length;
                } //end of while
                if (source.hasRemaining() && !target.hasRemaining()) {
                    /* target is full */
                    cr=CoderResult.OVERFLOW;
                }
                break directMode;
            } else { 
                /* Unicode Mode */
                while (source.hasRemaining()) {
                    if (target.hasRemaining()) {
                        c=source.get();
                        if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && isLegal(c, useIMAP))) {
                            /* encode directly */
                            inDirectMode=1;
                            
                            /* trick: back out this character to make this easier */
                            source.position(source.position() - 1);
                            
                            /* terminate the base64 sequence */
                            if (base64Counter!=0) {
                                /* write remaining bits for the previous character */
                                target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
                                if (offsets!=null) {
                                    offsets.put(sourceIndex-1);
                                }
                            }
                            if (FROM_BASE_64[c]!=-1 || useIMAP) {
                                /* need to terminate with a minus */
                                if (target.hasRemaining()) {
                                    target.put(MINUS);
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex-1);
                                    }
                                } else {
                                    errorBuffer[0]=MINUS;
                                    errorBufferLength=1;
                                    cr=CoderResult.OVERFLOW;
                                    break;
                                }
                            }
                            continue directMode;
                        } else {
                            /*
                             * base64 this character:
                             * Output 2 or 3 base64 bytres for the remaining bits of the previous character
                             * and the bits of this character, each implicitly in UTF-16BE.
                             * 
                             * Here, bits is an 8-bit variable because only 6 bits need to be kept from one
                             * character to the next.  The actual 2 or 4 bits are shifted to the left edge
                             * of the 6-bits filed 5..0 to make the termination of the base64 sequence easier.
                             */
                            switch (base64Counter) {
                            case 0:
                                b=(char)(c>>10);
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>4)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex);
                                        offsets.put(sourceIndex++);
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>4)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=1;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=(char)((c&15)<<2);
                                base64Counter=1;
                                break;
                            case 1:
                                b=(char)(bits|(c>>14));
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>8)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (target.hasRemaining()) {
                                        b=(char)((c>>2)&0x3f);
                                        target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                    } else {
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                        b=(char)((c>>2)&0x3f);
                                        errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                        errorBufferLength=1;
                                        cr=CoderResult.OVERFLOW;
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>8)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    b=(char)((c>>2)&0x3f);
                                    errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=2;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=(char)((c&3)<<4);
                                base64Counter=2;
                                break;
                            case 2:
                                b=(char)(bits|(c>>12));
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>6)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (target.hasRemaining()) {
                                        b=(char)(c&0x3f);
                                        target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                    } else {
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                        b=(char)(c&0x3f);
                                        errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                        errorBufferLength=1;
                                        cr=CoderResult.OVERFLOW;
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>6)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    b=(char)(c&0x3f);
                                    errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=2;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=0;
                                base64Counter=0;
                                break;
                           //default:
                               /* will never occur */
                               //break;
                           } //end of switch 
                        }                      
                    } else {
                        /* target is full */
                        cr=CoderResult.OVERFLOW;
                        break;
                    }
                } //end of while
                break directMode;
            }
            } //end of directMode label
            
            if (flush && !source.hasRemaining()) {
                /* flush remaining bits to the target */
                if (inDirectMode==0) {
                    if (base64Counter!=0) {
                        if (target.hasRemaining()) {
                            target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
                            if (offsets!=null) {
                                offsets.put(sourceIndex - 1);
                            }
                        } else {
                            errorBuffer[errorBufferLength++]=useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits];
                            cr=CoderResult.OVERFLOW;
                        }
                    }
                    
                    /* need to terminate with a minus */
                    if (target.hasRemaining()) {
                        target.put(MINUS);
                        if (offsets!=null) {
                            offsets.put(sourceIndex - 1);
                        }
                    } else {
                        errorBuffer[errorBufferLength++]=MINUS;
                        cr=CoderResult.OVERFLOW;
                    }
                }
                /*reset the state for the next conversion */
                fromUnicodeStatus=((status&0xf0000000) | 0x1000000); /* keep version, inDirectMode=TRUE */
            } else {
                /* set the converter state back */
                fromUnicodeStatus=((status&0xf0000000) | (inDirectMode<<24) | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | ((int)bits));
            }
            
            return cr;
        }
    }
    
    public CharsetDecoder newDecoder() {
        return new CharsetDecoderUTF7(this);
    }
    
    public CharsetEncoder newEncoder() {
        return new CharsetEncoderUTF7(this);
    }
    
    void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
        getCompleteUnicodeSet(setFillIn);
    }
}
