    private static Buffer rubySprintfToBuffer(CharSequence charFormat, Args args) {
        byte[] format;
        Buffer buf = new Buffer();
        int offset;
        int length;
        int start;
        int mark;        
        if (charFormat instanceof ByteList) {
            ByteList list = (ByteList)charFormat;
            format = list.unsafeBytes();
            int begin = list.begin(); 
            offset = begin;
            length = begin + list.length();
            start = begin;
            mark = begin;
        } else {
            format = stringToBytes(charFormat, false);
            offset = 0;
            length = charFormat.length();
            start = 0;
            mark = 0;             
        }
        while (offset < length) {
            start = offset;
            for ( ; offset < length && format[offset] != '%'; offset++) ;
            if (offset > start) {
                buf.write(format,start,offset-start);
                start = offset;
            }
            if (offset++ >= length)
                break;
            IRubyObject arg = null;
            int flags = 0;
            int width = 0;
            int precision = 0;
            int number = 0;
            byte fchar = 0;
            boolean incomplete = true;
            for ( ; incomplete && offset < length ; ) {
                switch(fchar = format[offset]) {
                default:
                    if (fchar == '\0' && flags == FLAG_NONE) {
                        buf.write('%');
                        incomplete = false;
                        offset++;
                        break;
                    } else if (isPrintable(fchar)) {
                        raiseArgumentError(args,"malformed format string - %" + (char)fchar);
                    } else {
                        raiseArgumentError(args,ERR_MALFORMED_FORMAT);
                    }
                    break;
                case ' ':
                    flags |= FLAG_SPACE;
                    offset++;
                    break;
                case '0':
                    flags |= FLAG_ZERO;
                    offset++;
                    break;
                case '+':
                    flags |= FLAG_PLUS;
                    offset++;
                    break;
                case '-':
                    flags |= FLAG_MINUS;
                    offset++;
                    break;
                case '#':
                    flags |= FLAG_SHARP;
                    offset++;
                    break;
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    number = 0;
                    for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                        number = extendWidth(args, number, fchar);
                    }
                    checkOffset(args,offset,length,ERR_MALFORMED_NUM);
                    if (fchar == '$') {
                        if (arg != null) {
                            raiseArgumentError(args,"value given twice - " + number + "$");
                        }
                        arg = args.getNth(number);
                        offset++;
                    } else {
                        width = number;
                        flags |= FLAG_WIDTH;
                    }
                    break;
                case '*':
                    if ((flags & FLAG_WIDTH) != 0) {
                        raiseArgumentError(args,"width given twice");
                    }
                    flags |= FLAG_WIDTH;
                    checkOffset(args,++offset,length,ERR_MALFORMED_STAR_NUM);
                    mark = offset;
                    number = 0;
                    for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                        number = extendWidth(args,number,fchar);
                    }
                    checkOffset(args,offset,length,ERR_MALFORMED_STAR_NUM);
                    if (fchar == '$') {
                        width = args.getNthInt(number);
                        if (width < 0) {
                            flags |= FLAG_MINUS;
                            width = -width;
                        }
                        offset++;
                    } else {
                        width = args.nextInt();
                        if (width < 0) {
                            flags |= FLAG_MINUS;
                            width = -width;
                        }
                        offset = mark;
                    }
                    break;
                case '.':
                    if ((flags & FLAG_PRECISION) != 0) {
                        raiseArgumentError(args,"precision given twice");
                    }
                    flags |= FLAG_PRECISION;
                    checkOffset(args,++offset,length,ERR_MALFORMED_DOT_NUM);
                    fchar = format[offset];
                    if (fchar == '*') {
                        checkOffset(args,++offset,length,ERR_MALFORMED_STAR_NUM);
                        mark = offset;
                        number = 0;
                        for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                            number = extendWidth(args,number,fchar);
                        }
                        checkOffset(args,offset,length,ERR_MALFORMED_STAR_NUM);
                        if (fchar == '$') {
                            precision = args.getNthInt(number);
                            if (precision < 0) {
                                flags &= ~FLAG_PRECISION;
                            }
                            offset++;
                        } else {
                            precision = args.nextInt();
                            if (precision < 0) {
                                flags &= ~FLAG_PRECISION;
                            }
                            offset = mark;
                        }
                    } else {
                        number = 0;
                        for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                            number = extendWidth(args,number,fchar);
                        }
                        checkOffset(args,offset,length,ERR_MALFORMED_DOT_NUM);
                        precision = number;
                    }
                    break;
                case '\n':
                    offset--;
                case '%':
                    if (flags != FLAG_NONE) {
                        raiseArgumentError(args,ERR_ILLEGAL_FORMAT_CHAR);
                    }
                    buf.write('%');
                    offset++;
                    incomplete = false;
                    break;
                case 'c': {
                    if (arg == null) arg = args.next();
                    int c = 0;
                    if (arg instanceof RubyString) {
                        ByteList bytes = ((RubyString)arg).getByteList();
                        if (bytes.length() == 1) {
                            c = bytes.unsafeBytes()[bytes.begin()];
                        } else {
                            raiseArgumentError(args,"%c requires a character");
                        }
                    } else {
                        c = args.intValue(arg);
                    }
                    if ((flags & FLAG_WIDTH) != 0 && width > 1) {
                        if ((flags & FLAG_MINUS) != 0) {
                            buf.write(c);
                            buf.fill(' ', width-1);
                        } else {
                            buf.fill(' ',width-1);
                            buf.write(c);
                        }
                    } else {
                        buf.write(c);
                    }
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'p':
                case 's': {
                    if (arg == null) arg = args.next();
                    if (fchar == 'p') {
                        arg = arg.callMethod(arg.getRuntime().getCurrentContext(),"inspect");
                    }
                    ByteList bytes = arg.asString().getByteList();
                    int len = bytes.length();
                    if (arg.isTaint()) {
                        buf.tainted = true;
                    }
                    if ((flags & FLAG_PRECISION) != 0 && precision < len) {
                        len = precision;
                    }
                    if ((flags & FLAG_WIDTH) != 0 && width > len) {
                        width -= len;
                        if ((flags & FLAG_MINUS) != 0) {
                            buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                            buf.fill(' ',width);
                        } else {
                            buf.fill(' ',width);
                            buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                        }
                    } else {
                        buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                    }
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'd':
                case 'i':
                case 'o':
                case 'x':
                case 'X':
                case 'b':
                case 'B':
                case 'u': {
                    if (arg == null) arg = args.next();
                    int type = arg.getMetaClass().index;
                    if (type != ClassIndex.FIXNUM && type != ClassIndex.BIGNUM) {
                        switch(type) {
                        case ClassIndex.FLOAT:
                            arg = RubyNumeric.dbl2num(arg.getRuntime(),((RubyFloat)arg).getValue());
                            break;
                        case ClassIndex.STRING:
                            arg = RubyNumeric.str2inum(arg.getRuntime(),(RubyString)arg,0,true);
                            break;
                        default:
                            if (arg.respondsTo("to_int")) {
                                arg = TypeConverter.convertToType(arg, arg.getRuntime().getInteger(), MethodIndex.TO_INT, "to_int", true);
                            } else {
                                arg = TypeConverter.convertToType(arg, arg.getRuntime().getInteger(), MethodIndex.TO_I, "to_i", true);
                            }
                            break;
                        }
                        type = arg.getMetaClass().index;
                    }
                    byte[] bytes = null;
                    int first = 0;
                    byte[] prefix = null;
                    boolean sign;
                    boolean negative;
                    byte signChar = 0;
                    byte leadChar = 0;
                    int base;
                    if (fchar == 'i') fchar = 'd';
                    if (fchar == 'u' && (flags & (FLAG_SPACE | FLAG_PLUS)) != 0) {
                        fchar = 'd';
                    }
                    sign = (fchar == 'd' || (flags & (FLAG_SPACE | FLAG_PLUS)) != 0);
                    switch (fchar) {
                    case 'o':
                        base = 8; break;
                    case 'x':
                    case 'X':
                        base = 16; break;
                    case 'b':
                    case 'B':
                        base = 2; break;
                    case 'u':
                    case 'd':
                    default:
                        base = 10; break;
                    }
                    if ((flags & FLAG_SHARP) != 0) {
                        switch(fchar) {
                        case 'o': prefix = PREFIX_OCTAL; break;
                        case 'x': prefix = PREFIX_HEX_LC; break;
                        case 'X': prefix = PREFIX_HEX_UC; break;
                        case 'b': prefix = PREFIX_BINARY_LC; break;
                        case 'B': prefix = PREFIX_BINARY_UC; break;
                        }
                        if (prefix != null) width -= prefix.length;
                    }
                    if (type == ClassIndex.FIXNUM) {
                        negative = ((RubyFixnum)arg).getLongValue() < 0;
                        if (negative && fchar == 'u') {
                            bytes = getUnsignedNegativeBytes((RubyFixnum)arg);
                        } else {
                            bytes = getFixnumBytes((RubyFixnum)arg,base,sign,fchar=='X');
                        }
                    } else {
                        negative = ((RubyBignum)arg).getValue().signum() < 0;
                        if (negative && fchar == 'u') {
                            bytes = getUnsignedNegativeBytes((RubyBignum)arg);
                        } else {
                            bytes = getBignumBytes((RubyBignum)arg,base,sign,fchar=='X');
                        }
                    }
                    int len = 0;
                    if (sign) {
                        if (negative) {
                            signChar = '-';
                            width--;
                            first = 1; 
                        } else if ((flags & FLAG_PLUS) != 0) {
                            signChar = '+';
                            width--;
                        } else if ((flags & FLAG_SPACE) != 0) {
                            signChar = ' ';
                            width--;
                        }
                    } else if (negative) {
                        if (base == 10) {
                            warning(args,"negative number for %u specifier");
                            leadChar = '.';
                            len += 2;
                        } else {
                            if ((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0) len += 2; 
                            first = skipSignBits(bytes,base);
                            switch(fchar) {
                            case 'b':
                            case 'B':
                                leadChar = '1';
                                break;
                            case 'o':
                                leadChar = '7';
                                break;
                            case 'x':
                                leadChar = 'f';
                                break;
                            case 'X':
                                leadChar = 'F';
                                break;
                            }
                            if (leadChar != 0) len++;
                        }
                    }
                    int numlen = bytes.length - first;
                    len += numlen;
                    if ((flags & (FLAG_ZERO|FLAG_PRECISION)) == FLAG_ZERO) {
                        precision = width;
                        width = 0;
                    } else {
                        if (precision < len) precision = len;
                        width -= precision;
                    }
                    if ((flags & FLAG_MINUS) == 0) {
                        buf.fill(' ',width);
                        width = 0;
                    }
                    if (signChar != 0) buf.write(signChar);
                    if (prefix != null) buf.write(prefix);
                    if (len < precision) {
                        if (leadChar == 0) {
                            buf.fill('0', precision - len);
                        } else if (leadChar == '.') {
                            buf.fill(leadChar,precision-len);
                            buf.write(PREFIX_NEGATIVE);
                        } else {
                            buf.fill(leadChar,precision-len+1); 
                        }
                    } else if (leadChar != 0) {
                        if ((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0) {
                            buf.write(PREFIX_NEGATIVE);
                        }
                        if (leadChar != '.') buf.write(leadChar);
                    }
                    buf.write(bytes,first,numlen);
                    if (width > 0) buf.fill(' ',width);
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'E':
                case 'e':
                case 'f':
                case 'G':
                case 'g': {
                    if (arg == null) arg = args.next();
                    if (!(arg instanceof RubyFloat)) {
                        arg = RubyKernel.new_float(arg,arg);
                    }
                    double dval = ((RubyFloat)arg).getDoubleValue();
                    boolean nan = dval != dval;
                    boolean inf = dval == Double.POSITIVE_INFINITY || dval == Double.NEGATIVE_INFINITY;
                    boolean negative = dval < 0.0d;
                    byte[] digits;
                    int nDigits = 0;
                    int exponent = 0;
                    int len = 0;
                    byte signChar;
                    if (nan || inf) {
                        if (nan) {
                            digits = NAN_VALUE;
                            len = NAN_VALUE.length;
                        } else {
                            digits = INFINITY_VALUE;
                            len = INFINITY_VALUE.length;
                        }
                        if (negative) {
                            signChar = '-';
                            width--;
                        } else if ((flags & FLAG_PLUS) != 0) {
                            signChar = '+';
                            width--;
                        } else if ((flags & FLAG_SPACE) != 0) {
                            signChar = ' ';
                            width--;
                        } else {
                            signChar = 0;
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) buf.write(signChar);
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        buf.write(digits);
                        if (width > 0) buf.fill(' ', width);
                        offset++;
                        incomplete = false;
                        break;
                    }
                    String str = Double.toString(dval);
                    int strlen = str.length();
                    digits = new byte[strlen];
                    int nTrailingZeroes = 0;
                    int i = negative ? 1 : 0;
                    int decPos = 0;
                    byte ival;
                int_loop:
                    for ( ; i < strlen ; ) {
                        switch(ival = (byte)str.charAt(i++)) {
                        case '0':
                            if (nDigits > 0) nTrailingZeroes++;
                            break; 
                        case '1': case '2': case '3': case '4':
                        case '5': case '6': case '7': case '8': case '9':
                            if (nTrailingZeroes > 0) {
                                for ( ; nTrailingZeroes > 0 ; nTrailingZeroes-- ) {
                                    digits[nDigits++] = '0';
                                }
                            }
                            digits[nDigits++] = ival;
                            break; 
                        case '.':
                            break int_loop;
                        }
                    }
                    decPos = nDigits + nTrailingZeroes;
                dec_loop:
                    for ( ; i < strlen ; ) {
                        switch(ival = (byte)str.charAt(i++)) {
                        case '0':
                            if (nDigits > 0) {
                                nTrailingZeroes++;
                            } else {
                                exponent--;
                            }
                            break; 
                        case '1': case '2': case '3': case '4':
                        case '5': case '6': case '7': case '8': case '9':
                            if (nTrailingZeroes > 0) {
                                for ( ; nTrailingZeroes > 0 ; nTrailingZeroes--  ) {
                                    digits[nDigits++] = '0';
                                }
                            }
                            digits[nDigits++] = ival;
                            break; 
                        case 'E':
                            break dec_loop;
                        }
                    }
                    if ( i < strlen) {
                        int expSign;
                        int expVal = 0;
                        if (str.charAt(i) == '-') {
                            expSign = -1;
                            i++;
                        } else {
                            expSign = 1;
                        }
                        for ( ; i < strlen ; ) {
                            expVal = expVal * 10 + ((int)str.charAt(i++)-(int)'0');
                        }
                        exponent += expVal * expSign;
                    }
                    exponent += decPos - nDigits;
                    if (nDigits == 0) {
                        digits[0] = '0';
                        nDigits = 1;
                        exponent = 0;
                    }
                    int intDigits, intZeroes, intLength;
                    int decDigits, decZeroes, decLength;
                    byte expChar;
                    if (negative) {
                        signChar = '-';
                        width--;
                    } else if ((flags & FLAG_PLUS) != 0) {
                        signChar = '+';
                        width--;
                    } else if ((flags & FLAG_SPACE) != 0) {
                        signChar = ' ';
                        width--;
                    } else {
                        signChar = 0;
                    }
                    if ((flags & FLAG_PRECISION) == 0) {
                        precision = 6;
                    }
                    switch(fchar) {
                    case 'E':
                    case 'G':
                        expChar = 'E';
                        break;
                    case 'e':
                    case 'g':
                        expChar = 'e';
                        break;
                    default:
                        expChar = 0;
                    }
                    switch(fchar) {
                    case 'g':
                    case 'G':
                        boolean expForm = (exponent + nDigits - 1 < -4 ||
                            exponent + nDigits > (precision == 0 ? 1 : precision));
                        if (expForm) {
                            decDigits = nDigits - 1;
                            precision = Math.max(0,precision - 1);
                            if (precision < decDigits) {
                                int n = round(digits,nDigits,precision,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                }
                                decDigits = Math.min(nDigits - 1,precision);
                            }
                            exponent += nDigits - 1;
                            boolean isSharp = (flags & FLAG_SHARP) != 0;
                            len++; 
                            if (exponent > 99)
                            	len += 5; 
                            else
                            	len += 4; 
                            if (isSharp) {
                            	len++;
                            }
                            if (precision > 0) {
                            	if (!isSharp) {
                            	    int j = decDigits;
                            	    for (; j >= 1; j--) {
                            	        if (digits[j]== '0') {
                            	            decDigits--;
                            	        } else {
                            	            break;
                            	        }
                            	    }
                            	    if (decDigits > 0) {
                            	        len += 1; 
                            	        len += decDigits;
                            	    }
                            	} else  {
                            	    len += precision;
                            	}
                            }
                            width -= len;
                            if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                                buf.fill(' ',width);
                                width = 0;
                            }
                            if (signChar != 0) {
                                buf.write(signChar);
                            }
                            if (width > 0 && (flags & FLAG_MINUS) == 0) {
                                buf.fill('0',width);
                                width = 0;
                            }
                            buf.write(digits[0]);
                            boolean dotToPrint = isSharp
                                    || (precision > 0 && decDigits > 0);
                            if (dotToPrint) {
                            	buf.write(args.getDecimalSeparator()); 
                            }
                            if (precision > 0 && decDigits > 0) {
                            	buf.write(digits, 1, decDigits);
                            	precision -= decDigits;
                            }
                            if (precision > 0 && isSharp) {
                            	buf.fill('0', precision);
                            }
                            writeExp(buf, exponent, expChar);
                            if (width > 0) {
                                buf.fill(' ', width);
                            }
                        } else { 
                            intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                            intZeroes = Math.max(0,exponent);
                            intLength = intDigits + intZeroes;
                            decDigits = nDigits - intDigits;
                            decZeroes = Math.max(0,-(decDigits + exponent));
                            decLength = decZeroes + decDigits;
                            precision = Math.max(0,precision - intLength);
                            if (precision < decDigits) {
                                int n = round(digits,nDigits,intDigits+precision-1,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                    intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                                    intLength = intDigits + intZeroes;
                                    decDigits = nDigits - intDigits;
                                    decZeroes = Math.max(0,-(decDigits + exponent));
                                    precision = Math.max(0,precision-1);
                                }
                                decDigits = precision;
                                decLength = decZeroes + decDigits;
                            }
                            len += intLength;
                            if (decLength > 0) {
                                len += decLength + 1;
                            } else {
                                if ((flags & FLAG_SHARP) != 0) {
                                    len++; 
                                    if (precision > 0) { 
                                        len += precision;
                                    }
                                }
                            }
                            width -= len;
                            if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                                buf.fill(' ',width);
                                width = 0;
                            }
                            if (signChar != 0) {
                                buf.write(signChar);
                            }
                            if (width > 0 && (flags & FLAG_MINUS) == 0) {
                                buf.fill('0',width);
                                width = 0;
                            }
                            if (intLength > 0){
                                if (intDigits > 0) { 
                                    buf.write(digits,0,intDigits);
                                }
                                if (intZeroes > 0) {
                                    buf.fill('0',intZeroes);
                                }
                            } else {
                                buf.write('0');
                            }
                            if (decLength > 0 || (flags & FLAG_SHARP) != 0) {
                                buf.write(args.getDecimalSeparator());
                            }
                            if (decLength > 0) {
                                if (decZeroes > 0) {
                                    buf.fill('0',decZeroes);
                                    precision -= decZeroes;
                                }
                                if (decDigits > 0) {
                                    buf.write(digits,intDigits,decDigits);
                                    precision -= decDigits;
                                }
                                if ((flags & FLAG_SHARP) != 0 && precision > 0) {
                                    buf.fill('0',precision);
                                 }
                            }
                            if ((flags & FLAG_SHARP) != 0 && precision > 0) {
                                buf.fill('0',precision);
                            }
                            if (width > 0) {
                                buf.fill(' ', width);
                            }
                        }
                        break;
                    case 'f':
                        intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                        intZeroes = Math.max(0,exponent);
                        intLength = intDigits + intZeroes;
                        decDigits = nDigits - intDigits;
                        decZeroes = Math.max(0,-(decDigits + exponent));
                        decLength = decZeroes + decDigits;
                        if (precision < decLength) {
                            if (precision < decZeroes) {
                                decDigits = 0;
                                decZeroes = precision;
                            } else {
                                int n = round(digits,nDigits,intDigits+precision-decZeroes-1,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                    intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                                    intLength = intDigits + intZeroes;
                                    decDigits = nDigits - intDigits;
                                    decZeroes = Math.max(0,-(decDigits + exponent));
                                    decLength = decZeroes + decDigits;
                                }
                                decDigits = precision - decZeroes;
                            }
                            decLength = decZeroes + decDigits;
                        }
                        if (precision > 0) {
                            len += Math.max(1,intLength) + 1 + precision;
                        } else {
                            len += Math.max(1,intLength);
                            if ((flags & FLAG_SHARP) != 0) {
                                len++; 
                            }
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) {
                            buf.write(signChar);
                        }
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        if (intLength > 0){
                            if (intDigits > 0) { 
                                buf.write(digits,0,intDigits);
                            }
                            if (intZeroes > 0) {
                                buf.fill('0',intZeroes);
                            }
                        } else {
                            buf.write('0');
                        }
                        if (precision > 0 || (flags & FLAG_SHARP) != 0) {
                            buf.write(args.getDecimalSeparator());
                        }
                        if (precision > 0) {
                            if (decZeroes > 0) {
                                buf.fill('0',decZeroes);
                                precision -= decZeroes;
                            }
                            if (decDigits > 0) {
                                buf.write(digits,intDigits,decDigits);
                                precision -= decDigits;
                            }
                            if (precision > 0) {
                                buf.fill('0',precision);
                            }
                        }
                        if (width > 0) {
                            buf.fill(' ', width);
                        }
                        break;
                    case 'E':
                    case 'e':
                        decDigits = nDigits - 1;
                        if (precision < decDigits) {
                            int n = round(digits,nDigits,precision,precision!=0);
                            if (n > nDigits) {
                                nDigits = n;
                            }
                            decDigits = Math.min(nDigits - 1,precision);
                        }
                        exponent += nDigits - 1;
                        boolean isSharp = (flags & FLAG_SHARP) != 0;
                        len++; 
                        if (exponent > 99)
                            len += 5; 
                        else
                            len += 4; 
                        if (precision > 0) {
                            len += 1 + precision;
                        } else  if (isSharp) {
                            len++;  
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) {
                            buf.write(signChar);
                        }
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        buf.write(digits[0]);
                        if (precision > 0) {
                            buf.write(args.getDecimalSeparator()); 
                            if (decDigits > 0) {
                                buf.write(digits,1,decDigits);
                                precision -= decDigits;
                            }
                            if (precision > 0) {
                                buf.fill('0',precision);
                            }
                        } else if ((flags & FLAG_SHARP) != 0) {
                            buf.write(args.getDecimalSeparator());
                        }
                        writeExp(buf, exponent, expChar);
                        if (width > 0) {
                            buf.fill(' ', width);
                        }
                        break;
                    } 
                    offset++;
                    incomplete = false;
                    break;
                } 
                } 
            } 
            if (incomplete) {
                if (flags == FLAG_NONE) {
                    buf.write('%');
                } else {
                    raiseArgumentError(args,ERR_ILLEGAL_FORMAT_CHAR);
                }
            }
        } 
        return buf;
    }

    private static Buffer rubySprintfToBuffer(CharSequence charFormat, Args args) {
        byte[] format;
        Buffer buf = new Buffer();
        int offset;
        int length;
        int start;
        int mark;        
        if (charFormat instanceof ByteList) {
            ByteList list = (ByteList)charFormat;
            format = list.unsafeBytes();
            int begin = list.begin(); 
            offset = begin;
            length = begin + list.length();
            start = begin;
            mark = begin;
        } else {
            format = stringToBytes(charFormat, false);
            offset = 0;
            length = charFormat.length();
            start = 0;
            mark = 0;             
        }
        while (offset < length) {
            start = offset;
            for ( ; offset < length && format[offset] != '%'; offset++) ;
            if (offset > start) {
                buf.write(format,start,offset-start);
                start = offset;
            }
            if (offset++ >= length)
                break;
            IRubyObject arg = null;
            int flags = 0;
            int width = 0;
            int precision = 0;
            int number = 0;
            byte fchar = 0;
            boolean incomplete = true;
            for ( ; incomplete && offset < length ; ) {
                switch(fchar = format[offset]) {
                default:
                    if (fchar == '\0' && flags == FLAG_NONE) {
                        buf.write('%');
                        buf.write(fchar);
                        incomplete = false;
                        offset++;
                        break;
                    } else if (isPrintable(fchar)) {
                        raiseArgumentError(args,"malformed format string - %" + (char)fchar);
                    } else {
                        raiseArgumentError(args,ERR_MALFORMED_FORMAT);
                    }
                    break;
                case ' ':
                    flags |= FLAG_SPACE;
                    offset++;
                    break;
                case '0':
                    flags |= FLAG_ZERO;
                    offset++;
                    break;
                case '+':
                    flags |= FLAG_PLUS;
                    offset++;
                    break;
                case '-':
                    flags |= FLAG_MINUS;
                    offset++;
                    break;
                case '#':
                    flags |= FLAG_SHARP;
                    offset++;
                    break;
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    number = 0;
                    for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                        number = extendWidth(args, number, fchar);
                    }
                    checkOffset(args,offset,length,ERR_MALFORMED_NUM);
                    if (fchar == '$') {
                        if (arg != null) {
                            raiseArgumentError(args,"value given twice - " + number + "$");
                        }
                        arg = args.getNth(number);
                        offset++;
                    } else {
                        width = number;
                        flags |= FLAG_WIDTH;
                    }
                    break;
                case '*':
                    if ((flags & FLAG_WIDTH) != 0) {
                        raiseArgumentError(args,"width given twice");
                    }
                    flags |= FLAG_WIDTH;
                    checkOffset(args,++offset,length,ERR_MALFORMED_STAR_NUM);
                    mark = offset;
                    number = 0;
                    for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                        number = extendWidth(args,number,fchar);
                    }
                    checkOffset(args,offset,length,ERR_MALFORMED_STAR_NUM);
                    if (fchar == '$') {
                        width = args.getNthInt(number);
                        if (width < 0) {
                            flags |= FLAG_MINUS;
                            width = -width;
                        }
                        offset++;
                    } else {
                        width = args.nextInt();
                        if (width < 0) {
                            flags |= FLAG_MINUS;
                            width = -width;
                        }
                        offset = mark;
                    }
                    break;
                case '.':
                    if ((flags & FLAG_PRECISION) != 0) {
                        raiseArgumentError(args,"precision given twice");
                    }
                    flags |= FLAG_PRECISION;
                    checkOffset(args,++offset,length,ERR_MALFORMED_DOT_NUM);
                    fchar = format[offset];
                    if (fchar == '*') {
                        checkOffset(args,++offset,length,ERR_MALFORMED_STAR_NUM);
                        mark = offset;
                        number = 0;
                        for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                            number = extendWidth(args,number,fchar);
                        }
                        checkOffset(args,offset,length,ERR_MALFORMED_STAR_NUM);
                        if (fchar == '$') {
                            precision = args.getNthInt(number);
                            if (precision < 0) {
                                flags &= ~FLAG_PRECISION;
                            }
                            offset++;
                        } else {
                            precision = args.nextInt();
                            if (precision < 0) {
                                flags &= ~FLAG_PRECISION;
                            }
                            offset = mark;
                        }
                    } else {
                        number = 0;
                        for ( ; offset < length && isDigit(fchar = format[offset]); offset++) {
                            number = extendWidth(args,number,fchar);
                        }
                        checkOffset(args,offset,length,ERR_MALFORMED_DOT_NUM);
                        precision = number;
                    }
                    break;
                case '\n':
                    offset--;
                case '%':
                    if (flags != FLAG_NONE) {
                        raiseArgumentError(args,ERR_ILLEGAL_FORMAT_CHAR);
                    }
                    buf.write('%');
                    offset++;
                    incomplete = false;
                    break;
                case 'c': {
                    if (arg == null) arg = args.next();
                    int c = 0;
                    if (arg instanceof RubyString) {
                        ByteList bytes = ((RubyString)arg).getByteList();
                        if (bytes.length() == 1) {
                            c = bytes.unsafeBytes()[bytes.begin()];
                        } else {
                            raiseArgumentError(args,"%c requires a character");
                        }
                    } else {
                        c = args.intValue(arg);
                    }
                    if ((flags & FLAG_WIDTH) != 0 && width > 1) {
                        if ((flags & FLAG_MINUS) != 0) {
                            buf.write(c);
                            buf.fill(' ', width-1);
                        } else {
                            buf.fill(' ',width-1);
                            buf.write(c);
                        }
                    } else {
                        buf.write(c);
                    }
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'p':
                case 's': {
                    if (arg == null) arg = args.next();
                    if (fchar == 'p') {
                        arg = arg.callMethod(arg.getRuntime().getCurrentContext(),"inspect");
                    }
                    ByteList bytes = arg.asString().getByteList();
                    int len = bytes.length();
                    if (arg.isTaint()) {
                        buf.tainted = true;
                    }
                    if ((flags & FLAG_PRECISION) != 0 && precision < len) {
                        len = precision;
                    }
                    if ((flags & FLAG_WIDTH) != 0 && width > len) {
                        width -= len;
                        if ((flags & FLAG_MINUS) != 0) {
                            buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                            buf.fill(' ',width);
                        } else {
                            buf.fill(' ',width);
                            buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                        }
                    } else {
                        buf.write(bytes.unsafeBytes(),bytes.begin(),len);
                    }
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'd':
                case 'i':
                case 'o':
                case 'x':
                case 'X':
                case 'b':
                case 'B':
                case 'u': {
                    if (arg == null) arg = args.next();
                    int type = arg.getMetaClass().index;
                    if (type != ClassIndex.FIXNUM && type != ClassIndex.BIGNUM) {
                        switch(type) {
                        case ClassIndex.FLOAT:
                            arg = RubyNumeric.dbl2num(arg.getRuntime(),((RubyFloat)arg).getValue());
                            break;
                        case ClassIndex.STRING:
                            arg = RubyNumeric.str2inum(arg.getRuntime(),(RubyString)arg,0,true);
                            break;
                        default:
                            if (arg.respondsTo("to_int")) {
                                arg = TypeConverter.convertToType(arg, arg.getRuntime().getInteger(), MethodIndex.TO_INT, "to_int", true);
                            } else {
                                arg = TypeConverter.convertToType(arg, arg.getRuntime().getInteger(), MethodIndex.TO_I, "to_i", true);
                            }
                            break;
                        }
                        type = arg.getMetaClass().index;
                    }
                    byte[] bytes = null;
                    int first = 0;
                    byte[] prefix = null;
                    boolean sign;
                    boolean negative;
                    byte signChar = 0;
                    byte leadChar = 0;
                    int base;
                    if (fchar == 'i') fchar = 'd';
                    if (fchar == 'u' && (flags & (FLAG_SPACE | FLAG_PLUS)) != 0) {
                        fchar = 'd';
                    }
                    sign = (fchar == 'd' || (flags & (FLAG_SPACE | FLAG_PLUS)) != 0);
                    switch (fchar) {
                    case 'o':
                        base = 8; break;
                    case 'x':
                    case 'X':
                        base = 16; break;
                    case 'b':
                    case 'B':
                        base = 2; break;
                    case 'u':
                    case 'd':
                    default:
                        base = 10; break;
                    }
                    if ((flags & FLAG_SHARP) != 0) {
                        switch(fchar) {
                        case 'o': prefix = PREFIX_OCTAL; break;
                        case 'x': prefix = PREFIX_HEX_LC; break;
                        case 'X': prefix = PREFIX_HEX_UC; break;
                        case 'b': prefix = PREFIX_BINARY_LC; break;
                        case 'B': prefix = PREFIX_BINARY_UC; break;
                        }
                        if (prefix != null) width -= prefix.length;
                    }
                    if (type == ClassIndex.FIXNUM) {
                        negative = ((RubyFixnum)arg).getLongValue() < 0;
                        if (negative && fchar == 'u') {
                            bytes = getUnsignedNegativeBytes((RubyFixnum)arg);
                        } else {
                            bytes = getFixnumBytes((RubyFixnum)arg,base,sign,fchar=='X');
                        }
                    } else {
                        negative = ((RubyBignum)arg).getValue().signum() < 0;
                        if (negative && fchar == 'u') {
                            bytes = getUnsignedNegativeBytes((RubyBignum)arg);
                        } else {
                            bytes = getBignumBytes((RubyBignum)arg,base,sign,fchar=='X');
                        }
                    }
                    int len = 0;
                    if (sign) {
                        if (negative) {
                            signChar = '-';
                            width--;
                            first = 1; 
                        } else if ((flags & FLAG_PLUS) != 0) {
                            signChar = '+';
                            width--;
                        } else if ((flags & FLAG_SPACE) != 0) {
                            signChar = ' ';
                            width--;
                        }
                    } else if (negative) {
                        if (base == 10) {
                            warning(args,"negative number for %u specifier");
                            leadChar = '.';
                            len += 2;
                        } else {
                            if ((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0) len += 2; 
                            first = skipSignBits(bytes,base);
                            switch(fchar) {
                            case 'b':
                            case 'B':
                                leadChar = '1';
                                break;
                            case 'o':
                                leadChar = '7';
                                break;
                            case 'x':
                                leadChar = 'f';
                                break;
                            case 'X':
                                leadChar = 'F';
                                break;
                            }
                            if (leadChar != 0) len++;
                        }
                    }
                    int numlen = bytes.length - first;
                    len += numlen;
                    if ((flags & (FLAG_ZERO|FLAG_PRECISION)) == FLAG_ZERO) {
                        precision = width;
                        width = 0;
                    } else {
                        if (precision < len) precision = len;
                        width -= precision;
                    }
                    if ((flags & FLAG_MINUS) == 0) {
                        buf.fill(' ',width);
                        width = 0;
                    }
                    if (signChar != 0) buf.write(signChar);
                    if (prefix != null) buf.write(prefix);
                    if (len < precision) {
                        if (leadChar == 0) {
                            buf.fill('0', precision - len);
                        } else if (leadChar == '.') {
                            buf.fill(leadChar,precision-len);
                            buf.write(PREFIX_NEGATIVE);
                        } else {
                            buf.fill(leadChar,precision-len+1); 
                        }
                    } else if (leadChar != 0) {
                        if ((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0) {
                            buf.write(PREFIX_NEGATIVE);
                        }
                        if (leadChar != '.') buf.write(leadChar);
                    }
                    buf.write(bytes,first,numlen);
                    if (width > 0) buf.fill(' ',width);
                    offset++;
                    incomplete = false;
                    break;
                }
                case 'E':
                case 'e':
                case 'f':
                case 'G':
                case 'g': {
                    if (arg == null) arg = args.next();
                    if (!(arg instanceof RubyFloat)) {
                        arg = RubyKernel.new_float(arg,arg);
                    }
                    double dval = ((RubyFloat)arg).getDoubleValue();
                    boolean nan = dval != dval;
                    boolean inf = dval == Double.POSITIVE_INFINITY || dval == Double.NEGATIVE_INFINITY;
                    boolean negative = dval < 0.0d;
                    byte[] digits;
                    int nDigits = 0;
                    int exponent = 0;
                    int len = 0;
                    byte signChar;
                    if (nan || inf) {
                        if (nan) {
                            digits = NAN_VALUE;
                            len = NAN_VALUE.length;
                        } else {
                            digits = INFINITY_VALUE;
                            len = INFINITY_VALUE.length;
                        }
                        if (negative) {
                            signChar = '-';
                            width--;
                        } else if ((flags & FLAG_PLUS) != 0) {
                            signChar = '+';
                            width--;
                        } else if ((flags & FLAG_SPACE) != 0) {
                            signChar = ' ';
                            width--;
                        } else {
                            signChar = 0;
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) buf.write(signChar);
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        buf.write(digits);
                        if (width > 0) buf.fill(' ', width);
                        offset++;
                        incomplete = false;
                        break;
                    }
                    String str = Double.toString(dval);
                    int strlen = str.length();
                    digits = new byte[strlen];
                    int nTrailingZeroes = 0;
                    int i = negative ? 1 : 0;
                    int decPos = 0;
                    byte ival;
                int_loop:
                    for ( ; i < strlen ; ) {
                        switch(ival = (byte)str.charAt(i++)) {
                        case '0':
                            if (nDigits > 0) nTrailingZeroes++;
                            break; 
                        case '1': case '2': case '3': case '4':
                        case '5': case '6': case '7': case '8': case '9':
                            if (nTrailingZeroes > 0) {
                                for ( ; nTrailingZeroes > 0 ; nTrailingZeroes-- ) {
                                    digits[nDigits++] = '0';
                                }
                            }
                            digits[nDigits++] = ival;
                            break; 
                        case '.':
                            break int_loop;
                        }
                    }
                    decPos = nDigits + nTrailingZeroes;
                dec_loop:
                    for ( ; i < strlen ; ) {
                        switch(ival = (byte)str.charAt(i++)) {
                        case '0':
                            if (nDigits > 0) {
                                nTrailingZeroes++;
                            } else {
                                exponent--;
                            }
                            break; 
                        case '1': case '2': case '3': case '4':
                        case '5': case '6': case '7': case '8': case '9':
                            if (nTrailingZeroes > 0) {
                                for ( ; nTrailingZeroes > 0 ; nTrailingZeroes--  ) {
                                    digits[nDigits++] = '0';
                                }
                            }
                            digits[nDigits++] = ival;
                            break; 
                        case 'E':
                            break dec_loop;
                        }
                    }
                    if ( i < strlen) {
                        int expSign;
                        int expVal = 0;
                        if (str.charAt(i) == '-') {
                            expSign = -1;
                            i++;
                        } else {
                            expSign = 1;
                        }
                        for ( ; i < strlen ; ) {
                            expVal = expVal * 10 + ((int)str.charAt(i++)-(int)'0');
                        }
                        exponent += expVal * expSign;
                    }
                    exponent += decPos - nDigits;
                    if (nDigits == 0) {
                        digits[0] = '0';
                        nDigits = 1;
                        exponent = 0;
                    }
                    int intDigits, intZeroes, intLength;
                    int decDigits, decZeroes, decLength;
                    byte expChar;
                    if (negative) {
                        signChar = '-';
                        width--;
                    } else if ((flags & FLAG_PLUS) != 0) {
                        signChar = '+';
                        width--;
                    } else if ((flags & FLAG_SPACE) != 0) {
                        signChar = ' ';
                        width--;
                    } else {
                        signChar = 0;
                    }
                    if ((flags & FLAG_PRECISION) == 0) {
                        precision = 6;
                    }
                    switch(fchar) {
                    case 'E':
                    case 'G':
                        expChar = 'E';
                        break;
                    case 'e':
                    case 'g':
                        expChar = 'e';
                        break;
                    default:
                        expChar = 0;
                    }
                    switch(fchar) {
                    case 'g':
                    case 'G':
                        boolean expForm = (exponent + nDigits - 1 < -4 ||
                            exponent + nDigits > (precision == 0 ? 1 : precision));
                        if (expForm) {
                            decDigits = nDigits - 1;
                            precision = Math.max(0,precision - 1);
                            if (precision < decDigits) {
                                int n = round(digits,nDigits,precision,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                }
                                decDigits = Math.min(nDigits - 1,precision);
                            }
                            exponent += nDigits - 1;
                            boolean isSharp = (flags & FLAG_SHARP) != 0;
                            len++; 
                            if (exponent > 99)
                            	len += 5; 
                            else
                            	len += 4; 
                            if (isSharp) {
                            	len++;
                            }
                            if (precision > 0) {
                            	if (!isSharp) {
                            	    int j = decDigits;
                            	    for (; j >= 1; j--) {
                            	        if (digits[j]== '0') {
                            	            decDigits--;
                            	        } else {
                            	            break;
                            	        }
                            	    }
                            	    if (decDigits > 0) {
                            	        len += 1; 
                            	        len += decDigits;
                            	    }
                            	} else  {
                            	    len += precision;
                            	}
                            }
                            width -= len;
                            if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                                buf.fill(' ',width);
                                width = 0;
                            }
                            if (signChar != 0) {
                                buf.write(signChar);
                            }
                            if (width > 0 && (flags & FLAG_MINUS) == 0) {
                                buf.fill('0',width);
                                width = 0;
                            }
                            buf.write(digits[0]);
                            boolean dotToPrint = isSharp
                                    || (precision > 0 && decDigits > 0);
                            if (dotToPrint) {
                            	buf.write(args.getDecimalSeparator()); 
                            }
                            if (precision > 0 && decDigits > 0) {
                            	buf.write(digits, 1, decDigits);
                            	precision -= decDigits;
                            }
                            if (precision > 0 && isSharp) {
                            	buf.fill('0', precision);
                            }
                            writeExp(buf, exponent, expChar);
                            if (width > 0) {
                                buf.fill(' ', width);
                            }
                        } else { 
                            intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                            intZeroes = Math.max(0,exponent);
                            intLength = intDigits + intZeroes;
                            decDigits = nDigits - intDigits;
                            decZeroes = Math.max(0,-(decDigits + exponent));
                            decLength = decZeroes + decDigits;
                            precision = Math.max(0,precision - intLength);
                            if (precision < decDigits) {
                                int n = round(digits,nDigits,intDigits+precision-1,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                    intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                                    intLength = intDigits + intZeroes;
                                    decDigits = nDigits - intDigits;
                                    decZeroes = Math.max(0,-(decDigits + exponent));
                                    precision = Math.max(0,precision-1);
                                }
                                decDigits = precision;
                                decLength = decZeroes + decDigits;
                            }
                            len += intLength;
                            if (decLength > 0) {
                                len += decLength + 1;
                            } else {
                                if ((flags & FLAG_SHARP) != 0) {
                                    len++; 
                                    if (precision > 0) { 
                                        len += precision;
                                    }
                                }
                            }
                            width -= len;
                            if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                                buf.fill(' ',width);
                                width = 0;
                            }
                            if (signChar != 0) {
                                buf.write(signChar);
                            }
                            if (width > 0 && (flags & FLAG_MINUS) == 0) {
                                buf.fill('0',width);
                                width = 0;
                            }
                            if (intLength > 0){
                                if (intDigits > 0) { 
                                    buf.write(digits,0,intDigits);
                                }
                                if (intZeroes > 0) {
                                    buf.fill('0',intZeroes);
                                }
                            } else {
                                buf.write('0');
                            }
                            if (decLength > 0 || (flags & FLAG_SHARP) != 0) {
                                buf.write(args.getDecimalSeparator());
                            }
                            if (decLength > 0) {
                                if (decZeroes > 0) {
                                    buf.fill('0',decZeroes);
                                    precision -= decZeroes;
                                }
                                if (decDigits > 0) {
                                    buf.write(digits,intDigits,decDigits);
                                    precision -= decDigits;
                                }
                                if ((flags & FLAG_SHARP) != 0 && precision > 0) {
                                    buf.fill('0',precision);
                                 }
                            }
                            if ((flags & FLAG_SHARP) != 0 && precision > 0) {
                                buf.fill('0',precision);
                            }
                            if (width > 0) {
                                buf.fill(' ', width);
                            }
                        }
                        break;
                    case 'f':
                        intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                        intZeroes = Math.max(0,exponent);
                        intLength = intDigits + intZeroes;
                        decDigits = nDigits - intDigits;
                        decZeroes = Math.max(0,-(decDigits + exponent));
                        decLength = decZeroes + decDigits;
                        if (precision < decLength) {
                            if (precision < decZeroes) {
                                decDigits = 0;
                                decZeroes = precision;
                            } else {
                                int n = round(digits,nDigits,intDigits+precision-decZeroes-1,precision!=0);
                                if (n > nDigits) {
                                    nDigits = n;
                                    intDigits = Math.max(0,Math.min(nDigits + exponent,nDigits));
                                    intLength = intDigits + intZeroes;
                                    decDigits = nDigits - intDigits;
                                    decZeroes = Math.max(0,-(decDigits + exponent));
                                    decLength = decZeroes + decDigits;
                                }
                                decDigits = precision - decZeroes;
                            }
                            decLength = decZeroes + decDigits;
                        }
                        if (precision > 0) {
                            len += Math.max(1,intLength) + 1 + precision;
                        } else {
                            len += Math.max(1,intLength);
                            if ((flags & FLAG_SHARP) != 0) {
                                len++; 
                            }
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) {
                            buf.write(signChar);
                        }
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        if (intLength > 0){
                            if (intDigits > 0) { 
                                buf.write(digits,0,intDigits);
                            }
                            if (intZeroes > 0) {
                                buf.fill('0',intZeroes);
                            }
                        } else {
                            buf.write('0');
                        }
                        if (precision > 0 || (flags & FLAG_SHARP) != 0) {
                            buf.write(args.getDecimalSeparator());
                        }
                        if (precision > 0) {
                            if (decZeroes > 0) {
                                buf.fill('0',decZeroes);
                                precision -= decZeroes;
                            }
                            if (decDigits > 0) {
                                buf.write(digits,intDigits,decDigits);
                                precision -= decDigits;
                            }
                            if (precision > 0) {
                                buf.fill('0',precision);
                            }
                        }
                        if (width > 0) {
                            buf.fill(' ', width);
                        }
                        break;
                    case 'E':
                    case 'e':
                        decDigits = nDigits - 1;
                        if (precision < decDigits) {
                            int n = round(digits,nDigits,precision,precision!=0);
                            if (n > nDigits) {
                                nDigits = n;
                            }
                            decDigits = Math.min(nDigits - 1,precision);
                        }
                        exponent += nDigits - 1;
                        boolean isSharp = (flags & FLAG_SHARP) != 0;
                        len++; 
                        if (exponent > 99)
                            len += 5; 
                        else
                            len += 4; 
                        if (precision > 0) {
                            len += 1 + precision;
                        } else  if (isSharp) {
                            len++;  
                        }
                        width -= len;
                        if (width > 0 && (flags & (FLAG_ZERO|FLAG_MINUS)) == 0) {
                            buf.fill(' ',width);
                            width = 0;
                        }
                        if (signChar != 0) {
                            buf.write(signChar);
                        }
                        if (width > 0 && (flags & FLAG_MINUS) == 0) {
                            buf.fill('0',width);
                            width = 0;
                        }
                        buf.write(digits[0]);
                        if (precision > 0) {
                            buf.write(args.getDecimalSeparator()); 
                            if (decDigits > 0) {
                                buf.write(digits,1,decDigits);
                                precision -= decDigits;
                            }
                            if (precision > 0) {
                                buf.fill('0',precision);
                            }
                        } else if ((flags & FLAG_SHARP) != 0) {
                            buf.write(args.getDecimalSeparator());
                        }
                        writeExp(buf, exponent, expChar);
                        if (width > 0) {
                            buf.fill(' ', width);
                        }
                        break;
                    } 
                    offset++;
                    incomplete = false;
                    break;
                } 
                } 
            } 
            if (incomplete) {
                if (flags == FLAG_NONE) {
                    buf.write('%');
                } else {
                    raiseArgumentError(args,ERR_ILLEGAL_FORMAT_CHAR);
                }
            }
        } 
        return buf;
    }
