diff --git a/libcore/luni/src/main/java/java/util/Formatter.java b/libcore/luni/src/main/java/java/util/Formatter.java
index db35ef1..a27e7a1 100644
--- a/libcore/luni/src/main/java/java/util/Formatter.java
+++ b/libcore/luni/src/main/java/java/util/Formatter.java
@@ -529,6 +529,9 @@
 public final class Formatter implements Closeable, Flushable {
     private static final char[] ZEROS = new char[] { '0', '0', '0', '0', '0', '0', '0', '0', '0' };
 
+    // The cached line separator.
+    private static String lineSeparator;
+
     /**
      * The enumeration giving the available styles for formatting very large
      * decimal numbers.
@@ -544,13 +547,16 @@
         DECIMAL_FLOAT
     }
 
+    // User-settable parameters.
     private Appendable out;
-
     private Locale locale;
 
+    // Implementation details.
+    private Object arg;
     private boolean closed = false;
-
+    private FormatToken formatToken;
     private IOException lastIOException;
+    private LocaleData localeData;
 
     /**
      * Constructs a {@code Formatter}.
@@ -824,9 +830,7 @@
      * @throws UnsupportedEncodingException
      *             if the charset with the specified name is not supported.
      */
-    public Formatter(OutputStream os, String csn)
-            throws UnsupportedEncodingException {
-
+    public Formatter(OutputStream os, String csn) throws UnsupportedEncodingException {
         this(os, csn, Locale.getDefault());
     }
 
@@ -870,7 +874,7 @@
         locale = Locale.getDefault();
     }
 
-    private void checkClosed() {
+    private void checkNotClosed() {
         if (closed) {
             throw new FormatterClosedException();
         }
@@ -884,7 +888,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public Locale locale() {
-        checkClosed();
+        checkNotClosed();
         return locale;
     }
 
@@ -896,7 +900,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public Appendable out() {
-        checkClosed();
+        checkNotClosed();
         return out;
     }
 
@@ -911,7 +915,7 @@
      */
     @Override
     public String toString() {
-        checkClosed();
+        checkNotClosed();
         return out.toString();
     }
 
@@ -923,7 +927,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public void flush() {
-        checkClosed();
+        checkNotClosed();
         if (out instanceof Flushable) {
             try {
                 ((Flushable) out).flush();
@@ -986,17 +990,10 @@
      *             if the {@code Formatter} has been closed.
      */
     public Formatter format(String format, Object... args) {
-        doFormat(format, args);
-        return this;
+        return format(this.locale, format, args);
     }
 
     /**
-     * Cached transformer. Improves performance when format() is called multiple
-     * times.
-     */
-    private Transformer transformer;
-
-    /**
      * Writes a formatted string to the output destination of the {@code Formatter}.
      *
      * @param l
@@ -1022,7 +1019,8 @@
     public Formatter format(Locale l, String format, Object... args) {
         Locale originalLocale = locale;
         try {
-            this.locale = l;
+            this.locale = (l == null ? Locale.US : l);
+            this.localeData = LocaleData.get(locale);
             doFormat(format, args);
         } finally {
             this.locale = originalLocale;
@@ -1031,15 +1029,9 @@
     }
 
     private void doFormat(String format, Object... args) {
-        checkClosed();
-
-        // Reuse the previous transformer if the locale matches.
-        if (transformer == null || !transformer.locale.equals(locale)) {
-            transformer = new Transformer(this, locale);
-        }
+        checkNotClosed();
 
         FormatSpecifierParser fsp = new FormatSpecifierParser(format);
-
         int currentObjectIndex = 0;
         Object lastArgument = null;
         boolean hasLastArgumentSet = false;
@@ -1068,7 +1060,7 @@
                     hasLastArgumentSet = true;
                 }
 
-                CharSequence substitution = transformer.transform(token, argument);
+                CharSequence substitution = transform(token, argument);
                 // The substitution is null if we called Formattable.formatTo.
                 if (substitution != null) {
                     outputCharSequence(substitution, 0, substitution.length());
@@ -1398,923 +1390,820 @@
         }
     }
 
+    private NumberFormat getNumberFormat() {
+        return LocaleCache.getNumberFormat(locale);
+    }
+
     /*
-     * Transforms the argument to the formatted string according to the format
-     * information contained in the format token.
+     * Gets the formatted string according to the format token and the
+     * argument.
      */
-    private static class Transformer {
-        private Formatter formatter;
-        private FormatToken formatToken;
-        private Object arg;
-        private Locale locale;
-        private LocaleData localeData;
-        private static String lineSeparator;
+    private CharSequence transform(FormatToken token, Object argument) {
+        this.formatToken = token;
+        this.arg = argument;
 
-        Transformer(Formatter formatter, Locale locale) {
-            this.formatter = formatter;
-            this.locale = (locale == null ? Locale.US : locale);
-            this.localeData = LocaleData.get(locale);
-        }
-
-        private NumberFormat getNumberFormat() {
-            return LocaleCache.getNumberFormat(locale);
-        }
-
-        /*
-         * Gets the formatted string according to the format token and the
-         * argument.
-         */
-        CharSequence transform(FormatToken token, Object argument) {
-            this.formatToken = token;
-            this.arg = argument;
-
-            // There are only two format specifiers that matter: "%d" and "%s".
-            // Nothing else is common in the wild. We fast-path these two to
-            // avoid the heavyweight machinery needed to cope with flags, width,
-            // and precision.
-            if (token.isDefault()) {
-                switch (token.getConversionType()) {
-                case 's':
-                    if (arg == null) {
-                        return "null";
-                    } else if (!(arg instanceof Formattable)) {
-                        return arg.toString();
-                    }
-                    break;
-                case 'd':
-                    if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) {
-                        if (localeData.zeroDigit == '0') {
-                            return arg.toString();
-                        }
-                    }
-                }
-            }
-
-            formatToken.checkFlags(arg);
-            CharSequence result;
+        // There are only two format specifiers that matter: "%d" and "%s".
+        // Nothing else is common in the wild. We fast-path these two to
+        // avoid the heavyweight machinery needed to cope with flags, width,
+        // and precision.
+        if (token.isDefault()) {
             switch (token.getConversionType()) {
-                case 'B':
-                case 'b': {
-                    result = transformFromBoolean();
-                    break;
+            case 's':
+                if (arg == null) {
+                    return "null";
+                } else if (!(arg instanceof Formattable)) {
+                    return arg.toString();
                 }
-                case 'H':
-                case 'h': {
-                    result = transformFromHashCode();
-                    break;
-                }
-                case 'S':
-                case 's': {
-                    result = transformFromString();
-                    break;
-                }
-                case 'C':
-                case 'c': {
-                    result = transformFromCharacter();
-                    break;
-                }
-                case 'd':
-                case 'o':
-                case 'x':
-                case 'X': {
-                    if (arg == null || arg instanceof BigInteger) {
-                        result = transformFromBigInteger();
-                    } else {
-                        result = transformFromInteger();
-                    }
-                    break;
-                }
-                case 'e':
-                case 'E':
-                case 'g':
-                case 'G':
-                case 'f':
-                case 'a':
-                case 'A': {
-                    result = transformFromFloat();
-                    break;
-                }
-                case '%': {
-                    result = transformFromPercent();
-                    break;
-                }
-                case 'n': {
-                    result = transformFromLineSeparator();
-                    break;
-                }
-                case 't':
-                case 'T': {
-                    result = transformFromDateTime();
-                    break;
-                }
-                default:
-                    throw token.unknownFormatConversionException();
-            }
-
-            if (Character.isUpperCase(token.getConversionType())) {
-                if (result != null) {
-                    result = result.toString().toUpperCase(locale);
+                break;
+            case 'd':
+                if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) {
+                    String result = arg.toString();
+                    return (localeData.zeroDigit == '0') ? result : localizeDigits(result);
                 }
             }
-            return result;
         }
 
-        private IllegalFormatConversionException badArgumentType() {
-            throw new IllegalFormatConversionException(formatToken.getConversionType(),
-                    arg.getClass());
-        }
-
-        /*
-         * Transforms the Boolean argument to a formatted string.
-         */
-        private CharSequence transformFromBoolean() {
-            CharSequence result;
-            if (arg instanceof Boolean) {
-                result = arg.toString();
-            } else if (arg == null) {
-                result = "false";
+        formatToken.checkFlags(arg);
+        CharSequence result;
+        switch (token.getConversionType()) {
+        case 'B': case 'b':
+            result = transformFromBoolean();
+            break;
+        case 'H': case 'h':
+            result = transformFromHashCode();
+            break;
+        case 'S': case 's':
+            result = transformFromString();
+            break;
+        case 'C': case 'c':
+            result = transformFromCharacter();
+            break;
+        case 'd': case 'o': case 'x': case 'X':
+            if (arg == null || arg instanceof BigInteger) {
+                result = transformFromBigInteger();
             } else {
-                result = "true";
+                result = transformFromInteger();
             }
-            return padding(result, 0);
+            break;
+        case 'A': case 'a': case 'E': case 'e': case 'f': case 'G': case 'g':
+            result = transformFromFloat();
+            break;
+        case '%':
+            result = transformFromPercent();
+            break;
+        case 'n':
+            result = transformFromLineSeparator();
+            break;
+        case 't': case 'T':
+            result = transformFromDateTime();
+            break;
+        default:
+            throw token.unknownFormatConversionException();
         }
 
-        /*
-         * Transforms the hash code of the argument to a formatted string.
-         */
-        private CharSequence transformFromHashCode() {
-            CharSequence result;
-            if (arg == null) {
-                result = "null";
-            } else {
-                result = Integer.toHexString(arg.hashCode());
-            }
-            return padding(result, 0);
-        }
-
-        /*
-         * Transforms the String to a formatted string.
-         */
-        private CharSequence transformFromString() {
-            if (arg instanceof Formattable) {
-                int flags = 0;
-                if (formatToken.flagMinus) {
-                    flags |= FormattableFlags.LEFT_JUSTIFY;
-                }
-                if (formatToken.flagSharp) {
-                    flags |= FormattableFlags.ALTERNATE;
-                }
-                if (Character.isUpperCase(formatToken.getConversionType())) {
-                    flags |= FormattableFlags.UPPERCASE;
-                }
-                ((Formattable) arg).formatTo(formatter, flags, formatToken.getWidth(),
-                        formatToken.getPrecision());
-                // all actions have been taken out in the
-                // Formattable.formatTo, thus there is nothing to do, just
-                // returns null, which tells the Parser to add nothing to the
-                // output.
-                return null;
-            }
-            CharSequence result = arg != null ? arg.toString() : "null";
-            return padding(result, 0);
-        }
-
-        /*
-         * Transforms the Character to a formatted string.
-         */
-        private CharSequence transformFromCharacter() {
-            if (arg == null) {
-                return padding("null", 0);
-            }
-            if (arg instanceof Character) {
-                return padding(String.valueOf(arg), 0);
-            } else if (arg instanceof Byte || arg instanceof Short || arg instanceof Integer) {
-                int codePoint = ((Number) arg).intValue();
-                if (!Character.isValidCodePoint(codePoint)) {
-                    throw new IllegalFormatCodePointException(codePoint);
-                }
-                CharSequence result = (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT)
-                        ? String.valueOf((char) codePoint)
-                        : String.valueOf(Character.toChars(codePoint));
-                return padding(result, 0);
-            } else {
-                throw badArgumentType();
+        if (Character.isUpperCase(token.getConversionType())) {
+            if (result != null) {
+                result = result.toString().toUpperCase(locale);
             }
         }
+        return result;
+    }
 
-        /*
-         * Transforms percent to a formatted string. Only '-' is legal flag.
-         * Precision and arguments are illegal.
-         */
-        private CharSequence transformFromPercent() {
-            return padding("%", 0);
+    private IllegalFormatConversionException badArgumentType() {
+        throw new IllegalFormatConversionException(formatToken.getConversionType(), arg.getClass());
+    }
+
+    /**
+     * Returns a CharSequence corresponding to {@code s} with all the ASCII digits replaced
+     * by digits appropriate to this formatter's locale. Other characters remain unchanged.
+     */
+    private CharSequence localizeDigits(String s) {
+        int length = s.length();
+        int offsetToLocalizedDigits = localeData.zeroDigit - '0';
+        StringBuilder result = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            char ch = s.charAt(i);
+            if (ch >= '0' && ch <= '9') {
+                ch += offsetToLocalizedDigits;
+            }
+            result.append(ch);
         }
+        return result;
+    }
 
-        /*
-         * Transforms line separator to a formatted string. Any flag, width,
-         * precision or argument is illegal.
-         */
-        private CharSequence transformFromLineSeparator() {
-            if (lineSeparator == null) {
-                lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
-                    public String run() {
-                        return System.getProperty("line.separator");
-                    }
-                });
-            }
-            return lineSeparator;
+    private CharSequence transformFromBoolean() {
+        CharSequence result;
+        if (arg instanceof Boolean) {
+            result = arg.toString();
+        } else if (arg == null) {
+            result = "false";
+        } else {
+            result = "true";
         }
+        return padding(result, 0);
+    }
 
-        /*
-         * Pads characters to the formatted string.
-         */
-        private CharSequence padding(CharSequence source, int startIndex) {
-            boolean sourceIsStringBuilder = (source instanceof StringBuilder);
-
-            int start = startIndex;
-            int width = formatToken.getWidth();
-            int precision = formatToken.getPrecision();
-
-            int length = source.length();
-            if (precision >= 0) {
-                length = Math.min(length, precision);
-                if (sourceIsStringBuilder) {
-                    ((StringBuilder) source).setLength(length);
-                } else {
-                    source = source.subSequence(0, length);
-                }
-            }
-            if (width > 0) {
-                width = Math.max(source.length(), width);
-            }
-            if (length >= width) {
-                return source;
-            }
-
-            char paddingChar = '\u0020'; // space as padding char.
-            if (formatToken.flagZero) {
-                if (formatToken.getConversionType() == 'd') {
-                    paddingChar = localeData.zeroDigit;
-                } else {
-                    paddingChar = '0'; // No localized digits for bases other than decimal.
-                }
-            } else {
-                // if padding char is space, always pad from the start.
-                start = 0;
-            }
-            char[] paddingChars = new char[width - length];
-            Arrays.fill(paddingChars, paddingChar);
-
-            boolean paddingRight = formatToken.flagMinus;
-            StringBuilder result = toStringBuilder(source);
-            if (paddingRight) {
-                result.append(paddingChars);
-            } else {
-                result.insert(start, paddingChars);
-            }
-            return result;
+    private CharSequence transformFromHashCode() {
+        CharSequence result;
+        if (arg == null) {
+            result = "null";
+        } else {
+            result = Integer.toHexString(arg.hashCode());
         }
+        return padding(result, 0);
+    }
 
-        private StringBuilder toStringBuilder(CharSequence cs) {
-            return cs instanceof StringBuilder ? (StringBuilder) cs : new StringBuilder(cs);
-        }
-
-        private StringBuilder wrapParentheses(StringBuilder result) {
-            result.setCharAt(0, '('); // Replace the '-'.
-            if (formatToken.flagZero) {
-                formatToken.setWidth(formatToken.getWidth() - 1);
-                result = (StringBuilder) padding(result, 1);
-                result.append(')');
-            } else {
-                result.append(')');
-                result = (StringBuilder) padding(result, 0);
+    private CharSequence transformFromString() {
+        if (arg instanceof Formattable) {
+            int flags = 0;
+            if (formatToken.flagMinus) {
+                flags |= FormattableFlags.LEFT_JUSTIFY;
             }
-            return result;
-        }
-
-        /*
-         * Transforms the Integer to a formatted string.
-         */
-        private CharSequence transformFromInteger() {
-            int startIndex = 0;
-            StringBuilder result = new StringBuilder();
-            char currentConversionType = formatToken.getConversionType();
-
-            long value;
-            if (arg instanceof Long) {
-                value = ((Long) arg).longValue();
-            } else if (arg instanceof Integer) {
-                value = ((Integer) arg).longValue();
-            } else if (arg instanceof Short) {
-                value = ((Short) arg).longValue();
-            } else if (arg instanceof Byte) {
-                value = ((Byte) arg).longValue();
-            } else {
-                throw badArgumentType();
-            }
-
             if (formatToken.flagSharp) {
-                if (currentConversionType == 'o') {
-                    result.append("0");
-                    startIndex += 1;
-                } else {
-                    result.append("0x");
-                    startIndex += 2;
-                }
+                flags |= FormattableFlags.ALTERNATE;
             }
-
-            if ('d' == currentConversionType) {
-                if (formatToken.flagComma || localeData.zeroDigit != '0') {
-                    NumberFormat numberFormat = getNumberFormat();
-                    numberFormat.setGroupingUsed(formatToken.flagComma);
-                    result.append(numberFormat.format(arg));
-                } else {
-                    result.append(value);
-                }
-
-                if (value < 0) {
-                    if (formatToken.flagParenthesis) {
-                        return wrapParentheses(result);
-                    } else if (formatToken.flagZero) {
-                        startIndex++;
-                    }
-                } else {
-                    if (formatToken.flagAdd) {
-                        result.insert(0, '+');
-                        startIndex += 1;
-                    } else if (formatToken.flagSpace) {
-                        result.insert(0, ' ');
-                        startIndex += 1;
-                    }
-                }
-            } else {
-                // Undo sign-extension, since we'll be using Long.to(Octal|Hex)String.
-                if (arg instanceof Byte) {
-                    value &= 0xffL;
-                } else if (arg instanceof Short) {
-                    value &= 0xffffL;
-                } else if (arg instanceof Integer) {
-                    value &= 0xffffffffL;
-                }
-                if ('o' == currentConversionType) {
-                    result.append(Long.toOctalString(value));
-                } else {
-                    result.append(Long.toHexString(value));
-                }
+            if (Character.isUpperCase(formatToken.getConversionType())) {
+                flags |= FormattableFlags.UPPERCASE;
             }
-
-            return padding(result, startIndex);
+            ((Formattable) arg).formatTo(this, flags, formatToken.getWidth(),
+                    formatToken.getPrecision());
+            // all actions have been taken out in the
+            // Formattable.formatTo, thus there is nothing to do, just
+            // returns null, which tells the Parser to add nothing to the
+            // output.
+            return null;
         }
+        CharSequence result = arg != null ? arg.toString() : "null";
+        return padding(result, 0);
+    }
 
-        private CharSequence transformFromSpecialNumber() {
-            if (!(arg instanceof Number) || arg instanceof BigDecimal) {
-                return null;
-            }
-
-            Number number = (Number) arg;
-            double d = number.doubleValue();
-            String source = null;
-            if (Double.isNaN(d)) {
-                source = "NaN";
-            } else if (d == Double.POSITIVE_INFINITY) {
-                if (formatToken.flagAdd) {
-                    source = "+Infinity";
-                } else if (formatToken.flagSpace) {
-                    source = " Infinity";
-                } else {
-                    source = "Infinity";
-                }
-            } else if (d == Double.NEGATIVE_INFINITY) {
-                if (formatToken.flagParenthesis) {
-                    source = "(Infinity)";
-                } else {
-                    source = "-Infinity";
-                }
-            } else {
-                return null;
-            }
-
-            formatToken.setPrecision(FormatToken.UNSET);
-            formatToken.flagZero = false;
-            return padding(source, 0);
-        }
-
-        private CharSequence transformFromNull() {
-            formatToken.flagZero = false;
+    private CharSequence transformFromCharacter() {
+        if (arg == null) {
             return padding("null", 0);
         }
-
-        /*
-         * Transforms a BigInteger to a formatted string.
-         */
-        private CharSequence transformFromBigInteger() {
-            int startIndex = 0;
-            boolean isNegative = false;
-            StringBuilder result = new StringBuilder();
-            BigInteger bigInt = (BigInteger) arg;
-            char currentConversionType = formatToken.getConversionType();
-
-            if (bigInt == null) {
-                return transformFromNull();
+        if (arg instanceof Character) {
+            return padding(String.valueOf(arg), 0);
+        } else if (arg instanceof Byte || arg instanceof Short || arg instanceof Integer) {
+            int codePoint = ((Number) arg).intValue();
+            if (!Character.isValidCodePoint(codePoint)) {
+                throw new IllegalFormatCodePointException(codePoint);
             }
+            CharSequence result = (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT)
+                    ? String.valueOf((char) codePoint)
+                    : String.valueOf(Character.toChars(codePoint));
+            return padding(result, 0);
+        } else {
+            throw badArgumentType();
+        }
+    }
 
-            isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0);
+    private CharSequence transformFromPercent() {
+        return padding("%", 0);
+    }
 
-            if ('d' == currentConversionType) {
-                NumberFormat numberFormat = getNumberFormat();
-                numberFormat.setGroupingUsed(formatToken.flagComma);
-                result.append(numberFormat.format(bigInt));
-            } else if ('o' == currentConversionType) {
-                // convert BigInteger to a string presentation using radix 8
-                result.append(bigInt.toString(8));
-            } else {
-                // convert BigInteger to a string presentation using radix 16
-                result.append(bigInt.toString(16));
-            }
-            if (formatToken.flagSharp) {
-                startIndex = isNegative ? 1 : 0;
-                if (currentConversionType == 'o') {
-                    result.insert(startIndex, "0");
-                    startIndex += 1;
-                } else if (currentConversionType == 'x' || currentConversionType == 'X') {
-                    result.insert(startIndex, "0x");
-                    startIndex += 2;
+    private CharSequence transformFromLineSeparator() {
+        if (lineSeparator == null) {
+            lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("line.separator");
                 }
+            });
+        }
+        return lineSeparator;
+    }
+
+    private CharSequence padding(CharSequence source, int startIndex) {
+        int start = startIndex;
+        int width = formatToken.getWidth();
+        int precision = formatToken.getPrecision();
+
+        int length = source.length();
+        if (precision >= 0) {
+            length = Math.min(length, precision);
+            if (source instanceof StringBuilder) {
+                ((StringBuilder) source).setLength(length);
+            } else {
+                source = source.subSequence(0, length);
+            }
+        }
+        if (width > 0) {
+            width = Math.max(source.length(), width);
+        }
+        if (length >= width) {
+            return source;
+        }
+
+        char paddingChar = '\u0020'; // space as padding char.
+        if (formatToken.flagZero) {
+            if (formatToken.getConversionType() == 'd') {
+                paddingChar = localeData.zeroDigit;
+            } else {
+                paddingChar = '0'; // No localized digits for bases other than decimal.
+            }
+        } else {
+            // if padding char is space, always pad from the start.
+            start = 0;
+        }
+        char[] paddingChars = new char[width - length];
+        Arrays.fill(paddingChars, paddingChar);
+
+        boolean paddingRight = formatToken.flagMinus;
+        StringBuilder result = toStringBuilder(source);
+        if (paddingRight) {
+            result.append(paddingChars);
+        } else {
+            result.insert(start, paddingChars);
+        }
+        return result;
+    }
+
+    private StringBuilder toStringBuilder(CharSequence cs) {
+        return cs instanceof StringBuilder ? (StringBuilder) cs : new StringBuilder(cs);
+    }
+
+    private StringBuilder wrapParentheses(StringBuilder result) {
+        result.setCharAt(0, '('); // Replace the '-'.
+        if (formatToken.flagZero) {
+            formatToken.setWidth(formatToken.getWidth() - 1);
+            result = (StringBuilder) padding(result, 1);
+            result.append(')');
+        } else {
+            result.append(')');
+            result = (StringBuilder) padding(result, 0);
+        }
+        return result;
+    }
+
+    private CharSequence transformFromInteger() {
+        int startIndex = 0;
+        StringBuilder result = new StringBuilder();
+        char currentConversionType = formatToken.getConversionType();
+
+        long value;
+        if (arg instanceof Long) {
+            value = ((Long) arg).longValue();
+        } else if (arg instanceof Integer) {
+            value = ((Integer) arg).longValue();
+        } else if (arg instanceof Short) {
+            value = ((Short) arg).longValue();
+        } else if (arg instanceof Byte) {
+            value = ((Byte) arg).longValue();
+        } else {
+            throw badArgumentType();
+        }
+
+        if (formatToken.flagSharp) {
+            if (currentConversionType == 'o') {
+                result.append("0");
+                startIndex += 1;
+            } else {
+                result.append("0x");
+                startIndex += 2;
+            }
+        }
+
+        if ('d' == currentConversionType) {
+            if (formatToken.flagComma) {
+                NumberFormat numberFormat = getNumberFormat();
+                numberFormat.setGroupingUsed(true);
+                result.append(numberFormat.format(arg));
+            } else if (localeData.zeroDigit != '0') {
+                result.append(localizeDigits(Long.toString(value)));
+            } else {
+                result.append(value);
             }
 
-            if (!isNegative) {
+            if (value < 0) {
+                if (formatToken.flagParenthesis) {
+                    return wrapParentheses(result);
+                } else if (formatToken.flagZero) {
+                    startIndex++;
+                }
+            } else {
                 if (formatToken.flagAdd) {
                     result.insert(0, '+');
                     startIndex += 1;
-                }
-                if (formatToken.flagSpace) {
+                } else if (formatToken.flagSpace) {
                     result.insert(0, ' ');
                     startIndex += 1;
                 }
             }
-
-            /* pad paddingChar to the output */
-            if (isNegative && formatToken.flagParenthesis) {
-                return wrapParentheses(result);
+        } else {
+            // Undo sign-extension, since we'll be using Long.to(Octal|Hex)String.
+            if (arg instanceof Byte) {
+                value &= 0xffL;
+            } else if (arg instanceof Short) {
+                value &= 0xffffL;
+            } else if (arg instanceof Integer) {
+                value &= 0xffffffffL;
             }
-            if (isNegative && formatToken.flagZero) {
-                startIndex++;
+            if ('o' == currentConversionType) {
+                result.append(Long.toOctalString(value));
+            } else {
+                result.append(Long.toHexString(value));
             }
-            return padding(result, startIndex);
         }
 
-        /*
-         * Transforms a Float,Double or BigDecimal to a formatted string.
-         */
-        private CharSequence transformFromFloat() {
-            StringBuilder result = new StringBuilder();
-            int startIndex = 0;
-            char currentConversionType = formatToken.getConversionType();
+        return padding(result, startIndex);
+    }
 
-            if (arg == null) {
-                return transformFromNull();
-            }
+    private CharSequence transformFromSpecialNumber() {
+        if (!(arg instanceof Number) || arg instanceof BigDecimal) {
+            return null;
+        }
 
-            if (!(arg instanceof Float || arg instanceof Double || arg instanceof BigDecimal)) {
-                throw badArgumentType();
-            }
-
-            CharSequence specialNumberResult = transformFromSpecialNumber();
-            if (null != specialNumberResult) {
-                return specialNumberResult;
-            }
-
-            if (currentConversionType != 'a' && currentConversionType != 'A' &&
-                    !formatToken.isPrecisionSet()) {
-                formatToken.setPrecision(FormatToken.DEFAULT_PRECISION);
-            }
-
-            // output result
-            FloatUtil floatUtil = new FloatUtil(result, formatToken,
-                    (DecimalFormat) getNumberFormat(), localeData, arg);
-            floatUtil.transform(currentConversionType);
-
-            formatToken.setPrecision(FormatToken.UNSET);
-
-            if (localeData.minusSign == result.charAt(0)) {
-                if (formatToken.flagParenthesis) {
-                    return wrapParentheses(result);
-                }
+        Number number = (Number) arg;
+        double d = number.doubleValue();
+        String source = null;
+        if (Double.isNaN(d)) {
+            source = "NaN";
+        } else if (d == Double.POSITIVE_INFINITY) {
+            if (formatToken.flagAdd) {
+                source = "+Infinity";
+            } else if (formatToken.flagSpace) {
+                source = " Infinity";
             } else {
-                if (formatToken.flagSpace) {
-                    result.insert(0, ' ');
-                    startIndex++;
-                }
-                if (formatToken.flagAdd) {
-                    result.insert(0, floatUtil.getAddSign());
-                    startIndex++;
-                }
+                source = "Infinity";
             }
-
-            char firstChar = result.charAt(0);
-            if (formatToken.flagZero && (firstChar == floatUtil.getAddSign() || firstChar == localeData.minusSign)) {
-                startIndex = 1;
+        } else if (d == Double.NEGATIVE_INFINITY) {
+            if (formatToken.flagParenthesis) {
+                source = "(Infinity)";
+            } else {
+                source = "-Infinity";
             }
+        } else {
+            return null;
+        }
 
-            if (currentConversionType == 'a' || currentConversionType == 'A') {
+        formatToken.setPrecision(FormatToken.UNSET);
+        formatToken.flagZero = false;
+        return padding(source, 0);
+    }
+
+    private CharSequence transformFromNull() {
+        formatToken.flagZero = false;
+        return padding("null", 0);
+    }
+
+    private CharSequence transformFromBigInteger() {
+        int startIndex = 0;
+        StringBuilder result = new StringBuilder();
+        BigInteger bigInt = (BigInteger) arg;
+        char currentConversionType = formatToken.getConversionType();
+
+        if (bigInt == null) {
+            return transformFromNull();
+        }
+
+        boolean isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0);
+
+        if ('d' == currentConversionType) {
+            NumberFormat numberFormat = getNumberFormat();
+            numberFormat.setGroupingUsed(formatToken.flagComma);
+            result.append(numberFormat.format(bigInt));
+        } else if ('o' == currentConversionType) {
+            // convert BigInteger to a string presentation using radix 8
+            result.append(bigInt.toString(8));
+        } else {
+            // convert BigInteger to a string presentation using radix 16
+            result.append(bigInt.toString(16));
+        }
+        if (formatToken.flagSharp) {
+            startIndex = isNegative ? 1 : 0;
+            if (currentConversionType == 'o') {
+                result.insert(startIndex, "0");
+                startIndex += 1;
+            } else if (currentConversionType == 'x' || currentConversionType == 'X') {
+                result.insert(startIndex, "0x");
                 startIndex += 2;
             }
-            return padding(result, startIndex);
         }
 
-        /*
-         * Transforms a Date to a formatted string.
-         */
-        private CharSequence transformFromDateTime() {
-            if (arg == null) {
-                return transformFromNull();
+        if (!isNegative) {
+            if (formatToken.flagAdd) {
+                result.insert(0, '+');
+                startIndex += 1;
             }
+            if (formatToken.flagSpace) {
+                result.insert(0, ' ');
+                startIndex += 1;
+            }
+        }
 
-            Calendar calendar;
-            if (arg instanceof Calendar) {
-                calendar = (Calendar) arg;
-            } else {
-                Date date = null;
-                if (arg instanceof Long) {
-                    date = new Date(((Long) arg).longValue());
-                } else if (arg instanceof Date) {
-                    date = (Date) arg;
-                } else {
-                    throw badArgumentType();
-                }
-                calendar = Calendar.getInstance(locale);
-                calendar.setTime(date);
-            }
+        /* pad paddingChar to the output */
+        if (isNegative && formatToken.flagParenthesis) {
+            return wrapParentheses(result);
+        }
+        if (isNegative && formatToken.flagZero) {
+            startIndex++;
+        }
+        return padding(result, startIndex);
+    }
 
-            StringBuilder result = new StringBuilder();
-            if (!appendT(result, formatToken.getDateSuffix(), calendar)) {
-                throw formatToken.unknownFormatConversionException();
-            }
-            return padding(result, 0);
+    private CharSequence transformFromDateTime() {
+        if (arg == null) {
+            return transformFromNull();
         }
-        
-        private boolean appendT(StringBuilder result, char conversion, Calendar calendar) {
-            switch (conversion) {
-            case 'A':
-                result.append(localeData.longWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
-                return true;
-            case 'a':
-                result.append(localeData.shortWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
-                return true;
-            case 'B':
-                result.append(localeData.longMonthNames[calendar.get(Calendar.MONTH)]);
-                return true;
-            case 'b': case 'h':
-                result.append(localeData.shortMonthNames[calendar.get(Calendar.MONTH)]);
-                return true;
-            case 'C':
-                appendLocalized(result, calendar.get(Calendar.YEAR) / 100, 2);
-                return true;
-            case 'D':
-                appendT(result, 'm', calendar);
-                result.append('/');
-                appendT(result, 'd', calendar);
-                result.append('/');
-                appendT(result, 'y', calendar);
-                return true;
-            case 'F':
-                appendT(result, 'Y', calendar);
-                result.append('-');
-                appendT(result, 'm', calendar);
-                result.append('-');
-                appendT(result, 'd', calendar);
-                return true;
-            case 'H':
-                appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 2);
-                return true;
-            case 'I':
-                appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 2);
-                return true;
-            case 'L':
-                appendLocalized(result, calendar.get(Calendar.MILLISECOND), 3);
-                return true;
-            case 'M':
-                appendLocalized(result, calendar.get(Calendar.MINUTE), 2);
-                return true;
-            case 'N':
-                appendLocalized(result, calendar.get(Calendar.MILLISECOND) * 1000000L, 9);
-                return true;
-            case 'Q':
-                appendLocalized(result, calendar.getTimeInMillis(), 0);
-                return true;
-            case 'R':
-                appendT(result, 'H', calendar);
-                result.append(':');
-                appendT(result, 'M', calendar);
-                return true;
-            case 'S':
-                appendLocalized(result, calendar.get(Calendar.SECOND), 2);
-                return true;
-            case 'T':
-                appendT(result, 'H', calendar);
-                result.append(':');
-                appendT(result, 'M', calendar);
-                result.append(':');
-                appendT(result, 'S', calendar);
-                return true;
-            case 'Y':
-                appendLocalized(result, calendar.get(Calendar.YEAR), 4);
-                return true;
-            case 'Z':
-                TimeZone timeZone = calendar.getTimeZone();
-                result.append(timeZone.getDisplayName(timeZone.inDaylightTime(calendar.getTime()),
-                        TimeZone.SHORT, locale));
-                return true;
-            case 'c':
-                appendT(result, 'a', calendar);
-                result.append(' ');
-                appendT(result, 'b', calendar);
-                result.append(' ');
-                appendT(result, 'd', calendar);
-                result.append(' ');
-                appendT(result, 'T', calendar);
-                result.append(' ');
-                appendT(result, 'Z', calendar);
-                result.append(' ');
-                appendT(result, 'Y', calendar);
-                return true;
-            case 'd':
-                appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 2);
-                return true;
-            case 'e':
-                appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 0);
-                return true;
-            case 'j':
-                appendLocalized(result, calendar.get(Calendar.DAY_OF_YEAR), 3);
-                return true;
-            case 'k':
-                appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 0);
-                return true;
-            case 'l':
-                appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 0);
-                return true;
-            case 'm':
-                // Calendar.JANUARY is 0; humans want January represented as 1.
-                appendLocalized(result, calendar.get(Calendar.MONTH) + 1, 2);
-                return true;
-            case 'p':
-                result.append(localeData.amPm[calendar.get(Calendar.AM_PM)].toLowerCase(locale));
-                return true;
-            case 'r':
-                appendT(result, 'I', calendar);
-                result.append(':');
-                appendT(result, 'M', calendar);
-                result.append(':');
-                appendT(result, 'S', calendar);
-                result.append(' ');
-                result.append(localeData.amPm[calendar.get(Calendar.AM_PM)]);
-                return true;
-            case 's':
-                appendLocalized(result, calendar.getTimeInMillis() / 1000, 0);
-                return true;
-            case 'y':
-                appendLocalized(result, calendar.get(Calendar.YEAR) % 100, 2);
-                return true;
-            case 'z':
-                long offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
-                char sign = '+';
-                if (offset < 0) {
-                    sign = '-';
-                    offset = -offset;
-                }
-                result.append(sign);
-                appendLocalized(result, offset / 3600000, 2);
-                appendLocalized(result, (offset % 3600000) / 60000, 2);
-                return true;
-            }
-            return false;
-        }
-        
-        private int to12Hour(int hour) {
-            return hour == 0 ? 12 : hour;
-        }
-        
-        private void appendLocalized(StringBuilder result, long value, int width) {
-            int paddingIndex = result.length();
-            char zeroDigit = localeData.zeroDigit;
-            if (zeroDigit == '0') {
-                result.append(value);
+
+        Calendar calendar;
+        if (arg instanceof Calendar) {
+            calendar = (Calendar) arg;
+        } else {
+            Date date = null;
+            if (arg instanceof Long) {
+                date = new Date(((Long) arg).longValue());
+            } else if (arg instanceof Date) {
+                date = (Date) arg;
             } else {
-                NumberFormat numberFormat = getNumberFormat();
-                numberFormat.setGroupingUsed(false);
-                result.append(numberFormat.format(value));
+                throw badArgumentType();
             }
-            int zeroCount = width - (result.length() - paddingIndex);
-            if (zeroCount <= 0) {
-                return;
+            calendar = Calendar.getInstance(locale);
+            calendar.setTime(date);
+        }
+
+        StringBuilder result = new StringBuilder();
+        if (!appendT(result, formatToken.getDateSuffix(), calendar)) {
+            throw formatToken.unknownFormatConversionException();
+        }
+        return padding(result, 0);
+    }
+        
+    private boolean appendT(StringBuilder result, char conversion, Calendar calendar) {
+        switch (conversion) {
+        case 'A':
+            result.append(localeData.longWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
+            return true;
+        case 'a':
+            result.append(localeData.shortWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
+            return true;
+        case 'B':
+            result.append(localeData.longMonthNames[calendar.get(Calendar.MONTH)]);
+            return true;
+        case 'b': case 'h':
+            result.append(localeData.shortMonthNames[calendar.get(Calendar.MONTH)]);
+            return true;
+        case 'C':
+            appendLocalized(result, calendar.get(Calendar.YEAR) / 100, 2);
+            return true;
+        case 'D':
+            appendT(result, 'm', calendar);
+            result.append('/');
+            appendT(result, 'd', calendar);
+            result.append('/');
+            appendT(result, 'y', calendar);
+            return true;
+        case 'F':
+            appendT(result, 'Y', calendar);
+            result.append('-');
+            appendT(result, 'm', calendar);
+            result.append('-');
+            appendT(result, 'd', calendar);
+            return true;
+        case 'H':
+            appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 2);
+            return true;
+        case 'I':
+            appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 2);
+            return true;
+        case 'L':
+            appendLocalized(result, calendar.get(Calendar.MILLISECOND), 3);
+            return true;
+        case 'M':
+            appendLocalized(result, calendar.get(Calendar.MINUTE), 2);
+            return true;
+        case 'N':
+            appendLocalized(result, calendar.get(Calendar.MILLISECOND) * 1000000L, 9);
+            return true;
+        case 'Q':
+            appendLocalized(result, calendar.getTimeInMillis(), 0);
+            return true;
+        case 'R':
+            appendT(result, 'H', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            return true;
+        case 'S':
+            appendLocalized(result, calendar.get(Calendar.SECOND), 2);
+            return true;
+        case 'T':
+            appendT(result, 'H', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            result.append(':');
+            appendT(result, 'S', calendar);
+            return true;
+        case 'Y':
+            appendLocalized(result, calendar.get(Calendar.YEAR), 4);
+            return true;
+        case 'Z':
+            TimeZone timeZone = calendar.getTimeZone();
+            result.append(timeZone.getDisplayName(timeZone.inDaylightTime(calendar.getTime()),
+                    TimeZone.SHORT, locale));
+            return true;
+        case 'c':
+            appendT(result, 'a', calendar);
+            result.append(' ');
+            appendT(result, 'b', calendar);
+            result.append(' ');
+            appendT(result, 'd', calendar);
+            result.append(' ');
+            appendT(result, 'T', calendar);
+            result.append(' ');
+            appendT(result, 'Z', calendar);
+            result.append(' ');
+            appendT(result, 'Y', calendar);
+            return true;
+        case 'd':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 2);
+            return true;
+        case 'e':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 0);
+            return true;
+        case 'j':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_YEAR), 3);
+            return true;
+        case 'k':
+            appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 0);
+            return true;
+        case 'l':
+            appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 0);
+            return true;
+        case 'm':
+            // Calendar.JANUARY is 0; humans want January represented as 1.
+            appendLocalized(result, calendar.get(Calendar.MONTH) + 1, 2);
+            return true;
+        case 'p':
+            result.append(localeData.amPm[calendar.get(Calendar.AM_PM)].toLowerCase(locale));
+            return true;
+        case 'r':
+            appendT(result, 'I', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            result.append(':');
+            appendT(result, 'S', calendar);
+            result.append(' ');
+            result.append(localeData.amPm[calendar.get(Calendar.AM_PM)]);
+            return true;
+        case 's':
+            appendLocalized(result, calendar.getTimeInMillis() / 1000, 0);
+            return true;
+        case 'y':
+            appendLocalized(result, calendar.get(Calendar.YEAR) % 100, 2);
+            return true;
+        case 'z':
+            long offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
+            char sign = '+';
+            if (offset < 0) {
+                sign = '-';
+                offset = -offset;
             }
-            if (zeroDigit == '0') {
-                result.insert(paddingIndex, ZEROS, 0, zeroCount);
-            } else {
-                for (int i = 0; i < zeroCount; ++i) {
-                    result.insert(paddingIndex, zeroDigit);
-                }
+            result.append(sign);
+            appendLocalized(result, offset / 3600000, 2);
+            appendLocalized(result, (offset % 3600000) / 60000, 2);
+            return true;
+        }
+        return false;
+    }
+    
+    private int to12Hour(int hour) {
+        return hour == 0 ? 12 : hour;
+    }
+    
+    private void appendLocalized(StringBuilder result, long value, int width) {
+        int paddingIndex = result.length();
+        char zeroDigit = localeData.zeroDigit;
+        if (zeroDigit == '0') {
+            result.append(value);
+        } else {
+            result.append(localizeDigits(Long.toString(value)));
+        }
+        int zeroCount = width - (result.length() - paddingIndex);
+        if (zeroCount <= 0) {
+            return;
+        }
+        if (zeroDigit == '0') {
+            result.insert(paddingIndex, ZEROS, 0, zeroCount);
+        } else {
+            for (int i = 0; i < zeroCount; ++i) {
+                result.insert(paddingIndex, zeroDigit);
             }
         }
     }
 
-    // TODO: merge this into Transformer; the distinction is not obviously useful.
-    private static class FloatUtil {
-        private final StringBuilder result;
-        private final DecimalFormat decimalFormat;
-        private final LocaleData localeData;
-        private final FormatToken formatToken;
-        private final Object argument;
-
-        FloatUtil(StringBuilder result, FormatToken formatToken, DecimalFormat decimalFormat,
-                LocaleData localeData, Object argument) {
-            this.result = result;
-            this.formatToken = formatToken;
-            this.decimalFormat = decimalFormat;
-            this.localeData = localeData;
-            this.argument = argument;
+    private CharSequence transformFromFloat() {
+        if (arg == null) {
+            return transformFromNull();
         }
 
-        void transform(char conversionType) {
-            switch (conversionType) {
-            case 'a': case 'A':
-                transform_a();
-                break;
-            case 'e': case 'E':
-                transform_e();
-                break;
-            case 'f':
-                transform_f();
-                break;
-            case 'g':
-            case 'G':
-                transform_g();
-                break;
-            default:
-                throw formatToken.unknownFormatConversionException();
+        if (!(arg instanceof Float || arg instanceof Double || arg instanceof BigDecimal)) {
+            throw badArgumentType();
+        }
+
+        CharSequence specialNumberResult = transformFromSpecialNumber();
+        if (specialNumberResult != null) {
+            return specialNumberResult;
+        }
+
+        char conversionType = formatToken.getConversionType();
+        if (conversionType != 'a' && conversionType != 'A' && !formatToken.isPrecisionSet()) {
+            formatToken.setPrecision(FormatToken.DEFAULT_PRECISION);
+        }
+
+        StringBuilder result = new StringBuilder();
+        switch (conversionType) {
+        case 'a': case 'A':
+            transform_a(result);
+            break;
+        case 'e': case 'E':
+            transform_e(result);
+            break;
+        case 'f':
+            transform_f(result);
+            break;
+        case 'g':
+        case 'G':
+            transform_g(result);
+            break;
+        default:
+            throw formatToken.unknownFormatConversionException();
+        }
+
+        formatToken.setPrecision(FormatToken.UNSET);
+
+        int startIndex = 0;
+        if (localeData.minusSign == result.charAt(0)) {
+            if (formatToken.flagParenthesis) {
+                return wrapParentheses(result);
+            }
+        } else {
+            if (formatToken.flagSpace) {
+                result.insert(0, ' ');
+                startIndex++;
+            }
+            if (formatToken.flagAdd) {
+                result.insert(0, '+');
+                startIndex++;
             }
         }
 
-        char getAddSign() {
-            return '+';
+        char firstChar = result.charAt(0);
+        if (formatToken.flagZero && (firstChar == '+' || firstChar == localeData.minusSign)) {
+            startIndex = 1;
         }
 
-        void transform_e() {
-            StringBuilder pattern = new StringBuilder();
-            pattern.append('0');
-            if (formatToken.getPrecision() > 0) {
-                pattern.append('.');
-                char[] zeros = new char[formatToken.getPrecision()];
-                Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
-                pattern.append(zeros);
-            }
-            pattern.append("E+00");
-            decimalFormat.applyPattern(pattern.toString());
-            String formattedString = decimalFormat.format(argument);
-            result.append(formattedString.replace('E', 'e'));
-
-            // if the flag is sharp and decimal separator is always given out.
-            if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
-                int indexOfE = result.indexOf("e");
-                result.insert(indexOfE, localeData.decimalSeparator);
-            }
+        if (conversionType == 'a' || conversionType == 'A') {
+            startIndex += 2;
         }
+        return padding(result, startIndex);
+    }
 
-        void transform_g() {
-            int precision = formatToken.getPrecision();
-            precision = (0 == precision ? 1 : precision);
+    private void transform_e(StringBuilder result) {
+        StringBuilder pattern = new StringBuilder();
+        pattern.append('0');
+        if (formatToken.getPrecision() > 0) {
+            pattern.append('.');
+            char[] zeros = new char[formatToken.getPrecision()];
+            Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
+            pattern.append(zeros);
+        }
+        pattern.append("E+00");
+        DecimalFormat decimalFormat = (DecimalFormat) getNumberFormat();
+        decimalFormat.applyPattern(pattern.toString());
+        String formattedString = decimalFormat.format(arg);
+        result.append(formattedString.replace('E', 'e'));
+
+        // if the flag is sharp and decimal separator is always given out.
+        if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
+            int indexOfE = result.indexOf("e");
+            result.insert(indexOfE, localeData.decimalSeparator);
+        }
+    }
+
+    private void transform_g(StringBuilder result) {
+        int precision = formatToken.getPrecision();
+        precision = (0 == precision ? 1 : precision);
+        formatToken.setPrecision(precision);
+
+        double d = ((Number) arg).doubleValue();
+        if (d == 0.0) {
+            precision--;
             formatToken.setPrecision(precision);
+            transform_f(result);
+            return;
+        }
 
-            if (0.0 == ((Number) argument).doubleValue()) {
-                precision--;
+        boolean requireScientificRepresentation = true;
+        d = Math.abs(d);
+        if (Double.isInfinite(d)) {
+            precision = formatToken.getPrecision();
+            precision--;
+            formatToken.setPrecision(precision);
+            transform_e(result);
+            return;
+        }
+        BigDecimal b = new BigDecimal(d, new MathContext(precision));
+        d = b.doubleValue();
+        long l = b.longValue();
+
+        if (d >= 1 && d < Math.pow(10, precision)) {
+            if (l < Math.pow(10, precision)) {
+                requireScientificRepresentation = false;
+                precision -= String.valueOf(l).length();
+                precision = precision < 0 ? 0 : precision;
+                l = Math.round(d * Math.pow(10, precision + 1));
+                if (String.valueOf(l).length() <= formatToken.getPrecision()) {
+                    precision++;
+                }
                 formatToken.setPrecision(precision);
-                transform_f();
-                return;
             }
-
-            boolean requireScientificRepresentation = true;
-            double d = ((Number) argument).doubleValue();
-            d = Math.abs(d);
-            if (Double.isInfinite(d)) {
-                precision = formatToken.getPrecision();
-                precision--;
-                formatToken.setPrecision(precision);
-                transform_e();
-                return;
-            }
-            BigDecimal b = new BigDecimal(d, new MathContext(precision));
-            d = b.doubleValue();
-            long l = b.longValue();
-
-            if (d >= 1 && d < Math.pow(10, precision)) {
-                if (l < Math.pow(10, precision)) {
-                    requireScientificRepresentation = false;
-                    precision -= String.valueOf(l).length();
-                    precision = precision < 0 ? 0 : precision;
-                    l = Math.round(d * Math.pow(10, precision + 1));
-                    if (String.valueOf(l).length() <= formatToken
-                            .getPrecision()) {
-                        precision++;
-                    }
+        } else {
+            l = b.movePointRight(4).longValue();
+            if (d >= Math.pow(10, -4) && d < 1) {
+                requireScientificRepresentation = false;
+                precision += 4 - String.valueOf(l).length();
+                l = b.movePointRight(precision + 1).longValue();
+                if (String.valueOf(l).length() <= formatToken.getPrecision()) {
+                    precision++;
+                }
+                l = b.movePointRight(precision).longValue();
+                if (l >= Math.pow(10, precision - 4)) {
                     formatToken.setPrecision(precision);
                 }
+            }
+        }
+        if (requireScientificRepresentation) {
+            precision = formatToken.getPrecision();
+            precision--;
+            formatToken.setPrecision(precision);
+            transform_e(result);
+        } else {
+            transform_f(result);
+        }
+    }
 
-            } else {
-                l = b.movePointRight(4).longValue();
-                if (d >= Math.pow(10, -4) && d < 1) {
-                    requireScientificRepresentation = false;
-                    precision += 4 - String.valueOf(l).length();
-                    l = b.movePointRight(precision + 1).longValue();
-                    if (String.valueOf(l).length() <= formatToken
-                            .getPrecision()) {
-                        precision++;
-                    }
-                    l = b.movePointRight(precision).longValue();
-                    if (l >= Math.pow(10, precision - 4)) {
-                        formatToken.setPrecision(precision);
-                    }
+    private void transform_f(StringBuilder result) {
+        // TODO: store a default DecimalFormat we can clone?
+        String pattern = "0.000000";
+        DecimalFormat decimalFormat = (DecimalFormat) getNumberFormat();
+        if (formatToken.flagComma || formatToken.getPrecision() != 6) {
+            StringBuilder patternBuilder = new StringBuilder();
+            if (formatToken.flagComma) {
+                patternBuilder.append(',');
+                int groupingSize = decimalFormat.getGroupingSize();
+                if (groupingSize > 1) {
+                    char[] sharps = new char[groupingSize - 1];
+                    Arrays.fill(sharps, '#');
+                    patternBuilder.append(sharps);
                 }
             }
-            if (requireScientificRepresentation) {
-                precision = formatToken.getPrecision();
-                precision--;
-                formatToken.setPrecision(precision);
-                transform_e();
-            } else {
-                transform_f();
+            patternBuilder.append('0');
+            if (formatToken.getPrecision() > 0) {
+                patternBuilder.append('.');
+                char[] zeros = new char[formatToken.getPrecision()];
+                Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
+                patternBuilder.append(zeros);
             }
+            pattern = patternBuilder.toString();
+        }
+        // TODO: if DecimalFormat.toPattern was cheap, we could make this cheap (preferably *in* DecimalFormat).
+        decimalFormat.applyPattern(pattern);
+        result.append(decimalFormat.format(arg));
+        // if the flag is sharp and decimal separator is always given out.
+        if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
+            result.append(localeData.decimalSeparator);
+        }
+    }
+
+    private void transform_a(StringBuilder result) {
+        if (arg instanceof Float) {
+            result.append(Float.toHexString(((Float) arg).floatValue()));
+        } else if (arg instanceof Double) {
+            result.append(Double.toHexString(((Double) arg).doubleValue()));
+        } else {
+            throw badArgumentType();
         }
 
-        void transform_f() {
-            // TODO: store a default DecimalFormat we can clone?
-            String pattern = "0.000000";
-            if (formatToken.flagComma || formatToken.getPrecision() != 6) {
-                StringBuilder patternBuilder = new StringBuilder();
-                if (formatToken.flagComma) {
-                    patternBuilder.append(',');
-                    int groupingSize = decimalFormat.getGroupingSize();
-                    if (groupingSize > 1) {
-                        char[] sharps = new char[groupingSize - 1];
-                        Arrays.fill(sharps, '#');
-                        patternBuilder.append(sharps);
-                    }
-                }
-                patternBuilder.append('0');
-                if (formatToken.getPrecision() > 0) {
-                    patternBuilder.append('.');
-                    char[] zeros = new char[formatToken.getPrecision()];
-                    Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
-                    patternBuilder.append(zeros);
-                }
-                pattern = patternBuilder.toString();
-            }
-            // TODO: if DecimalFormat.toPattern was cheap, we could make this cheap (preferably *in* DecimalFormat).
-            decimalFormat.applyPattern(pattern);
-            result.append(decimalFormat.format(argument));
-            // if the flag is sharp and decimal separator is always given out.
-            if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
-                result.append(localeData.decimalSeparator);
-            }
+        if (!formatToken.isPrecisionSet()) {
+            return;
         }
 
-        void transform_a() {
-            if (argument instanceof Float) {
-                Float F = (Float) argument;
-                result.append(Float.toHexString(F.floatValue()));
-            } else if (argument instanceof Double) {
-                Double D = (Double) argument;
-                result.append(Double.toHexString(D.doubleValue()));
-            } else {
-                throw badArgumentType();
-            }
+        int precision = formatToken.getPrecision();
+        precision = (0 == precision ? 1 : precision);
+        int indexOfFirstFractionalDigit = result.indexOf(".") + 1;
+        int indexOfP = result.indexOf("p");
+        int fractionalLength = indexOfP - indexOfFirstFractionalDigit;
 
-            if (!formatToken.isPrecisionSet()) {
-                return;
-            }
-
-            int precision = formatToken.getPrecision();
-            precision = (0 == precision ? 1 : precision);
-            int indexOfFirstFractionalDigit = result.indexOf(".") + 1;
-            int indexOfP = result.indexOf("p");
-            int fractionalLength = indexOfP - indexOfFirstFractionalDigit;
-
-            if (fractionalLength == precision) {
-                return;
-            }
-
-            if (fractionalLength < precision) {
-                char zeros[] = new char[precision - fractionalLength];
-                Arrays.fill(zeros, '0'); // %a shouldn't be localized.
-                result.insert(indexOfP, zeros);
-                return;
-            }
-            result.delete(indexOfFirstFractionalDigit + precision, indexOfP);
+        if (fractionalLength == precision) {
+            return;
         }
 
-        private IllegalFormatConversionException badArgumentType() {
-            throw new IllegalFormatConversionException(formatToken.getConversionType(),
-                    argument.getClass());
+        if (fractionalLength < precision) {
+            char zeros[] = new char[precision - fractionalLength];
+            Arrays.fill(zeros, '0'); // %a shouldn't be localized.
+            result.insert(indexOfP, zeros);
+            return;
         }
+        result.delete(indexOfFirstFractionalDigit + precision, indexOfP);
     }
 
     private static class FormatSpecifierParser {
